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>