linux内核部件分析(九)——设备驱动模型之device-driver
(15页)
本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦!
14.9 积分
前面我们分析了device、driver、bus三种类型,主要是三者的注册与注销,在sysfs中的目录与属性文件创建等内容。本节就来详细分析下,在设备注册到总线上时,总线是如何为其寻找对应的驱动的;在驱动注册到总线上时,总线又是如何为其寻找对应的设备的。 本节的实现代码集中在drivers/base/bus.c和drivers/base/dd.c中。先来回忆下,在device_register()->device_add()中,先是调用bus_add_device()添加device与bus间的联系,并添加bus为device定义的属性,然后会调用bus_probe_device()。bus_probe_device()会试图为已挂在总线上的该设备寻找对应的驱动。我们的故事就从这里开始。[cpp] view plaincopyprint?1. /** 2. * bus_probe_device - probe drivers for a new device 3. * @dev: device to probe 4. * 5. * - Automatically probe for a driver if the bus allows it. 6. */ 7. void bus_probe_device(struct device *dev) 8. { 9. struct bus_type *bus = dev->bus; 10. int ret; 11. 12. if (bus && bus->p->drivers_autoprobe) { 13. ret = device_attach(dev); 14. WARN_ON(ret p->drivers_autoprobe,看是否允许自动探测。允许了才会调用device_attach()进行实际的寻找工作。说到bus->p->drivers_autoprobe这个变量,它是在bus_type_private中的,在调用bus_register()前都初始化不了,在bus_register()中自动定为1。所以,除非是用户空间通过drivers_autoprobe属性文件主动禁止,bus总是允许自动探测的,所有的bus都是如此。[cpp] view plaincopyprint?1. /** 2. * device_attach - try to attach device to a driver. 3. * @dev: device. 4. * 5. * Walk the list of drivers that the bus has and call 6. * driver_probe_device() for each pair. If a compatible 7. * pair is found, break out and return. 8. * 9. * Returns 1 if the device was bound to a driver; 10. * 0 if no matching driver was found; 11. * -ENODEV if the device is not registered. 12. * 13. * When called for a USB interface, @dev->parent->sem must be held. 14. */ 15. int device_attach(struct device *dev) 16. { 17. int ret = 0; 18. 19. down(&dev->sem); 20. if (dev->driver) { 21. ret = device_bind_driver(dev); 22. if (ret == 0) 23. ret = 1; 24. else { 25. dev->driver = NULL; 26. ret = 0; 27. } 28. } else { 29. pm_runtime_get_noresume(dev); 30. ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); 31. pm_runtime_put_sync(dev); 32. } 33. up(&dev->sem); 34. return ret; 35. } device_attach()在实际绑定之前,会用dev->sem进行加锁。不错,dev->sem几乎就是为了在设备与驱动绑定或者解除绑定时加锁用的。还没有看到它在其它地方被调用。如果在调用device_attach()前就已经有了dev->driver(),就调用device_bind_driver()进行绑定,不然还要调用bus_for_each_drv()进行依次匹配。至于pm_runtime_get_noresume之类的函数,属于电源管理部分,我们现在先忽略。[cpp] view plaincopyprint?1. static void driver_bound(struct device *dev) 2. { 3. if (klist_node_attached(&dev->p->knode_driver)) { 4. printk(KERN_WARNING "%s: device %s already bound\n", 5. __func__, kobject_name(&dev->kobj)); 6. return; 7. } 8. 9. pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev), 10. __func__, dev->driver->name); 11. 12. if (dev->bus) 13. blocking_notifier_call_ 关 键 词: linux 内核 部件 分析 设备 驱动 模型 device driver
天天文库所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
关于本文
本文标题:linux内核部件分析(九)——设备驱动模型之device-driver
链接地址: https://www.wenku365.com/p-42604127.html