2016-08-06 9 views
1

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; 
} 
+0

マッチング機能は、これがあります。このドライバで制御したいデバイスの実際のベンダ/デバイス(場合によってはサブベンダー/サブデバイスID)を指定する必要があります。 –

+0

@ChaitanyaLala、それは必ずしもそうではありません。多くのドライバーはクラスごとに一致します。 AHCI、8250、... – 0andriy

+0

'.vendor = PCI_ANY_ID、.device = PCI_ANY_ID'は、ドライバが最初の_matching_デバイスに対してプローブされることを意味します。最初にマッチングされたデバイスには、すでにドライバがロードされている可能性があります。 – 0andriy

答えて

0

またsubvendorsubdeviceフィールド(だけでなく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; 
} 

あなたが適切なsubメンバーを供給するPCI_DEVICEマクロを使用することができます:あなたは、ベンダー&デバイスIDのためにANY、ANYを言うことができない

static struct pci_device_id my_pci_id = { 
    PCI_DEVICE(PCI_ANY_ID, PCI_ANY_ID), 
}; 
関連する問題