summaryrefslogtreecommitdiff
path: root/sys/arch/sparc64
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-04-06 22:38:15 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-04-06 22:38:15 +0000
commit76e7df893e701ea630e25e420debd7a4c8a1071f (patch)
treebe31c9c5006978ed628c61f414ef06369ed9d42c /sys/arch/sparc64
parentc186e542b69b2c292c29dc80a51671340421bc63 (diff)
Add support for PCIe. Don't map interrupts that are already mapped correctly.
Tested by deraadt@, nick@, sturm@, naddy@ and others.
Diffstat (limited to 'sys/arch/sparc64')
-rw-r--r--sys/arch/sparc64/sparc64/ofw_machdep.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/sys/arch/sparc64/sparc64/ofw_machdep.c b/sys/arch/sparc64/sparc64/ofw_machdep.c
index a078b257f4e..76b6ea40dc2 100644
--- a/sys/arch/sparc64/sparc64/ofw_machdep.c
+++ b/sys/arch/sparc64/sparc64/ofw_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_machdep.c,v 1.16 2007/01/16 14:39:57 tsi Exp $ */
+/* $OpenBSD: ofw_machdep.c,v 1.17 2007/04/06 22:38:14 kettenis Exp $ */
/* $NetBSD: ofw_machdep.c,v 1.16 2001/07/20 00:07:14 eeh Exp $ */
/*
@@ -677,7 +677,8 @@ find_pci_host_node(int node)
&dev_type, sizeof(dev_type));
if (len <= 0)
continue;
- if (!strcmp(dev_type, "pci"))
+ if (strcmp(dev_type, "pci") == 0 ||
+ strcmp(dev_type, "pciex") == 0)
pch = node;
}
return pch;
@@ -727,8 +728,7 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
}
phc_node = find_pci_host_node(node);
-
- for (; node; node = OF_parent(node)) {
+ while (node) {
#ifdef DEBUG
char name[40];
@@ -746,7 +746,8 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
/* Swizzle interrupt if this is a PCI bridge. */
if (((len = OF_getprop(node, "device_type", &dev_type,
sizeof(dev_type))) > 0) &&
- !strcmp(dev_type, "pci") &&
+ (strcmp(dev_type, "pci") == 0 ||
+ strcmp(dev_type, "pciex") == 0) &&
(node != phc_node)) {
*interrupt = ((*interrupt +
OFW_PCI_PHYS_HI_DEVICE(reg[0]) - 1) & 3) + 1;
@@ -757,6 +758,8 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
/* Get reg for next level compare. */
reg[0] = 0;
OF_getprop(node, "reg", &reg, sizeof(reg));
+
+ node = OF_parent(node);
continue;
}
/* Convert from bytes to cells. */
@@ -799,9 +802,9 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
#endif
- /* finally we can attempt the compare */
- i=0;
- while ( i < interrupt_map_len + address_cells + interrupt_cells) {
+ /* Finally we can attempt the compare. */
+ i = 0;
+ while (i < interrupt_map_len + address_cells + interrupt_cells) {
int pintr_cells;
int *imap = &interrupt_map[i];
int *parent = &imap[address_cells + interrupt_cells];
@@ -836,6 +839,7 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
/* Error -- ran out of storage. */
return (-1);
}
+ node = *parent;
parent++;
#ifdef DEBUG
DPRINTF(("Match! using "));
@@ -845,6 +849,8 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
for (i=0; i<pintr_cells; i++)
interrupt[i] = parent[i];
rc = validlen = pintr_cells;
+ if (node == phc_node)
+ return (rc);
break;
}
/* Move on to the next interrupt_map entry. */
@@ -866,6 +872,7 @@ OF_mapintr(int node, int *interrupt, int validlen, int buflen)
}
DPRINTF(("reg len %d\n", len));
+ node = OF_parent(node);
}
return (rc);
}