有人会解释如何在linux中使用pci_enable_device()

时间:2013-11-14 17:50:40

标签: c linux-kernel linux-device-driver device-driver pci

我开始学习编写PCI驱动程序,我采取的第一个练习是查找总线上是否存在给定设备。在搜索了一些书籍和互联网之后,我能够写下下面的程序,它确实有用,但我不清楚几个概念。

1 /*
  2  Program to find a device on the PCI sub-system 
  3 */
  4 #define VENDOR_ID       0x8086
  5 #define DEVICE_ID       0x7113
  6 
  7 #include <linux/kernel.h>
  8 #include <linux/module.h>
  9 #include <linux/stddef.h>
 10 #include <linux/pci.h>
 11 #include <linux/init.h>
 12 #include <linux/cdev.h>
 13 #include <linux/device.h>
 14 
 15 #define LOG(string...) printk(KERN_NOTICE string)
 16 
 17 #define CDEV_MAJOR      227
 18 #define CDEV_MINOR      0
 19 
 20 
 21 MODULE_LICENSE("GPL");
 22 
 23 struct pci_dev *pci_dev;
 24 unsigned long mmio_addr;
 25 unsigned long reg_len;
 26 unsigned long *base_addr;
 27 
 28 int device_probe(struct pci_dev *dev, const struct pci_device_id *id);
 29 void device_remove(struct pci_dev *dev);
 30 
 31 struct pci_device_id  pci_device_id_DevicePCI[] =
 32 {

33         {VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 34         {}  // end of list
 35 };
 36 
 37 struct pci_driver  pci_driver_DevicePCI =
 38 {
 39   name: "MyPCIDevice",
 40   id_table: pci_device_id_DevicePCI,
 41   probe: device_probe,
 42   remove: device_remove
 43 };
 44 
 45 
 46 int init_module(void)
 47 {
 48         struct pci_dev *pdev = NULL;
 49         int ret = 0;
 50 
 51         pci_register_driver(&pci_driver_DevicePCI);
 52         pdev = pci_get_device(VENDOR_ID, DEVICE_ID, NULL);
 53         if (pdev)
 54         {
 55                 LOG("Device found ... ");
 56                 pci_dev = pdev;
 57         }
 58         else
 59         {
 60                 LOG("Device not found ... ");
 61         }
 62         return ret;

 63 
 64 
 65 }
 66 
 67 void cleanup_module(void)
 68 {
 69         pci_unregister_driver(&pci_driver_DevicePCI);
 70 
 71 }
 72 
 73 int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
 74 {
 75         int ret;
 76         LOG("Devie probed");
 77         ret  = pci_enable_device(dev);
 78         if (ret < 0 ) LOG("Failed while enabling ... ");
 79 
 80         return ret;
 81 }
 82 
 83 void device_remove(struct pci_dev *dev)
 84 {
 85   pci_release_regions(dev);
 86   pci_disable_device(dev);
 87 }

在init_module()函数内部,找到给定的用户VID和DID设备,如果成功,struct pdev指向相应的pci设备。正如我所读到的,一旦找到设备,probe()函数就会启动。

这是否意味着在调用pci_enable_device()之前我们总是要做pci_get_device()? IMO,是的但是如果是这样的话,即使我没有传递它,device_probe()如何获得对dev结构的引用?

如果我100%确定我的设备存在于系统上,如何在不注册的情况下调用pci_enable_device()?

我目前正在参考LDD3的书,他们解释了所有的电话,但对于初学者我觉得它错过了如何连接点。有没有人有指针广泛使用的pci_xx()调用用简洁的例子解释?

1 个答案:

答案 0 :(得分:1)

您的probe函数由pci_register_driver调用,用于搜索具有匹配设备ID的无人认领设备。

pci_get_device调用在probe返回后发生,并且不需要。