gdt-A20

导航

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

posted on 2011-05-17 16:40  gdt-A20  阅读(2245)  评论(0编辑  收藏  举报