Electronic – PCI express devices are required to support MSI: what does that mean


I am a bit confused concerning an issue I had with a PCI Express (PCIe) card used to interface serial device on a Linux computer. The card is based on the XR17V354 chip from MaxLinear.

From the beginning, the card was correctly recognized by the OS (it was listed in the lspci output), but reading and writing to the serial device (/dev/ttySx or /dev/ttyXRx) failed, no matter which driver was used (8250 serial driver built into the Linux kernel or device/chip manufacturer driver).

Now, I eventually traced back the problem to an interrupt issue: interrupts were correctly raised on the card (visible by polling the UART ISR register and also in the PCI INTx register), but never "reached" the CPU (counter in /proc/interrupt stuck at 0).
The issue was solved by disabling MSI (Message Signaled Interrupts), by adding pci=nomsi in the Linux kernel command line parameters.

Now, this is the part that confuses me:

  • I read that PCIe devices are required to support MSI

PCI Express permits devices to use these legacy interrupt messages,
retaining software compatibility with PCI drivers, but they are
required to also support MSI or MSI-X in the PCI layer.

  • In the chip datasheet and also in the lspci -v output, I see that there is an entry in the PCI Configuration Registers for the MSI capability (MSI Capacity ID = 0x05).
  • However, all the associated registers (eg Message Control Register) are Read-Only… which explains why MSI is not working and I had to disable it in the OS so it would handle INTx interrupts raised by the device

Does it mean the device is "broken", ie not compliant to PCIe requirements?
Or does the MSI support required from PCIe devices just implies to have a MSI Capacity ID (0x05), but doesn't actually require to implement the MSI feature?

Best Answer

The PCI Express specification says:

MSI/MSI-X interrupt support, which is optional for PCI 3.0 devices, is required for PCI Express devices. All PCI Express device Functions that are capable of generating interrupts must support MSI or MSI-X or both.

It also adds:

MSI and MSI-X are edge-triggered interrupt mechanisms; neither the PCI Local Bus Specification, Revision 3.0 nor this specification support level-triggered MSI/MSI-X interrupts. Certain PCI devices and their drivers rely on INTx-type level-triggered interrupt behavior (addressed by the PCI Express legacy INTx emulation mechanism). To take advantage of the MSI or MSI-X capability and edge-triggered interrupt semantics, these devices and their drivers may have to be redesigned.

Many manufacturers want to avoid the redesign effort, especially if they need to support legacy interrupts for older operating systems.

There are tests to check for PCIe compliance. However, a generic test cannot actually run the device (because most devices behave differently), so to check for MSI support, all it can do is to search for the presence of the MSI registers. This implies that the simplest way to pass such a PCIe compliance test is to add a bunch of non-working MSI registers. (The driver then must never try to enable MSI.)

So yes, your device violates the PCIe specification. (I guess that manufacturer driver simply added new PCI device IDs to the standard driver, and was never tested on a system that actually supports MSI.)