PCI Rework HOWTO

Here's a list of steps you need to take to convert a video driver to the new libpciaccess library. Please feel free to fix this page where you find it inaccurate or incomplete. The examples here are from the intel driver and assume that you want to continue allowing the driver to be built with older X servers by making all of the changes conditional on whether the server uses libpciaccess.

configure.ac changes

This patch adds a check to see if the X server is using libpciaccess (the server will have XSERVER_LIBPCIACCESS defined in xorg-server.h), then makes sure the pciaccess package is installed and available.

Note: I have always encountered the xorg header files in /usr/include/xorg/, so i corrected the include. If this is not the usual location, please revert it.

pciVideoPtr → struct pci_device *

In the ScrnInfoRec driver private structure, there is a pointer to the pciVideoPtr structure which contains identification information about the associated PCI device. libpciaccess has a parallel structure, struct pci_device which contains the same information using different names. Another change here is to compute (and store) the PCI base address register indices in this structure; mapping PCI space now requires using these register indices instead of just the physical address of the hardware.

Macros to fetch PCI device ids

Instead of changing the code to have conditional use of these new structures everywhere, we create macros to fetch various PCI identification data from either the old or new structures. Now, everywhere the driver used to refer to one of the old fields, just replace that using one of these macros. Placing these macros in your header file keeps the driver building against older servers.

Mechanical API conversions

Where your driver code calls various pci access functions, you need to mechanically convert them to using functions from libpciaccess

Mapping built-in PCI functions to libpciaccess functions

Built-in

libpciaccess

xf86ReadPciBIOS

pci_device_read_rom

pciReadByte

pci_device_cfg_read_u8

pciReadWord

pci_device_cfg_read_u16

pciReadLong

pci_device_cfg_read_u32

Listing the supported devices

The device probing function will now relies on the libpciaccess code to identify all devices automatically. The match works much like the kernel; you fill in a description of which devices your driver supports and the library finds the available devices on the system.

DriverRec changes

The exported DriverRec has some new fields that refer to the above list of devices and a new libpciaccess-compatible probe function. Note that the structure places NULL for the old Probe field while listing the new probe function in the new slot.

Registering the driver with the system

In your setup function, you'll be adding a driver to the system. To make the server know that your DriverRec contains the new fields for libpciaccess, you need to pass the HaveDriverFuncs or the server will never call your new probe function:

Mapping device regions

The final changes here affect how the driver maps bus regions into the server address space. This is a fairly mechanical change, except that the driver must know which BAR refers to each portion of the card address space.

That's it

The steps above are all that I found necessary to convert the intel driver; of course there are lots of other changes than the short patch excerpts here, but they're all available by looking at the intel driver git log.