enable interrupt routing for mcpcia based systems

Reviewed by:	mjacob, gallatin
This commit is contained in:
Bernd Walter 2003-06-28 13:47:23 +00:00
parent 1824eaaff5
commit 7d83324cdc

View file

@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <alpha/mcbus/mcpciareg.h>
#include <alpha/mcbus/mcpciavar.h>
#include <alpha/pci/pcibus.h>
#include <pci/pcireg.h>
#include <pci/pcivar.h>
#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 }
};