summaryrefslogtreecommitdiffstats
path: root/sys/i386/pci
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-12-21 16:53:27 +0000
committerjhb <jhb@FreeBSD.org>2007-12-21 16:53:27 +0000
commitca176184207c9b8a9cbb9cd35b05bba195bdaf45 (patch)
tree3c39add769ca11fd6ddc5c952800aafd00b360ef /sys/i386/pci
parent6f627a80edd408edbcc4ee4b3f15e7759eae45d8 (diff)
downloadFreeBSD-src-ca176184207c9b8a9cbb9cd35b05bba195bdaf45.zip
FreeBSD-src-ca176184207c9b8a9cbb9cd35b05bba195bdaf45.tar.gz
More properly handle links who only have 1 valid IRQ in their bitmask. The
old code special cased them too early which caused a few differences for these sort of links relative to other PCI links: - They were always re-routed via the BIOS call instead of assuming that they were already routed if the BIOS had programmed the IRQ into a matching device during POST. - If the BIOS did route that link to a different IRQ that was marked as invalid, we trusted the $PIR table rather than the BIOS IRQ. This change moves the special casing for "unique IRQ" links to only take that into account when picking an IRQ for an unrouted link so that these links will now not be routed if the BIOS appears to have routed it already (some BIOSen have problems with that) and so that if the BIOS uses a different IRQ than the $PIR, we trust the BIOS routing instead (this is what we do for all other links as well). Reported by: Bruce Walter walter of fortean com MFC after: 1 week
Diffstat (limited to 'sys/i386/pci')
-rw-r--r--sys/i386/pci/pci_pir.c25
1 files changed, 12 insertions, 13 deletions
diff --git a/sys/i386/pci/pci_pir.c b/sys/i386/pci/pci_pir.c
index 3dd10c1..52fb62f 100644
--- a/sys/i386/pci/pci_pir.c
+++ b/sys/i386/pci/pci_pir.c
@@ -398,12 +398,6 @@ pci_pir_parse(void)
pci_pir_dump_links();
}
- /* Check for unique IRQ masks. */
- TAILQ_FOREACH(pci_link, &pci_links, pl_links) {
- if (pci_link->pl_irqmask != 0 && powerof2(pci_link->pl_irqmask))
- pci_link->pl_irq = ffs(pci_link->pl_irqmask) - 1;
- }
-
/*
* Check to see if the BIOS has already routed any of the links by
* checking each device connected to each link to see if it has a
@@ -516,15 +510,20 @@ pci_pir_route_interrupt(int bus, int device, int func, int pin)
}
/*
- * Pick a new interrupt if we don't have one already. We look for
- * an interrupt from several different sets. First, we check the
- * set of PCI only interrupts from the $PIR. Second, we check the
- * set of known-good interrupts that the BIOS has already used.
- * Lastly, we check the "all possible valid IRQs" set.
+ * Pick a new interrupt if we don't have one already. We look
+ * for an interrupt from several different sets. First, if
+ * this link only has one valid IRQ, use that. Second, we
+ * check the set of PCI only interrupts from the $PIR. Third,
+ * we check the set of known-good interrupts that the BIOS has
+ * already used. Lastly, we check the "all possible valid
+ * IRQs" set.
*/
if (!PCI_INTERRUPT_VALID(pci_link->pl_irq)) {
- irq = pci_pir_choose_irq(pci_link,
- pci_route_table->pt_header.ph_pci_irqs);
+ if (pci_link->pl_irqmask != 0 && powerof2(pci_link->pl_irqmask))
+ irq = ffs(pci_link->pl_irqmask) - 1;
+ else
+ irq = pci_pir_choose_irq(pci_link,
+ pci_route_table->pt_header.ph_pci_irqs);
if (!PCI_INTERRUPT_VALID(irq))
irq = pci_pir_choose_irq(pci_link, pir_bios_irqs);
if (!PCI_INTERRUPT_VALID(irq))
OpenPOWER on IntegriCloud