Nach der Registrierung eines PCI-Treibers unter pci_register_driver()
innerhalb der init_module
-Funktion soll der Treiber die Kontrolle über alle PCI-Geräte übernehmen, die noch keine Treiber haben, vorausgesetzt, die Geräte entsprechen der Hersteller-ID. Geräte-ID usw., wie in der struct pci_device_id
angegeben.Benutzerdefinierter PCI-Treiber kann Gerät nicht testen
Ich möchte den Ethernet-Controller zwingen, meinen Treiber nur für Experimente zu verwenden (z. B. das Lesen von Konfigurationsbytes). Auf einem Virtualbox-Gast (Mint, Kernel 3.13.0) habe ich den Treiber des Ethernet-Controllers auf die schwarze Liste gesetzt, update-initramfs -u
ausgeführt und neu gestartet. Dadurch wurde der Standardtreiber vom Controller getrennt, da der Treiber nicht mehr in der Ausgabe lspci -k
angezeigt wurde.
Allerdings, als ich das Modul geladen habe, zeigten ein paar Geräte, die vorher fehlten, in der Ausgabe von lspci -k
(mit meinem Treiber, der sie steuert), aber der Ethernet-Controller fehlte noch eine "Kernel driver in use: "
Zeile. Wie kann ich erreichen, dass mein Modul den Controller erkennt und besitzt?
Beachten Sie, dass ich PCI_ANY_ID
für die Hersteller- und Gerätefelder verwendete und die anderen Felder der struct pci_device_id
nicht initialisiert. Also würde ich erwarten, dass der Treiber jedes Gerät sondiert, dem ein Treiber fehlt.
#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;
}
Sie können nicht nur ANY sagen, ANY für Anbieter und Geräte-ID. Sie müssen den tatsächlichen Hersteller/das Gerät (und möglicherweise die Unterlieferanten-/Untergerät-IDs) für das Gerät angeben, das Sie über diesen Treiber steuern möchten. –
@ChaitanyaLala, ist es nicht immer der Fall. Viele Treiber entsprechen der Klasse, z. AHCI, 8250, ... – 0andriy
'.vendor = PCI_ANY_ID, .device = PCI_ANY_ID 'bedeutet, dass Ihr Treiber mit dem ersten _matching_-Gerät verglichen wird. Das erste passende Gerät kann den Treiber wahrscheinlich bereits geladen haben. – 0andriy