Few Notes About The PCI Subsystem or "What should you avoid when writing PCI drivers" by Martin Mares on 13-Feb-1998 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1. How to find PCI devices ~~~~~~~~~~~~~~~~~~~~~~~~~~ In case your driver wants to search for all devices with given vendor/device ID, it should use: struct pci_dev *dev = NULL; while (dev = pci_find_device(VENDOR_ID, DEVICE_ID, dev)) configure_device(dev); For class-based search, use pci_find_class(CLASS_ID, dev). In case you want to do some complex matching, look at pci_devices -- it's a linked list of pci_dev structures for all PCI devices in the system. All these methods return a pointer to a pci_dev structure which is used as a parameter for many other PCI functions. The rest of them accept bus and device/function numbers which can be found in pci_dev->bus->number and pci_dev->devfn. Feel free to use all other fields of the pci_dev structure, but don't modify them. The pci_present() function can be used to test presence of PCI in the machine. 2. How to access PCI config space ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can use pci_(read|write)_config_(byte|word|dword) to access the config space of a device represented by pci_dev. All these functions return 0 when successful or an error code (PCIBIOS_...) which can be translated to a text string by pcibios_strerror. Most drivers expect that accesses to valid PCI devices don't fail. In case you want to address the devices by bus/device/function numbers, use pcibios_(read_write)_config_(byte|word|dword). If you access fields in the standard portion of the config header, please use symbolic names of locations and bits declared in . 3. Addresses and interrupts ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Memory and port addresses and interrupt numbers should NOT be read from the config space. You should use the values in the pci_dev structure as they might have been remapped by the kernel. If your PCI device uses PCI I/O space, you need to use the check_region(), request_region() and release_region() routines. These prevent devices from having conflicting I/O regions. You access your registers using the inb(), inw(), inl(), outb(), outw(), or outl() routines passing the value of (struct pci_dev *) dev->base_address[] masked by PCI_BASE_ADDRESS_IO_MASK as the base address of your registers. If your PCI device uses PCI memory space, use ioremap() to create a cookie mapping to your PCI device. The mask (struct pci_dev *) dev->base_address[] with PCI_BASE_ADDRESS_MEM_MASK before passing it into ioremap(). This cookie is passed to the readb(), readw(), readl(), writeb(), writew(), and writel() routines when accessing PCI space. You must always use these routines when accessing PCI space from the kernel. Not all architectures allow direct access to PCI memory space from the kernel. The IO-mapping.txt file has information about converting between the various address spaces. People writing DMA device drivers should pay special attention to this information. PCI interrupt routines are always SA_SHIRQ and should use the value from (struct pci_dev *) dev->irq field for the interrupt number passed into request_irq(). Since it is a shared interrupt, you must also always pass a unique dev_id to request_irq(). 4. Obsolete functions ~~~~~~~~~~~~~~~~~~~~~ is obsolete and should not be included in new code. pcibios_find_(device|class) are also obsolete and should be replaced by pci_find_(device|class). 5. Bus mastering ~~~~~~~~~~~~~~~~ If you need to setup a bus-mastering card, just call pci_set_master(). It should set PCI_COMMAND_MASTER in the command register and adjust the latency timer if needed.