mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
enable interrupt routing for mcpcia based systems
Reviewed by: mjacob, gallatin
This commit is contained in:
parent
1824eaaff5
commit
7d83324cdc
1 changed files with 44 additions and 53 deletions
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue