Add support for scc(4).
This commit is contained in:
parent
0215f8085c
commit
11ffb007e1
@ -81,7 +81,8 @@ struct uart_softc {
|
||||
struct uart_bas sc_bas;
|
||||
device_t sc_dev;
|
||||
|
||||
struct mtx sc_hwmtx; /* Spinlock protecting hardware. */
|
||||
struct mtx sc_hwmtx_s; /* Spinlock protecting hardware. */
|
||||
struct mtx *sc_hwmtx;
|
||||
|
||||
struct resource *sc_rres; /* Register resource. */
|
||||
int sc_rrid;
|
||||
@ -139,7 +140,9 @@ extern char uart_driver_name[];
|
||||
|
||||
int uart_bus_attach(device_t dev);
|
||||
int uart_bus_detach(device_t dev);
|
||||
serdev_intr_t *uart_bus_ihand(device_t dev, int ipend);
|
||||
int uart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan);
|
||||
int uart_bus_sysdev(device_t dev);
|
||||
|
||||
int uart_tty_attach(struct uart_softc *);
|
||||
int uart_tty_detach(struct uart_softc *);
|
||||
|
@ -70,6 +70,24 @@ uart_add_sysdev(struct uart_devinfo *di)
|
||||
SLIST_INSERT_HEAD(&uart_sysdevs, di, next);
|
||||
}
|
||||
|
||||
/*
|
||||
* Schedule a soft interrupt. We do this on the 0 to !0 transition
|
||||
* of the TTY pending interrupt status.
|
||||
*/
|
||||
static void
|
||||
uart_sched_softih(struct uart_softc *sc, uint32_t ipend)
|
||||
{
|
||||
uint32_t new, old;
|
||||
|
||||
do {
|
||||
old = sc->sc_ttypend;
|
||||
new = old | ipend;
|
||||
} while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
|
||||
|
||||
if ((old & SER_INT_MASK) == 0)
|
||||
swi_sched(sc->sc_softih, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* A break condition has been detected. We treat the break condition as
|
||||
* a special case that should not happen during normal operation. When
|
||||
@ -79,18 +97,20 @@ uart_add_sysdev(struct uart_devinfo *di)
|
||||
* the exceptional nature of the break condition, so we permit ourselves
|
||||
* to be sloppy.
|
||||
*/
|
||||
static void
|
||||
uart_intr_break(struct uart_softc *sc)
|
||||
static __inline int
|
||||
uart_intr_break(void *arg)
|
||||
{
|
||||
struct uart_softc *sc = arg;
|
||||
|
||||
#if defined(KDB) && defined(BREAK_TO_DEBUGGER)
|
||||
if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) {
|
||||
kdb_enter("Line break on console");
|
||||
return;
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
if (sc->sc_opened)
|
||||
atomic_set_32(&sc->sc_ttypend, SER_INT_BREAK);
|
||||
uart_sched_softih(sc, SER_INT_BREAK);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -108,25 +128,28 @@ uart_intr_break(struct uart_softc *sc)
|
||||
* token represents the loss of at least one, but possible more bytes in
|
||||
* the input stream.
|
||||
*/
|
||||
static void
|
||||
uart_intr_overrun(struct uart_softc *sc)
|
||||
static __inline int
|
||||
uart_intr_overrun(void *arg)
|
||||
{
|
||||
struct uart_softc *sc = arg;
|
||||
|
||||
if (sc->sc_opened) {
|
||||
UART_RECEIVE(sc);
|
||||
if (uart_rx_put(sc, UART_STAT_OVERRUN))
|
||||
sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
|
||||
atomic_set_32(&sc->sc_ttypend, SER_INT_RXREADY);
|
||||
uart_sched_softih(sc, SER_INT_RXREADY);
|
||||
}
|
||||
UART_FLUSH(sc, UART_FLUSH_RECEIVER);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Received data ready.
|
||||
*/
|
||||
static void
|
||||
uart_intr_rxready(struct uart_softc *sc)
|
||||
static __inline int
|
||||
uart_intr_rxready(void *arg)
|
||||
{
|
||||
struct uart_softc *sc = arg;
|
||||
int rxp;
|
||||
|
||||
rxp = sc->sc_rxput;
|
||||
@ -142,9 +165,10 @@ uart_intr_rxready(struct uart_softc *sc)
|
||||
}
|
||||
#endif
|
||||
if (sc->sc_opened)
|
||||
atomic_set_32(&sc->sc_ttypend, SER_INT_RXREADY);
|
||||
uart_sched_softih(sc, SER_INT_RXREADY);
|
||||
else
|
||||
sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -154,9 +178,10 @@ uart_intr_rxready(struct uart_softc *sc)
|
||||
* bits. This is to avoid loosing state transitions due to having more
|
||||
* than 1 hardware interrupt between software interrupts.
|
||||
*/
|
||||
static void
|
||||
uart_intr_sigchg(struct uart_softc *sc)
|
||||
static __inline int
|
||||
uart_intr_sigchg(void *arg)
|
||||
{
|
||||
struct uart_softc *sc = arg;
|
||||
int new, old, sig;
|
||||
|
||||
sig = UART_GETSIG(sc);
|
||||
@ -169,24 +194,37 @@ uart_intr_sigchg(struct uart_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep track of signal changes, even when the device is not
|
||||
* opened. This allows us to inform upper layers about a
|
||||
* possible loss of DCD and thus the existence of a (possibly)
|
||||
* different connection when we have DCD back, during the time
|
||||
* that the device was closed.
|
||||
*/
|
||||
do {
|
||||
old = sc->sc_ttypend;
|
||||
new = old & ~SER_MASK_STATE;
|
||||
new |= sig & SER_INT_SIGMASK;
|
||||
new |= SER_INT_SIGCHG;
|
||||
} while (!atomic_cmpset_32(&sc->sc_ttypend, old, new));
|
||||
|
||||
if (sc->sc_opened)
|
||||
uart_sched_softih(sc, SER_INT_SIGCHG);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The transmitter can accept more data.
|
||||
*/
|
||||
static void
|
||||
uart_intr_txidle(struct uart_softc *sc)
|
||||
static __inline int
|
||||
uart_intr_txidle(void *arg)
|
||||
{
|
||||
struct uart_softc *sc = arg;
|
||||
|
||||
if (sc->sc_txbusy) {
|
||||
sc->sc_txbusy = 0;
|
||||
atomic_set_32(&sc->sc_ttypend, SER_INT_TXIDLE);
|
||||
uart_sched_softih(sc, SER_INT_TXIDLE);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -195,13 +233,7 @@ uart_intr(void *arg)
|
||||
struct uart_softc *sc = arg;
|
||||
int ipend;
|
||||
|
||||
if (sc->sc_leaving)
|
||||
return;
|
||||
|
||||
do {
|
||||
ipend = UART_IPEND(sc);
|
||||
if (ipend == 0)
|
||||
break;
|
||||
while (!sc->sc_leaving && (ipend = UART_IPEND(sc)) != 0) {
|
||||
if (ipend & SER_INT_OVERRUN)
|
||||
uart_intr_overrun(sc);
|
||||
if (ipend & SER_INT_BREAK)
|
||||
@ -212,10 +244,35 @@ uart_intr(void *arg)
|
||||
uart_intr_sigchg(sc);
|
||||
if (ipend & SER_INT_TXIDLE)
|
||||
uart_intr_txidle(sc);
|
||||
} while (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->sc_opened && sc->sc_ttypend != 0)
|
||||
swi_sched(sc->sc_softih, 0);
|
||||
serdev_intr_t *
|
||||
uart_bus_ihand(device_t dev, int ipend)
|
||||
{
|
||||
|
||||
switch (ipend) {
|
||||
case SER_INT_BREAK:
|
||||
return (uart_intr_break);
|
||||
case SER_INT_OVERRUN:
|
||||
return (uart_intr_overrun);
|
||||
case SER_INT_RXREADY:
|
||||
return (uart_intr_rxready);
|
||||
case SER_INT_SIGCHG:
|
||||
return (uart_intr_sigchg);
|
||||
case SER_INT_TXIDLE:
|
||||
return (uart_intr_txidle);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int
|
||||
uart_bus_sysdev(device_t dev)
|
||||
{
|
||||
struct uart_softc *sc;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
return ((sc->sc_sysdev != NULL) ? 1 : 0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -313,7 +370,9 @@ uart_bus_attach(device_t dev)
|
||||
*/
|
||||
sc->sc_leaving = 1;
|
||||
|
||||
mtx_init(&sc->sc_hwmtx, "uart_hwmtx", NULL, MTX_SPIN);
|
||||
mtx_init(&sc->sc_hwmtx_s, "uart_hwmtx", NULL, MTX_SPIN);
|
||||
if (sc->sc_hwmtx == NULL)
|
||||
sc->sc_hwmtx = &sc->sc_hwmtx_s;
|
||||
|
||||
/*
|
||||
* Re-allocate. We expect that the softc contains the information
|
||||
@ -322,7 +381,7 @@ uart_bus_attach(device_t dev)
|
||||
sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid,
|
||||
0, ~0, sc->sc_class->uc_range, RF_ACTIVE);
|
||||
if (sc->sc_rres == NULL) {
|
||||
mtx_destroy(&sc->sc_hwmtx);
|
||||
mtx_destroy(&sc->sc_hwmtx_s);
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres);
|
||||
@ -425,6 +484,9 @@ uart_bus_attach(device_t dev)
|
||||
if (error)
|
||||
goto fail;
|
||||
|
||||
if (sc->sc_sysdev != NULL)
|
||||
sc->sc_sysdev->hwmtx = sc->sc_hwmtx;
|
||||
|
||||
sc->sc_leaving = 0;
|
||||
uart_intr(sc);
|
||||
return (0);
|
||||
@ -440,7 +502,7 @@ uart_bus_attach(device_t dev)
|
||||
}
|
||||
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
|
||||
|
||||
mtx_destroy(&sc->sc_hwmtx);
|
||||
mtx_destroy(&sc->sc_hwmtx_s);
|
||||
|
||||
return (error);
|
||||
}
|
||||
@ -454,6 +516,9 @@ uart_bus_detach(device_t dev)
|
||||
|
||||
sc->sc_leaving = 1;
|
||||
|
||||
if (sc->sc_sysdev != NULL)
|
||||
sc->sc_sysdev->hwmtx = NULL;
|
||||
|
||||
UART_DETACH(sc);
|
||||
|
||||
if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL)
|
||||
@ -471,7 +536,7 @@ uart_bus_detach(device_t dev)
|
||||
}
|
||||
bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres);
|
||||
|
||||
mtx_destroy(&sc->sc_hwmtx);
|
||||
mtx_destroy(&sc->sc_hwmtx_s);
|
||||
|
||||
if (sc->sc_class->size > sizeof(*sc)) {
|
||||
device_set_softc(dev, NULL);
|
||||
|
@ -29,6 +29,10 @@
|
||||
#ifndef _DEV_UART_CPU_H_
|
||||
#define _DEV_UART_CPU_H_
|
||||
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
|
||||
/*
|
||||
* Low-level operations for use by console and/or debug port support.
|
||||
*/
|
||||
@ -68,6 +72,7 @@ struct uart_devinfo {
|
||||
int (*attach)(struct uart_softc*);
|
||||
int (*detach)(struct uart_softc*);
|
||||
void *cookie; /* Type dependent use. */
|
||||
struct mtx *hwmtx;
|
||||
};
|
||||
|
||||
int uart_cpu_eqres(struct uart_bas *, struct uart_bas *);
|
||||
@ -80,41 +85,77 @@ void uart_add_sysdev(struct uart_devinfo *);
|
||||
* Operations for low-level access to the UART. Primarily for use
|
||||
* by console and debug port logic.
|
||||
*/
|
||||
|
||||
static __inline void
|
||||
uart_lock(struct mtx *hwmtx)
|
||||
{
|
||||
if (!kdb_active && hwmtx != NULL)
|
||||
mtx_lock_spin(hwmtx);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_unlock(struct mtx *hwmtx)
|
||||
{
|
||||
if (!kdb_active && hwmtx != NULL)
|
||||
mtx_unlock_spin(hwmtx);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
uart_probe(struct uart_devinfo *di)
|
||||
{
|
||||
return (di->ops.probe(&di->bas));
|
||||
int res;
|
||||
|
||||
uart_lock(di->hwmtx);
|
||||
res = di->ops.probe(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
return (res);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_init(struct uart_devinfo *di)
|
||||
{
|
||||
uart_lock(di->hwmtx);
|
||||
di->ops.init(&di->bas, di->baudrate, di->databits, di->stopbits,
|
||||
di->parity);
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_term(struct uart_devinfo *di)
|
||||
{
|
||||
uart_lock(di->hwmtx);
|
||||
di->ops.term(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
static __inline void
|
||||
uart_putc(struct uart_devinfo *di, int c)
|
||||
{
|
||||
uart_lock(di->hwmtx);
|
||||
di->ops.putc(&di->bas, c);
|
||||
uart_unlock(di->hwmtx);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
uart_poll(struct uart_devinfo *di)
|
||||
{
|
||||
return (di->ops.poll(&di->bas));
|
||||
int res;
|
||||
|
||||
uart_lock(di->hwmtx);
|
||||
res = di->ops.poll(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
return (res);
|
||||
}
|
||||
|
||||
static __inline int
|
||||
uart_getc(struct uart_devinfo *di)
|
||||
{
|
||||
return (di->ops.getc(&di->bas));
|
||||
int res;
|
||||
|
||||
uart_lock(di->hwmtx);
|
||||
res = di->ops.getc(&di->bas);
|
||||
uart_unlock(di->hwmtx);
|
||||
return (res);
|
||||
}
|
||||
|
||||
#endif /* _DEV_UART_CPU_H_ */
|
||||
|
@ -432,7 +432,7 @@ ns8250_bus_flush(struct uart_softc *sc, int what)
|
||||
int error;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
if (sc->sc_hasfifo) {
|
||||
ns8250_flush(bas, what);
|
||||
uart_setreg(bas, REG_FCR, ns8250->fcr);
|
||||
@ -440,7 +440,7 @@ ns8250_bus_flush(struct uart_softc *sc, int what)
|
||||
error = 0;
|
||||
} else
|
||||
error = ns8250_drain(bas, what);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -453,9 +453,9 @@ ns8250_bus_getsig(struct uart_softc *sc)
|
||||
do {
|
||||
old = sc->sc_hwsig;
|
||||
sig = old;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
msr = uart_getreg(&sc->sc_bas, REG_MSR);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
|
||||
SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
|
||||
SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
|
||||
@ -474,7 +474,7 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
error = 0;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
switch (request) {
|
||||
case UART_IOCTL_BREAK:
|
||||
lcr = uart_getreg(bas, REG_LCR);
|
||||
@ -533,7 +533,7 @@ ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -545,16 +545,16 @@ ns8250_bus_ipend(struct uart_softc *sc)
|
||||
uint8_t iir, lsr;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
iir = uart_getreg(bas, REG_IIR);
|
||||
if (iir & IIR_NOPEND) {
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
ipend = 0;
|
||||
if (iir & IIR_RXRDY) {
|
||||
lsr = uart_getreg(bas, REG_LSR);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
if (lsr & LSR_OE)
|
||||
ipend |= SER_INT_OVERRUN;
|
||||
if (lsr & LSR_BI)
|
||||
@ -562,7 +562,7 @@ ns8250_bus_ipend(struct uart_softc *sc)
|
||||
if (lsr & LSR_RXRDY)
|
||||
ipend |= SER_INT_RXREADY;
|
||||
} else {
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
if (iir & IIR_TXRDY)
|
||||
ipend |= SER_INT_TXIDLE;
|
||||
else
|
||||
@ -579,9 +579,9 @@ ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
|
||||
int error;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
error = ns8250_param(bas, baudrate, databits, stopbits, parity);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -740,7 +740,7 @@ ns8250_bus_receive(struct uart_softc *sc)
|
||||
uint8_t lsr;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
lsr = uart_getreg(bas, REG_LSR);
|
||||
while (lsr & LSR_RXRDY) {
|
||||
if (uart_rx_full(sc)) {
|
||||
@ -761,7 +761,7 @@ ns8250_bus_receive(struct uart_softc *sc)
|
||||
uart_barrier(bas);
|
||||
lsr = uart_getreg(bas, REG_LSR);
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -785,7 +785,7 @@ ns8250_bus_setsig(struct uart_softc *sc, int sig)
|
||||
SER_DRTS);
|
||||
}
|
||||
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
|
||||
if (new & SER_DTR)
|
||||
ns8250->mcr |= MCR_DTR;
|
||||
@ -793,7 +793,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);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -805,7 +805,7 @@ ns8250_bus_transmit(struct uart_softc *sc)
|
||||
int i;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
|
||||
;
|
||||
uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY);
|
||||
@ -815,6 +815,6 @@ ns8250_bus_transmit(struct uart_softc *sc)
|
||||
uart_barrier(bas);
|
||||
}
|
||||
sc->sc_txbusy = 1;
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
@ -437,9 +437,9 @@ static int
|
||||
sab82532_bus_flush(struct uart_softc *sc, int what)
|
||||
{
|
||||
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
sab82532_flush(&sc->sc_bas, what);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -454,7 +454,7 @@ sab82532_bus_getsig(struct uart_softc *sc)
|
||||
do {
|
||||
old = sc->sc_hwsig;
|
||||
sig = old;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
star = uart_getreg(bas, SAB_STAR);
|
||||
SIGCHG(star & SAB_STAR_CTS, sig, SER_CTS, SER_DCTS);
|
||||
vstr = uart_getreg(bas, SAB_VSTR);
|
||||
@ -469,7 +469,7 @@ sab82532_bus_getsig(struct uart_softc *sc)
|
||||
break;
|
||||
}
|
||||
SIGCHG(pvr, sig, SER_DSR, SER_DDSR);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
new = sig & ~SER_MASK_DELTA;
|
||||
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
|
||||
return (sig);
|
||||
@ -484,7 +484,7 @@ sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
error = 0;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
switch (request) {
|
||||
case UART_IOCTL_BREAK:
|
||||
dafo = uart_getreg(bas, SAB_DAFO);
|
||||
@ -520,7 +520,7 @@ sab82532_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -532,7 +532,7 @@ sab82532_bus_ipend(struct uart_softc *sc)
|
||||
uint8_t isr0, isr1;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
isr0 = uart_getreg(bas, SAB_ISR0);
|
||||
isr1 = uart_getreg(bas, SAB_ISR1);
|
||||
uart_barrier(bas);
|
||||
@ -542,7 +542,7 @@ sab82532_bus_ipend(struct uart_softc *sc)
|
||||
uart_setreg(bas, SAB_CMDR, SAB_CMDR_RFRD);
|
||||
uart_barrier(bas);
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
|
||||
ipend = 0;
|
||||
if (isr1 & SAB_ISR1_BRKT)
|
||||
@ -567,9 +567,9 @@ sab82532_bus_param(struct uart_softc *sc, int baudrate, int databits,
|
||||
int error;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
error = sab82532_param(bas, baudrate, databits, stopbits, parity);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -617,7 +617,7 @@ sab82532_bus_receive(struct uart_softc *sc)
|
||||
uint8_t s;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
if (uart_getreg(bas, SAB_STAR) & SAB_STAR_RFNE) {
|
||||
rbcl = uart_getreg(bas, SAB_RBCL) & 31;
|
||||
if (rbcl == 0)
|
||||
@ -641,7 +641,7 @@ sab82532_bus_receive(struct uart_softc *sc)
|
||||
;
|
||||
uart_setreg(bas, SAB_CMDR, SAB_CMDR_RMC);
|
||||
uart_barrier(bas);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -666,7 +666,7 @@ sab82532_bus_setsig(struct uart_softc *sc, int sig)
|
||||
}
|
||||
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
|
||||
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
/* Set DTR pin. */
|
||||
pvr = uart_getreg(bas, SAB_PVR);
|
||||
switch (bas->chan) {
|
||||
@ -693,7 +693,7 @@ sab82532_bus_setsig(struct uart_softc *sc, int sig)
|
||||
mode |= SAB_MODE_FRTS;
|
||||
uart_setreg(bas, SAB_MODE, mode);
|
||||
uart_barrier(bas);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -704,7 +704,7 @@ sab82532_bus_transmit(struct uart_softc *sc)
|
||||
int i;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
while (!(uart_getreg(bas, SAB_STAR) & SAB_STAR_XFW))
|
||||
;
|
||||
for (i = 0; i < sc->sc_txdatasz; i++)
|
||||
@ -714,6 +714,6 @@ sab82532_bus_transmit(struct uart_softc *sc)
|
||||
;
|
||||
uart_setreg(bas, SAB_CMDR, SAB_CMDR_XF);
|
||||
sc->sc_txbusy = 1;
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
@ -348,9 +348,9 @@ z8530_bus_getsig(struct uart_softc *sc)
|
||||
do {
|
||||
old = sc->sc_hwsig;
|
||||
sig = old;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
bes = uart_getmreg(&sc->sc_bas, RR_BES);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
|
||||
SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
|
||||
SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
|
||||
@ -368,7 +368,7 @@ z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
error = 0;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
switch (request) {
|
||||
case UART_IOCTL_BREAK:
|
||||
if (data)
|
||||
@ -382,7 +382,7 @@ z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -398,7 +398,7 @@ z8530_bus_ipend(struct uart_softc *sc)
|
||||
bas = &sc->sc_bas;
|
||||
ipend = 0;
|
||||
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
switch (bas->chan) {
|
||||
case 1:
|
||||
ip = uart_getmreg(bas, RR_IP);
|
||||
@ -454,7 +454,7 @@ z8530_bus_ipend(struct uart_softc *sc)
|
||||
uart_barrier(bas);
|
||||
}
|
||||
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
|
||||
return (ipend);
|
||||
}
|
||||
@ -466,10 +466,10 @@ z8530_bus_param(struct uart_softc *sc, int baudrate, int databits,
|
||||
struct z8530_softc *z8530 = (struct z8530_softc*)sc;
|
||||
int error;
|
||||
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity,
|
||||
&z8530->tpc);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -499,7 +499,7 @@ z8530_bus_receive(struct uart_softc *sc)
|
||||
uint8_t bes, src;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
bes = uart_getmreg(bas, RR_BES);
|
||||
while (bes & BES_RXA) {
|
||||
if (uart_rx_full(sc)) {
|
||||
@ -533,7 +533,7 @@ z8530_bus_receive(struct uart_softc *sc)
|
||||
}
|
||||
bes = uart_getmreg(bas, RR_BES);
|
||||
}
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -558,7 +558,7 @@ z8530_bus_setsig(struct uart_softc *sc, int sig)
|
||||
}
|
||||
} while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
|
||||
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
if (new & SER_DTR)
|
||||
z8530->tpc |= TPC_DTR;
|
||||
else
|
||||
@ -569,7 +569,7 @@ z8530_bus_setsig(struct uart_softc *sc, int sig)
|
||||
z8530->tpc &= ~TPC_RTS;
|
||||
uart_setmreg(bas, WR_TPC, z8530->tpc);
|
||||
uart_barrier(bas);
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -580,13 +580,13 @@ z8530_bus_transmit(struct uart_softc *sc)
|
||||
struct uart_bas *bas;
|
||||
|
||||
bas = &sc->sc_bas;
|
||||
mtx_lock_spin(&sc->sc_hwmtx);
|
||||
uart_lock(sc->sc_hwmtx);
|
||||
while (!(uart_getmreg(bas, RR_BES) & BES_TXE))
|
||||
;
|
||||
uart_setreg(bas, REG_DATA, sc->sc_txbuf[0]);
|
||||
uart_barrier(bas);
|
||||
sc->sc_txbusy = 1;
|
||||
z8530->txidle = 1; /* Report SER_INT_TXIDLE again. */
|
||||
mtx_unlock_spin(&sc->sc_hwmtx);
|
||||
uart_unlock(sc->sc_hwmtx);
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user