pci_bus_type 定义如下, struct bus_type pci_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, }; static int pci_bus_match(struct device *dev, struct device_driver *drv) ...{ struct pci_dev *pci_dev = to_pci_dev(dev); struct pci_driver *pci_drv = to_pci_driver(drv); const struct pci_device_id *found_id; found_id = pci_match_device(pci_drv, pci_dev); if (found_id) return 1; return 0; } 总的来说,判断一个设备和驱动是否匹配,是看设备的描述符是否和驱动所支持的一样。pci_match_device()分别在 driver->dynid,driver->id_table这两个列表(由一系列的pci_device_id构成)里面查找。找到则返回这个设备的pci_device_id。(不妨比较一下pci_bus_type->match 和 usb_bus_type->match) struct pci_device_id ...{ __u32 vendor, device; /**//* Vendor and device ID or PCI_ANY_ID*/ __u32 subvendor, subdevice; /**//* Subsystem ID's or PCI_ANY_ID */ __u32 class, class_mask; /**//* (class,subclass,prog-if) triplet */ kernel_ulong_t driver_data; /**//* Data private to the driver */ }; 注意,pci_device_id->driver_data指向了每个pci设备驱动所特有的数据结构,比如ehci来说:.driver_data = (unsigned long) &ehci_pci_hc_driver。 另外就是, static int pci_device_probe(struct device * dev) ...{ int error = 0; struct pci_driver *drv; struct pci_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); return error; } 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
最新推荐文章于 2023-08-21 11:08:27 发布