diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-04-06 22:38:15 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2007-04-06 22:38:15 +0000 |
commit | 76e7df893e701ea630e25e420debd7a4c8a1071f (patch) | |
tree | be31c9c5006978ed628c61f414ef06369ed9d42c /sys/arch/sparc64 | |
parent | c186e542b69b2c292c29dc80a51671340421bc63 (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.c | 23 |
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", ®, 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); } |