linux设备驱动程序第3版,linux 3.2 实现 LINUX设备驱动程序(第3版) 中的 lddbus

PC操作系统:ubuntu 11.10

使用的开发板:am335x_evm

开发板使用的操作系统:linux 3.2

在新版本的内核中struct device 已经没有bus_id成员,取而代之的是通过dev_name和dev_set_name对设备的名字进行操作。

dev_name和dev_set_name在2.6.35.6内核中的源代码如下:

static inline const char *dev_name(const struct device *dev)

{

/* Use the init name until the kobject becomes available */

if (dev->init_name)

return dev->init_name;

return kobject_name(&dev->kobj);

}

extern int dev_set_name(struct device *dev, const char *name, ...)

__attribute__((format(printf, 2, 3)));

kernel 邮件列表

中讲了:struct device - replace bus_id with dev_name(),以后只要使用dev->bus_id的时候,改成dev_name(dev)就可以了。

lddbus.h 文件不需要修改;

lddbus.c 文件有所修改。

#include #include #include #include #include #include "ldd_bus.h"

MODULE_LICENSE("Dual BSD/GPL");

MODULE_AUTHOR("SM");

static    char *version = "$revision : 2.0 $";

//respond to hotplug events

/*

struct kobj_uevent_env {

char *envp[UEVENT_NUM_ENVP];

int envp_idx;

char buf[UEVENT_BUFFER_SIZE];

int buflen;

};

*/

static    int        ldd_hotplug(struct device * dev,struct kobj_uevent_env *env)

{

env->envp[0]    = env->buf;

if(snprintf(env->buf,env->buflen,"LDDBUS_VERSION=%s",version) >= env->buflen)

return -ENOMEM;

env->envp[1]    = NULL;

return 0;

}

//match ldd device to drivers

static    int        ldd_match(struct device *dev,struct device_driver *driver)

{

return !strncmp(dev->init_name,driver->name,strlen(driver->name));

}

//ldd bus device

static    void    ldd_bus_release(struct device *dev)

{

printk(KERN_NOTICE"lddbus release \n");

}

struct device ldd_bus =

{

.init_name    = "lld0",

.release    = ldd_bus_release,

};

//the bus type

struct bus_type ldd_bus_type =

{

.name        = "ldd",

.match        = ldd_match,

.uevent        = ldd_hotplug,

};

//export a simple attribute

static    ssize_t    show_bus_version(struct bus_type *bus,char *buf)

{

return snprintf(buf,PAGE_SIZE,"%s\n",version);

}

static    BUS_ATTR(version,S_IRUGO,show_bus_version,NULL);

//ldd devices

static    void    ldd_dev_release(struct device *dev)

{

printk(KERN_NOTICE"ldddev release \n");

}

int        register_ldd_device(struct ldd_device *ldddev)

{

ldddev->dev.bus        = &ldd_bus_type;

ldddev->dev.parent    = &ldd_bus;

ldddev->dev.release    = ldd_dev_release;

//struct device 中没有 bus_id 成员,应用过 init_name 替代

//    strncpy(ldddev->dev.bus_id,ldddev->name,BUS_ID_SIZE);

dev_set_name(&ldddev->dev,ldddev->name);

return device_register(&ldddev->dev);

}

EXPORT_SYMBOL(register_ldd_device);

void    unregister_ldd_device(struct ldd_device * ldddev)

{

device_unregister(&ldddev->dev);

}

EXPORT_SYMBOL(unregister_ldd_device);

static    ssize_t    show_version(struct device_driver *driver,char *buf)

{

struct    ldd_driver *ldriver    = to_ldd_driver(driver);

sprintf(buf,"%s\n",ldriver->version);

return strlen(buf);

}

int     register_ldd_driver(struct ldd_driver *driver)

{

int        ret;

driver->driver.bus    = &ldd_bus_type;

ret    = driver_register(&driver->driver);

if(ret)

return ret;

/*

struct attribute {

const char        *name;

mode_t            mode;

#ifdef CONFIG_DEBUG_LOCK_ALLOC

struct lock_class_key    *key;

struct lock_class_key    skey;

#endif

};

*/

driver->version_attr.attr.name        = "version";

//struct attribute 中没有 owner 成员

//    driver->version_attr.attr.owner        = driver->module;

driver->version_attr.attr.mode        = S_IRUGO;

driver->version_attr.show            = show_version;

return driver_create_file(&driver->driver,&driver->version_attr);

}

EXPORT_SYMBOL(register_ldd_driver);

void    unregister_ldd_driver(struct ldd_driver * driver)

{

driver_unregister(&driver->driver);

}

EXPORT_SYMBOL(unregister_ldd_driver);

static    int        __init    ldd_bus_init(void)

{

int        ret;

ret        = bus_register(&ldd_bus_type);

if(ret)

return ret;

if(bus_create_file(&ldd_bus_type,&bus_attr_version))

printk(KERN_NOTICE"Unable to create version attribute\n");

ret    = device_register(&ldd_bus);

if(ret)

printk(KERN_NOTICE"Unable  to register ldd0\n");

printk(KERN_NOTICE"ldd bus init \n");

return ret;

}

static    void            ldd_bus_exit(void)

{

device_unregister(&ldd_bus);

bus_unregister(&ldd_bus_type);

printk(KERN_NOTICE"ldd bus exit \n");

}

module_init(ldd_bus_init);

module_exit(ldd_bus_exit);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值