mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-03 23:28:58 +00:00
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:
parent
0ca54a0fc8
commit
618f2b4d55
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=175222
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue