四. 关于驱动(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内核。 宋宝华著
*/