Linux PCI Device Driver - Bus v. IRQ core

I am writing a device driver for a PCIe card in Linux. I am trying to use interrupts in my driver.

Reading the section "IRQ String" in the PCI configuration register (offset 0x3C) reports that the assigned IRQ string for device 11 . lspci -b -vv also reports that the number of interruptions of my device is 11 .

That's where it is strange ... cat /sys/bus/pci/devices/<my_device>/irq reports that the interrupt number is 19 . lspci -vv also reports that the interrupt number is 19.

Request 11 in my driver does not work. If I request 19 in the driver, I just interrupt the interrupts.

What gives?

Thanks!!!

+4
source share
2 answers

I believe this is due to the difference between the “physical” and “virtual” IRQ lines. Because the processor has a limited number of physical IRQ lines, it assigns virtual IRQ lines so that the total number of PCI devices exceeds the number of physical lines.

In this case, 19 is your virtual IRQ line (as recognized by the processor), and 11 is the physical line (as recognized by the PCI device).

By the way, you probably should really get the IRQ number from struct pci_dev for this device, since they are dynamically generated.

+5
source

Sean's answer is easy to understand. However, here I would try to make it more complete.

The output of the IRQ CPU is almost always not connected directly to the peripheral device, but through a programmable interrupt controller (PIC, for example, Intel 8259A). This helps to handle the device’s large fan, as well as a heterogeneous interrupt format (buffer-based message vs, PCIe-based).

If you run the latest version of lspci, it will print information like

 Interrupt: pin A routed to IRQ 26 

Here pin A as 11 in the OP, is a physical output. This is what the PCI device saves and is used by the hardware to communicate between interrupt controllers. From LDP:

The PCI setup code writes the pin number of the interrupt controller to the PCI configuration header for each device. He determines the interrupt number (or IRQ) using his knowledge of the PCI interrupt routing topology along with the PCI slot of the device slots and the PCI interrupt that he uses. The interrupt output is that device usage is fixed and is stored in a field in the PCI configuration header for this device. It writes this information to the interrupt line which is reserved for this purpose. When the device driver is running, it reads this information and uses it to request control of the interrupt from the Linux kernel.

IRQ 26 , since 19 in OP is kernel code and processor. According to the Linux / IRQ.txt documentation:

The IRQ number is the kernel identifier used to discuss the hardware source of the interrupt. Usually this is an index in the global irq_desc array, but with the exception that linux / interrupt.h implements architecture-specific details.

Thus, the PCI first receives interrupts from the device, transfers the interrupt source to the IRQ number, and informs the CPU. The CPU uses the IRQ number to view the interrupt descriptor table (IDT) and find the correct software handler.

Ref:

http://www.tldp.org/LDP/tlk/dd/interrupts.html http://www.brokenthorn.com/Resources/OSDevPic.html

0
source

All Articles