diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-04-19 15:13:07 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-04-19 15:13:07 +0000 |
commit | ac22e2be433298054c835baf9d09bec8e1434654 (patch) | |
tree | ae2bfd9c20c68dfaa6f580a34ca3589018815627 /sys | |
parent | ec8ddac0b1b2a0ba80424a1b47bb6bab9e35bcf5 (diff) |
Fix interrupt mapping for devices behind PCI-PCI bridges.
ok miod@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sgi/pci/macepcibridge.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/sys/arch/sgi/pci/macepcibridge.c b/sys/arch/sgi/pci/macepcibridge.c index 338312a4397..9b140e68855 100644 --- a/sys/arch/sgi/pci/macepcibridge.c +++ b/sys/arch/sgi/pci/macepcibridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: macepcibridge.c,v 1.19 2009/04/18 19:26:16 miod Exp $ */ +/* $OpenBSD: macepcibridge.c,v 1.20 2009/04/19 15:13:06 kettenis Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se) @@ -46,6 +46,7 @@ #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> +#include <dev/pci/ppbreg.h> #include <mips64/archtype.h> #include <sgi/localbus/crimebus.h> @@ -397,7 +398,7 @@ mace_pcibr_conf_write(cpv, tag, offset, data) int mace_pcibr_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) { - int bus, device, pirq; + int bus, dev, pin = pa->pa_rawintrpin; static const signed char intrmap[][PCI_INTERRUPT_PIN_MAX] = { { -1, -1, -1, -1 }, { 9, -1, -1, -1 }, /* ahc0 */ @@ -409,25 +410,30 @@ mace_pcibr_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) *ihp = -1; - if (pa->pa_intrpin == 0) { + if (pin == 0) { /* No IRQ used. */ return 1; } #ifdef DIAGNOSTIC - if (pa->pa_intrpin > 4) { - printf("mace_pcibr_intr_map: bad interrupt pin %d\n", pa->pa_intrpin); + if (pin > PCI_INTERRUPT_PIN_MAX) { + printf("mace_pcibr_intr_map: bad interrupt pin %d\n", pin); return 1; } #endif - pci_decompose_tag(pa->pa_pc, pa->pa_intrtag, &bus, &device, NULL); + pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, NULL); - pirq = -1; - if ((unsigned int)device < sizeof(intrmap) / PCI_INTERRUPT_PIN_MAX) - pirq = intrmap[device][pa->pa_intrpin - PCI_INTERRUPT_PIN_A]; + if (pa->pa_bridgetag) { + pin = PPB_INTERRUPT_SWIZZLE(pin, dev); + *ihp = pa->pa_bridgeih[pin - PCI_INTERRUPT_PIN_A]; - *ihp = pirq; - return pirq >= 0 ? 0 : 1; + return ((*ihp == -1) ? 1 : 0); + } + + if (dev < nitems(intrmap)) + *ihp = intrmap[dev][pin - PCI_INTERRUPT_PIN_A]; + + return ((*ihp == -1) ? 1 : 0); } const char * |