The PCI server

Updated: May 06, 2022

The PCI server (pci-server) is a resource manager process that manages the PCI hierarchy.

It's responsible for enumerating and optionally configuring all PCI/PCIe devices, providing access control to some device information and settings, and for all configuration space writes. For information about the command-line options, see the entry for pci-server in the Utilities Reference.

Without any command-line arguments, the PCI server enumerates the PCI bus, but doesn't configure it. This is the mode of operation for systems that have already enumerated and configured the PCI devices.

If requested, the PCI server configures a bus (after doing the enumeration), using the bus configuration module specified with the PCI_SERVER_BUSCFG_MODULE environment variable, or the generic module identified by the PCI_SERVER_BUSCFG_MODULE_DEFAULT string (which is defined in <pci/pci.h>) if that variable is unset. A bus is configured if you provide the -c and/or the --config=filename option, where filename is a server configuration file that contains the parameter DO_BUS_CONFIG=yes/true in the [buscfg] section.

As mentioned in Configuration files and as documented in ${QNX_TARGET}/etc/system/config/pci/pci_server-template.cfg, the PCI server can load other optional modules, each with its own set of arguments.

Server modules

To provide maximum flexibility, the PCI server can use a number of server-specific modules. One such module is for device configuration. As previously mentioned, device configuration is optional, and so this functionality is supplied by a bus configuration module that you can specify with the PCI_SERVER_BUSCFG_MODULE environment variable. If not specified, and configuration is to be done, the default module pci_server-buscfg_generic.so is used.

The server module mechanism is a means of extending the functionality of the PCI server while minimizing impacts to the server code base. This is facilitated by a set of internal APIs between the server and server modules. It doesn't necessarily mean that a new pci-server binary won't be required when a new module is created, but because of the defined module interface, the impacts will be localized and minimized. It all depends on the functionality being added.

Server configuration modules are contained in ${QNX_TARGET}/processor/lib/dll/pci and have the prefix pci_server-. There is “use” information in each module explaining what it's for and how to use it.

The “Known Devices” list (pci_db)

The PCI server creates and maintains a known devices list in /dev/shmem/pci_db. This database is created during the enumeration phase. If live insertion and deletion of devices (i.e., hotplug) is enabled, this database is updated by the PCI server to reflect the current hierarchy.

This shared object is available to every process that uses libpci, and this database is consulted when you call pci_device_find(). This allows every driver process to search for supported devices independently of one another and without ever generating any PCI bus/link activity. You can use rsrcdb_query to view the resource database entries.