PERFORCE change 95480 for review
Marcel Moolenaar
marcel at FreeBSD.org
Tue Apr 18 05:56:54 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=95480
Change 95480 by marcel at marcel_nfs on 2006/04/18 05:55:54
o Implement puc_bus_setup_intr()
o Implement puc_bus_teardown_intr()
Affected files ...
.. //depot/projects/uart/dev/puc/puc.c#25 edit
Differences ...
==== //depot/projects/uart/dev/puc/puc.c#25 (text+ko) ====
@@ -56,6 +56,10 @@
int p_type;
int p_rclk;
+ int p_hasintr:1;
+ int p_fastintr:1;
+ int p_giantintr:1;
+
driver_intr_t *p_ih;
serdev_intr_t *p_ihsrc[PUC_ISRCCNT];
void *p_iharg;
@@ -392,6 +396,8 @@
} else if (type == SYS_RES_IRQ) {
if (res != port->p_ires)
return (EINVAL);
+ if (port->p_hasintr)
+ return (EBUSY);
} else
return (EINVAL);
@@ -445,6 +451,7 @@
struct puc_port *port;
struct puc_softc *sc;
device_t originator;
+ int i, isrc;
sc = device_get_softc(dev);
@@ -463,6 +470,36 @@
if (rman_get_device(port->p_ires) != originator)
return (ENXIO);
+ /*
+ * If one of our children doesn't have a fast interrupt handler,
+ * downgrade our interrupt handler from a fast handler to a
+ * MP safe handler. We acquire giant on a need to have basis.
+ */
+ if (sc->sc_fastintr && !(flags & INTR_FAST)) {
+ sc->sc_fastintr = 0;
+ bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie);
+ bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY | INTR_MPSAFE,
+ puc_intr, sc, &sc->sc_icookie);
+ }
+
+ port->p_hasintr = 1;
+ port->p_fastintr = (flags & INTR_FAST) ? 1 : 0;
+ port->p_giantintr = (flags & INTR_MPSAFE) ? 0 : 1;
+ port->p_ih = ihand;
+ port->p_iharg = arg;
+
+ *cookiep = originator;
+
+ if (port->p_type == PUC_TYPE_SERIAL) {
+ i = 0, isrc = SER_INT_OVERRUN;
+ while (i < PUC_ISRCCNT) {
+ port->p_ihsrc[i] = SERDEV_IHAND(originator, isrc);
+ if (port->p_ihsrc[i] != NULL)
+ port->p_ih = NULL;
+ i++, isrc <<= 1;
+ }
+ }
+
return (0);
}
@@ -472,6 +509,7 @@
{
struct puc_port *port;
device_t originator;
+ int i;
/* Get our immediate child. */
originator = child;
@@ -483,8 +521,23 @@
port = device_get_ivars(child);
KASSERT(port != NULL, ("%s %d", __func__, __LINE__));
- if (res == NULL || cookie == NULL)
+ if (res != port->p_ires || cookie != originator)
return (EINVAL);
+ if (rman_get_device(port->p_ires) != originator)
+ return (ENXIO);
+ if (!port->p_hasintr)
+ return (ENXIO);
+
+ port->p_hasintr = 0;
+ port->p_fastintr = 0;
+ port->p_giantintr = 0;
+ port->p_ih = NULL;
+ port->p_iharg = NULL;
+
+ if (port->p_type == PUC_TYPE_SERIAL) {
+ for (i = 0; i < PUC_ISRCCNT; i++)
+ port->p_ihsrc[i] = NULL;
+ }
return (ENXIO);
}
More information about the p4-projects
mailing list