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