From ac22e2be433298054c835baf9d09bec8e1434654 Mon Sep 17 00:00:00 2001 From: Mark Kettenis Date: Sun, 19 Apr 2009 15:13:07 +0000 Subject: Fix interrupt mapping for devices behind PCI-PCI bridges. ok miod@ --- sys/arch/sgi/pci/macepcibridge.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'sys/arch') 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 #include +#include #include #include @@ -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 * -- cgit v1.2.3