每个pci驱动都有一个pci_driver实例,用以描述驱动名称,支持的设备信息,以及对应的操作函数;
1 /* 2 描述一个pci设备,每个pci驱动必须创建一个pci_driver实例 3 */ 4 struct pci_driver { 5 struct list_head node; 6 /* 驱动程序名,内核中所有pci驱动程序名都是唯一的 */ 7 const char *name; 8 /* pci设备配置信息数组 */ 9 const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ 10 /* 设备插入内核时调用 */ 11 int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ 12 /* 设备从内核移除时调用 */ 13 void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ 14 /* 设备被挂起时调用 */ 15 int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */ 16 int (*suspend_late) (struct pci_dev *dev, pm_message_t state); 17 int (*resume_early) (struct pci_dev *dev); 18 /* 设备被恢复时调用 */ 19 int (*resume) (struct pci_dev *dev); /* Device woken up */ 20 /* 设备关闭时调用 */ 21 void (*shutdown) (struct pci_dev *dev); 22 int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */ 23 /* 错误处理 */ 24 const struct pci_error_handlers *err_handler; 25 struct device_driver driver; 26 struct pci_dynids dynids; 27 };
以e100为例,在驱动初始化过程中,会调用pci_register_driver来注册pci_driver实例;
1 static const struct pci_error_handlers e100_err_handler = { 2 .error_detected = e100_io_error_detected, 3 .slot_reset = e100_io_slot_reset, 4 .resume = e100_io_resume, 5 }; 6 7 static struct pci_driver e100_driver = { 8 .name = DRV_NAME, 9 .id_table = e100_id_table, 10 .probe = e100_probe, 11 .remove = e100_remove, 12 #ifdef CONFIG_PM 13 /* Power Management hooks */ 14 .suspend = e100_suspend, 15 .resume = e100_resume, 16 #endif 17 .shutdown = e100_shutdown, 18 .err_handler = &e100_err_handler, 19 }; 20 21 static int __init e100_init_module(void) 22 { 23 if (((1 << debug) - 1) & NETIF_MSG_DRV) { 24 pr_info("%s, %s ", DRV_DESCRIPTION, DRV_VERSION); 25 pr_info("%s ", DRV_COPYRIGHT); 26 } 27 return pci_register_driver(&e100_driver); 28 } 29 30 static void __exit e100_cleanup_module(void) 31 { 32 pci_unregister_driver(&e100_driver); 33 } 34 35 module_init(e100_init_module); 36 module_exit(e100_cleanup_module);