Chinaunix首页 | 论坛 | 博客
  • 博客访问: 405302
  • 博文数量: 143
  • 博客积分: 455
  • 博客等级: 一等列兵
  • 技术积分: 860
  • 用 户 组: 普通用户
  • 注册时间: 2012-08-03 00:11
文章分类

全部博文(143)

文章存档

2018年(10)

2017年(6)

2016年(28)

2015年(14)

2014年(67)

2013年(1)

2012年(17)

我的朋友

分类: LINUX

2014-09-03 17:33:30

===============================
本文系本站原创,欢迎转载!
转载请注明出处:http://blog.csdn.net/gdt_a20
===============================

  上篇分析了bus,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的流程给出一个框图

以便更明确其间的流程:

阅读(312) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册