1. How does PCI work at boot time?
2. How does a driver look for its device?
The driver uses (vendor id, device id, class, ...) to tell kernel the devices it supports. The struct pci_device_id is used to define a list of different types of PCI devices the driver supports.
3. How does a driver access the device's configuration space?
Register a PCI driver:
1. name: driver name, must be unique
2. id_table: all supported device, point to struct pci_device_id (一個driver可以support多個device, 列在此list之中)
3. int (*probe): "This function is called by the PCI core when it has a struct pci_dev that it thinks this driver wants to control" [ref1]
PCI core找到一個pci_dev, 呼叫driver, 檢查driver裡面的pci_device_id list. If the PCI driver claims the pci_dev that is passed to it, it should initialize the device properly and return 0.
4. void (*remove):
5. int (*suspend):
6. int (*resume):
Kernel PCI functions:
1. pci_get_device: scan the list of PCI devices in the system.
2. pci_get_subsys: allow subsystem vendor and subsystem device ID to be specified.
3. pci_get_slot: search the pci device on specific slot.
(all these functions can no be called from interrupt context)
4. pci_enable_device:Enabling the PCI device, setup interrupt line and I/O region
Accessing the configuration space:
當device driver已經偵測到device, driver就會去讀寫configuration space去找到這個device被map到那些memory or I/O space.
pci_read_config_byte
pci_read_config_word
pci_write_config_byte
Accessing the I/O and Memory space:
每個PCI device有六個I/O address regions.每個region可以是memory or I/O locations.
pci_resource_start
pci_resource_end
pci_resource_flags
>lspci | cut -d: -f1,2
[bus number, 8 bit]:[device number, 5 bit].[function, 3 bit]
00:00.0 Host bridge
00:01.0 PCI bridge
00:1c.0 PCI bridge
00:1c.4 PCI bridge
00:1c.5 PCI bridge
00:1d.0 USB Controller
00:1d.1 USB Controller
00:1d.2 USB Controller
00:1d.7 USB Controller
00:1e.0 PCI bridge
00:1f.0 ISA bridge
00:1f.1 IDE interface
00:1f.2 IDE interface
00:1f.3 SMBus
02:00.0 PCI bridge
03:02.0 Ethernet controller
04:00.0 Ethernet controller
06:05.0 VGA compatible controller
ecslgw@ecslgw-cewit:~$ cat /proc/bus/pci/devices | cut -f1,2,3
Field 1 - Bus Dev Func
Field 2 - Vendor Id + Device Id
Field 3 - Interrupt Line
Field 4 - BAR 0
and the rest of the BAR registers (0 - 5) after that.
Field 2 - Vendor Id + Device Id
Field 3 - Interrupt Line
Field 4 - BAR 0
and the rest of the BAR registers (0 - 5) after that.
0000 80862778 0 0
0008 80862779 df 0
00e0 808627d0 de 0
00e4 808627e0 dd 0
00e5 808627e2 dc 0
00e8 808627c8 14 0
00e9 808627c9 15 0
00ea 808627ca 16 0
0200 8086032c 0 00310 80861026 23 fe9e0004
0400 14e41659 10 fe6f0004
0628 18ca0020 0 fd000008
3. /lib/modules/2.6.39.4/modules.pcimap
The kernel search this file when hot-pluggable devices are found.
4. drivers/pci/search.c
/* For boot time work */
EXPORT_SYMBOL(pci_find_bus);
EXPORT_SYMBOL(pci_find_next_bus);
/* For everyone */
EXPORT_SYMBOL(pci_get_device);
EXPORT_SYMBOL(pci_get_subsys);
EXPORT_SYMBOL(pci_get_slot);
EXPORT_SYMBOL(pci_get_class);
Reference:
1. Linux Device Driver, Chapter 12
沒有留言:
張貼留言