PERFORCE change 37543 for review
Marcel Moolenaar
marcel at FreeBSD.org
Thu Sep 4 18:42:11 PDT 2003
http://perforce.freebsd.org/chv.cgi?CH=37543
Change 37543 by marcel at marcel_nfs on 2003/09/04 18:41:32
Atomically update sc->sc_hwsig. This avoids having to use
a lock, which pessimizes the common case more than the
overhead of the cmpset operation.
Affected files ...
.. //depot/projects/uart/dev/uart/uart_bus.h#26 edit
.. //depot/projects/uart/dev/uart/uart_dev_ns8250.c#25 edit
.. //depot/projects/uart/dev/uart/uart_dev_sab82532.c#23 edit
.. //depot/projects/uart/dev/uart/uart_dev_z8530.c#11 edit
Differences ...
==== //depot/projects/uart/dev/uart/uart_bus.h#26 (text+ko) ====
@@ -119,7 +119,7 @@
struct uart_devinfo *sc_sysdev; /* System device (or NULL). */
int sc_altbrk; /* State for alt break sequence. */
- int sc_hwsig; /* Signal state. Used by HW driver. */
+ uint32_t sc_hwsig; /* Signal state. Used by HW driver. */
/* Receiver data. */
uint16_t *sc_rxbuf;
==== //depot/projects/uart/dev/uart/uart_dev_ns8250.c#25 (text+ko) ====
@@ -441,16 +441,19 @@
static int
ns8250_bus_getsig(struct uart_softc *sc)
{
- int sig;
+ uint32_t new, old, sig;
uint8_t msr;
- msr = uart_getreg(&sc->sc_bas, REG_MSR);
- sig = sc->sc_hwsig;
- 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);
- SIGCHG(msr & MSR_RI, sig, UART_SIG_RI, UART_SIG_DRI);
- sc->sc_hwsig = sig & ~UART_SIGMASK_DELTA;
+ do {
+ old = sc->sc_hwsig;
+ sig = old;
+ msr = uart_getreg(&sc->sc_bas, REG_MSR);
+ 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);
+ SIGCHG(msr & MSR_RI, sig, UART_SIG_RI, UART_SIG_DRI);
+ new = sig & ~UART_SIGMASK_DELTA;
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
}
@@ -677,20 +680,25 @@
{
struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
struct uart_bas *bas;
+ uint32_t new, old;
bas = &sc->sc_bas;
- if (sig & UART_SIG_DDTR) {
- SIGCHG(sig & UART_SIG_DTR, sc->sc_hwsig, UART_SIG_DTR,
- UART_SIG_DDTR);
- }
- if (sig & UART_SIG_DRTS) {
- SIGCHG(sig & UART_SIG_RTS, sc->sc_hwsig, UART_SIG_RTS,
- UART_SIG_DRTS);
- }
+ do {
+ old = sc->sc_hwsig;
+ new = old;
+ if (sig & UART_SIG_DDTR) {
+ SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR,
+ UART_SIG_DDTR);
+ }
+ if (sig & UART_SIG_DRTS) {
+ SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS,
+ UART_SIG_DRTS);
+ }
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
- if (sc->sc_hwsig & UART_SIG_DTR)
+ if (new & UART_SIG_DTR)
ns8250->mcr |= MCR_DTR;
- if (sc->sc_hwsig & UART_SIG_RTS)
+ if (new & UART_SIG_RTS)
ns8250->mcr |= MCR_RTS;
uart_setreg(bas, REG_MCR, ns8250->mcr);
uart_barrier(bas);
==== //depot/projects/uart/dev/uart/uart_dev_sab82532.c#23 (text+ko) ====
@@ -429,19 +429,22 @@
sab82532_bus_getsig(struct uart_softc *sc)
{
struct uart_bas *bas;
- int sig;
+ uint32_t new, old, sig;
uint8_t pvr, star, vstr;
bas = &sc->sc_bas;
- sig = sc->sc_hwsig;
- star = uart_getreg(bas, SAB_STAR);
- SIGCHG(star & SAB_STAR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
- vstr = uart_getreg(bas, SAB_VSTR);
- SIGCHG(vstr & SAB_VSTR_CD, sig, UART_SIG_DCD, UART_SIG_DDCD);
- pvr = uart_getreg(bas, SAB_PVR);
- pvr &= (IS_CHANNEL_A(bas)) ? SAB_PVR_DSR_A : SAB_PVR_DSR_B;
- SIGCHG(~pvr, sig, UART_SIG_DSR, UART_SIG_DDSR);
- sc->sc_hwsig = sig & ~UART_SIGMASK_DELTA;
+ do {
+ old = sc->sc_hwsig;
+ sig = old;
+ star = uart_getreg(bas, SAB_STAR);
+ SIGCHG(star & SAB_STAR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
+ vstr = uart_getreg(bas, SAB_VSTR);
+ SIGCHG(vstr & SAB_VSTR_CD, sig, UART_SIG_DCD, UART_SIG_DDCD);
+ pvr = uart_getreg(bas, SAB_PVR);
+ pvr &= (IS_CHANNEL_A(bas)) ? SAB_PVR_DSR_A : SAB_PVR_DSR_B;
+ SIGCHG(~pvr, sig, UART_SIG_DSR, UART_SIG_DDSR);
+ new = sig & ~UART_SIGMASK_DELTA;
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
}
@@ -607,25 +610,34 @@
sab82532_bus_setsig(struct uart_softc *sc, int sig)
{
struct uart_bas *bas;
+ uint32_t new, old;
uint8_t mode, pvr;
bas = &sc->sc_bas;
- if (sig & UART_SIG_DDTR) {
- SIGCHG(sig & UART_SIG_DTR, sc->sc_hwsig, UART_SIG_DTR,
- UART_SIG_DDTR);
- }
- if (sig & UART_SIG_DRTS) {
- SIGCHG(sig & UART_SIG_RTS, sc->sc_hwsig, UART_SIG_RTS,
- UART_SIG_DRTS);
- }
+ do {
+ old = sc->sc_hwsig;
+ new = old;
+ if (sig & UART_SIG_DDTR) {
+ SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR,
+ UART_SIG_DDTR);
+ }
+ if (sig & UART_SIG_DRTS) {
+ SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS,
+ UART_SIG_DRTS);
+ }
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+ /* Set DTR pin. */
pvr = uart_getreg(bas, SAB_PVR);
- if (sc->sc_hwsig & UART_SIG_DTR)
+ if (new & UART_SIG_DTR)
pvr &= (IS_CHANNEL_A(bas)) ? ~SAB_PVR_DTR_A : ~SAB_PVR_DTR_B;
else
pvr |= (IS_CHANNEL_A(bas)) ? SAB_PVR_DTR_A : SAB_PVR_DTR_B;
uart_setreg(bas, SAB_PVR, pvr);
+
+ /* Set RTS pin. */
mode = uart_getreg(bas, SAB_MODE);
- if (sc->sc_hwsig & UART_SIG_RTS)
+ if (new & UART_SIG_RTS)
mode &= ~SAB_MODE_FRTS;
else
mode |= SAB_MODE_FRTS;
==== //depot/projects/uart/dev/uart/uart_dev_z8530.c#11 (text+ko) ====
@@ -334,14 +334,19 @@
static int
z8530_bus_getsig(struct uart_softc *sc)
{
- int sig;
+ struct uart_bas *bas;
+ uint32_t new, old, sig;
uint8_t bes;
- sig = sc->sc_hwsig;
- bes = uart_getmreg(&sc->sc_bas, RR_BES);
- SIGCHG(bes & BES_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
- SIGCHG(bes & BES_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD);
- sc->sc_hwsig = sig & ~UART_SIGMASK_DELTA;
+ bas = &sc->sc_bas;
+ do {
+ old = sc->sc_hwsig;
+ sig = old;
+ bes = uart_getmreg(bas, RR_BES);
+ SIGCHG(bes & BES_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
+ SIGCHG(bes & BES_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD);
+ new = sig & ~UART_SIGMASK_DELTA;
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
return (sig);
}
@@ -372,6 +377,7 @@
{
struct uart_bas *bas;
int ipend;
+ uint32_t sig;
uint8_t bes, src;
bas = &sc->sc_bas;
@@ -389,9 +395,10 @@
}
if (bes & BES_RXA)
ipend |= UART_IPEND_RXREADY;
- SIGCHG(bes & BES_CTS, sc->sc_hwsig, UART_SIG_CTS, UART_SIG_DCTS);
- SIGCHG(bes & BES_DCD, sc->sc_hwsig, UART_SIG_DCD, UART_SIG_DDCD);
- if (sc->sc_hwsig & UART_SIGMASK_DELTA)
+ sig = sc->sc_hwsig;
+ SIGCHG(bes & BES_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS);
+ SIGCHG(bes & BES_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD);
+ if (sig & UART_SIGMASK_DELTA)
ipend |= UART_IPEND_SIGCHG;
src = uart_getmreg(bas, RR_SRC);
if (src & SRC_OVR) {
@@ -461,21 +468,27 @@
{
struct z8530_softc *z8530 = (struct z8530_softc*)sc;
struct uart_bas *bas;
+ uint32_t new, old;
bas = &sc->sc_bas;
- if (sig & UART_SIG_DDTR) {
- SIGCHG(sig & UART_SIG_DTR, sc->sc_hwsig, UART_SIG_DTR,
- UART_SIG_DDTR);
- }
- if (sig & UART_SIG_DRTS) {
- SIGCHG(sig & UART_SIG_RTS, sc->sc_hwsig, UART_SIG_RTS,
- UART_SIG_DRTS);
- }
- if (sc->sc_hwsig & UART_SIG_DTR)
+ do {
+ old = sc->sc_hwsig;
+ new = old;
+ if (sig & UART_SIG_DDTR) {
+ SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR,
+ UART_SIG_DDTR);
+ }
+ if (sig & UART_SIG_DRTS) {
+ SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS,
+ UART_SIG_DRTS);
+ }
+ } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
+
+ if (new & UART_SIG_DTR)
z8530->tpc |= TPC_DTR;
else
z8530->tpc &= ~TPC_DTR;
- if (sc->sc_hwsig & UART_SIG_RTS)
+ if (new & UART_SIG_RTS)
z8530->tpc |= TPC_RTS;
else
z8530->tpc &= ~TPC_RTS;
More information about the p4-projects
mailing list