===============================
本文系本站原创,欢迎转载!
转载请注明出处: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的流程给出一个框图
以便更明确其间的流程:
分类:
Kernel