From 84c7b427f562f218837ea277f90b1266df9a3676 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Sat, 13 Sep 2003 06:25:04 +0000 Subject: [PATCH] Add support for automatic hardware flow control for 16[679]50 UARTs. We simply use the detected FIFO size to determine whether we have a post 16550 UART or not. The support lacks proper serialization of hardware access for now. --- sys/dev/uart/uart_dev_ns8250.c | 38 +++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index ea5d5d04f8f8..ada5710cafba 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -461,7 +461,7 @@ static int ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) { struct uart_bas *bas; - uint8_t lcr; + uint8_t efr, lcr; bas = &sc->sc_bas; switch (request) { @@ -474,6 +474,36 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) uart_setreg(bas, REG_LCR, lcr); uart_barrier(bas); break; + case UART_IOCTL_IFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_RTS; + else + efr &= ~EFR_RTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; + case UART_IOCTL_OFLOW: + lcr = uart_getreg(bas, REG_LCR); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, 0xbf); + uart_barrier(bas); + efr = uart_getreg(bas, REG_EFR); + if (data) + efr |= EFR_CTS; + else + efr &= ~EFR_CTS; + uart_setreg(bas, REG_EFR, efr); + uart_barrier(bas); + uart_setreg(bas, REG_LCR, lcr); + uart_barrier(bas); + break; default: return (EINVAL); } @@ -650,6 +680,12 @@ ns8250_bus_probe(struct uart_softc *sc) */ sc->sc_txfifosz = 16; + /* 16650s or higher have automatic flow control. */ + if (sc->sc_rxfifosz > 16) { + sc->sc_hwiflow = 1; + sc->sc_hwoflow = 1; + } + return (0); }