init_module
ファンクション内でpci_register_driver()
を呼び出してPCIドライバを登録した後、ドライバは、デバイスがベンダIDと一致していると仮定してドライバがないPCIデバイスを制御し、デバイスIDなどを指定します(struct pci_device_id
)。カスタムPCIドライバがデバイスのプローブに失敗する
私はイーサネットコントローラに実験用にドライバを使用させたいと思っています(設定バイトの読み込みなど)。 Virtualboxゲスト(Mint、カーネル3.13.0)で、イーサネットコントローラのドライバをブラックリストに登録し、update-initramfs -u
を実行して再起動しました。これにより、ドライバーがもはやlspci -k
の出力に現れなくなったため、デフォルトドライバーとコントローラーの正常な関連付けが解除されました。
しかし、モジュールをロードすると、以前に見つからなかったいくつかのデバイスが(ドライバを制御して)lspci -k
の出力に現れましたが、イーサネットコントローラにはまだ"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;
}
マッチング機能は、これがあります。このドライバで制御したいデバイスの実際のベンダ/デバイス(場合によってはサブベンダー/サブデバイスID)を指定する必要があります。 –
@ChaitanyaLala、それは必ずしもそうではありません。多くのドライバーはクラスごとに一致します。 AHCI、8250、... – 0andriy
'.vendor = PCI_ANY_ID、.device = PCI_ANY_ID'は、ドライバが最初の_matching_デバイスに対してプローブされることを意味します。最初にマッチングされたデバイスには、すでにドライバがロードされている可能性があります。 – 0andriy