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

===============================
本文系本站原创,欢迎转载!
转载请注明出处:http://www.cnblogs.com/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的流程给出一个框图

以便更明确其间的流程:

bus_driver_device

分类:  Kernel
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值