From 0f43ae5b7d648754565e6fe58259790b4d9faf9e Mon Sep 17 00:00:00 2001 From: ticso Date: Sat, 28 Jun 2003 13:47:23 +0000 Subject: enable interrupt routing for mcpcia based systems Reviewed by: mjacob, gallatin --- sys/alpha/mcbus/mcpcia.c | 97 ++++++++++++++++++++++-------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) diff --git a/sys/alpha/mcbus/mcpcia.c b/sys/alpha/mcbus/mcpcia.c index 6af235a..ee2ecff 100644 --- a/sys/alpha/mcbus/mcpcia.c +++ b/sys/alpha/mcbus/mcpcia.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "alphapci_if.h" @@ -387,43 +388,49 @@ mcpcia_enable_intr_vec(int vector) } static int -mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, - driver_intr_t *intr, void *arg, void **cp) +mcpcia_pci_route_interrupt(device_t bus, device_t dev, int pin) { - struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); - int slot, mid, gid, birq, irq, error, intpin, h; - - intpin = pci_get_intpin(child); - if (intpin == 0) { - /* No IRQ used */ - return (0); - } - if (intpin < 1 || intpin > 4) { - /* Bad IRQ */ - return (ENXIO); + int irq, slot, mid; + + /* + * Validate requested pin number. + */ + if ((pin < 1) || (pin > 4)) { + printf("mcpcia_pci_route_interrupt: bad interrupt pin %d\n", + pin); + return(255); } - slot = pci_get_slot(child); - mid = mcbus_get_mid(dev); - gid = mcbus_get_gid(dev); + slot = pci_get_slot(dev); + mid = mcbus_get_mid(bus); - if (slot == 0) { - device_t bdev; - /* bridged - get slot from grandparent */ - /* note that this is broken for all but the most trival case */ - bdev = device_get_parent(device_get_parent(child)); - slot = pci_get_slot(bdev); - } +#if 0 + printf("mcpcia_pci_route_interrupt: called for slot=%d, pin=%d, mid=%d\n", slot, pin, mid); +#endif if (mid == 5 && slot == 1) { irq = 16; /* MID 5, slot 1, is the internal NCR 53c810 */ } else if (slot >= 2 && slot <= 5) { - irq = ((slot - 2) * 4) + (intpin - 1); + irq = ((slot - 2) * 4) + (pin - 1); } else { - device_printf(child, "weird slot number (%d); can't make irq\n", + printf("mcpcia_pci_route_interrupt: weird device number %d\n", slot); - return (ENXIO); + return (255); } + + return(irq); +} + +static int +mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, + driver_intr_t *intr, void *arg, void **cp) +{ + struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); + int mid, birq, irq, error, h; + + irq = ir->r_start; + mid = mcbus_get_mid(dev); + error = rman_activate_resource(ir); if (error) return error; @@ -437,8 +444,8 @@ mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, } else { h = MCPCIA_VEC_PCI + ((mid - MCPCIA_PCI_MIDMIN) * MCPCIA_VECWIDTH_PER_MCPCIA) + - (slot * MCPCIA_VECWIDTH_PER_SLOT) + - ((intpin - 1) * MCPCIA_VECWIDTH_PER_INTPIN); + irq * MCPCIA_VECWIDTH_PER_INTPIN + + 2 * MCPCIA_VECWIDTH_PER_SLOT; } birq = irq + INTRCNT_KN300_IRQ; error = alpha_setup_intr(device_get_nameunit(child), h, @@ -449,8 +456,8 @@ mcpcia_setup_intr(device_t dev, device_t child, struct resource *ir, int flags, mtx_lock_spin(&icu_lock); mcpcia_enable_intr(sc, irq); mtx_unlock_spin(&icu_lock); - device_printf(child, "interrupting at IRQ 0x%x int%c (vec 0x%x)\n", - irq, intpin - 1 + 'A' , h); + device_printf(child, "interrupting at IRQ 0x%x (vec 0x%x)\n", + irq , h); return (0); } @@ -458,30 +465,9 @@ static int mcpcia_teardown_intr(device_t dev, device_t child, struct resource *i, void *c) { struct mcpcia_softc *sc = MCPCIA_SOFTC(dev); - int slot, mid, intpin, irq; - - intpin = pci_get_intpin(child); - if (intpin == 0) { - /* No IRQ used */ - return (0); - } - if (intpin < 1 || intpin > 4) { - /* Bad IRQ */ - return (ENXIO); - } - - slot = pci_get_slot(child); - mid = mcbus_get_mid(dev); - if (mid == 5 && slot == 1) { - irq = 16; - } else if (slot >= 2 && slot <= 5) { - irq = ((slot - 2) << 4) + (intpin - 1); - } else { - return (ENXIO); - } mtx_lock_spin(&icu_lock); - mcpcia_disable_intr(sc, irq); + mcpcia_disable_intr(sc, i->r_start); mtx_unlock_spin(&icu_lock); alpha_teardown_intr(c); return (rman_deactivate_resource(i)); @@ -554,6 +540,11 @@ mcpcia_read_config(device_t dev, int bus, int slot, int func, u_int32_t *dp, data, rvp; u_int64_t paddr; + if ((off == PCIR_INTLINE) && (sz == 1)) { + /* SRM left bad value; let intr_route fill them in later */ + return ~0; + } + rvp = data = ~0; /* @@ -789,7 +780,7 @@ static device_method_t mcpcia_methods[] = { DEVMETHOD(pcib_maxslots, mcpcia_maxslots), DEVMETHOD(pcib_read_config, mcpcia_read_config), DEVMETHOD(pcib_write_config, mcpcia_write_config), - DEVMETHOD(pcib_route_interrupt, alpha_pci_route_interrupt), + DEVMETHOD(pcib_route_interrupt, mcpcia_pci_route_interrupt), { 0, 0 } }; -- cgit v1.1