summaryrefslogtreecommitdiffstats
path: root/sys/dev/ppbus
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2008-09-15 22:26:32 +0000
committerjhb <jhb@FreeBSD.org>2008-09-15 22:26:32 +0000
commitc0edaf988ab997509a5c7a738c5fb5c5305cc014 (patch)
treec5d594dd29d8cb1dbd07768c75b6649ad621cee2 /sys/dev/ppbus
parenta55e334c2b95f0796667f2ecdd2434e08fe6f8fc (diff)
downloadFreeBSD-src-c0edaf988ab997509a5c7a738c5fb5c5305cc014.zip
FreeBSD-src-c0edaf988ab997509a5c7a738c5fb5c5305cc014.tar.gz
Rework the handling of interrupt handlers for children of ppc and ppbus:
- Retire IVARs for passing IRQs around. Instead, ppbus and ppc now allow child devices to access the interrupt by via a rid 0 IRQ resource using bus_alloc_resource_any(). - ppc creates its own interrupt event to manage the interrupt handlers of child devices. ppc does not allow child devices to use filters. It could allow this if needed, but none of the current drivers use them and it adds a good bit of complication. It uses intr_event_execute_handlers() to fire the child device interrupt handlers from its threaded interrupt handler. - Remove the ppbus_dummy_intr() hack. Now the ppc device always has an interrupt handler registered and we no longer bounce all the way up to nexus to manage adding/removing ppbus child interrupt handlers. Instead, the child handlers are added and removed to the private interrupt event in the ppc device.
Diffstat (limited to 'sys/dev/ppbus')
-rw-r--r--sys/dev/ppbus/if_plip.c39
-rw-r--r--sys/dev/ppbus/lpt.c16
-rw-r--r--sys/dev/ppbus/ppbconf.c40
-rw-r--r--sys/dev/ppbus/ppbconf.h5
-rw-r--r--sys/dev/ppbus/ppi.c10
-rw-r--r--sys/dev/ppbus/pps.c14
6 files changed, 27 insertions, 97 deletions
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index 8eb200b..291c2db 100644
--- a/sys/dev/ppbus/if_plip.c
+++ b/sys/dev/ppbus/if_plip.c
@@ -193,33 +193,6 @@ lp_identify(driver_t *driver, device_t parent)
static int
lp_probe(device_t dev)
{
- device_t ppbus = device_get_parent(dev);
- struct lp_data *lp;
- int zero = 0;
- uintptr_t irq;
-
- lp = DEVTOSOFTC(dev);
-
- /* retrieve the ppbus irq */
- BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
-
- /* if we haven't interrupts, the probe fails */
- if (irq == -1) {
- device_printf(dev, "not an interrupt driven port, failed.\n");
- return (ENXIO);
- }
-
- /* reserve the interrupt resource, expecting irq is available to continue */
- lp->res_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, irq, irq, 1,
- RF_SHAREABLE);
- if (lp->res_irq == 0) {
- device_printf(dev, "cannot reserve interrupt, failed.\n");
- return (ENXIO);
- }
-
- /*
- * lp dependent initialisation.
- */
device_set_desc(dev, "PLIP network interface");
@@ -231,6 +204,18 @@ lp_attach (device_t dev)
{
struct lp_data *lp = DEVTOSOFTC(dev);
struct ifnet *ifp;
+ int rid = 0;
+
+ /*
+ * Reserve the interrupt resource. If we don't have one, the
+ * attach fails.
+ */
+ lp->res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE);
+ if (lp->res_irq == 0) {
+ device_printf(dev, "cannot reserve interrupt, failed.\n");
+ return (ENXIO);
+ }
ifp = lp->sc_ifp = if_alloc(IFT_PARA);
if (ifp == NULL) {
diff --git a/sys/dev/ppbus/lpt.c b/sys/dev/ppbus/lpt.c
index 1986d56..d507f14 100644
--- a/sys/dev/ppbus/lpt.c
+++ b/sys/dev/ppbus/lpt.c
@@ -367,9 +367,8 @@ lpt_attach(device_t dev)
{
device_t ppbus = device_get_parent(dev);
struct lpt_data *sc = DEVTOSOFTC(dev);
- int zero = 0, unit = device_get_unit(dev);
+ int rid = 0, unit = device_get_unit(dev);
int error;
- intptr_t irq;
sc->sc_primed = 0; /* not primed yet */
@@ -383,14 +382,9 @@ lpt_attach(device_t dev)
/* check if we can use interrupt, should be done by ppc stuff */
lprintf(("oldirq %x\n", sc->sc_irq));
- /* retrieve the ppbus irq */
- BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
-
- if (irq > 0) {
- /* declare our interrupt handler */
- sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
- &zero, irq, irq, 1, RF_SHAREABLE);
- }
+ /* declare our interrupt handler */
+ sc->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE);
if (sc->intr_resource) {
sc->sc_irq = LP_HAS_IRQ | LP_USE_IRQ | LP_ENABLE_IRQ;
device_printf(dev, "Interrupt-driven port\n");
@@ -398,7 +392,7 @@ lpt_attach(device_t dev)
sc->sc_irq = 0;
device_printf(dev, "Polled port\n");
}
- lprintf(("irq %x %x\n", (int)irq, sc->sc_irq));
+ lprintf(("irq %x\n", sc->sc_irq));
lpt_release_ppbus(dev);
diff --git a/sys/dev/ppbus/ppbconf.c b/sys/dev/ppbus/ppbconf.c
index 7fbd801..c0401c8 100644
--- a/sys/dev/ppbus/ppbconf.c
+++ b/sys/dev/ppbus/ppbconf.c
@@ -121,9 +121,6 @@ ppbus_read_ivar(device_t bus, device_t dev, int index, uintptr_t* val)
case PPBUS_IVAR_AVM:
*val = (u_long)ppbdev->avm;
break;
- case PPBUS_IVAR_IRQ:
- BUS_READ_IVAR(device_get_parent(bus), bus, PPC_IVAR_IRQ, val);
- break;
default:
return (ENOENT);
}
@@ -383,38 +380,9 @@ end_scan:
#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);
@@ -433,7 +401,6 @@ 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;
@@ -445,10 +412,6 @@ 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);
}
@@ -602,7 +565,8 @@ static device_method_t ppbus_methods[] = {
DEVMETHOD(bus_write_ivar, ppbus_write_ivar),
DEVMETHOD(bus_setup_intr, ppbus_setup_intr),
DEVMETHOD(bus_teardown_intr, ppbus_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_release_resource, bus_generic_release_resource),
{ 0, 0 }
};
diff --git a/sys/dev/ppbus/ppbconf.h b/sys/dev/ppbus/ppbconf.h
index 5f7a201..88e4a1f 100644
--- a/sys/dev/ppbus/ppbconf.h
+++ b/sys/dev/ppbus/ppbconf.h
@@ -179,7 +179,6 @@ struct ppb_context {
*/
#define PPBUS_IVAR_MODE 0
#define PPBUS_IVAR_AVM 1
-#define PPBUS_IVAR_IRQ 2
/* other fields are reserved to the ppbus internals */
@@ -216,7 +215,6 @@ struct ppb_device {
/* Parallel Port Chipset IVARS */ /* elsewhere XXX */
#define PPC_IVAR_EPP_PROTO 0
-#define PPC_IVAR_IRQ 1
/*
* Maximum size of the PnP info string
@@ -248,9 +246,6 @@ 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
diff --git a/sys/dev/ppbus/ppi.c b/sys/dev/ppbus/ppi.c
index c6ab7a7..ca8aa04 100644
--- a/sys/dev/ppbus/ppi.c
+++ b/sys/dev/ppbus/ppi.c
@@ -163,16 +163,12 @@ static int
ppi_attach(device_t dev)
{
#ifdef PERIPH_1284
- uintptr_t irq;
- int zero = 0;
+ int rid = 0;
struct ppi_data *ppi = DEVTOSOFTC(dev);
- /* retrive the irq */
- BUS_READ_IVAR(device_get_parent(dev), dev, PPBUS_IVAR_IRQ, &irq);
-
/* declare our interrupt handler */
- ppi->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
- &zero, irq, irq, 1, RF_ACTIVE);
+ ppi->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_ACTIVE);
#endif /* PERIPH_1284 */
make_dev(&ppi_cdevsw, device_get_unit(dev), /* XXX cleanup */
diff --git a/sys/dev/ppbus/pps.c b/sys/dev/ppbus/pps.c
index e491ed2..6ab904c 100644
--- a/sys/dev/ppbus/pps.c
+++ b/sys/dev/ppbus/pps.c
@@ -107,18 +107,14 @@ ppsattach(device_t dev)
struct pps_data *sc = DEVTOSOFTC(dev);
device_t ppbus = device_get_parent(dev);
struct cdev *d;
- intptr_t irq;
- int i, unit, zero = 0;
+ int i, unit, rid = 0;
mtx_init(&sc->mtx, device_get_nameunit(dev), "pps", MTX_SPIN);
- /* retrieve the ppbus irq */
- BUS_READ_IVAR(ppbus, dev, PPBUS_IVAR_IRQ, &irq);
- if (irq > 0) {
- /* declare our interrupt handler */
- sc->intr_resource = bus_alloc_resource(dev, SYS_RES_IRQ,
- &zero, irq, irq, 1, RF_SHAREABLE);
- }
+ /* declare our interrupt handler */
+ sc->intr_resource = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
+ RF_SHAREABLE);
+
/* interrupts seem mandatory */
if (sc->intr_resource == NULL)
return (ENXIO);
OpenPOWER on IntegriCloud