Date: Mon, 15 Oct 2012 12:20:41 +0000 (UTC) From: Aleksandr Rybalko <ray@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r241578 - in head/sys/dev/etherswitch: . arswitch Message-ID: <201210151220.q9FCKf3F086297@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ray Date: Mon Oct 15 12:20:40 2012 New Revision: 241578 URL: http://svn.freebsd.org/changeset/base/241578 Log: Locking for etherswitch framework: * add lock/unlock methods; * add lock/unlock default implementation; * surround switch IOCTLs with locking; * add lock/unlock implementation for arswitch; Submitted by: Luiz Otavio O Souza Approved by: adrian (mentor) Modified: head/sys/dev/etherswitch/arswitch/arswitch.c head/sys/dev/etherswitch/arswitch/arswitch_phy.c head/sys/dev/etherswitch/etherswitch.c head/sys/dev/etherswitch/etherswitch_if.m Modified: head/sys/dev/etherswitch/arswitch/arswitch.c ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitch.c Mon Oct 15 12:03:11 2012 (r241577) +++ head/sys/dev/etherswitch/arswitch/arswitch.c Mon Oct 15 12:20:40 2012 (r241578) @@ -263,7 +263,10 @@ arswitch_attach(device_t dev) return (err); callout_init_mtx(&sc->callout_tick, &sc->sc_mtx, 0); + + ARSWITCH_LOCK(sc); arswitch_tick(sc); + ARSWITCH_UNLOCK(sc); return (err); } @@ -371,6 +374,8 @@ arswitch_miipollstat(struct arswitch_sof struct mii_softc *miisc; int portstatus; + ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); + for (i = 0; i < sc->numphys; i++) { if (sc->miibus[i] == NULL) continue; @@ -404,6 +409,24 @@ arswitch_tick(void *arg) callout_reset(&sc->callout_tick, hz, arswitch_tick, sc); } +static void +arswitch_lock(device_t dev) +{ + struct arswitch_softc *sc = device_get_softc(dev); + + ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); + ARSWITCH_LOCK(sc); +} + +static void +arswitch_unlock(device_t dev) +{ + struct arswitch_softc *sc = device_get_softc(dev); + + ARSWITCH_LOCK_ASSERT(sc, MA_OWNED); + ARSWITCH_UNLOCK(sc); +} + static etherswitch_info_t * arswitch_getinfo(device_t dev) { @@ -552,6 +575,8 @@ static device_method_t arswitch_methods[ DEVMETHOD(mdio_writereg, arswitch_writephy), /* etherswitch interface */ + DEVMETHOD(etherswitch_lock, arswitch_lock), + DEVMETHOD(etherswitch_unlock, arswitch_unlock), DEVMETHOD(etherswitch_getinfo, arswitch_getinfo), DEVMETHOD(etherswitch_readreg, arswitch_readreg), DEVMETHOD(etherswitch_writereg, arswitch_writereg), Modified: head/sys/dev/etherswitch/arswitch/arswitch_phy.c ============================================================================== --- head/sys/dev/etherswitch/arswitch/arswitch_phy.c Mon Oct 15 12:03:11 2012 (r241577) +++ head/sys/dev/etherswitch/arswitch/arswitch_phy.c Mon Oct 15 12:20:40 2012 (r241578) @@ -75,13 +75,19 @@ static SYSCTL_NODE(_debug, OID_AUTO, ars int arswitch_readphy(device_t dev, int phy, int reg) { + struct arswitch_softc *sc; uint32_t data = 0, ctrl; int err, timeout; + sc = device_get_softc(dev); + ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); + if (phy < 0 || phy >= 32) return (ENXIO); if (reg < 0 || reg >= 32) return (ENXIO); + + ARSWITCH_LOCK(sc); err = arswitch_writereg_msb(dev, AR8X16_REG_MDIO_CTRL, AR8X16_MDIO_CTRL_BUSY | AR8X16_MDIO_CTRL_MASTER_EN | AR8X16_MDIO_CTRL_CMD_READ | @@ -89,41 +95,50 @@ arswitch_readphy(device_t dev, int phy, (reg << AR8X16_MDIO_CTRL_REG_ADDR_SHIFT)); DEVERR(dev, err, "arswitch_readphy()=%d: phy=%d.%02x\n", phy, reg); if (err != 0) - return (-1); + goto fail; for (timeout = 100; timeout--; ) { ctrl = arswitch_readreg_msb(dev, AR8X16_REG_MDIO_CTRL); if ((ctrl & AR8X16_MDIO_CTRL_BUSY) == 0) break; } if (timeout < 0) - err = EIO; + goto fail; data = arswitch_readreg_lsb(dev, AR8X16_REG_MDIO_CTRL) & AR8X16_MDIO_CTRL_DATA_MASK; + ARSWITCH_UNLOCK(sc); return (data); + +fail: + ARSWITCH_UNLOCK(sc); + return (-1); } int arswitch_writephy(device_t dev, int phy, int reg, int data) { + struct arswitch_softc *sc; uint32_t ctrl; int err, timeout; - + + sc = device_get_softc(dev); + ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED); + if (reg < 0 || reg >= 32) return (ENXIO); + + ARSWITCH_LOCK(sc); err = arswitch_writereg_lsb(dev, AR8X16_REG_MDIO_CTRL, (data & AR8X16_MDIO_CTRL_DATA_MASK)); - DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); if (err != 0) - return (err); + goto out; err = arswitch_writereg_msb(dev, AR8X16_REG_MDIO_CTRL, AR8X16_MDIO_CTRL_BUSY | AR8X16_MDIO_CTRL_MASTER_EN | AR8X16_MDIO_CTRL_CMD_WRITE | (phy << AR8X16_MDIO_CTRL_PHY_ADDR_SHIFT) | (reg << AR8X16_MDIO_CTRL_REG_ADDR_SHIFT)); - DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); if (err != 0) - return (err); + goto out; for (timeout = 100; timeout--; ) { ctrl = arswitch_readreg(dev, AR8X16_REG_MDIO_CTRL); if ((ctrl & AR8X16_MDIO_CTRL_BUSY) == 0) @@ -131,6 +146,8 @@ arswitch_writephy(device_t dev, int phy, } if (timeout < 0) err = EIO; +out: DEVERR(dev, err, "arswitch_writephy()=%d: phy=%d.%02x\n", phy, reg); + ARSWITCH_UNLOCK(sc); return (err); } Modified: head/sys/dev/etherswitch/etherswitch.c ============================================================================== --- head/sys/dev/etherswitch/etherswitch.c Mon Oct 15 12:03:11 2012 (r241577) +++ head/sys/dev/etherswitch/etherswitch.c Mon Oct 15 12:20:40 2012 (r241578) @@ -213,12 +213,16 @@ etherswitchioctl(struct cdev *cdev, u_lo case IOETHERSWITCHGETREG: reg = (etherswitch_reg_t *)data; + ETHERSWITCH_LOCK(etherswitch); reg->val = ETHERSWITCH_READREG(etherswitch, reg->reg); + ETHERSWITCH_UNLOCK(etherswitch); break; case IOETHERSWITCHSETREG: reg = (etherswitch_reg_t *)data; + ETHERSWITCH_LOCK(etherswitch); error = ETHERSWITCH_WRITEREG(etherswitch, reg->reg, reg->val); + ETHERSWITCH_UNLOCK(etherswitch); break; case IOETHERSWITCHGETPORT: Modified: head/sys/dev/etherswitch/etherswitch_if.m ============================================================================== --- head/sys/dev/etherswitch/etherswitch_if.m Mon Oct 15 12:03:11 2012 (r241577) +++ head/sys/dev/etherswitch/etherswitch_if.m Mon Oct 15 12:20:40 2012 (r241578) @@ -11,6 +11,21 @@ INTERFACE etherswitch; # +# Default implementation +# +CODE { + static void + null_etherswitch_lock(device_t dev) + { + } + + static void + null_etherswitch_unlock(device_t dev) + { + } +}; + +# # Return device info # METHOD etherswitch_info_t* getinfo { @@ -18,6 +33,20 @@ METHOD etherswitch_info_t* getinfo { } # +# Lock access to switch registers +# +METHOD void lock { + device_t dev; +} DEFAULT null_etherswitch_lock; + +# +# Unlock access to switch registers +# +METHOD void unlock { + device_t dev; +} DEFAULT null_etherswitch_unlock; + +# # Read switch register # METHOD int readreg {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201210151220.q9FCKf3F086297>