diff options
author | tmm <tmm@FreeBSD.org> | 2002-12-01 23:06:14 +0000 |
---|---|---|
committer | tmm <tmm@FreeBSD.org> | 2002-12-01 23:06:14 +0000 |
commit | fd64c667053d30c37409805102f3e1ab46a18cf9 (patch) | |
tree | c9420825323d1b764816c28ceca4f9dac0fd0903 /sys/sparc64/pci | |
parent | efc50261ded89bf1501b4fe634861f8b9866e989 (diff) | |
download | FreeBSD-src-fd64c667053d30c37409805102f3e1ab46a18cf9.zip FreeBSD-src-fd64c667053d30c37409805102f3e1ab46a18cf9.tar.gz |
Reverse the quirk table entry for swizzling on a missing interrupt map;
this is now done on all machines except for some known problematic ones.
Add an additional guard to make sure that the interrupt numbers are
in the correct range before swizzling. This should catch any remaining
models for which the swizzle is inappropriate.
Correct the swizzle calculation to account for the fact that the parent
interrupt numbers to be swizzled are 1-based.
Approved by: re
Diffstat (limited to 'sys/sparc64/pci')
-rw-r--r-- | sys/sparc64/pci/ofw_pci.c | 17 |
1 files changed, 10 insertions, 7 deletions
diff --git a/sys/sparc64/pci/ofw_pci.c b/sys/sparc64/pci/ofw_pci.c index 6d7754b..9e3b679 100644 --- a/sys/sparc64/pci/ofw_pci.c +++ b/sys/sparc64/pci/ofw_pci.c @@ -55,12 +55,13 @@ u_int8_t pci_bus_cnt; phandle_t *pci_bus_map; int pci_bus_map_sz; -#define OPQ_NEED_SWIZZLE 1 +#define OPQ_NO_SWIZZLE 1 static struct ofw_pci_quirk { char *opq_model; int opq_quirks; } ofw_pci_quirks[] = { - { "SUNW,UltraSPARC-IIi-cEngine", OPQ_NEED_SWIZZLE } + { "SUNW,Ultra-4", OPQ_NO_SWIZZLE }, + { "SUNW,Ultra-1-Engine", OPQ_NO_SWIZZLE }, }; #define OPQ_NENT (sizeof(ofw_pci_quirks) / sizeof(ofw_pci_quirks[0])) @@ -77,18 +78,20 @@ ofw_pci_orb_callback(phandle_t node, u_int8_t *pintptr, int pintsz, u_int32_t pintr, intr; char type[32]; - if ((pci_quirks & OPQ_NEED_SWIZZLE) != 0 && - pintsz == sizeof(u_int32_t) && pregsz >= sizeof(preg) && + if (pintsz != sizeof(u_int32_t)) + return (-1); + bcopy(pintptr, &pintr, sizeof(pintr)); + if ((pci_quirks & OPQ_NO_SWIZZLE) == 0 && pregsz >= sizeof(preg) && OF_getprop(node, "device_type", type, sizeof(type)) != -1 && - strcmp(type, OFW_PCI_PCIBUS) == 0) { + strcmp(type, OFW_PCI_PCIBUS) == 0 && pintr >= 1 && pintr <= 4) { /* * Handle a quirk found on some Netra t1 models: there exist * PCI bridges without interrupt maps, where we apparently must * do the PCI swizzle and continue to map on at the parent. */ - bcopy(pintptr, &pintr, sizeof(pintr)); bcopy(pregptr, &preg, sizeof(preg)); - intr = (OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi) + pintr) % 4; + intr = (OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi) + pintr + 3) % + 4 + 1; *rintr = malloc(sizeof(intr), M_OFWPROP, M_WAITOK); bcopy(&intr, *rintr, sizeof(intr)); *terminate = 0; |