Few Notes About The PCI Subsystem or "What should you avoid when writing PCI drivers" by Martin Mares on 09-Oct-1999 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 0. Structure of PCI drivers ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Aa typical PCI device driver needs to perform the following actions: 1. Find PCI devices it's able to handle 2. Enable them 3. Access their configuration space 4. Discover addresses and IRQ numbers 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). If you need to match by subsystem vendor/device ID, use pci_find_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev). You can use the constant PCI_ANY_ID as a wildcard replacement for VENDOR_ID or DEVICE_ID. This allows searching for any device from a specific vendor, for example. 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. The `struct pci_dev *' pointer serves as an identification of a PCI device and is passed to all other functions operating on PCI devices. 2. Enabling devices ~~~~~~~~~~~~~~~~~~~ Before you do anything with the device you've found, you need to enable it by calling pci_enable_device() which enables I/O and memory regions of the device, assigns missing resources if needed and wakes up the device if it was in suspended state. Please note that this function can fail. If you want to use the device in bus mastering mode, call pci_set_master() which enables the bus master bit in PCI_COMMAND register and also fixes the latency timer value if it's set to something bogus by the BIOS. 3. 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 struct 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. If you access fields in the standard portion of the config header, please use symbolic names of locations and bits declared in . If you need to access Extended PCI Capability registers, just call pci_find_capability() for the particular capability and it will find the corresponding register block for you. 4. 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. 5. Other interesting functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pci_find_slot() Find pci_dev corresponding to given bus and slot numbers. pci_set_power_state() Set PCI Power Management state (0=D0 ... 3=D3) 6. Obsolete functions ~~~~~~~~~~~~~~~~~~~~~ There are several functions kept only for compatibility with old drivers not updated to the new PCI interface. Please don't use them in new code. pcibios_present() Since ages, you don't need to test presence of PCI subsystem when trying to talk with it. If it's not there, the list of PCI devices is empty and all functions for searching for devices just return NULL. pcibios_(read|write)_* Superseded by their pci_(read|write)_* counterparts. pcibios_find_* Superseded by their pci_find_* counterparts.