http://www.csdn.net/ http://www.arm.com/zh/ https://www.kernel.org/ http://www.linuxpk.com/ http://www.51develop.net/ http://linux.chinaitlab.com/ http://www.embeddedlinux.org.cn http://bbs.pediy.com/
分类: 嵌入式
2013-01-06 09:43:44
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);