summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2009-04-19 15:13:07 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2009-04-19 15:13:07 +0000
commitac22e2be433298054c835baf9d09bec8e1434654 (patch)
treeae2bfd9c20c68dfaa6f580a34ca3589018815627 /sys/arch
parentec8ddac0b1b2a0ba80424a1b47bb6bab9e35bcf5 (diff)
Fix interrupt mapping for devices behind PCI-PCI bridges.
ok miod@
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/sgi/pci/macepcibridge.c28
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 *