summaryrefslogtreecommitdiff
path: root/sys/dev/pci/ppb.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-05-21 22:10:46 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-05-21 22:10:46 +0000
commit39b73c48db0b5f8169f56b2d9f66f105f7330089 (patch)
treec0517bc9c60ca58c893ac6ec7b5b233782c7d1e5 /sys/dev/pci/ppb.c
parent9d903cf258c7152aeb91ccb923233df9c9017c86 (diff)
Implement deep interrupt swizzling by mapping all four PCI interrupt pins
for PCI-PCI bridges and passing the mapping to the attached bus device. MD code can use these when mapping PCI device interrupts. This diff adds such code for amd64 and i386. This fixes interrupt mapping for devices that sit behind two PCI-PCI bridges where the firmware only provides a mapping for the first PCI-PCI bridge. tested by sturm@, krw@, and a few others, ok deraadt@
Diffstat (limited to 'sys/dev/pci/ppb.c')
-rw-r--r--sys/dev/pci/ppb.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/dev/pci/ppb.c b/sys/dev/pci/ppb.c
index df391182b74..2a9361785dc 100644
--- a/sys/dev/pci/ppb.c
+++ b/sys/dev/pci/ppb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ppb.c,v 1.18 2007/02/13 18:35:32 tom Exp $ */
+/* $OpenBSD: ppb.c,v 1.19 2007/05/21 22:10:45 kettenis Exp $ */
/* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */
/*
@@ -45,6 +45,7 @@ struct ppb_softc {
struct device sc_dev; /* generic device glue */
pci_chipset_tag_t sc_pc; /* our PCI chipset... */
pcitag_t sc_tag; /* ...and tag. */
+ pci_intr_handle_t sc_ih[4];
};
int ppbmatch(struct device *, void *, void *);
@@ -91,6 +92,7 @@ ppbattach(struct device *parent, struct device *self, void *aux)
pci_chipset_tag_t pc = pa->pa_pc;
struct pcibus_attach_args pba;
pcireg_t busdata;
+ int pin;
printf("\n");
@@ -105,6 +107,12 @@ ppbattach(struct device *parent, struct device *self, void *aux)
return;
}
+ for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) {
+ pa->pa_intrpin = pa->pa_rawintrpin = pin;
+ pa->pa_intrline = 0;
+ pci_intr_map(pa, &sc->sc_ih[pin - PCI_INTERRUPT_PIN_A]);
+ }
+
#if 0
/*
* XXX can't do this, because we're not given our bus number
@@ -133,6 +141,7 @@ ppbattach(struct device *parent, struct device *self, void *aux)
#endif
pba.pba_domain = pa->pa_domain;
pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata);
+ pba.pba_bridgeih = sc->sc_ih;
pba.pba_bridgetag = &sc->sc_tag;
pba.pba_intrswiz = pa->pa_intrswiz;
pba.pba_intrtag = pa->pa_intrtag;