pci_bus_type 定义如下,
struct
bus_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,
} ;
.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)
... {
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;
}
... {
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)
struct
pci_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*/
} ;
__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。
另外就是,
static
int
pci_device_probe(
struct
device
*
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;
}
... {
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了。