Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 Mar 2017 21:47:43 +0000 (UTC)
From:      Ian Lepore <ian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314681 - head/sys/dev/uart
Message-ID:  <201703042147.v24Llh2k088030@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ian
Date: Sat Mar  4 21:47:43 2017
New Revision: 314681
URL: https://svnweb.freebsd.org/changeset/base/314681

Log:
  Fix bugs exposed by the recent enabling of FIFOs in the pl011 uart.  These
  have been in the code all along, but were masked by having a fifo depth of
  one byte at the hardware level, so everything kinda worked by accident.
  
  The hardware interrupts when the TX fifo is half empty, so set
  sc->sc_txfifosz to 8 bytes (half the hardware fifo size) to match.  This
  eliminates dropped characters on output.
  
  Restructure the read loop to consume all the bytes in the fifo by using
  the "rx fifo empty" bit of the flags register rather than the "rx ready"
  bit of the interrupt status register.  The rx-ready interrupt is cleared
  when the number of bytes in the fifo fall below the interrupt trigger
  level, leaving the fifo half full every time receive routine was called.
  Now it loops until the fifo is completely empty every time (including
  when the function is called due to a receive timeout as well as for
  fifo-full).

Modified:
  head/sys/dev/uart/uart_dev_pl011.c

Modified: head/sys/dev/uart/uart_dev_pl011.c
==============================================================================
--- head/sys/dev/uart/uart_dev_pl011.c	Sat Mar  4 21:32:23 2017	(r314680)
+++ head/sys/dev/uart/uart_dev_pl011.c	Sat Mar  4 21:47:43 2017	(r314681)
@@ -419,7 +419,7 @@ uart_pl011_bus_probe(struct uart_softc *
 	device_set_desc(sc->sc_dev, "PrimeCell UART (PL011)");
 
 	sc->sc_rxfifosz = 16;
-	sc->sc_txfifosz = 16;
+	sc->sc_txfifosz =  8;
 
 	return (0);
 }
@@ -434,8 +434,10 @@ uart_pl011_bus_receive(struct uart_softc
 	bas = &sc->sc_bas;
 	uart_lock(sc->sc_hwmtx);
 
-	ints = __uart_getreg(bas, UART_MIS);
-	while (ints & (UART_RXREADY | RIS_RTIM)) {
+	for (;;) {
+		ints = __uart_getreg(bas, UART_FR);
+		if (ints & FR_RXFE)
+			break;
 		if (uart_rx_full(sc)) {
 			sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
 			break;
@@ -450,7 +452,6 @@ uart_pl011_bus_receive(struct uart_softc
 			rx |= UART_STAT_PARERR;
 
 		uart_rx_put(sc, rx);
-		ints = __uart_getreg(bas, UART_MIS);
 	}
 
 	uart_unlock(sc->sc_hwmtx);



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