zoukankan      html  css  js  c++  java
  • Linux kernel驱动相关抽象概念及其实现 之“bus,device,driver”

    bus,device,driver三个很重要的概念贯穿Linux内核驱动架构,特转载一篇博文:

    (转载自http://blog.csdn.net/gdt_a20/article/details/6425894

    内核的开发者将总线,设备,驱动这三者用软件思想抽象了出来,巧妙的建立了其间的关系,使之更形象化。结合前面所学的知识,总的来说其三者间的关系为bus有两条链表,分别用于挂接设备和驱动,指定了其自身bus的device或者driver最后都会分别连接到对应bus的这两条链表上,而总线又有其始端,为bus_kset,一个driver可以对应于几个设备,因此driver同样有其设备链表,用于挂接可以操作的设备,其自身也有bus挂接点,用于将自身挂接到对应bus(每个driver只属于一条总线),而对于device,一个设备只属于一条总线,只能有一个driver与其对应,因此对于device,都是单一的,一个driver挂接点,一个bus挂接点,device与bus相同的是都有始端,device为devices_kset,因此device的注册同时会出现在对应的bus目录和device总目录下。好了,下面就以源码为例分别分析一下bus,device,driver的注册过程。

    一、bus的注册

          bus的注册比较简单,首先来看一下bus的结构:

     1 struct bus_type {  
     2     const char      *name;                //名字  
     3     struct bus_attribute    *bus_attrs;           //bus属性集  
     4     struct device_attribute *dev_attrs;           //device属性集  
     5     struct driver_attribute *drv_attrs;           //driver属性集  
     6     int (*match)(struct device *dev, struct device_driver *drv);  
     7     int (*uevent)(struct device *dev, struct kobj_uevent_env *env);  
     8     int (*probe)(struct device *dev);  
     9     int (*remove)(struct device *dev);  
    10     void (*shutdown)(struct device *dev);  
    11     int (*suspend)(struct device *dev, pm_message_t state);  
    12     int (*resume)(struct device *dev);  
    13     const struct dev_pm_ops *pm;  
    14     struct bus_type_private *p;                   //bus的私有成员  
    15 };  
    16 //其中重点看一下私有成员结构体:  
    17 struct bus_type_private {  
    18     struct kset subsys;                           //bus内嵌的kset,代表其自身  
    19     struct kset *drivers_kset;                      
    20     struct kset *devices_kset;  
    21     struct klist klist_devices;                   //包含devices链表及其操作函数  
    22     struct klist klist_drivers;                   //driver链表及其操作函数  
    23     struct blocking_notifier_head bus_notifier;  
    24     unsigned int drivers_autoprobe:1;              //匹配成功自动初始化标志  
    25     struct bus_type *bus;                            
    26 };  

     无论是bus,driver,还是device其本身特征都放在私有成员里,其注册时,都会申请并填充这个结构体,下面具体分析一下bus的注册流程,从bus_register开始:

     1 int bus_register(struct bus_type *bus)  
     2 {  
     3     int retval;  
     4     struct bus_type_private *priv;  
     5     priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL);    //进入时bus_type->bus_type_private为NULL  
     6     if (!priv)                                                      //该函数主要是对其的设置  
     7         return -ENOMEM;  
     8     priv->bus = bus;                                                //私有成员的bus回指该bus  
     9     bus->p = priv;                                                  //初始化bus->p,即其私有属性  
    10     BLOCKING_INIT_NOTIFIER_HEAD(&priv->bus_notifier);  
    11     retval = kobject_set_name(&priv->subsys.kobj, "%s", bus->name);  //设置该bus的名字,bus是kset的封装  
    12     if (retval)  
    13         goto out;  
    14                                                       //bus_kset即为所有bus的总起始端点  
    15                                                       //围绕bus内嵌的kset初始化,和kset的初始化时围绕  
    16     priv->subsys.kobj.kset = bus_kset;                //kobj相似,没有parent时,就会用kset的kobj,此处即是  
    17     priv->subsys.kobj.ktype = &bus_ktype;                    //属性操作级别统一为bus_ktype  
    18     priv->drivers_autoprobe = 1;                                    //设置该标志,当有driver注册时,会自动匹配devices  
    19                                                                     //上的设备并用probe初始化,  
    20                                                                     //当有device注册时也同样找到  driver并会初始化  
    21     retval = kset_register(&priv->subsys);                          //注册kset,创建目录结构,以及层次关系  
    22     if (retval)  
    23         goto out;  
    24     retval = bus_create_file(bus, &bus_attr_uevent);                //当前bus目录下生成bus_attr_uevent属性文件  
    25     if (retval)  
    26         goto bus_uevent_fail;  
    27     priv->devices_kset = kset_create_and_add("devices", NULL,       //初始化bus目录下的devices目录,里面级联了该bus下设备,  
    28                          &priv->subsys.kobj);                    //仍然以kset为原型  
    29     if (!priv->devices_kset) {  
    30         retval = -ENOMEM;  
    31         goto bus_devices_fail;  
    32     }  
    33     priv->drivers_kset = kset_create_and_add("drivers", NULL,       //初始化bus目录下的drivers目录,里面级联了该bus下设备的driver  
    34                          &priv->subsys.kobj);  
    35     if (!priv->drivers_kset) {  
    36         retval = -ENOMEM;  
    37         goto bus_drivers_fail;  
    38     }  
    39     klist_init(&priv->klist_devices, klist_devices_get, klist_devices_put);  //初始化klist_devices里的操作函数成员  
    40     klist_init(&priv->klist_drivers, NULL, NULL);                            //klist_drivers里的操作函数置空  
    41     retval = add_probe_files(bus);                                           //增加bus_attr_drivers_probe和bus_attr_drivers_autoprobe  
    42     if (retval)                                                              //属性文件  
    43         goto bus_probe_files_fail;  
    44     retval = bus_add_attrs(bus);                                             //增加默认的属性文件  
    45     if (retval)  
    46         goto bus_attrs_fail;  
    47     pr_debug("bus: '%s': registered/n", bus->name);  
    48     return 0;  
    49 bus_attrs_fail:                                                               //以下为错误处理  
    50     remove_probe_files(bus);  
    51 bus_probe_files_fail:  
    52     kset_unregister(bus->p->drivers_kset);  
    53 bus_drivers_fail:  
    54     kset_unregister(bus->p->devices_kset);  
    55 bus_devices_fail:  
    56     bus_remove_file(bus, &bus_attr_uevent);  
    57 bus_uevent_fail:  
    58     kset_unregister(&bus->p->subsys);  
    59 out:  
    60     kfree(bus->p);  
    61     bus->p = NULL;  
    62     return retval;  
    63 }  

    由此可见,bus又是kset的封装,bus_register主要完成了其私有成员bus_type_private的初始化,并初始化了其下的两个目录devices和drivers,及其属性文件,bus有个自己的根目录也就是bus有个起始端点,是bus_kset,经过此番的注册,bus目录下将会出现我们注册的bus,并且其下会有device和driver两个子目录,代表它下面的driver和device链表。

    二、driver的注册

      下面看一下driver是怎么和bus关联起来的,首先看下driver的结构:

     1 struct device_driver {  
     2     const char      *name;            //名字  
     3     struct bus_type     *bus;        //其所在的bus  
     4     struct module       *owner;  
     5     const char      *mod_name;  /* used for built-in modules */  
     6     bool suppress_bind_attrs;   /* disables bind/unbind via sysfs */  
     7 #if defined(CONFIG_OF)  
     8     const struct of_device_id   *of_match_table;  
     9 #endif  
    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     const struct dev_pm_ops *pm;  
    17     struct driver_private *p;                 //私有成员,表示driver  
    18 };  
    19 //重点看下driver的私有成员  
    20 struct driver_private {  
    21     struct kobject kobj;                      //代表driver自身  
    22     struct klist klist_devices;               //可以操控的设备链表  
    23     struct klist_node knode_bus;              //挂接到bus的节点  
    24     struct module_kobject *mkobj;             //模块相关  
    25     struct device_driver *driver;             //回指该driver  
    26 };  

      如同bus一样,重点的仍是可以代表其自身的私有属性,下面具体看一下driver的注册过程,从driver_register开始:

      1 int driver_register(struct device_driver *drv)  
      2 {  
      3     int ret;  
      4     struct device_driver *other;  
      5     BUG_ON(!drv->bus->p);  
      6     if ((drv->bus->probe && drv->probe) ||           //driver和bus的同名操作函数如果同时存在,会出现警告  
      7         (drv->bus->remove && drv->remove) ||         //并且会优先选用bus的  
      8         (drv->bus->shutdown && drv->shutdown))  
      9         printk(KERN_WARNING "Driver '%s' needs updating - please use "  
     10             "bus_type methods/n", drv->name);  
     11     other = driver_find(drv->name, drv->bus);        //进入bus的driver链表,确认该driver是否已经注册  
     12     if (other) {  
     13         put_driver(other);                            //找到了再减少引用计数,并且报错退出  
     14         printk(KERN_ERR "Error: Driver '%s' is already registered, "  
     15             "aborting.../n", drv->name);  
     16         return -EBUSY;  
     17     }  
     18     ret = bus_add_driver(drv);                       //如果没有注册,那么把该driver加入所在bus  
     19     if (ret)  
     20         return ret;  
     21     ret = driver_add_groups(drv, drv->groups);  
     22     if (ret)  
     23         bus_remove_driver(drv);  
     24     return ret;  
     25 }  
     26 /**************************************************** 
     27 × 跟踪一下driver_find(drv->name, drv->bus) 
     28 ****************************************************/  
     29 struct device_driver *driver_find(const char *name, struct bus_type *bus)  
     30 {  
     31     struct kobject *k = kset_find_obj(bus->p->drivers_kset, name);  //bus->p->drivers_kset代表bus下  
     32     struct driver_private *priv;                                    //的driver目录,此处会遍历bus的      
     33                                                                     //driver链表,通过driver内嵌的  
     34     if (k) {                                                        //kobj名字比较  
     35         priv = to_driver(k);  
     36         return priv->driver;                                 //如果找到同名的kobj那么返回该driver  
     37     }  
     38     return NULL;  
     39 }  
     40 //看一下kset_find_obj吧:  
     41 struct kobject *kset_find_obj(struct kset *kset, const char *name)  
     42 {  
     43     struct kobject *k;  
     44     struct kobject *ret = NULL;  
     45     spin_lock(&kset->list_lock);  
     46     list_for_each_entry(k, &kset->list, entry) {                   //遍历bus下的driver链表,如果  
     47         if (kobject_name(k) && !strcmp(kobject_name(k), name)) {   //找到那么返回找到的kobj,并且把  
     48             ret = kobject_get(k);                                  //该driver的kobj引用计数+1  
     49             break;  
     50         }  
     51     }  
     52     spin_unlock(&kset->list_lock);  
     53     return ret;  
     54 }  
     55 /************************************************ 
     56 × 再来跟踪一下driver_register里面的另外一个函数 
     57 × bus_add_driver(drv) 
     58 ************************************************/  
     59 int bus_add_driver(struct device_driver *drv)   
     60 {  
     61     struct bus_type *bus;  
     62     struct driver_private *priv;  
     63     int error = 0;  
     64     bus = bus_get(drv->bus);                                        //取得其所在bus的指针  
     65     if (!bus)  
     66         return -EINVAL;  
     67     pr_debug("bus: '%s': add driver %s/n", bus->name, drv->name);   //开始初始化这个driver的私有成员,  
     68                                                                     //和bus类似  
     69     priv = kzalloc(sizeof(*priv), GFP_KERNEL);  
     70     if (!priv) {  
     71         error = -ENOMEM;  
     72         goto out_put_bus;  
     73     }  
     74     klist_init(&priv->klist_devices, NULL, NULL);                   //设备操作函数清空,设备链表初始化  
     75     priv->driver = drv;                                               
     76     drv->p = priv;  
     77     priv->kobj.kset = bus->p->drivers_kset;                          //kset指定到bus下面  
     78     error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,   //建立层次结构和属性文件  
     79                      "%s", drv->name);  
     80     if (error)  
     81         goto out_unregister;  
     82     if (drv->bus->p->drivers_autoprobe) {                            //bus的自动匹配如果设置为真,  
     83         error = driver_attach(drv);                                  //那么到bus的devices上去匹配设备  
     84         if (error)  
     85             goto out_unregister;  
     86     }  
     87     klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);        //把driver挂接到bus的driver链表  
     88     module_add_driver(drv->owner, drv);  
     89     error = driver_create_file(drv, &driver_attr_uevent);            //以下添加该driver相关属性文件  
     90     if (error) {  
     91         printk(KERN_ERR "%s: uevent attr (%s) failed/n",  
     92             __func__, drv->name);  
     93     }  
     94     error = driver_add_attrs(bus, drv);  
     95     if (error) {  
     96         /* How the hell do we get out of this pickle? Give up */  
     97         printk(KERN_ERR "%s: driver_add_attrs(%s) failed/n",  
     98             __func__, drv->name);  
     99     }  
    100     if (!drv->suppress_bind_attrs) {  
    101         error = add_bind_files(drv);  
    102         if (error) {  
    103             /* Ditto */  
    104             printk(KERN_ERR "%s: add_bind_files(%s) failed/n",  
    105                 __func__, drv->name);  
    106         }  
    107     }  
    108     kobject_uevent(&priv->kobj, KOBJ_ADD);  
    109     return 0;  
    110 out_unregister:  
    111     kobject_put(&priv->kobj);  
    112     kfree(drv->p);  
    113     drv->p = NULL;  
    114 out_put_bus:  
    115     bus_put(bus);  
    116     return error;  
    117 }  
    118 /**************************************************************** 
    119 × 接下来就剩下最终要的匹配函数driver_attach(drv)了,我们来看一下: 
    120 ****************************************************************/  
    121 int driver_attach(struct device_driver *drv)                            //遍历bus的设备链表找到  
    122 {                                                                       //合适的设备就调用__driver_attach,  
    123     return bus_for_each_dev(drv->bus, NULL, drv, __driver_attach);      //NULL表示从头开始遍历  
    124 }    
    125 //============  
    126 int bus_for_each_dev(struct bus_type *bus, struct device *start,  
    127              void *data, int (*fn)(struct device *, void *))  
    128 {  
    129     struct klist_iter i;  
    130     struct device *dev;  
    131     int error = 0;  
    132     if (!bus)  
    133         return -EINVAL;  
    134     klist_iter_init_node(&bus->p->klist_devices, &i,              //进入bus的devices链表  
    135                  (start ? &start->p->knode_bus : NULL));  
    136     while ((dev = next_device(&i)) && !error)                     //设备存在则调用fn即__driver_attach  
    137         error = fn(dev, data);                                    //进行匹配  
    138     klist_iter_exit(&i);  
    139     return error;  
    140 }   
    141 /********************************************* 
    142 × 接着看一下__driver_attach这个函数 
    143 *********************************************/  
    144 static int __driver_attach(struct device *dev, void *data)  
    145 {  
    146     struct device_driver *drv = data;  
    147     if (!driver_match_device(drv, dev))                //进行匹配  
    148         return 0;  
    149     if (dev->parent) /* Needed for USB */  
    150         device_lock(dev->parent);  
    151     device_lock(dev);  
    152     if (!dev->driver)                               //如果设备没有指定driver  
    153         driver_probe_device(drv, dev);              //那么需要初始化匹配到的这个设备  
    154     device_unlock(dev);  
    155     if (dev->parent)  
    156         device_unlock(dev->parent);  
    157     return 0;  
    158 }  
    159 /********************************************* 
    160 × 又遇到两个分支,囧,先看一下driver_match_device  
    161 *********************************************/   
    162 static inline int driver_match_device(struct device_driver *drv,      //bus的match存在就用bus的  
    163                                       struct device *dev)             //,否则就直接匹配成功...  
    164 {                                                                     //match通常实现为首先扫描  
    165     return drv->bus->match ? drv->bus->match(dev, drv) : 1;           //driver支持的id设备表,如果  
    166 }                                                                     //为NULL就用名字进行匹配  
    167 /************************************ 
    168 × 再来看一下driver_probe_device这个函数  
    169 ************************************/   
    170 int driver_probe_device(struct device_driver *drv, struct device *dev)  
    171 {  
    172     int ret = 0;  
    173     if (!device_is_registered(dev))                              //判断该设备是否已经注册  
    174         return -ENODEV;  
    175     pr_debug("bus: '%s': %s: matched device %s with driver %s/n",  
    176          drv->bus->name, __func__, dev_name(dev), drv->name);  
    177     pm_runtime_get_noresume(dev);  
    178     pm_runtime_barrier(dev);  
    179     ret = really_probe(dev, drv);                               //调用really_probe  
    180     pm_runtime_put_sync(dev);  
    181     return ret;  
    182 }  
    183 /************************************ 
    184 × 看一下device_is_registered 
    185 ************************************/  
    186 static inline int device_is_registered(struct device *dev)  
    187 {  
    188     return dev->kobj.state_in_sysfs;                           //在sysfs中表示已经注册  
    189 }  
    190 /************************************ 
    191 × 再看really_probe 
    192 ************************************/  
    193 static int really_probe(struct device *dev, struct device_driver *drv)  
    194 {  
    195     int ret = 0;  
    196     atomic_inc(&probe_count);  
    197     pr_debug("bus: '%s': %s: probing driver %s with device %s/n",  
    198          drv->bus->name, __func__, drv->name, dev_name(dev));  
    199     WARN_ON(!list_empty(&dev->devres_head));  
    200     dev->driver = drv;                                     //device的driver初始化成该driver  
    201     if (driver_sysfs_add(dev)) {                        
    202                  printk(KERN_ERR "%s: driver_sysfs_add(%s) failed/n",  
    203             __func__, dev_name(dev));  
    204         goto probe_failed;  
    205     }  
    206                                                          //利用probe初始化设备  
    207     if (dev->bus->probe) {                               //如果bus的probe存在就用bus的,  
    208         ret = dev->bus->probe(dev);                      //如果bus的不存在driver的存在  
    209         if (ret)                                         //再用driver的  
    210             goto probe_failed;  
    211     } else if (drv->probe) {  
    212         ret = drv->probe(dev);  
    213         if (ret)  
    214             goto probe_failed;  
    215     }  
    216     driver_bound(dev);                              //调用driver_bound进行绑定  
    217     ret = 1;  
    218     pr_debug("bus: '%s': %s: bound device %s to driver %s/n",  
    219          drv->bus->name, __func__, dev_name(dev), drv->name);  
    220     goto done;  
    221 probe_failed:  
    222     devres_release_all(dev);  
    223     driver_sysfs_remove(dev);  
    224     dev->driver = NULL;  
    225     if (ret != -ENODEV && ret != -ENXIO) {  
    226         /* driver matched but the probe failed */  
    227         printk(KERN_WARNING  
    228                "%s: probe of %s failed with error %d/n",  
    229                drv->name, dev_name(dev), ret);  
    230     }  
    231     /* 
    232      * Ignore errors returned by ->probe so that the next driver can try 
    233      * its luck. 
    234      */  
    235     ret = 0;  
    236 done:  
    237     atomic_dec(&probe_count);  
    238     wake_up(&probe_waitqueue);  
    239     return ret;  
    240 }  
    241 /********************************** 
    242 * 最后跟一下driver_bound(dev)这个函数 
    243 **********************************/  
    244 static void driver_bound(struct device *dev)  
    245 {  
    246     if (klist_node_attached(&dev->p->knode_driver)) {                   //判断是否已经绑定  
    247         printk(KERN_WARNING "%s: device %s already bound/n",  
    248             __func__, kobject_name(&dev->kobj));  
    249         return;  
    250     }  
    251     pr_debug("driver: '%s': %s: bound to device '%s'/n", dev_name(dev),  
    252          __func__, dev->driver->name);  
    253     klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);  //将设备添加  
    254                                                                             //到driver的链表  
    255     if (dev->bus)  
    256         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,  
    257                          BUS_NOTIFY_BOUND_DRIVER, dev);  
    258 }  
    259 //all end  

      总结一下,driver的注册,主要涉及将自身挂接到bus的driver链表,并将匹配到的设备加入自己的device链表,并且将匹配到的device的driver成员初始化为该driver,私有属性的driver节点也挂到driver的设备链表下,其中匹配函数是利用利用bus的match函数,该函数通常判断如果driver有id表,就查表匹配,如果没有就用driver和device名字匹配。当匹配成功后如果自动初始化标志允许则调用初始化函数probe,bus的probe优先级始终高于driver的,而一般bus的probe最终也是调用bus-->dev-->driver的probe。另外注意一点driver是没有总的起始端点的,driver不是可具体描述的事物。

    ===========================================================================================================

      由于篇幅比较长,device的分析单独放到以下:

    三、device的注册

       还是照例先看一下device的结构:

     1 struct device {  
     2     struct device       *parent;  
     3     struct device_private   *p;                                              //私有属性结构,重点  
     4     struct kobject kobj;  
     5     const char      *init_name; /* initial name of the device */  
     6     struct device_type  *type;  
     7     struct mutex        mutex;  /* mutex to synchronize calls to 
     8                      * its driver. 
     9                      */  
    10     struct bus_type *bus;       /* type of bus device is on */            //所在bus  
    11     struct device_driver *driver;   /* which driver has allocated this    //匹配的driver 
    12                        device */  
    13     void        *platform_data; /* Platform specific data, device 
    14                        core doesn't touch it */  
    15     struct dev_pm_info  power;  
    16 #ifdef CONFIG_NUMA  
    17     int     numa_node;  /* NUMA node this device is close to */  
    18 #endif  
    19     u64     *dma_mask;  /* dma mask (if dma'able device) */  
    20     u64     coherent_dma_mask;/* Like dma_mask, but for 
    21                          alloc_coherent mappings as 
    22                          not all hardware supports 
    23                          64 bit addresses for consistent 
    24                          allocations such descriptors. */  
    25     struct device_dma_parameters *dma_parms;  
    26     struct list_head    dma_pools;  /* dma pools (if dma'ble) */  
    27     struct dma_coherent_mem *dma_mem; /* internal for coherent mem 
    28                          override */  
    29     /* arch specific additions */  
    30     struct dev_archdata archdata;  
    31 #ifdef CONFIG_OF  
    32     struct device_node  *of_node;  
    33 #endif  
    34     dev_t           devt;   /* dev_t, creates the sysfs "dev" */  
    35     spinlock_t      devres_lock;  
    36     struct list_head    devres_head;  
    37     struct klist_node   knode_class;  
    38     struct class        *class;  
    39     const struct attribute_group **groups;  /* optional groups */  
    40     void    (*release)(struct device *dev);  
    41 };  
    42 //重点看一下私有属性结构  
    43 struct device_private {  
    44     struct klist klist_children;             //子集结构  
    45     struct klist_node knode_parent;          //父级挂接点  
    46     struct klist_node knode_driver;          //driver挂接点  
    47     struct klist_node knode_bus;             //bus挂接点  
    48     void *driver_data;  
    49     struct device *device;                   //回指  
    50 };  

      接下来详细看一下device的注册device_register:

      1 int device_register(struct device *dev)  
      2 {  
      3     device_initialize(dev);                //初始化dev  
      4     return device_add(dev);                //添加dev  
      5 }  
      6 /****************************** 
      7 * 先看一下device_initialize(dev) 
      8 ******************************/  
      9 void device_initialize(struct device *dev)  
     10 {  
     11     dev->kobj.kset = devices_kset;                  //可见device和bus都有其起始的kset,而driver没有  
     12     kobject_init(&dev->kobj, &device_ktype);        //初始化这个kobj并建立层次关系以及属性文件,此时  
     13     INIT_LIST_HEAD(&dev->dma_pools);                //是放到了总的device文件目录下面  
     14     mutex_init(&dev->mutex);  
     15     lockdep_set_novalidate_class(&dev->mutex);  
     16     spin_lock_init(&dev->devres_lock);  
     17     INIT_LIST_HEAD(&dev->devres_head);  
     18     device_pm_init(dev);  
     19     set_dev_node(dev, -1);  
     20 }  
     21 /****************************** 
     22 * 再来看一下device_add(dev) 
     23 ******************************/  
     24 int device_add(struct device *dev)  
     25 {  
     26     struct device *parent = NULL;  
     27     struct class_interface *class_intf;  
     28     int error = -EINVAL;  
     29     dev = get_device(dev);  
     30     if (!dev)  
     31         goto done;  
     32     if (!dev->p) {  
     33         error = device_private_init(dev);                        //初始化dev的私有成员,及其链表操作函数  
     34         if (error)  
     35             goto done;  
     36     }  
     37     /* 
     38      * for statically allocated devices, which should all be converted 
     39      * some day, we need to initialize the name. We prevent reading back 
     40      * the name, and force the use of dev_name() 
     41      */  
     42     if (dev->init_name) {  
     43         dev_set_name(dev, "%s", dev->init_name);                 //设置名字,给kobj  
     44         dev->init_name = NULL;  
     45     }  
     46     if (!dev_name(dev)) {                                         //名字为空出错退出  
     47         error = -EINVAL;  
     48         goto name_error;  
     49     }  
     50     pr_debug("device: '%s': %s/n", dev_name(dev), __func__);  
     51     parent = get_device(dev->parent);                          //返回父节点,如果有返回,没有返回NULL  
     52     setup_parent(dev, parent);                     
     53     /* use parent numa_node */  
     54     if (parent)  
     55         set_dev_node(dev, dev_to_node(parent));  
     56     /* first, register with generic layer. */  
     57     /* we require the name to be set before, and pass NULL */  
     58     error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);   //初始化kobj与其父节点的连接  
     59     if (error)  
     60         goto Error;  
     61     /* notify platform of device entry */  
     62     if (platform_notify)  
     63         platform_notify(dev);  
     64     error = device_create_file(dev, &uevent_attr);             //产生属性文件  
     65     if (error)  
     66         goto attrError;  
     67     if (MAJOR(dev->devt)) {  
     68         error = device_create_file(dev, &devt_attr);             //在sys下产生dev属性文件  
     69         if (error)  
     70             goto ueventattrError;  
     71         error = device_create_sys_dev_entry(dev);  
     72         if (error)  
     73             goto devtattrError;  
     74         devtmpfs_create_node(dev);                                 
     75     }  
     76     error = device_add_class_symlinks(dev);                      
     77     if (error)  
     78         goto SymlinkError;  
     79     error = device_add_attrs(dev);                             //增加属性文件  
     80     if (error)  
     81         goto AttrsError;  
     82     error = bus_add_device(dev);                               //把device的bus节点挂到bus的设备节点上  
     83     if (error)  
     84         goto BusError;  
     85     error = dpm_sysfs_add(dev);  
     86     if (error)  
     87         goto DPMError;  
     88     device_pm_add(dev);  
     89     /* Notify clients of device addition.  This call must come 
     90      * after dpm_sysf_add() and before kobject_uevent(). 
     91      */  
     92     if (dev->bus)  
     93         blocking_notifier_call_chain(&dev->bus->p->bus_notifier,  
     94                          BUS_NOTIFY_ADD_DEVICE, dev);  
     95     kobject_uevent(&dev->kobj, KOBJ_ADD);  
     96     bus_probe_device(dev);                                    //匹配driver  
     97     if (parent)  
     98         klist_add_tail(&dev->p->knode_parent,                 //把该设备的节点挂到其父节点的链表  
     99                    &parent->p->klist_children);  
    100     if (dev->class) {  
    101         mutex_lock(&dev->class->p->class_mutex);  
    102         /* tie the class to the device */  
    103         klist_add_tail(&dev->knode_class,  
    104                    &dev->class->p->class_devices);  
    105         /* notify any interfaces that the device is here */  
    106         list_for_each_entry(class_intf,  
    107                     &dev->class->p->class_interfaces, node)  
    108             if (class_intf->add_dev)  
    109                 class_intf->add_dev(dev, class_intf);  
    110         mutex_unlock(&dev->class->p->class_mutex);  
    111     }  
    112 done:  
    113     put_device(dev);  
    114     return error;  
    115  DPMError:  
    116     bus_remove_device(dev);  
    117  BusError:  
    118     device_remove_attrs(dev);  
    119  AttrsError:  
    120     device_remove_class_symlinks(dev);  
    121  SymlinkError:  
    122     if (MAJOR(dev->devt))  
    123         devtmpfs_delete_node(dev);  
    124     if (MAJOR(dev->devt))  
    125         device_remove_sys_dev_entry(dev);  
    126  devtattrError:  
    127     if (MAJOR(dev->devt))  
    128         device_remove_file(dev, &devt_attr);  
    129  ueventattrError:  
    130     device_remove_file(dev, &uevent_attr);  
    131  attrError:  
    132     kobject_uevent(&dev->kobj, KOBJ_REMOVE);  
    133     kobject_del(&dev->kobj);  
    134  Error:  
    135     cleanup_device_parent(dev);  
    136     if (parent)  
    137         put_device(parent);  
    138 name_error:  
    139     kfree(dev->p);  
    140     dev->p = NULL;  
    141     goto done;  
    142 }  
    143 /*********************************************** 
    144 * 重点看一下bus_probe_device匹配driver以及初始化过程 
    145 ***********************************************/  
    146 void bus_probe_device(struct device *dev)  
    147 {  
    148     struct bus_type *bus = dev->bus;  
    149     int ret;  
    150     if (bus && bus->p->drivers_autoprobe) {         //设置了自动匹配初始化那么就开始匹配  
    151         ret = device_attach(dev);  
    152         WARN_ON(ret < 0);  
    153     }  
    154 }  
    155 /****************** 
    156 * 继续device_attach 
    157 ******************/  
    158 int device_attach(struct device *dev)  
    159 {  
    160     int ret = 0;  
    161     device_lock(dev);  
    162     if (dev->driver) {                            //默认指定了driver就直接绑定  
    163         ret = device_bind_driver(dev);  
    164         if (ret == 0)  
    165             ret = 1;  
    166         else {  
    167             dev->driver = NULL;  
    168             ret = 0;  
    169         }  
    170     } else {                                      //没有指定就进行遍历匹配  
    171         pm_runtime_get_noresume(dev);  
    172         ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);  
    173         pm_runtime_put_sync(dev);  
    174     }  
    175     device_unlock(dev);  
    176     return ret;  
    177 }  
    178 /************************** 
    179 * 再来看device_bind_driver分支 
    180 **************************/  
    181 int device_bind_driver(struct device *dev)  
    182 {  
    183     int ret;  
    184     ret = driver_sysfs_add(dev);  
    185     if (!ret)  
    186         driver_bound(dev);              //主要是完成了将私有成员的driver节点挂到  
    187     return ret;                         //了driver的设备链表  
    188 }  
    189 /************************** 
    190 * 先看bus_for_each_drv分支 
    191 **************************/  
    192 int bus_for_each_drv(struct bus_type *bus, struct device_driver *start,  
    193              void *data, int (*fn)(struct device_driver *, void *))  
    194 {  
    195     struct klist_iter i;  
    196     struct device_driver *drv;  
    197     int error = 0;  
    198     if (!bus)  
    199         return -EINVAL;  
    200     klist_iter_init_node(&bus->p->klist_drivers, &i,           //和driver遍历device类似,从头开始遍历bus的driver链表  
    201                  start ? &start->p->knode_bus : NULL);         //发现一个driver就调用fn即__device_attach进行匹配  
    202     while ((drv = next_driver(&i)) && !error)  
    203         error = fn(drv, data);  
    204     klist_iter_exit(&i);  
    205     return error;  
    206 }  
    207 /********************************* 
    208 * 最后来看一下__device_attach这个函数 
    209 *********************************/  
    210 static int __device_attach(struct device_driver *drv, void *data)  
    211 {  
    212     struct device *dev = data;  
    213     if (!driver_match_device(drv, dev))      
    214         return 0;  
    215     return driver_probe_device(drv, dev);  
    216 }  
    217 /* 
    218   对比driver的注册最后调用的__driver_attach可以发现其实质是一样的,都最后归宿到了 
    219   这driver_match_device,driver_probe_device两个函数,本质参数的和谐做到了通用 
    220   性在这里就不继续分析了,不是很清楚的可以看前一篇文章driver最后一部分的分析  ^_^ 
    221 */    

     

    以上便是device的注册,可以发现device和driver围绕着bus最后有种殊途同归的感觉,下面结合driver的流程给出一个框图

    以便更明确其间的流程:

  • 相关阅读:
    DAS存储未死,再次欲获重生
    Minimum edit distance(levenshtein distance)(最小编辑距离)初探
    AC自己主动机
    手动脱UPX 壳实战
    edge中断分析
    ubuntu默认的Python版本号修改
    Linux 下 pushd,popd,cd- 用法
    目标检测算法的历史及分类
    openjtag 的硬件连接踩坑历程
    ubuntu 16.04 python版本切换(python2和python3)
  • 原文地址:https://www.cnblogs.com/RandyQ/p/3457518.html
Copyright © 2011-2022 走看看