在 init_module
函数中调用 pci_register_driver()
注册 PCI 驱动程序后,驱动程序应该控制任何还没有驱动程序的 PCI 设备,假设设备与 struct pci_device_id
中指定的供应商 ID、设备 ID 等匹配。
我想强制以太网 Controller 使用我的驱动程序,只是为了实验(例如读取配置字节)。在 Virtualbox 客户机(Mint,内核 3.13.0)上,我将以太网 Controller 的驱动程序列入黑名单,运行 update-initramfs -u
,然后重新启动。这成功地解除了默认驱动程序与 Controller 的关联,因为该驱动程序不再出现在 lspci -k
的输出中。
然而,当我加载模块时,一些以前丢失的设备出现在 lspci -k
的输出中(由我的驱动程序控制它们),但是以太网 Controller 仍然缺少一个“正在使用的内核驱动程序:”
行。如何让我的模块识别并拥有 Controller ?
请注意,我对供应商和设备字段使用了 PCI_ANY_ID
,并且未初始化 struct pci_device_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;
}
最佳答案
您还需要包括 subvendor
和 subdevice
字段(也将它们设置为 PCI_ANY_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_DEVICE
宏来提供适当的 sub
成员:
static struct pci_device_id my_pci_id = {
PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID),
};
关于自定义 PCI 驱动程序无法探测设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38799867/