The PCI bus is designed so that multiple devices may physically share a single interrupt line. Most current Linux device drivers for PCI devices support this feature, but there are exceptions and several potential problem you may encounter.
The usual symptom of an interrupt problem with an Ethernet device driver is that 'ifconfig' reports an EAGAIN error when the interface is started. This error is typically reported with the message "Try again", which means "try again when the interrupt conflict is cleared".
When you encounter this error message you can run the 'ifconfig' or 'dmesg' programs and compare the requested IRQ with the contents of /proc/interrupts to determine the device conflicts.
If the card is reporting IRQ0 or IRQ255, that indicates the card has not been assigned an interrupt. There are two likely fixes: either the BIOS does not have enough IRQ lines available for PCI devices (e.g. all are assigned to "legacy" ISA devices instead of "PnP"), or the BIOS has a "PnP OS" setting that must be disabled. Yes, this is confusing: the "PnP OS" setting is bad (it really means "Windows OS?"), but the PnP IRQ assignment is good.
If the card is reporting a valid IRQ, but that IRQ is being used by another device you have an interrupt conflict. The easiest and generally best solution is to put the conflicting device on another IRQ line. This can only be done through the PCI BIOS setup. Unlike ISA cards, PCI cards have no way of setting their own IRQ. That is done at boot time by the PCI BIOS, and the BIOS reports its selection
If the conflicting device is a SCSI driver, updating the kernel to 2.0.33 or later will often allow you to use the newer SCSI drivers that are willing to share an IRQ line. (See below for information on how to do with without upgrading to 2.0.33.)
- if (request_irq(config->irq, aic7xxx_isr, SA_INTERRUPT | SA_SHIRQ, + if (request_irq(config->irq, aic7xxx_isr, SA_SHIRQ, "aic7xxx", NULL))
An alternate solution when using the PR440FX "Providence" motherboard is to force assignment of separate interrupt lines. A way to do this is detailed in Configuring the PR440FX motherboard written by Larry M. Augustin at VA Research.
Larry also reports that
PCI cards are detected in PCI device order. There is no fixed rule, but use the following guidelines:
You might as well learn something pointlessly technical while you are here...
The SA_INTERRUPT flag indicates "fast interrupts", where interrupt handlers run with all other interrupts disabled in return for the promise that they will limit their work to trivial, strictly-limited actions. But the SA_INTERRUPT requirement cannot be met when the interrupt line is shared: an arbitrary collection of trivial tasks is no longer trivial.
SA_INTERRUPT was designed for no-FIFO (and thus high-priority) serial ports where the only work that needed to be done was removing a single byte from the UART, writing it to a queue, and setting the "bottom half" flag. All other work was done later, with interrupts enabled, in the kernel "bottom half".
While the Ethernet drivers (and most other drivers) will work with the SA_INTERRUPT flag, it could potentially have a very negative impact on all other interrupt-driven kernel service. That includes just about everything that the system does, including timer ticks.
I believe that very few complex devices can be correctly run by a device driver that uses SA_INTERRUPT. The BusLogic driver, in particular, does an extensive and potentially unlimited amount of work. It should *not* be using SA_INTERRUPT. My Ethernet drivers do much less work at interrupt time, and have strict work limits, and even I don't feel that they should be run with SA_INTERRUPT.
Clarifications, suggestions, changes and updates to this page are always welcome.