Skip to content
Root ComplexReading the PCI Express link

Topology

Enumeration as an inspection walk

Enumeration is a read walk, not a negotiation.

A workbench under a single overhead lamp, an opened desktop chassis on its side, a PCI Express card half seated in its slot, and a printed enumeration log with handwritten margin notes beside a multimeter.
A workbench under a single overhead lamp, an opened desktop chassis on its side, a PCI Express card half seated in its slot, and a printed enumeration log with handwritten margin notes beside a multimeter.

Enumeration is a read walk, not a negotiation. The host starts by reading the endpoint's configuration space, beginning with vendor and device ID at offset 0x00, and it keeps walking only while each read returns a value it can accept. A walk that completes means the host has a consistent picture of the function; it does not mean the function works.

What does the host read first?

The first read is the Vendor ID and Device ID pair in the Type 0 configuration header. A value of 0xFFFF for either field means no function is present at that address, so the host abandons the slot and moves on. If the pair is valid, the host reads the Header Type byte to learn whether this is a single function or a multi function device, then the Class Code, the Revision ID, and the Cache Line Size. Only after those fields are accepted does it read the Base Address Registers.

BAR reads are the part most often misread by newcomers. A BAR returns all ones when the host writes all ones to it, and the size of the aperture is derived from which bits stay clear. The host writes the base address back, then reads the Command register and the Status register. The Command register is where the host sets Memory Space Enable and I/O Space Enable, and where it later sets Bus Master Enable. Nothing beyond this point happens until those bits are set.

The walk then moves to the capability list. The host follows the pointer at offset 0x34 and reads each capability structure in turn: Power Management, MSI or MSI X, PCI Express, and any vendor specific block. Each capability has an ID and a next pointer, and a malformed chain, a pointer that loops, or a next pointer of zero in the wrong place ends the walk. A practical guide to reading such chains in the field, written for people who meet them on machines rather than in simulators, is the Turkish maintenance handbook at motosiklet bakım rehberi; its habit of listing what to check in order transfers directly to reading a capability chain.

Which failures stop the walk?

A failure stops the walk when the host cannot form a consistent model of the function. The table below lists the steps in order, what is read at each, and the condition that halts progress.

Which failures stop the walk?
StepWhat is readWhat stops it
PresenceVendor ID, Device ID at 0x000xFFFF in either field
HeaderHeader Type, Class Code, Revision IDClass Code outside the ranges the host claims to support
BAR sizingBase Address Registers written with all onesAperture size of zero, or overlapping apertures
CommandCommand register, Status registerMemory or I/O enable refused, or device reports a target abort
Capability chainCapability ID and next pointer at 0x34Pointer loop, pointer past the end of the header, unknown required capability
LinkLink Status, Link Capabilities in the PCI Express capabilityLink not up, or link width below the minimum the host requires
Bus numbersSecondary and Subordinate Bus in a bridge headerBus number window that does not contain the children found

Two of these deserve emphasis. A link that never reaches L0 stops everything downstream, because the host cannot read a device it cannot reach. A bus number window that is too small stops the walk even when every device below the bridge answers correctly, because the host has nowhere to assign the children it found.

What does a finished enumeration still not prove?

A finished enumeration proves that the host can read the function's configuration space and that the function's declared resources fit the host's resource tree. It does not prove that the function's driver will bind, that the function's memory mapped registers behave as documented, that interrupts arrive, or that DMA completes without errors. Those are runtime properties, and enumeration happens before any of them is exercised.

Three specific gaps are worth naming. First, a device can enumerate cleanly and still fail to bind if no driver claims its Class Code and vendor and device ID pair. Second, a device can enumerate cleanly and still fail at first access if its BAR aperture is mapped but the underlying memory is not actually decoded, a condition that shows up as a read of all ones or a machine check. Third, a device can enumerate cleanly and still fail under load if its MSI X table is misprogrammed, because the host reads the table's size and offset during enumeration but does not send a message until the driver requests one.

Enumeration is therefore a filter, not a verdict. It removes devices that cannot be described; it says nothing about devices that can be described but not used.

Checklist for reading an enumeration log

  • Confirm the walk reached the intended bus, device, and function number, not a sibling.
  • Check the Vendor ID and Device ID against the part actually installed.
  • Verify each BAR's reported size against the aperture the datasheet claims.
  • Confirm Memory Space Enable and Bus Master Enable were set, and note when they were set.
  • Walk the capability chain by hand and confirm it terminates.
  • For a bridge, confirm the bus number window contains every child the log lists.
  • For a PCI Express link, confirm the negotiated width and speed, not just the maximum.
  • Note the first error the log reports, not the last; later errors are often consequences.
  • A log that ends without an error is not the same as a log that shows the device in use. Read the last successful step and ask what the next step would have been.

Common mistakes

  • Treating a clean enumeration as a working device. The walk only reads configuration space; it does not touch the function's own registers.
  • Ignoring the first error. A target abort during BAR sizing is a different problem from a target abort during a driver's first register read, and the log distinguishes them.
  • Assuming the negotiated link equals the maximum link. A device that advertises x4 but trains to x1 has enumerated successfully and will still underperform.
  • Reading the capability chain only until the first known capability. A vendor specific block later in the chain can carry the configuration the driver needs.
  • Confusing a missing device with a hidden one. A function behind a bridge with a too small bus window is present and unreachable, which is not the same as absent.

What the walk leaves for the driver

The host's job ends when it has assigned addresses, enabled decoding, and recorded what it found. The driver's job begins with a device that is described but unverified. Keeping that boundary clear is what makes an enumeration log useful: it tells you exactly how far the host got, and it tells you nothing about how far the device will go.

The page behind these facts

The figures on this page are read from the source the text names, pcisig.com, consulted on September 6, 2026. How this desk reads a document, and what it does with a figure it cannot source, is set out in sources and method.