svn commit: r314681 - head/sys/dev/uart
Ian Lepore
ian at FreeBSD.org
Sat Mar 4 21:47:45 UTC 2017
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);
More information about the svn-src-all
mailing list