diff options
| author | Marcel Moolenaar <marcel@FreeBSD.org> | 2003-09-17 01:41:21 +0000 |
|---|---|---|
| committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2003-09-17 01:41:21 +0000 |
| commit | 06287620b4f768f18a0874557b1cfa70e35791df (patch) | |
| tree | 976d5fcb92d42c5763ac054fcd83a3a3ba593d98 /sys/dev/uart/uart_dev_ns8250.c | |
| parent | 6ab09ca79bf6727d6e0a146211c3ed18c7195d0f (diff) | |
Notes
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
| -rw-r--r-- | sys/dev/uart/uart_dev_ns8250.c | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/sys/dev/uart/uart_dev_ns8250.c b/sys/dev/uart/uart_dev_ns8250.c index ada5710cafba..7c4d26424c97 100644 --- a/sys/dev/uart/uart_dev_ns8250.c +++ b/sys/dev/uart/uart_dev_ns8250.c @@ -427,15 +427,19 @@ ns8250_bus_flush(struct uart_softc *sc, int what) { struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; struct uart_bas *bas; + int error; bas = &sc->sc_bas; + mtx_lock_spin(&sc->sc_hwmtx); if (sc->sc_hasfifo) { ns8250_flush(bas, what); uart_setreg(bas, REG_FCR, ns8250->fcr); uart_barrier(bas); - return (0); - } - return (ns8250_drain(bas, what)); + error = 0; + } else + error = ns8250_drain(bas, what); + mtx_unlock_spin(&sc->sc_hwmtx); + return (error); } static int @@ -447,7 +451,9 @@ ns8250_bus_getsig(struct uart_softc *sc) do { old = sc->sc_hwsig; sig = old; + mtx_lock_spin(&sc->sc_hwmtx); msr = uart_getreg(&sc->sc_bas, REG_MSR); + mtx_unlock_spin(&sc->sc_hwmtx); SIGCHG(msr & MSR_DSR, sig, UART_SIG_DSR, UART_SIG_DDSR); SIGCHG(msr & MSR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS); SIGCHG(msr & MSR_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD); @@ -461,9 +467,12 @@ static int ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) { struct uart_bas *bas; + int error; uint8_t efr, lcr; bas = &sc->sc_bas; + error = 0; + mtx_lock_spin(&sc->sc_hwmtx); switch (request) { case UART_IOCTL_BREAK: lcr = uart_getreg(bas, REG_LCR); @@ -505,9 +514,11 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) uart_barrier(bas); break; default: - return (EINVAL); + error = EINVAL; + break; } - return (0); + mtx_unlock_spin(&sc->sc_hwmtx); + return (error); } static int @@ -518,13 +529,16 @@ ns8250_bus_ipend(struct uart_softc *sc) uint8_t iir, lsr; bas = &sc->sc_bas; + mtx_lock_spin(&sc->sc_hwmtx); iir = uart_getreg(bas, REG_IIR); - if (iir & IIR_NOPEND) + if (iir & IIR_NOPEND) { + mtx_unlock_spin(&sc->sc_hwmtx); return (0); - + } ipend = 0; if (iir & IIR_RXRDY) { lsr = uart_getreg(bas, REG_LSR); + mtx_unlock_spin(&sc->sc_hwmtx); if (lsr & LSR_OE) ipend |= UART_IPEND_OVERRUN; if (lsr & LSR_BI) @@ -532,12 +546,12 @@ ns8250_bus_ipend(struct uart_softc *sc) if (lsr & LSR_RXRDY) ipend |= UART_IPEND_RXREADY; } else { + mtx_unlock_spin(&sc->sc_hwmtx); if (iir & IIR_TXRDY) ipend |= UART_IPEND_TXIDLE; else ipend |= UART_IPEND_SIGCHG; } - return ((sc->sc_leaving) ? 0 : ipend); } @@ -546,9 +560,13 @@ ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits, int stopbits, int parity) { struct uart_bas *bas; + int error; bas = &sc->sc_bas; - return (ns8250_param(bas, baudrate, databits, stopbits, parity)); + mtx_lock_spin(&sc->sc_hwmtx); + error = ns8250_param(bas, baudrate, databits, stopbits, parity); + mtx_unlock_spin(&sc->sc_hwmtx); + return (error); } static int @@ -697,6 +715,7 @@ ns8250_bus_receive(struct uart_softc *sc) uint8_t lsr; 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) @@ -708,6 +727,7 @@ ns8250_bus_receive(struct uart_softc *sc) xc |= UART_STAT_PARERR; uart_rx_put(sc, xc); } + mtx_unlock_spin(&sc->sc_hwmtx); return (0); } @@ -731,6 +751,7 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig) UART_SIG_DRTS); } } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); + mtx_lock_spin(&sc->sc_hwmtx); ns8250->mcr &= ~(MCR_DTR|MCR_RTS); if (new & UART_SIG_DTR) ns8250->mcr |= MCR_DTR; @@ -738,6 +759,7 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig) ns8250->mcr |= MCR_RTS; uart_setreg(bas, REG_MCR, ns8250->mcr); uart_barrier(bas); + mtx_unlock_spin(&sc->sc_hwmtx); return (0); } @@ -749,6 +771,7 @@ ns8250_bus_transmit(struct uart_softc *sc) int i; bas = &sc->sc_bas; + mtx_lock_spin(&sc->sc_hwmtx); while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) ; uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); @@ -758,5 +781,6 @@ ns8250_bus_transmit(struct uart_softc *sc) uart_barrier(bas); } sc->sc_txbusy = 1; + mtx_unlock_spin(&sc->sc_hwmtx); return (0); } |
