Linux-PCI Driver
Linux PCI设备驱动包括:
Linux PCI设备驱动
设备本身驱动
一、Linux PCI设备驱动程序
- 是内核自带的
- 这个伪设备驱动程序从总线0开始查询PCI系统,并定位系统中所有的PCI设备和PCI桥。它建立一个可以用来描述这个PCI系统拓朴层次的数据结构链表。并且对所有的发现的PCI桥编号
二、PCI设备驱动
1. 注册一个PCI驱动
为了正确地将驱动注册到kernel,每个PCI驱动必须创建 struct pci_driver主结构体。结构体中至少含有下面四个成员:
1 | static struct pci_driver pcie_dev_driver = { |
2. 模块初始化
模块初始化时需要使用module_init函数。例如:
1 | module_init(pcie_dev_init); |
pcie_dev_init函数为手动加载驱动模块.ko时执行的函数,其中做的主要工作时注册pci驱动。例如:
1 | static int __init pcie_dev_init(void) |
3. 卸载模块
卸载模块时要使用module_exit函数。module_exit和module_init通常放在一起。例如:
1 | module_exit(pcie_dev_exit); |
pcie_dev_exit函数为手动卸载驱动模块时执行的函数,其中做的主要工作时注册pci驱动。例如:
1 | static void __exit pcie_dev_exit(void) |
4. Probe函数
在init函数中pci_register_driver()完成后,一旦检测到了与驱动匹配的设备并且驱动控制了设备,驱动通常会在probe函数中做以下的动作。
Enable the device
pci_enable_device()
Request MMIO/IOP resources
pci_request_regions()
Set the DMA mask size (for both coherent and streaming DMA)
pci_set_dma_mask()
Allocate and initialize shared control data
pci_allocate_coherent()
Access device configuration space (if needed)
Register IRQ handler
request_irq())
Initialize non-PCI (i.e. LAN/SCSI/etc parts of the chip)
Enable DMA/processing engines
4.1 Enable the device
在access任何设备寄存器之前,驱动程序需要通过调用pci_enable_device()来启用 PCI 设备。
This will:
- wake up the device if it was in suspended state,
- allocate I/O and memory regions of the device (if BIOS did not),
- allocate an IRQ (if BIOS did not).