From owner-p4-projects@FreeBSD.ORG Thu Sep 4 18:42:11 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 35B6416A4C1; Thu, 4 Sep 2003 18:42:11 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BADE416A4BF for ; Thu, 4 Sep 2003 18:42:10 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1D04143FE0 for ; Thu, 4 Sep 2003 18:42:10 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h851g90U068372 for ; Thu, 4 Sep 2003 18:42:09 -0700 (PDT) (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h851g9Pl068369 for perforce@freebsd.org; Thu, 4 Sep 2003 18:42:09 -0700 (PDT) Date: Thu, 4 Sep 2003 18:42:09 -0700 (PDT) Message-Id: <200309050142.h851g9Pl068369@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Subject: PERFORCE change 37543 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 05 Sep 2003 01:42:11 -0000 http://perforce.freebsd.org/chv.cgi?CH=37543 Change 37543 by marcel@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;