当Linux调用PCI驱动程序的探测功能时?

时间:2015-07-09 23:28:03

标签: linux linux-kernel linux-device-driver pci

在注册PCI驱动程序之前,我们必须初始化struct pci_driver并将其传递给pci_register_driver。结构的一个字段是指向驱动程序probe函数的指针。

我的问题是 - 当内核调用驱动程序的探测例程时。是保证在致电pci_register_driver之后还是可能在任何其他时间发生?是什么决定了这种行为?

更新 pci_register_driver是一个展开为__pci_register_driver的宏,后者又调用driver_registerdriver_register调用bus_add_driver

bus_add_driver中有以下代码:

if (drv->bus->p->drivers_autoprobe) {
        error = driver_attach(drv);
        if (error)
            goto out_unregister;
}

driver_attach将使用参数bus_for_each_dev调用__driver_attach,这将调用driver_probe_device

driver_probe_device最终会调用really_probe

if (dev->bus->probe) {
    ret = dev->bus->probe(dev);

我不确定的一件事是,是否为pci_bus设置了标志drivers_autoprobe

2 个答案:

答案 0 :(得分:2)

在Linux内核中的PCI核心在链接训练阶段(默认情况下在启动时发生)枚举了您的设备之后,它将收集有关连接到它的终结点设备的信息,其中包括供应商ID,以及设备编号。然后,PCI内核将使用函数`pci_register_driver'来迭代已经注册到它的所有驱动程序。并查看驱动程序是否支持此供应商/设备组合。

驱动程序使用struct pci_device_id id_table结构的pci_driver字段标识它支持该供应商/设备组合。

典型的实现看起来像这样:

#define VENDOR 0xBEEF // vendor of EP device
#define DEVICE 0x1111 // device id of EP

static struct pci_device_id module_dev_table[] = {
    { PCI_DEVICE(VENDOR, DEVICE)},
    {0, },
};

// PCI driver structure used to register this driver with the kernel
static struct pci_driver fpga_driver = {
    .id_table   = module_dev_table,
    .probe      = module_probe,
    .remove     = module_remove,
    .suspend    = module_suspend,
    .resume     = module_resume,
};

当PCI内核将您的驱动程序识别为支持总线上设备的驱动程序时,将调用您的探测功能。

所以回答你的问题,不,你的探针功能不能保证在你注册你的驱动程序后立即调用,几乎肯定不会。在PCI核心枚举/链接培训识别您的驱动程序支持的设备后,将立即调用您的探测功能。

答案 1 :(得分:1)

当内核在PCI总线上检测到PCI设备时,内核会根据设备树获取设备名称。在此内核扫描已注册驱动程序列表后,如果任何驱动程序处理此设备。如果是,那么内核将调用该特定驱动程序的探测。