標籤:
1. pci_driver結構
struct pci_driver {
struct list_head node;
const char *name;
const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */
void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */
int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */
int (*suspend_late) (struct pci_dev *dev, pm_message_t state);
int (*resume_early) (struct pci_dev *dev);
int (*resume) (struct pci_dev *dev); /* Device woken up */
void (*shutdown) (struct pci_dev *dev);
int (*sriov_configure) (struct pci_dev *dev, int num_vfs); /* PF pdev */
const struct pci_error_handlers *err_handler;
struct device_driver driver;
struct pci_dynids dynids;
};
1. name 名稱,如下:
# ls /sys/bus/pci/drivers/
JMicron IDE Promise_IDE ata_piix e100 e1000e igb ixgbe
2. id_table
是一個指向pci裝置的id編號的指標,用於描述當前PCI裝置的編號,一般用做probe的輸入參數。如下表:
/* ixgbe_pci_tbl - PCI Device ID Table
*
* Wildcard entries (PCI_ANY_ID) should come last
* Last entry must be all 0s
*
* { Vendor ID, Device ID, SubVendor ID, SubDevice ID,
* Class, Class Mask, private data (not used) }
*/
static DEFINE_PCI_DEVICE_TABLE(ixgbe_pci_tbl) = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AF_SINGLE_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598AT2), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_DA_DUAL_PORT), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_SR_DUAL_PORT_EM), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_SFP_LOM), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_BX), board_82598 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_XAUI_LOM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KR), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_EM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_KX4_MEZZ), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_CX4), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_BACKPLANE_FCOE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_FCOE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_T3_LOM), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_COMBO_BACKPLANE), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T), board_X540 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599EN_SFP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF_QP), board_82599 },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T1), board_X540 },
/* required last entry */
{0, }
};
MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl);
pci_device_id 結構如下:
struct pci_device_id {
__u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
__u32 subvendor, subdevice; /* Subsystem ID‘s or PCI_ANY_ID */
__u32 class, class_mask; /* (class,subclass,prog-if) triplet */
kernel_ulong_t driver_data; /* Data private to the driver */
};
3. probe
int (*probe) (struct pci_dev *dev, const struct pci_device_id *id)
指向PCI驅動中的probe函數指標,這個函數被PCI核心調用,當它有一個它認為這個驅動想控制的 struct pci_dev時,
一個指向pci_device_id的指標,PCI核心用來做這個決定,也被告傳遞給這個函數,如果這個PCI驅動需要這個傳遞給它的struct pci_dev,
它應當正初始化這個裝置,並返回0, 如果這個驅動不想擁有這個裝置,或者產生一個錯誤,它應當返回一個負的錯誤值。
4. remove
void (*remove) (struct pci_dev *dev)
指向PCI核心在struct pci_dev被告從系統中去除時調用的函數指標,或者當PCI驅動被從核心中卸載時。
5. suspend
int (*suspend) (struct pci_dev *dev, pm_message_t state)
當struct pci_dev被掛起時PCI核心調用的函數指標,掛起狀態在state 變數時傳遞,這個函數是可選的
6. resume
int (*resume) (struct pci_def *dev)
當pci_dev被告恢複時PCI核心調用的函數指標,它的調用一定是在suspend函數執行之後,這個函數可選。
7. shutdown
void (*shutdown) (struct pci_dev *dev)
當此裝置需要關閉時,此函數指標所指向的函數將會被調用。
8. ixgbe註冊
static struct pci_driver ixgbe_driver = {
.name = ixgbe_driver_name,
.id_table = ixgbe_pci_tbl,
.probe = ixgbe_probe,
.remove = __devexit_p(ixgbe_remove),
#ifdef CONFIG_PM
.suspend = ixgbe_suspend,
.resume = ixgbe_resume,
#endif
#ifndef USE_REBOOT_NOTIFIER
.shutdown = ixgbe_shutdown,
#endif
#ifdef HAVE_PCI_ERS
.err_handler = &ixgbe_err_handler
#endif
};
static int __init ixgbe_init_module(void)
{
int ret;
...
ret = pci_register_driver(&ixgbe_driver);
return ret;
}
module_init(ixgbe_init_module);
9. ixgbe登出
static void __exit ixgbe_exit_module(void)
{
pci_unregister_driver(&ixgbe_driver);
...
}
module_exit(ixgbe_exit_module);
http://blog.chinaunix.net/uid-7187477-id-3220913.html
PCI在linux系統中註冊與登出樣本