Skip site navigation (1)Skip section navigation (2)
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>