aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/uart/uart_dev_ns8250.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c
index 7c4d26424c97c..44d1304fc149a 100644
--- a/sys/dev/uart/uart_dev_ns8250.c
+++ b/sys/dev/uart/uart_dev_ns8250.c
@@ -716,16 +716,25 @@ ns8250_bus_receive(struct uart_softc *sc)
bas = &sc->sc_bas;
mtx_lock_spin(&sc->sc_hwmtx);
- while (!uart_rx_full(sc)) {
- lsr = uart_getreg(bas, REG_LSR);
- if ((lsr & LSR_RXRDY) == 0)
+ lsr = uart_getreg(bas, REG_LSR);
+ while (lsr & LSR_RXRDY) {
+ if (uart_rx_full(sc)) {
+ sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
break;
+ }
xc = uart_getreg(bas, REG_DATA);
if (lsr & LSR_FE)
xc |= UART_STAT_FRAMERR;
if (lsr & LSR_PE)
xc |= UART_STAT_PARERR;
uart_rx_put(sc, xc);
+ lsr = uart_getreg(bas, REG_LSR);
+ }
+ /* Discard everything left in the Rx FIFO. */
+ while (lsr & LSR_RXRDY) {
+ (void)uart_getreg(bas, REG_DATA);
+ uart_barrier(bas);
+ lsr = uart_getreg(bas, REG_LSR);
}
mtx_unlock_spin(&sc->sc_hwmtx);
return (0);