После регистрации драйвера PCI по телефону pci_register_driver()
в функции init_module
драйвер должен взять под контроль любые устройства PCI, у которых еще нет драйверов, при условии, что устройства соответствуют идентификатору поставщика, идентификатор устройства и т. д., как указано в struct pci_device_id
.Пользовательский драйвер PCI не может обнаружить устройство
Я хотел бы заставить контроллер Ethernet использовать мой драйвер только для экспериментов (например, чтение байтов конфигурации). В гостевой системе Virtualbox (Mint, kernel 3.13.0) я занес в черный список драйвер контроллера Ethernet, запустил update-initramfs -u
и перезагрузился. Это успешно отключило драйвер по умолчанию от контроллера, поскольку драйвер больше не отображался на выходе lspci -k
.
Однако, когда я загрузил модуль, на выходе lspci -k
появилось несколько устройств (с моим драйвером, управляющим ими), но Ethernet-контроллеру по-прежнему не хватало линии "Kernel driver in use: "
. Как я могу заставить мой модуль распознавать и владеть контроллером?
Обратите внимание, что я использовал 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;
}
Вы не можете просто сказать ЛЮБЫЕ ЛЮБЫЕ для поставщика и идентификатора устройства. Вы должны указать фактического поставщика/устройства (и, возможно, идентификаторы суб-поставщика/под-устройства) для устройства, которым вы хотите управлять с помощью этого вашего драйвера. –
@ChaitanyaLala, это не всегда так. Многие драйверы соответствуют классу, например. AHCI, 8250, ... – 0andriy
'.vendor = PCI_ANY_ID, .device = PCI_ANY_ID' означает, что ваш драйвер будет проверен на первое устройство _matching_. У первого подходящего устройства, скорее всего, может быть уже загружен драйвер. – 0andriy