浅析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).
|