PERFORCE change 64192 for review
Marcel Moolenaar
marcel at FreeBSD.org
Wed Nov 3 20:55:13 PST 2004
http://perforce.freebsd.org/chv.cgi?CH=64192
Change 64192 by marcel at marcel_nfs on 2004/11/04 04:54:58
Make uart_intr_break(), uart_intr_overrun(), uart_intr_rxready(),
uart_intr_sigchg() and uart_intr_txidle() inlines and change the
argument to void* so as to match the prototype of interrupt
handlers. Also have them call swi_sched() so that there's no more
dependency on uart_intr().
The whole point being that puc(4) or scc(4) can synthesize 5 IRQ
resources for uart(4) to attach to with these functions so that
puc(4) or scc(4) can poll the hardware and call the specific
interrupt handlers for each interrupt source. This gives puc(4)
or scc(4) the ability to prioritize across different devices or
channels.
Affected files ...
.. //depot/projects/uart/dev/uart/uart_core.c#36 edit
Differences ...
==== //depot/projects/uart/dev/uart/uart_core.c#36 (text+ko) ====
@@ -79,9 +79,10 @@
* the exceptional nature of the break condition, so we permit ourselves
* to be sloppy.
*/
-static void
-uart_intr_break(struct uart_softc *sc)
+static __inline void
+uart_intr_break(void *arg)
{
+ struct uart_softc *sc = arg;
#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
@@ -89,8 +90,10 @@
return;
}
#endif
- if (sc->sc_opened)
+ if (sc->sc_opened) {
atomic_set_32(&sc->sc_ttypend, UART_IPEND_BREAK);
+ swi_sched(sc->sc_softih, 0);
+ }
}
/*
@@ -108,15 +111,17 @@
* token represents the loss of at least one, but possible more bytes in
* the input stream.
*/
-static void
-uart_intr_overrun(struct uart_softc *sc)
+static __inline void
+uart_intr_overrun(void *arg)
{
+ struct uart_softc *sc = arg;
if (sc->sc_opened) {
UART_RECEIVE(sc);
if (uart_rx_put(sc, UART_STAT_OVERRUN))
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
+ swi_sched(sc->sc_softih, 0);
}
UART_FLUSH(sc, UART_FLUSH_RECEIVER);
}
@@ -124,9 +129,10 @@
/*
* Received data ready.
*/
-static void
-uart_intr_rxready(struct uart_softc *sc)
+static __inline void
+uart_intr_rxready(void *arg)
{
+ struct uart_softc *sc = arg;
int rxp;
rxp = sc->sc_rxput;
@@ -141,9 +147,10 @@
}
}
#endif
- if (sc->sc_opened)
+ if (sc->sc_opened) {
atomic_set_32(&sc->sc_ttypend, UART_IPEND_RXREADY);
- else
+ swi_sched(sc->sc_softih, 0);
+ } else
sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */
}
@@ -154,9 +161,10 @@
* bits. This is to avoid loosing state transitions due to having more
* than 1 hardware interrupt between software interrupts.
*/
-static void
-uart_intr_sigchg(struct uart_softc *sc)
+static __inline void
+uart_intr_sigchg(void *arg)
{
+ struct uart_softc *sc = arg;
int new, old, sig;
sig = UART_GETSIG(sc);
@@ -169,23 +177,37 @@
}
}
+ /*
+ * Keep track of signal changes, even when the device is not
+ * opened. This allows us to inform upper layers about a
+ * possible loss of DCD and thus the existence of a (possibly)
+ * different connection when we have DCD back, during the time
+ * that the device was closed.
+ */
do {
old = sc->sc_ttypend;
new = old & ~UART_SIGMASK_STATE;
new |= sig & UART_IPEND_SIGMASK;
new |= UART_IPEND_SIGCHG;
} while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
+ if (sc->sc_opened)
+ swi_sched(sc->sc_softih, 0);
}
/*
* The transmitter can accept more data.
*/
-static void
-uart_intr_txidle(struct uart_softc *sc)
+static __inline void
+uart_intr_txidle(void *arg)
{
+ struct uart_softc *sc = arg;
+
if (sc->sc_txbusy) {
sc->sc_txbusy = 0;
- atomic_set_32(&sc->sc_ttypend, UART_IPEND_TXIDLE);
+ if (sc->sc_opened) {
+ atomic_set_32(&sc->sc_ttypend, UART_IPEND_TXIDLE);
+ swi_sched(sc->sc_softih, 0);
+ }
}
}
@@ -195,13 +217,7 @@
struct uart_softc *sc = arg;
int ipend;
- if (sc->sc_leaving)
- return;
-
- do {
- ipend = UART_IPEND(sc);
- if (ipend == 0)
- break;
+ while (!sc->sc_leaving && (ipend = UART_IPEND(sc)) != 0) {
if (ipend & UART_IPEND_OVERRUN)
uart_intr_overrun(sc);
if (ipend & UART_IPEND_BREAK)
@@ -212,10 +228,7 @@
uart_intr_sigchg(sc);
if (ipend & UART_IPEND_TXIDLE)
uart_intr_txidle(sc);
- } while (1);
-
- if (sc->sc_opened && sc->sc_ttypend != 0)
- swi_sched(sc->sc_softih, 0);
+ }
}
int
More information about the p4-projects
mailing list