在linux内核中,PCI驱动使用 struct pic_driver 结构来描述:
struct pci_driver
{
/*以上还有很多成员*/
//id_table 中包含了PCI设备的相关信息
const struct pci_device_id *id_table;
int (*probe) (struct pci_dev *dev,const struct pci_device_id *id);
void (*remove) (struct pci_dev *dev);
/*Device removed (NULL if not a hot-plug capable driver)*/
};
注册PCI驱动,使用
pci_register_driver(struct pci_driver *drv);
在PCI驱动使用PCI设备的任何资源(I/O区或者中断)之前,驱动必须调用如下函数来使能设备:
int pci_enable_device(struct pci_dev *dev)
一个PCI设备最多可以实现6个地址区域,大多数PCI设备在这些区域实现I/O寄存器。Linux提供了一组函数来获取这些区间的基地址:
pci_resource_start(struct pci_dev *dev,int bar)
返回指定区域的起始地址;这个区域通过参数 bar 指定,范围从 0—5,表示6个PCI区域的一个
pci_resource_end(struct pci_dev *dev,int bar)
返回指定区域的末地址
中断号存放于配置寄存器 PCI_INTERRUPT_LINE 中,驱动不必去检查它,因为从PCI_INTERRUPT_LINE 中找到的值保证是正确的。**如果设备不支持中断,寄存器 PCI_INTERRUPT_LINE 中的值是0,**否则它是非0的值。但因为驱动开发者通常知道设备是否是支持中断,所以常常不需要访问 PCI_INTERRUPT_LINE。
相关的驱动程序分析,在内核文件 /driver/net/hamachi.c
init函数
static int __init hamachi_init (void)
{
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
printk(version);
#endif
if (pci_register_driver(&hamachi_driver) > 0)
return 0;
pci_unregister_driver(&hamachi_driver);
return -ENODEV;
}
驱动描述
static struct pci_driver hamachi_driver = {
name: DRV_NAME,
id_table: hamachi_pci_tbl,
probe: hamachi_init_one,
remove: __devexit_p(hamachi_remove_one),
};
PCI 设备表
static struct pci_device_id hamachi_pci_tbl[] = {
{ 0x1318, 0x0911, PCI_ANY_ID, PCI_ANY_ID, },
{ 0, }
};
该表记录的能够支持的PCI设备,分别是厂商号,设备号,子厂商号,子设备号,其中子厂商号,子设备号为 PCI_ANY_ID ,表示支持各种子类型。
其他更多函数可在内核代码 /driver/hamachi.c