浅析linux 2.6.23 bus总线模型下match()和probe()函数调用顺序
文章来源:http://gliethttp.cublog.cn
将driver驱动内嵌的kobj对象添加到管理该driver的总线层次管理集合kset所管理的链表中,
然后调用driver_attach()函数,遍历驱动所在bus总线的设备链表klist_devices检测该driver
驱动程序是否可以为bus总线上未获得驱动的device设备提供驱动,进一步通过__driver_attach()
函数检测设备是否可以被该driver驱动管理.
__driver_attach()->driver_probe_device()->调用bus总线的match函数drv->bus->match()
之后在really_probe()中dev->driver = drv;驱动和设备通过driver_sysfs_add()建立符号链接,
使得驱动能够真正的通过VFS文件接口操作dev设备,如果dev->bus->probe()存在那么调用之,
否则如果drv->probe()存在那么调用之,
最后调用driver_bound()将klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
设备的knode_driver节点链接到驱动的klist_devices设备链表上[对于bus_attach_device同样是这样]
所以当insmod手动安装驱动程序或者usb-hub端口检测到usb设备插入后调用add_device添加设备时,
均通过如下2步自动检测驱动和设备是否匹配,来为设备安装驱动或者为驱动寻找设备:
1.drv->bus->match()首先调用驱动或者设备所属bus总线提供的match函数,初步检测在bus总线级别是否能匹配
2.dev->bus->probe()如果不存在,那么调用drv->probe(),更详细的检测驱动和设备的匹配程度.
对于usb系统match函数由usb系统自有的usb_bus_type结构体提供,usb的bus系统不提供probe()函数,必须由用户
的驱动程序提供,比如:mct_u232_driver->probe()函数会使用用户驱动结构体提供的id表--id_table,根据match_flags
标志,来检索usb id表中的厂商号、产品号、设备号、设备类型、设备子类、设备协议、接口类型、接口子类或者
接口协议等是否有按照匹配标志match_flags匹配运算后和匹配要求符合的设备,如果有那么说明驱动和设备匹配上了,
设备找到了管理它的驱动,驱动的klist_devices链表上又多了一个它要管理的设备小baby(gliethttp_20071029).
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/38994/showart_409678.html