Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Apr 2006 00:04:55 GMT
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 95562 for review
Message-ID:  <200604190004.k3J04taP086515@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=95562

Change 95562 by marcel@marcel_nfs on 2006/04/19 00:03:56

	Implement puc_intr().

Affected files ...

.. //depot/projects/uart/dev/puc/puc.c#29 edit

Differences ...

==== //depot/projects/uart/dev/puc/puc.c#29 (text+ko) ====

@@ -63,6 +63,8 @@
 	driver_intr_t	*p_ih;
 	serdev_intr_t	*p_ihsrc[PUC_ISRCCNT];
 	void		*p_iharg;
+
+	int		p_ipend;
 };
 
 devclass_t puc_devclass;
@@ -127,6 +129,63 @@
 static void
 puc_intr(void *arg)
 {
+	struct puc_port *port;
+	struct puc_softc *sc = arg;
+	u_long dev, devs;
+	int i, idx, ipend, isrc;
+
+	/* handle serdev I/F compliant devices first. */
+	ipend = 0;
+	idx = 0, dev = 1UL;
+	devs = sc->sc_serdevs;
+	while (devs != 0UL) {
+		while ((devs & dev) == 0UL)
+			idx++, dev <<= 1;
+		devs &= ~dev;
+		port = &sc->sc_port[idx];
+		port->p_ipend = SERDEV_IPEND(port->p_dev);
+		ipend |= port->p_ipend;
+	}
+
+	if (ipend == 0) {
+		idx = 0, dev = 1UL;
+		devs = ~sc->sc_serdevs & ((1UL << sc->sc_nports) - 1);
+		while (devs != 0UL) {
+			while ((devs & dev) == 0UL)
+				idx++, dev <<= 1;
+			devs &= ~dev;
+			port = &sc->sc_port[idx];
+			if (port->p_ih != NULL) {
+				if (port->p_giantintr) {
+			                mtx_lock(&Giant);
+					(*port->p_ih)(port->p_iharg);
+					mtx_unlock(&Giant);
+				} else
+					(*port->p_ih)(port->p_iharg);
+			}
+		}
+		return;
+	}
+
+	i = 0, isrc = SER_INT_OVERRUN;
+	while (ipend) {
+		while (i < PUC_ISRCCNT && !(ipend & isrc))
+			i++, isrc <<= 1;
+		KASSERT(i < PUC_ISRCCNT, ("%s", __func__));
+		ipend &= ~isrc;
+		idx = 0, dev = 1UL;
+		devs = sc->sc_serdevs;
+		while (devs != 0UL) {
+			while ((devs & dev) == 0UL)
+				idx++, dev <<= 1;
+			devs &= ~dev;
+			port = &sc->sc_port[idx];
+			if (!(port->p_ipend & isrc))
+				continue;
+			if (port->p_ihsrc[i] != NULL)
+				(*port->p_ihsrc[i])(port->p_iharg);
+		}
+	}
 }
 
 int



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200604190004.k3J04taP086515>