diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-05-03 21:23:05 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2009-05-03 21:23:05 +0000 |
commit | 444cf09812c53e424a7a660801091456e94aeaa0 (patch) | |
tree | 6235fdb8b6a09b6eba7f9a6c8839abfedeaaca64 /sys/arch/sparc64/dev/pci_machdep.c | |
parent | 85fcad227f1983194b01453d5855f1093bfb187f (diff) |
On the UltraBook the PROM privides two interrupts for its ccb(4)'s. Handle
this case by choosing the interrupt that corresponds to the PCI function.
Makes the second PCMCIA slot work.
Diffstat (limited to 'sys/arch/sparc64/dev/pci_machdep.c')
-rw-r--r-- | sys/arch/sparc64/dev/pci_machdep.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/sys/arch/sparc64/dev/pci_machdep.c b/sys/arch/sparc64/dev/pci_machdep.c index 0066ec2b73e..08ef6504b91 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.36 2008/03/24 21:24:30 kettenis Exp $ */ +/* $OpenBSD: pci_machdep.c,v 1.37 2009/05/03 21:23:04 kettenis Exp $ */ /* $NetBSD: pci_machdep.c,v 1.22 2001/07/20 00:07:13 eeh Exp $ */ /* @@ -344,38 +344,47 @@ pci_intr_map(pa, ihp) pci_intr_handle_t *ihp; { pcitag_t tag = pa->pa_tag; - int interrupts; + int interrupts[4], ninterrupts; int len, node = PCITAG_NODE(tag); char devtype[30]; len = OF_getproplen(node, "interrupts"); - if (len < 0 || len < sizeof(interrupts)) { + if (len < 0 || len < sizeof(interrupts[0])) { DPRINTF(SPDB_INTMAP, ("pci_intr_map: interrupts len %d too small\n", len)); return (ENODEV); } - if (OF_getprop(node, "interrupts", (void *)&interrupts, - sizeof(interrupts)) != len) { + if (OF_getprop(node, "interrupts", interrupts, + sizeof(interrupts)) != len) { DPRINTF(SPDB_INTMAP, ("pci_intr_map: could not read interrupts\n")); return (ENODEV); } - if (OF_mapintr(node, &interrupts, sizeof(interrupts), - sizeof(interrupts)) < 0) { - interrupts = -1; + /* + * If we have multiple interrupts for a device, choose the one + * that corresponds to the PCI function. This makes the + * second PC Card slot on the UltraBook get the right interrupt. + */ + ninterrupts = len / sizeof(interrupts[0]); + if (PCITAG_FUN(pa->pa_tag) < ninterrupts) + interrupts[0] = interrupts[PCITAG_FUN(pa->pa_tag)]; + + if (OF_mapintr(node, &interrupts[0], sizeof(interrupts[0]), + sizeof(interrupts)) < 0) { + interrupts[0] = -1; } /* Try to find an IPL for this type of device. */ if (OF_getprop(node, "device_type", &devtype, sizeof(devtype)) > 0) { for (len = 0; intrmap[len].in_class; len++) if (strcmp(intrmap[len].in_class, devtype) == 0) { - interrupts |= INTLEVENCODE(intrmap[len].in_lev); + interrupts[0] |= INTLEVENCODE(intrmap[len].in_lev); break; } } /* XXXX -- we use the ino. What if there is a valid IGN? */ - *ihp = interrupts; + *ihp = interrupts[0]; if (pa->pa_pc->intr_map) return ((*pa->pa_pc->intr_map)(pa, ihp)); |