> Linux教程 > linux基础 >

linux文件系统的系统分析--(十四)sysfs和设备模型--Driver

 看完了device看driver,给出device_driver的结构体:

 

[cpp] view plain copy
 
  1. struct device_driver {  
  2.     const char      *name;  
  3.     struct bus_type     *bus;  
  4.   
  5.     struct module       *owner;  
  6.     const char      *mod_name;  /* used for built-in modules */  
  7.   
  8.     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */  
  9.   
  10.     int (*probe) (struct device *dev);  
  11.     int (*remove) (struct device *dev);  
  12.     void (*shutdown) (struct device *dev);  
  13.     int (*suspend) (struct device *dev, pm_message_t state);  
  14.     int (*resume) (struct device *dev);  
  15.     const struct attribute_group **groups;  
  16.   
  17.     const struct dev_pm_ops *pm;  
  18.   
  19.     struct driver_private *p;  
  20. };  

[cpp] view plain copy
 
  1. struct driver_private {  
  2.     struct kobject kobj;  
  3.     struct klist klist_devices;  
  4.     struct klist_node knode_bus;  
  5.     struct module_kobject *mkobj;  
  6.     struct device_driver *driver;  
  7. };  
      驱动的注册:

 

int driver_register(struct device_driver *drv)

主体部分分为三块看:

1、other = driver_find(drv->name, drv->bus);

      driver_find函数是利用驱动模型的基石kobject和kset结构体的双向循环链表,根据name查找。这里的kset是bus->p->drivers_kset,也

      就是bus上已经挂着的驱动的集合。如果找到了,就有问题了:已经注册了该驱动,不能再注册了,kernel会打印error并返回EBUSY。

      如果没找到,就到了第二步

2、bus_add_driver(drv);

       这个过程和bus_add_device比较类似

       2.1、建立driver_private和device_driver你中有我 我中有你的亲密关系

       2.2、priv->kobj.kset = bus->p->drivers_kset;   意味了/bus/xxbus/driver下面就是具体driver的目录

       2.3、

if (drv->bus->p->drivers_autoprobe) {
error = driver_attach(drv);
if (error)
goto out_unregister;
}

        调用driver_attach-->bus_for_each_dev(drv->bus, NULL, drv, __driver_attach)

        对于bus的klist_devices链表上挂着的所有device,都来和我们的driver进行匹配,进行匹配的函数是__driver_attach

        __driver_attach首先调用driver_match_device,也就是总线级别的match函数进行匹配

        如果没匹配上,就调用driver_probe_device

        这里的函数都是与device中用到的一样

        2.4、klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);

                将driver加入bus的klist_drivers链表中

        2.5、driver_create_file(drv, &driver_attr_uevent);

                创建uevent属性文件

        2.6、添加driver指向的bus的驱动属性文件bus->drv_attrs

        2.7、如果需要的话,添加bind和unbind属性文件

        2.8、kobject_uevent(&priv->kobj, KOBJ_ADD);  发送uevent

 

driver的注册就是这样了,没什么好说的了。。。

(责任编辑:IT)