Work around problems with the ppbus(4)'s interesting way of managing

interrupt handlers for child devices by adding a dummy handler that is
always present so that the underlying interrupt thread is always around
avoiding panics from stray interrupts.

MFC after:	3 days
This commit is contained in:
John Baldwin 2008-01-10 23:43:47 +00:00
parent 0ca54a0fc8
commit 618f2b4d55
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175222
2 changed files with 40 additions and 0 deletions

View file

@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <dev/ppbus/ppbconf.h>
#include <dev/ppbus/ppb_1284.h>
@ -380,9 +383,38 @@ ppb_scan_bus(device_t bus)
#endif /* !DONTPROBE_1284 */
static void
ppbus_dummy_intr(void *arg)
{
}
static int
ppbus_attach(device_t dev)
{
struct ppb_data *ppb = (struct ppb_data *)device_get_softc(dev);
uintptr_t irq;
int error, rid;
/* Attach a dummy interrupt handler to suck up any stray interrupts. */
BUS_READ_IVAR(device_get_parent(dev), dev, PPC_IVAR_IRQ, &irq);
if (irq > 0) {
rid = 0;
ppb->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, irq,
irq, 1, RF_SHAREABLE);
if (ppb->irq_res != NULL) {
error = bus_setup_intr(dev, ppb->irq_res,
INTR_TYPE_TTY | INTR_MPSAFE, NULL, ppbus_dummy_intr,
ppb, &ppb->intr_cookie);
if (error) {
device_printf(dev,
"failed to setup interrupt handler\n");
bus_release_resource(dev, SYS_RES_IRQ, 0,
ppb->irq_res);
return (error);
}
}
}
/* Locate our children */
bus_generic_probe(dev);
@ -401,6 +433,7 @@ ppbus_attach(device_t dev)
static int
ppbus_detach(device_t dev)
{
struct ppb_data *ppb = (struct ppb_data *)device_get_softc(dev);
device_t *children;
int nchildren, i;
@ -412,6 +445,10 @@ ppbus_detach(device_t dev)
free(children, M_TEMP);
}
if (ppb->irq_res != NULL) {
bus_teardown_intr(dev, ppb->irq_res, ppb->intr_cookie);
bus_release_resource(dev, SYS_RES_IRQ, 0, ppb->irq_res);
}
return (0);
}

View file

@ -248,6 +248,9 @@ struct ppb_data {
* NIBBLE, PS2, EPP or ECP */
void *ppb_owner; /* device which owns the bus */
struct resource *irq_res;
void *intr_cookie;
};
#ifdef _KERNEL