linux设备模型之bus,device,driver分析二


//本文转载地址:http://blog.csdn.net/gdt_a20/article/details/6427331


上篇分析了bus,driver的注册过程,这篇主要分析device的注册,并总结给出个流程图。

三、device的注册

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

[cpp]  view plain copy
  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:

[cpp]  view plain copy
  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的流程给出一个框图

以便更明确其间的流程:

4


This is, on the surface, a book about writing device drivers for the Linux system. That is a worthy goal, of course; the flow of new hardware products is not likely to slow down anytime soon, and somebody is going to have to make all those new gadgets work with Linux. But this book is also about how the Linux kernel works and how to adapt its workings to your needs or interests. Linux is an open system; with this book, we hope, it is more open and accessible to a larger community of developers. This is the third edition of Linux Device Drivers. The kernel has changed greatly since this book was first published, and we have tried to evolve the text to match. This edition covers the 2.6.10 kernel as completely as we are able. We have, this time around, elected to omit the discussion of backward compatibility with previous kernel versions. The changes from 2.4 are simply too large, and the 2.4 interface remains well documented in the (freely available) second edition. This edition contains quite a bit of new material relevant to the 2.6 kernel. The discussion of locking and concurrency has been expanded and moved into its own chapter. The Linux device model, which is new in 2.6, is covered in detail. There are new chapters on the USB bus and the serial driver subsystem; the chapter on PCI has also been enhanced. While the organization of the rest of the book resembles that of the earlier editions, every chapter has been thoroughly updated. We hope you enjoy reading this book as much as we have enjoyed writing it.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值