Linux设备驱动模型探究--4(driver)
来源:互联网 发布:刷贴软件 编辑:程序博客网 时间:2024/06/03 17:02
四. 关于驱动(driver)--driver.c
/*数据结构*/
struct device_driver {
const char *name; /*驱动名字*/
struct bus_type *bus; /*驱动所属总线*/
struct module *owner; /*驱动所在内核模块*/
int (*probe) (struct device *dev); /*当总线bus将该驱动和对应得设备相互绑定的时候,
/*内核会首先调用bus的probe函数,如果没有就会调用该probe函数,在driver_register中调用*/
int (*remove) (struct device *dev); /*原理和probe一样, 但是在driver_unregister中调用*/
struct driver_private *p;
};
驱动上主要的操作:
/*在bus的drivers_kset集合查找驱动,name-查找名称,bus-哪个总线*/-->在bus上查找名称为name的驱动,成功返回driver
struct device_driver *driver_find(const char *name, struct bus_type *bus)
{
struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);
struct driver_private *priv;
if (k) {
priv = to_driver(k);
return priv->driver;
}
return NULL;
}
/**
* driver_register - register driver with bus
* @drv: driver to register
*
* We pass off most of the work to the bus_add_driver() call,
* since most of the things we have to do deal with the bus
* structures.
*/
int driver_register(struct device_driver *drv)
{
int ret;
struct device_driver *other;
if ((drv->bus->probe && drv->probe) ||
(drv->bus->remove && drv->remove) ||
(drv->bus->shutdown && drv->shutdown))
printk(KERN_WARNING "Driver '%s' needs updating - please use "
"bus_type methods\n", drv->name);
other = driver_find(drv->name, drv->bus); /*先判断驱动是否注册了*/
if (other) {
put_driver(other);
printk(KERN_ERR "Error: Driver '%s' is already registered, "
"aborting...\n", drv->name);
return -EBUSY;
}
ret = bus_add_driver(drv); /*往bus上注册(添加)驱动*/
if (ret)
return ret;
ret = driver_add_groups(drv, drv->groups);
if (ret)
bus_remove_driver(drv);
return ret;
}
***********************接下分析bus_add_driver()****************************
/**
* bus_add_driver - Add a driver to the bus.
* @drv: driver.
*/
int bus_add_driver(struct device_driver *drv)
{
struct bus_type *bus;
struct driver_private *priv;
int error = 0;
bus = bus_get(drv->bus);
if (!bus)
return -EINVAL;
/*初始化驱动私有数据 p*/
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
error = -ENOMEM;
goto out_put_bus;
}
klist_init(&priv->klist_devices, NULL, NULL);
priv->driver = drv;
drv->p = priv;
/*建立priv->kobj和bus->p->drivers_kset(扮演parent)层次关系,*/
priv->kobj.kset = bus->p->drivers_kset;
error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
"%s", drv->name);
if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv); //匹配设备
if (error)
goto out_unregister;
}
klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);//向bus驱动链表中添加驱动
module_add_driver(drv->owner, drv); //向模块中添加驱动
error = driver_create_file(drv, &driver_attr_uevent); //创建uevent属性文件
error = driver_add_attrs(bus, drv); //创先驱动属性文件
/* * kobject_uevent - notify userspace by sending an uevent
*
* @action: action that is happening
* @kobj: struct kobject that the action is happening to
*
*/
kobject_uevent(&priv->kobj, KOBJ_ADD);
return 0;
}
/*参考资料:
深入Linux设备驱动程序内核机制。 陈雪松著
Linux设备驱动开发详解--基于最新的Linux4.0内核。 宋宝华著
*/
- Linux设备驱动模型探究--4(driver)
- Linux设备驱动模型-Driver
- Linux设备驱动模型探究--1(kobject)
- Linux设备驱动模型探究--2(bus)
- Linux设备驱动模型探究--3(device)
- linux设备驱动模型七之driver
- linux设备驱动模型之driver
- linux设备驱动模型之device-driver
- LINUX设备驱动之设备模型三--device&driver&bus
- LINUX设备驱动之设备模型四--device&driver&bus
- LINUX设备驱动之设备模型五--device&driver&bus
- 设备驱动模型之driver
- 设备驱动模型之driver
- linux设备驱动模型一上层容器之driver
- Linux内核部件分析--设备驱动模型之driver
- Linux内核部件分析--设备驱动模型之device-driver
- Linux内核部件分析<7> 设备驱动模型之driver
- linux内核组件分析之---设备驱动模型之driver
- RoundTrip (Tarjan)
- 清华大学2003年机试-查找学生信息-1069
- CF C. Sorting by Subsequences AIM Tech Round 4 (Div. 2)(简单模拟)
- Android 开发之屏幕适配 dimens
- HTML中如何自动切换页面背景图片
- Linux设备驱动模型探究--4(driver)
- spring-data-jpa只查询实体部分字段
- Java Web开发
- d3.js+react实现算法可视化:排序篇
- LLocation使用文档
- 八大排序算法——冒泡算法
- linux装mysql问题
- openstack常用命令
- 推荐一些相见恨晚的 Python 库 「一」