summaryrefslogtreecommitdiff
path: root/sys/dev/uart/uart_dev_ns8250.c
diff options
context:
space:
mode:
authorMarcel Moolenaar <marcel@FreeBSD.org>2003-09-17 01:41:21 +0000
committerMarcel Moolenaar <marcel@FreeBSD.org>2003-09-17 01:41:21 +0000
commit06287620b4f768f18a0874557b1cfa70e35791df (patch)
tree976d5fcb92d42c5763ac054fcd83a3a3ba593d98 /sys/dev/uart/uart_dev_ns8250.c
parent6ab09ca79bf6727d6e0a146211c3ed18c7195d0f (diff)
Notes
Diffstat (limited to 'sys/dev/uart/uart_dev_ns8250.c')
-rw-r--r--sys/dev/uart/uart_dev_ns8250.c42
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);
}