自定义PCI驱动程序无法探测设备

自定义PCI驱动程序无法探测设备,c,linux-kernel,linux-device-driver,kernel-module,pci,C,Linux Kernel,Linux Device Driver,Kernel Module,Pci,通过调用init\u module函数中的PCI\u register\u driver()注册PCI驱动程序后,假设设备与struct PCI\u device\u ID中指定的供应商ID、设备ID等相匹配,则驱动程序应控制任何尚未具有驱动程序的PCI设备 我想强制以太网控制器使用我的驱动程序,只是为了实验(例如读取配置字节)。在Virtualbox客户机(Mint,内核3.13.0)上,我将以太网控制器的驱动程序列入黑名单,运行updateinitramfs-u,然后重新启动。这成功地解除了

通过调用
init\u module
函数中的
PCI\u register\u driver()
注册PCI驱动程序后,假设设备与
struct PCI\u device\u ID
中指定的供应商ID、设备ID等相匹配,则驱动程序应控制任何尚未具有驱动程序的PCI设备

我想强制以太网控制器使用我的驱动程序,只是为了实验(例如读取配置字节)。在Virtualbox客户机(Mint,内核3.13.0)上,我将以太网控制器的驱动程序列入黑名单,运行
updateinitramfs-u
,然后重新启动。这成功地解除了默认驱动程序与控制器的关联,因为驱动程序不再显示在
lspci-k
的输出中

然而,当我加载模块时,
lspci-k
的输出中显示了一些以前丢失的设备(由我的驱动程序控制),但是以太网控制器仍然缺少一个
“正在使用的内核驱动程序:”
行。如何使我的模块识别并拥有控制器

注意,我对供应商和设备字段使用了
PCI\u ANY\u ID
,而未初始化
struct PCI\u device\u ID
的其他字段。因此,我希望驱动程序能够探测任何当前缺少驱动程序的设备

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pci.h>

MODULE_LICENSE("GPL");

int init_module(void);
void cleanup_module(void);
static int pci_probe(struct pci_dev *, const struct pci_device_id *);
static void pci_remove(struct pci_dev *dev);

#define SUCCESS 0
#define FAILURE -1


static struct pci_device_id my_pci_id = {
        .vendor = PCI_ANY_ID,
        .device = PCI_ANY_ID
};

static struct pci_driver my_pci_driver = {
        .name = "kmod_driver",
        .id_table = &my_pci_id,
        .probe = pci_probe,
        .remove = pci_remove
};


int init_module(void)
{
        return pci_register_driver(&my_pci_driver);
}

void cleanup_module(void)
{
        pci_unregister_driver(&my_pci_driver);
}

static int pci_probe(struct pci_dev *dev, const pci_device_id *id)
{
        int enableStatus = pci_enable_device(dev);
        .....
        return SUCCESS;
}

static void pci_remove(struct pci_dev *dev)
{
        return;
}
#包括
#包括
#包括
#包括
模块许可证(“GPL”);
int init_模块(void);
空洞清理模块(空洞);
静态int pci_探测器(结构pci_dev*,常量结构pci_device_id*);
静态void pci_remove(struct pci_dev*dev);
#定义成功0
#定义故障-1
静态结构pci\U设备\U id我的\U pci\U id={
.vendor=PCI\u任何\u ID,
.device=PCI\u任意\u ID
};
静态结构pci_驱动程序my_pci_驱动程序={
.name=“kmod\u驱动程序”,
.id\u table=&my\u pci\u id,
.probe=pci_探头,
.remove=pci_remove
};
int init_模块(void)
{
返回pci\ U寄存器\ U驱动程序(&my\ U pci\ U驱动程序);
}
空洞清理_模块(空洞)
{
取消注册pci\ U驱动程序(&my\ U pci\ U驱动程序);
}
静态int pci_探测器(结构pci_dev*dev,常量pci_device_id*id)
{
int enableStatus=pci_enable_设备(dev);
.....
回归成功;
}
静态void pci_remove(结构pci_dev*dev)
{
返回;
}

您还需要包括
子供应商
子设备
字段(将它们设置为
PCI\u ANY\u ID
)。匹配功能如下所示:

static inline const struct pci_device_id *
pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
{
        if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
            (id->device == PCI_ANY_ID || id->device == dev->device) &&
            (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
            (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
            !((id->class ^ dev->class) & id->class_mask))
                return id;
        return NULL;
}
您可以使用
PCI\U设备
宏来提供适当的
成员:

static struct pci_device_id my_pci_id = {
    PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID),
};

对于供应商和设备ID,您不能只说ANY,ANY。您必须为要通过您的驱动程序控制的设备指定实际的供应商/设备(可能还有子供应商/子设备ID)。@Chaitanyallala,情况并非总是如此。许多驱动程序按类别匹配,例如AHCI、8250、
。vendor=PCI_ANY_ID、.device=PCI_ANY_ID
意味着将根据第一个匹配的设备探测驱动程序。第一个匹配的设备很可能已经加载了驱动程序。