PERFORCE change 35119 for review

Marcel Moolenaar marcel at FreeBSD.org
Sun Jul 27 23:11:21 PDT 2003


http://perforce.freebsd.org/chv.cgi?CH=35119

Change 35119 by marcel at marcel_nfs on 2003/07/27 23:11:17

	o  Simplify the TX buffer. We always send in chucks the size of
	   the TX FIFO.
	o  Add a txbusy flag that's set when the transmitter is actually
	   transmitting.
	o  Improve UART_IPEND for the ns8250.

Affected files ...

.. //depot/projects/uart/dev/uart/uart_bus.h#11 edit
.. //depot/projects/uart/dev/uart/uart_core.c#12 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#12 edit

Differences ...

==== //depot/projects/uart/dev/uart/uart_bus.h#11 (text+ko) ====

@@ -100,6 +100,7 @@
 	int		sc_hasfifo:1;	/* This UART has FIFOs. */
 	int		sc_leaving:1;	/* This UART is going away. */
 	int		sc_polled:1;	/* This UART has no interrupts. */
+	int		sc_txbusy:1;	/* This UART is transmitting. */
 
 	/* Receiver data. */
 	uint16_t	*sc_rxbuf;
@@ -110,10 +111,8 @@
 
 	/* Transmitter data. */
 	uint8_t		*sc_txbuf;
-	int		sc_txbufsz;
-	int		sc_txput;
-	int		sc_txget;
-	int		sc_txfifosz;	/* Size of TX FIFO. */
+	int		sc_txdatasz;
+	int		sc_txfifosz;	/* Size of TX FIFO and buffer. */
 
 	dev_t		sc_si;
 	void		*sc_softih;
@@ -176,46 +175,4 @@
 	return (0);
 }
 
-/*
- * Transmit buffer operations.
- */
-static __inline int
-uart_tx_empty(struct uart_softc *sc)
-{
-	return ((sc->sc_txget == sc->sc_txput) ? 1 : 0);
-}
-
-static __inline int
-uart_tx_full(struct uart_softc *sc)
-{
-	return ((sc->sc_txput + 1 < sc->sc_txbufsz)
-	    ? (sc->sc_txput + 1 == sc->sc_txget) : (sc->sc_txget == 0));
-}
-
-static __inline int
-uart_tx_get(struct uart_softc *sc)
-{
-	int ptr, c;
-
-	ptr = sc->sc_txget;
-	if (ptr == sc->sc_txput)
-		return (-1);
-	c = sc->sc_txbuf[ptr++];
-	sc->sc_txget = (ptr < sc->sc_txbufsz) ? ptr : 0;
-	return (c);
-}
-
-static __inline int
-uart_tx_put(struct uart_softc *sc, int c)
-{
-	int ptr;
-
-	ptr = (sc->sc_txput + 1 < sc->sc_txbufsz) ? sc->sc_txput + 1 : 0;
-	if (ptr == sc->sc_txget)
-		return (ENOSPC);
-	sc->sc_txbuf[sc->sc_txput] = c;
-	sc->sc_txput = ptr;
-	return (0);
-}
-
 #endif /* _DEV_UART_BUS_H_ */

==== //depot/projects/uart/dev/uart/uart_core.c#12 (text+ko) ====

@@ -75,7 +75,6 @@
 uart_tty_oproc(struct tty *tp)
 {
 	struct uart_softc *sc;
-	int c;
 
 	sc = tp->t_dev->si_drv1;
 	if (sc == NULL || sc->sc_leaving)
@@ -92,12 +91,12 @@
 		return;
 	}
 
-	while (!uart_tx_full(sc) && tp->t_outq.c_cc > 0) {
-		c = getc(&tp->t_outq);
-		uart_tx_put(sc, c);
+	if (tp->t_outq.c_cc > 0 && !sc->sc_txbusy) {
+		sc->sc_txdatasz = q_to_b(&tp->t_outq, sc->sc_txbuf,
+		    sc->sc_txfifosz);
+		tp->t_state |= TS_BUSY;
+		UART_TRANSMIT(sc);
 	}
-	tp->t_state |= TS_BUSY;
-	UART_TRANSMIT(sc);
 	ttwwakeup(tp);
 }
 
@@ -229,10 +228,10 @@
 static void
 uart_intr_txidle(struct uart_softc *sc)
 {
-	if (sc->sc_txget != sc->sc_txput)
-		UART_TRANSMIT(sc);
-	else
+	if (sc->sc_txbusy) {
+		sc->sc_txbusy = 0;
 		atomic_set_32(&sc->sc_ttypend, UART_IPEND_TXIDLE);
+	}
 }
 
 static void
@@ -389,8 +388,7 @@
 	sc->sc_rxbufsz = IBUFSIZ;
 	sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf),
 	    M_UART, M_WAITOK);
-	sc->sc_txbufsz = OBUFSIZ;
-	sc->sc_txbuf = malloc(sc->sc_txbufsz * sizeof(*sc->sc_txbuf),
+	sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf),
 	    M_UART, M_WAITOK);
 
 	error = UART_ATTACH(sc);

==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#12 (text+ko) ====

@@ -423,29 +423,31 @@
 static int
 ns8250_bus_ipend(struct uart_softc *sc)
 {
-	struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
 	struct uart_bas *bas;
-	int ipend, sig;
-	uint8_t lsr;
+	int ipend;
+	uint8_t iir, lsr;
 
 	bas = &sc->sc_bas;
+	iir = uart_getreg(bas, REG_IIR);
+	if (iir & IIR_NOPEND)
+		return (0);
+
 	ipend = 0;
-	lsr = uart_getreg(bas, REG_LSR);
-	if (lsr & LSR_OE)
-		ipend |= UART_IPEND_OVERRUN;
-	if (lsr & LSR_BI)
-		ipend |= UART_IPEND_BREAK;
-	if (lsr & LSR_RXRDY)
-		ipend |= UART_IPEND_RXREADY;
-	if (lsr & LSR_TEMT) {
-		(void)uart_getreg(bas, REG_IIR);
-		ipend |= UART_IPEND_TXIDLE;
+	if (iir & IIR_RXRDY) {
+		lsr = uart_getreg(bas, REG_LSR);
+		if (lsr & LSR_OE)
+			ipend |= UART_IPEND_OVERRUN;
+		if (lsr & LSR_BI)
+			ipend |= UART_IPEND_BREAK;
+		if (lsr & LSR_RXRDY)
+			ipend |= UART_IPEND_RXREADY;
+	} else {
+		if (iir & IIR_TXRDY)
+			ipend |= UART_IPEND_TXIDLE;
+		else
+			ipend |= UART_IPEND_SIGCHG;
 	}
-	sig = ns8250_bus_getsig(sc);
-	if (sig & UART_SIGMASK_DELTA) {
-		ns8250->signals = sig;	/* restore delta bits. */
-		ipend |= UART_IPEND_SIGCHG;
-	}
+
 	return ((sc->sc_leaving) ? 0 : ipend);
 }
 
@@ -626,15 +628,16 @@
 ns8250_bus_transmit(struct uart_softc *sc)
 {
 	struct uart_bas *bas;
-	int xc;
+	int i;
 
 	bas = &sc->sc_bas;
-	while (!uart_tx_empty(sc)) {
-		if ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
-			break;
-		xc = uart_tx_get(sc);
-		uart_setreg(bas, REG_DATA, xc);
+
+	for (i = 0; i < sc->sc_txdatasz; i++) {
+		while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
+			;
+		uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]);
 		uart_barrier(bas);
 	}
+	sc->sc_txbusy = 1;
 	return (0);
 }


More information about the p4-projects mailing list