diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-06-27 21:22:15 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2006-06-27 21:22:15 +0000 |
commit | 3b04cdc3ff7ae587663d97378f727afa528c6ac5 (patch) | |
tree | 88517e9548bcac06a71f9a2f649fe4cd1a113c88 /sys/arch/sparc64/dev | |
parent | ecc659c5fc44a1aedeab96ad777ecbe242dc948b (diff) |
Fix interrupt mapping. This now seems to work on all machines, even with
pci cards that have a pci-pci bridge and lack fcode.
tested by many, ok jason@, dlg@
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r-- | sys/arch/sparc64/dev/pci_machdep.c | 6 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/psycho.c | 63 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizo.c | 37 |
3 files changed, 48 insertions, 58 deletions
diff --git a/sys/arch/sparc64/dev/pci_machdep.c b/sys/arch/sparc64/dev/pci_machdep.c index b4e4565b6ca..3d1dfada715 100644 --- a/sys/arch/sparc64/dev/pci_machdep.c +++ b/sys/arch/sparc64/dev/pci_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci_machdep.c,v 1.24 2006/06/02 08:26:01 jason Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.25 2006/06/27 21:22:14 kettenis Exp $ */ /* $NetBSD: pci_machdep.c,v 1.22 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -436,7 +436,7 @@ pci_intr_map(pa, ihp) if (OF_mapintr(node, &interrupts, sizeof(interrupts), sizeof(interrupts)) < 0) { - printf("OF_mapintr failed\n"); + interrupts = -1; } /* Try to find an IPL for this type of device. */ if (OF_getprop(node, "device_type", &devtype, sizeof(devtype)) > 0) { @@ -464,7 +464,7 @@ pci_intr_string(pc, ih) static char str[16]; DPRINTF(SPDB_INTR, ("pci_intr_string: ih %u", ih)); - snprintf(str, sizeof str, "ivec %x", ih); + snprintf(str, sizeof str, "ivec 0x%x", INTVEC(ih)); DPRINTF(SPDB_INTR, ("; returning %s\n", str)); return (str); diff --git a/sys/arch/sparc64/dev/psycho.c b/sys/arch/sparc64/dev/psycho.c index 0f3defc211d..53c24be1878 100644 --- a/sys/arch/sparc64/dev/psycho.c +++ b/sys/arch/sparc64/dev/psycho.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psycho.c,v 1.43 2006/03/19 02:43:38 brad Exp $ */ +/* $OpenBSD: psycho.c,v 1.44 2006/06/27 21:22:14 kettenis Exp $ */ /* $NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp $ */ /* @@ -1031,40 +1031,37 @@ psycho_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) struct psycho_pbm *pp = pa->pa_pc->cookie; struct psycho_softc *sc = pp->pp_sc; u_int dev; - u_int ino; - ino = *ihp; - - if ((ino & ~INTMAP_PCIINT) == 0) { - /* - * This deserves some documentation. Should anyone - * have anything official looking, please speak up. - */ - if (sc->sc_mode == PSYCHO_MODE_PSYCHO && - pp->pp_id == PSYCHO_PBM_B) - dev = pa->pa_device - 2; - else - dev = pa->pa_device - 1; - - if (ino == 0 || ino > 4) { - u_int32_t intreg; - - intreg = pci_conf_read(pa->pa_pc, pa->pa_tag, - PCI_INTERRUPT_REG); - - ino = PCI_INTERRUPT_PIN(intreg) - 1; - } else - ino -= 1; - - ino &= INTMAP_PCIINT; - - ino |= sc->sc_ign; - ino |= ((pp->pp_id == PSYCHO_PBM_B) ? INTMAP_PCIBUS : 0); - ino |= (dev << 2) & INTMAP_PCISLOT; - - *ihp = ino; + if (*ihp != (pci_intr_handle_t)-1) { + *ihp |= sc->sc_ign; + return (0); } - + + /* + * We didn't find a PROM mapping for this interrupt. Try to + * construct one ourselves based on the swizzled interrupt pin + * and the interrupt mapping for PCI slots documented in the + * UltraSPARC-IIi User's Manual. + */ + + if (pa->pa_intrpin == 0) + return (-1); + + /* + * This deserves some documentation. Should anyone + * have anything official looking, please speak up. + */ + if (sc->sc_mode == PSYCHO_MODE_PSYCHO && + pp->pp_id == PSYCHO_PBM_B) + dev = PCITAG_DEV(pa->pa_intrtag) - 2; + else + dev = PCITAG_DEV(pa->pa_intrtag) - 1; + + *ihp = (pa->pa_intrpin - 1) & INTMAP_PCIINT; + *ihp |= ((pp->pp_id == PSYCHO_PBM_B) ? INTMAP_PCIBUS : 0); + *ihp |= (dev << 2) & INTMAP_PCISLOT; + *ihp |= sc->sc_ign; + return (0); } diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c index b5960956182..d7062c61e8f 100644 --- a/sys/arch/sparc64/dev/schizo.c +++ b/sys/arch/sparc64/dev/schizo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schizo.c,v 1.27 2006/06/23 16:09:45 deraadt Exp $ */ +/* $OpenBSD: schizo.c,v 1.28 2006/06/27 21:22:14 kettenis Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -364,42 +364,35 @@ schizo_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) struct schizo_pbm *sp = pa->pa_pc->cookie; struct schizo_softc *sc = sp->sp_sc; u_int dev; - u_int ino; u_int64_t agentid; - ino = *ihp; - agentid = schizo_read(sc, SCZ_CONTROL_STATUS); agentid = ((agentid >> 20) & 31) << 6; - if (ino & ~INTMAP_PCIINT) { + if (*ihp != (pci_intr_handle_t)-1) { *ihp |= agentid; return (0); } /* + * We didn't find a PROM mapping for this interrupt. Try to + * construct one ourselves based on the swizzled interrupt pin + * and the interrupt mapping for PCI slots documented in the + * UltraSPARC-IIi User's Manual. + */ + + if (pa->pa_intrpin == 0) + return (-1); + + /* * This deserves some documentation. Should anyone * have anything official looking, please speak up. */ dev = pa->pa_device - 1; - if (ino == 0 || ino > 4) { - u_int32_t intreg; - - intreg = pci_conf_read(pa->pa_pc, pa->pa_tag, - PCI_INTERRUPT_REG); - - ino = PCI_INTERRUPT_PIN(intreg) - 1; - } else - ino -= 1; - - ino &= INTMAP_PCIINT; - ino |= agentid; - ino |= (dev << 2) & INTMAP_PCISLOT; - - printf("******** mapping interrupt %x -> %x\n", *ihp, ino); - - *ihp = ino; + *ihp = (pa->pa_intrpin - 1) & INTMAP_PCIINT; + *ihp |= (dev << 2) & INTMAP_PCISLOT; + *ihp |= agentid; return (0); } |