summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-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
-rw-r--r--sys/dev/ppc/ppc.c158
-rw-r--r--sys/dev/ppc/ppc_acpi.c3
-rw-r--r--sys/dev/ppc/ppc_isa.c5
-rw-r--r--sys/dev/ppc/ppc_pci.c3
-rw-r--r--sys/dev/ppc/ppc_puc.c3
-rw-r--r--sys/dev/ppc/ppcreg.h3
-rw-r--r--sys/dev/ppc/ppcvar.h4
13 files changed, 143 insertions, 160 deletions
diff --git a/sys/dev/ppbus/if_plip.c b/sys/dev/ppbus/if_plip.c
index 8eb200bba951..291c2dba54b4 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 1986d56dccb2..d507f1498f25 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 7fbd801a0394..c0401c82e496 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 5f7a20196395..88e4a1f3005e 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 c6ab7a7f484e..ca8aa04955f2 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 e491ed25093d..6ab904cf9ee1 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);
diff --git a/sys/dev/ppc/ppc.c b/sys/dev/ppc/ppc.c
index 9a3f5e958159..a3724037da6f 100644
--- a/sys/dev/ppc/ppc.c
+++ b/sys/dev/ppc/ppc.c
@@ -32,10 +32,12 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/kernel.h>
+#include <sys/interrupt.h>
#include <sys/module.h>
-#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/proc.h>
#include <machine/bus.h>
#include <machine/resource.h>
@@ -1515,10 +1517,21 @@ ppc_exec_microseq(device_t dev, struct ppb_microseq **p_msq)
static void
ppcintr(void *arg)
{
- device_t dev = (device_t)arg;
- struct ppc_data *ppc = (struct ppc_data *)device_get_softc(dev);
+ struct ppc_data *ppc = arg;
u_char ctr, ecr, str;
+ /*
+ * If we have any child interrupt handlers registered, let
+ * them handle this interrupt.
+ *
+ * XXX: If DMA is in progress should we just complete that w/o
+ * doing this?
+ */
+ if (ppc->ppc_child_handlers > 0) {
+ intr_event_execute_handlers(curproc, ppc->ppc_intr_event);
+ return;
+ }
+
str = r_str(ppc);
ctr = r_ctr(ppc);
ecr = r_ecr(ppc);
@@ -1790,8 +1803,8 @@ int
ppc_attach(device_t dev)
{
struct ppc_data *ppc = DEVTOSOFTC(dev);
-
device_t ppbus;
+ int error;
device_printf(dev, "%s chipset (%s) in %s mode%s\n",
ppc_models[ppc->ppc_model], ppc_avms[ppc->ppc_avm],
@@ -1802,6 +1815,30 @@ ppc_attach(device_t dev)
device_printf(dev, "FIFO with %d/%d/%d bytes threshold\n",
ppc->ppc_fifo, ppc->ppc_wthr, ppc->ppc_rthr);
+ if (ppc->res_irq) {
+ /*
+ * Create an interrupt event to manage the handlers of
+ * child devices.
+ */
+ error = intr_event_create(&ppc->ppc_intr_event, ppc, 0, -1,
+ NULL, NULL, NULL, NULL, "%s:", device_get_nameunit(dev));
+ if (error) {
+ device_printf(dev,
+ "failed to create interrupt event: %d\n", error);
+ return (error);
+ }
+
+ /* default to the tty mask for registration */ /* XXX */
+ error = bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY,
+ NULL, ppcintr, ppc, &ppc->intr_cookie);
+ if (error) {
+ device_printf(dev,
+ "failed to register interrupt handler: %d\n",
+ error);
+ return (error);
+ }
+ }
+
/* add ppbus as a child of this isa to parallel bridge */
ppbus = device_add_child(dev, "ppbus", -1);
@@ -1810,17 +1847,6 @@ ppc_attach(device_t dev)
*/
device_probe_and_attach(ppbus);
- /* register the ppc interrupt handler as default */
- if (ppc->res_irq) {
- /* default to the tty mask for registration */ /* XXX */
- if (bus_setup_intr(dev, ppc->res_irq, INTR_TYPE_TTY,
- NULL, ppcintr, dev, &ppc->intr_cookie) == 0) {
-
- /* remember the ppcintr is registered */
- ppc->ppc_registered = 1;
- }
- }
-
return (0);
}
@@ -1935,9 +1961,6 @@ ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
case PPC_IVAR_EPP_PROTO:
*val = (u_long)ppc->ppc_epp;
break;
- case PPC_IVAR_IRQ:
- *val = (u_long)ppc->ppc_irq;
- break;
default:
return (ENOENT);
}
@@ -1946,63 +1969,84 @@ ppc_read_ivar(device_t bus, device_t dev, int index, uintptr_t *val)
}
/*
- * Resource is useless here since ppbus devices' interrupt handlers are
- * multiplexed to the same resource initially allocated by ppc
+ * We allow child devices to allocate an IRQ resource at rid 0 for their
+ * interrupt handlers.
*/
-int
-ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
- driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep)
+struct resource *
+ppc_alloc_resource(device_t bus, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
{
- int error;
struct ppc_data *ppc = DEVTOSOFTC(bus);
- if (ppc->ppc_registered) {
- /* XXX refuse registration if DMA is in progress */
-
- /* first, unregister the default interrupt handler */
- if ((error = BUS_TEARDOWN_INTR(device_get_parent(bus),
- bus, ppc->res_irq, ppc->intr_cookie)))
- return (error);
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (*rid == 0)
+ return (ppc->res_irq);
+ break;
+ }
+ return (NULL);
+}
-/* bus_deactivate_resource(bus, SYS_RES_IRQ, ppc->rid_irq, */
-/* ppc->res_irq); */
+int
+ppc_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r)
+{
+#ifdef INVARIANTS
+ struct ppc_data *ppc = DEVTOSOFTC(bus);
+#endif
- /* DMA/FIFO operation won't be possible anymore */
- ppc->ppc_registered = 0;
+ switch (type) {
+ case SYS_RES_IRQ:
+ if (rid == 0) {
+ KASSERT(r == ppc->res_irq,
+ ("ppc child IRQ resource mismatch"));
+ return (0);
+ }
+ break;
}
-
- /*
- * pass registration to the upper layer, ignore the incoming
- * resource
- */
- return (BUS_SETUP_INTR(device_get_parent(bus), child,
- r, flags, filt, ihand, arg, cookiep));
+ return (EINVAL);
}
/*
- * When no underlying device has a registered interrupt, register the ppc
- * layer one
+ * If a child wants to add a handler for our IRQ, add it to our interrupt
+ * event. Otherwise, fail the request.
*/
int
-ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *ih)
+ppc_setup_intr(device_t bus, device_t child, struct resource *r, int flags,
+ driver_filter_t *filt, void (*ihand)(void *), void *arg, void **cookiep)
{
- int error;
struct ppc_data *ppc = DEVTOSOFTC(bus);
- device_t parent = device_get_parent(bus);
+ int error;
- /* pass unregistration to the upper layer */
- if ((error = BUS_TEARDOWN_INTR(parent, child, r, ih)))
- return (error);
+ if (r != ppc->res_irq)
+ return (EINVAL);
- /* default to the tty mask for registration */ /* XXX */
- if (ppc->ppc_irq &&
- !(error = BUS_SETUP_INTR(parent, bus, ppc->res_irq,
- INTR_TYPE_TTY, NULL, ppcintr, bus, &ppc->intr_cookie))) {
+ /* We don't allow filters. */
+ if (filt != NULL)
+ return (EINVAL);
- /* remember the ppcintr is registered */
- ppc->ppc_registered = 1;
- }
+ error = intr_event_add_handler(ppc->ppc_intr_event,
+ device_get_nameunit(child), NULL, ihand, arg, intr_priority(flags),
+ flags, cookiep);
+ if (error == 0)
+ ppc->ppc_child_handlers++;
+ return (error);
+}
+
+int
+ppc_teardown_intr(device_t bus, device_t child, struct resource *r, void *cookie)
+{
+ struct ppc_data *ppc = DEVTOSOFTC(bus);
+ int error;
+
+ if (r != ppc->res_irq)
+ return (EINVAL);
+ KASSERT(intr_handler_source(cookie) == ppc,
+ ("ppc_teardown_intr: source mismatch"));
+ error = intr_event_remove_handler(cookie);
+ if (error == 0)
+ ppc->ppc_child_handlers--;
return (error);
}
diff --git a/sys/dev/ppc/ppc_acpi.c b/sys/dev/ppc/ppc_acpi.c
index 1f85c729a698..04cee681a921 100644
--- a/sys/dev/ppc/ppc_acpi.c
+++ b/sys/dev/ppc/ppc_acpi.c
@@ -65,7 +65,8 @@ static device_method_t ppc_acpi_methods[] = {
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
DEVMETHOD(bus_setup_intr, ppc_setup_intr),
DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
+ DEVMETHOD(bus_release_resource, ppc_release_resource),
/* ppbus interface */
DEVMETHOD(ppbus_io, ppc_io),
diff --git a/sys/dev/ppc/ppc_isa.c b/sys/dev/ppc/ppc_isa.c
index b23ce823e153..5ac6990c7406 100644
--- a/sys/dev/ppc/ppc_isa.c
+++ b/sys/dev/ppc/ppc_isa.c
@@ -62,7 +62,8 @@ static device_method_t ppc_isa_methods[] = {
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
DEVMETHOD(bus_setup_intr, ppc_setup_intr),
DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
+ DEVMETHOD(bus_release_resource, ppc_release_resource),
/* ppbus interface */
DEVMETHOD(ppbus_io, ppc_io),
@@ -142,7 +143,7 @@ ppc_isa_write(device_t dev, char *buf, int len, int how)
int s, error = 0;
int spin;
- if (!(ppc->ppc_avm & PPB_ECP) || !ppc->ppc_registered)
+ if (!(ppc->ppc_avm & PPB_ECP))
return (EINVAL);
if (ppc->ppc_dmachan == 0)
return (EINVAL);
diff --git a/sys/dev/ppc/ppc_pci.c b/sys/dev/ppc/ppc_pci.c
index 77331e2524e2..a64a3fdf634b 100644
--- a/sys/dev/ppc/ppc_pci.c
+++ b/sys/dev/ppc/ppc_pci.c
@@ -55,7 +55,8 @@ static device_method_t ppc_pci_methods[] = {
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
DEVMETHOD(bus_setup_intr, ppc_setup_intr),
DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
+ DEVMETHOD(bus_release_resource, ppc_release_resource),
/* ppbus interface */
DEVMETHOD(ppbus_io, ppc_io),
diff --git a/sys/dev/ppc/ppc_puc.c b/sys/dev/ppc/ppc_puc.c
index adcc0580bed8..0aec89cc4bc4 100644
--- a/sys/dev/ppc/ppc_puc.c
+++ b/sys/dev/ppc/ppc_puc.c
@@ -57,7 +57,8 @@ static device_method_t ppc_puc_methods[] = {
DEVMETHOD(bus_read_ivar, ppc_read_ivar),
DEVMETHOD(bus_setup_intr, ppc_setup_intr),
DEVMETHOD(bus_teardown_intr, ppc_teardown_intr),
- DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
+ DEVMETHOD(bus_alloc_resource, ppc_alloc_resource),
+ DEVMETHOD(bus_release_resource, ppc_release_resource),
/* ppbus interface */
DEVMETHOD(ppbus_io, ppc_io),
diff --git a/sys/dev/ppc/ppcreg.h b/sys/dev/ppc/ppcreg.h
index 25f3fc2db852..8464f9c0a3df 100644
--- a/sys/dev/ppc/ppcreg.h
+++ b/sys/dev/ppc/ppcreg.h
@@ -109,7 +109,8 @@ struct ppc_data {
void *intr_cookie;
- int ppc_registered; /* 1 if ppcintr() is the registered interrupt */
+ struct intr_event *ppc_intr_event;
+ int ppc_child_handlers;
};
/*
diff --git a/sys/dev/ppc/ppcvar.h b/sys/dev/ppc/ppcvar.h
index b8723bc23518..18c159fc4171 100644
--- a/sys/dev/ppc/ppcvar.h
+++ b/sys/dev/ppc/ppcvar.h
@@ -42,6 +42,10 @@ int ppc_exec_microseq(device_t, struct ppb_microseq **);
int ppc_setup_intr(device_t, device_t, struct resource *, int,
driver_filter_t *filt, void (*)(void *), void *, void **);
int ppc_teardown_intr(device_t, device_t, struct resource *, void *);
+struct resource *ppc_alloc_resource(device_t bus, device_t child, int type,
+ int *rid, u_long start, u_long end, u_long count, u_int flags);
+int ppc_release_resource(device_t bus, device_t child, int type, int rid,
+ struct resource *r);
void ppc_reset_epp(device_t);
void ppc_ecp_sync(device_t);
int ppc_setmode(device_t, int);