summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgrehan <grehan@FreeBSD.org>2004-02-10 23:57:35 +0000
committergrehan <grehan@FreeBSD.org>2004-02-10 23:57:35 +0000
commita32b342ca2e893915bb6648e925d7ef61900ee7d (patch)
tree8268b77b3ec47f5544a9d09cb55993e3f843d3d7
parent5280743f492aea0d78704ccca6afe522cb67061d (diff)
downloadFreeBSD-src-a32b342ca2e893915bb6648e925d7ef61900ee7d.zip
FreeBSD-src-a32b342ca2e893915bb6648e925d7ef61900ee7d.tar.gz
Correctly create interrupt key for PCI, which is the OpenFirmware
pci-hi/med/lo + node 'interrupts' property. This worked by accident until recent notebooks required correct operation. Tested by: Suleiman Souhlal <refugee@segfaulted.com>
-rw-r--r--sys/powerpc/ofw/ofw_pci.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/powerpc/ofw/ofw_pci.c b/sys/powerpc/ofw/ofw_pci.c
index 2c9cff5..5c78d02 100644
--- a/sys/powerpc/ofw/ofw_pci.c
+++ b/sys/powerpc/ofw/ofw_pci.c
@@ -94,7 +94,7 @@ ofw_pci_fixup(device_t dev, u_int bus, phandle_t parentnode)
static void
fixup_node(device_t dev, phandle_t node)
{
- u_int32_t csr, intr, irqs[4];
+ u_int32_t csr, intr, irqs[4], npintr, paddr[4];
struct ofw_pci_register addr[8];
int len, i;
@@ -123,7 +123,19 @@ fixup_node(device_t dev, phandle_t node)
OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
OFW_PCI_PHYS_HI_FUNCTION(addr[0].phys_hi), PCIR_COMMAND, csr, 4);
- if (find_node_intr(node, &addr[0].phys_hi, irqs) != -1) {
+ /*
+ * Create PCI interrupt-map array element. pci-mid/pci-lo
+ * aren't required, but the 'interrupts' property needs
+ * to be appended
+ */
+ npintr = 0;
+ OF_getprop(node, "interrupts", &npintr, 4);
+ paddr[0] = addr[0].phys_hi;
+ paddr[1] = 0;
+ paddr[2] = 0;
+ paddr[3] = npintr;
+
+ if (find_node_intr(node, paddr, irqs) != -1) {
intr = PCIB_READ_CONFIG(dev,
OFW_PCI_PHYS_HI_BUS(addr[0].phys_hi),
OFW_PCI_PHYS_HI_DEVICE(addr[0].phys_hi),
@@ -159,9 +171,8 @@ find_node_intr(phandle_t node, u_int32_t *addr, u_int32_t *intr)
if (len == -1 || mlen == -1)
goto nomap;
- /* mask addr by "interrupt-map-mask" */
- bcopy(addr, maskedaddr, mlen);
- for (i = 0; i < mlen / 4; i++)
+ memcpy(maskedaddr, addr, mlen);
+ for (i = 0; i < mlen/4; i++)
maskedaddr[i] &= imask[i];
mp = map;
@@ -209,15 +220,10 @@ nomap:
len = OF_getprop(parent, "interrupt-map", map, sizeof(map));
if (len >= 36) {
addr = &map[5];
+ /* XXX Use 0 for 'interrupts' for compat */
return (find_node_intr(parent, addr, intr));
}
}
- /* XXX This may be wrong... */
- len = OF_getprop(node, "interrupts", intr, 4);
- if (len == 4) {
- return (len);
- }
-
return (-1);
}
OpenPOWER on IntegriCloud