Linux那些事儿之我是EHCI(3) pci match 和 probe – fudan

pci_bus_type 定义如下,

structbus_typepci_bus_type=…{.name="pci",.match=pci_bus_match,.uevent=pci_uevent,.probe=pci_device_probe,.remove=pci_device_remove,.suspend=pci_device_suspend,.suspend_late=pci_device_suspend_late,.resume_early=pci_device_resume_early,.resume=pci_device_resume,.shutdown=pci_device_shutdown,.dev_attrs=pci_dev_attrs,};staticintpci_bus_match(structdevice*dev,structdevice_driver*drv)…{structpci_dev*pci_dev=to_pci_dev(dev);structpci_driver*pci_drv=to_pci_driver(drv);conststructpci_device_id*found_id;found_id=pci_match_device(pci_drv,pci_dev);if(found_id)return1;return0;}

总的来说,判断一个设备和驱动是否匹配,是看设备的描述符是否和驱动所支持的一样。pci_match_device()分别在driver->dynid,driver->id_table这两个列表(由一系列的pci_device_id构成)里面查找。找到则返回这个设备的pci_device_id。(不妨比较一下pci_bus_type->match 和 usb_bus_type->match)

structpci_device_id…{__u32vendor,device;/**//*VendoranddeviceIDorPCI_ANY_ID*/__u32subvendor,subdevice;/**//*SubsystemID’sorPCI_ANY_ID*/__u32class,class_mask;/**//*(class,subclass,prog-if)triplet*/kernel_ulong_tdriver_data;/**//*Dataprivatetothedriver*/};

注意,pci_device_id->driver_data指向了每个pci设备驱动所特有的数据结构,比如ehci来说:.driver_data =(unsigned long) &ehci_pci_hc_driver。

另外就是,

staticintpci_device_probe(structdevice*dev)…{interror=0;structpci_driver*drv;structpci_dev*pci_dev;drv=to_pci_driver(dev->driver);pci_dev=to_pci_dev(dev);pci_dev_get(pci_dev);error=__pci_device_probe(drv,pci_dev);if(error)pci_dev_put(pci_dev);returnerror;}

pci_device_probe()—> __pci_device_probe() —> pci_call_probe() —> ( pci_driver->probe() )

而ehci_pci_driver->probe = usb_hcd_pci_probe()。像pci_device_probe的外包函数,就是一种面向对象的设计。不管怎样,经历了千辛万苦,咱终于绕到usb了。

抱最大的希望,为最大的努力,做最坏的打算

Linux那些事儿之我是EHCI(3) pci match 和 probe – fudan

相关文章:

你感兴趣的文章:

标签云: