转载本文解释linux下设备和驱动的不同注册顺序时设备probe的时机;增加两个case以解决PCI/USB等可热插拔设备不同插入过程的probe时机的疑问。
Linux 2.6的设备驱动模型中,所有的device都是通过Bus相连。device_register() / driver_register()执行时通过枚举BUS上的Driver/Device来实现绑定,本文详解这一过程。这是整个LINUX设备驱动的基础,PLATFORM设备,I2C上的设备等诸设备的注册最终也是调用本文讲述的注册函数来实现的。
Linux Device的注册最终都是通过device_register()实现,Driver的注册最终都是通过driver_register()实现。下图对照说明了Device和Driver的注册过程。
上面的图解一目了然,详细过程不再赘述。注意以下几点说明:
Device一般是先于Driver注册,但也不全是这样的顺序。
Linux的Device和Driver的注册过程分别枚举挂在该BUS上所有的Driver和Device实现了这种时序无关性。
[增加两个例子以解惑]
1 一个设备A已经attach驱动,不管两个注册的顺序如何,完成这一步,说明driver已经加载;同类设备B再次hot pluggin加入,则device_attach仅为设备B与驱动attach上,不会重做设备A的attach;
2 一个设备A注册,但是没有找到驱动,用户也不加载驱动;同类设备B hot pluggin,这时用户加载驱动,驱动注册,driver_attach,针对总线上的每个设备扫描,此时匹配的设备肯定没有加载驱动(如果没有一个设备对应同层次两个驱动的情况),则对设备A和B都attach该driver;
3 如果一个设备可以对应同层次两个驱动,是否允许,什么策略?需要时研究代码。
[附really_probe的代码]
250static int really_probe(struct device *dev, struct device_driver *drv) 251{ 252 int ret = 0; 253 254 atomic_inc(&probe_count); 255 pr_debug("bus: '%s': %s: probing driver %s with device %s\n", 256 drv->bus->name, __func__, drv->name, dev_name(dev)); 257 WARN_ON(!list_empty(&dev->devres_head)); 258 259 dev->driver = drv; // 已经bus->match上, 所以可以将该device和driver关联起来 260 if (driver_sysfs_add(dev)) { 261 printk(KERN_ERR "%s: driver_sysfs_add(%s) failed\n", 262 __func__, dev_name(dev)); 263 goto probe_failed; 264 } 265 266 if (dev->bus->probe) { // 调用bus->probe, 由bus->probe调用'具体'dev_drv->probe 267 ret = dev->bus->probe(dev); 268 if (ret) 269 goto probe_failed; 270 } else if (drv->probe) { // 使用'顶层'驱动device_driver的probe 271 ret = drv->probe(dev); 272 if (ret) 273 goto probe_failed; 274 } 275 276 driver_bound(dev); // 设备与驱动已经关联好了 277 ret = 1; 278 pr_debug("bus: '%s': %s: bound device %s to driver %s\n", 279 drv->bus->name, __func__, dev_name(dev), drv->name); 280 goto done; 281 282probe_failed: 283 devres_release_all(dev); 284 driver_sysfs_remove(dev); 285 dev->driver = NULL; 286 287 if (ret == -EPROBE_DEFER) { 288 /* Driver requested deferred probing */ 289 dev_info(dev, "Driver %s requests probe deferral\n", drv->name); 290 driver_deferred_probe_add(dev); 291 } else if (ret != -ENODEV && ret != -ENXIO) { 292 /* driver matched but the probe failed */ 293 printk(KERN_WARNING 294 "%s: probe of %s failed with error %d\n", 295 drv->name, dev_name(dev), ret); 296 } else { 297 pr_debug("%s: probe of %s rejects match %d\n", 298 drv->name, dev_name(dev), ret); 299 } 300 /* 301 * Ignore errors returned by ->probe so that the next driver can try 302 * its luck. 303 */ 304 ret = 0; 305done: 306 atomic_dec(&probe_count); 307 wake_up(&probe_waitqueue); 308 return ret; 309}