export需实现函数:
module_init(xx_init_module);
module_exit(xx_cleanup_module);
xx_init_module函数:
1. 使用struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from)探测相关设备。
//First 256 bytes are a mirror of PCI config space.具体划分请参考“PCI设置头示意图”
vendor:厂家标识符, 16bit--(0-15)
device:设备标识符,芯片上电后立即发送过来的注册值, 16bit--(16-31)
from:没有就填NULL
2. 接着进行注册驱动。
int __must_check pci_register_driver(struct pci_driver *driver)
struct pci_driver {
struct list_head node;
char *name;
const struct pci_device_id *id_table; /* NULL if wants all devices */
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)
*/
void (*suspend)(struct pci_dev *dev); /* Device suspended */
void (*resume)(struct pci_dev *dev); /* Device woken up */
};
1)node 不设置。name填你驱动名称。
2)建立一个
static int __devinit xx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)作为probe
2.1) allocate device private data,然后通过pci_set_drvdata(pdev, void* data)进行设置进去。
2.2) pci_enable_device() 使能PCI驱动
2.3) pci_resource_flags(pdev, 0),进行check whether find proper PCI device base address
2.4) pci_request_regions(pdev, driverName) , Reserved PCI I/O and memory resources,从而判断是否obtain PCI resources
2.5) pci_set_master(pdev) - enables bus-mastering for device dev
2.6) pci_resource_start
2.7) 编写你的private data对应的各个function实现
2.8) request_irq 注册中断handler。
request_irq的大致流程为先对申请的中断线进行安全检测,然后根据request_irq传进来的参数,动态创建该中断对应的irqaction结构体,最后通过setup_irq函数将该irqaction注册进内核适当的位置。
3)
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 */
};
这个id_table表,填的vendor,device和前面值一样。剩下的填PCI_ANY_ID
4)建立一个static void __devexit xx_remove(struct pci_dev *pdev) 作为remove
5)剩下的自己觉得要不要。
基本上这样。待续。