The branch main has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=725962a9f4c050b21488edd58d317e87c76d6f66

commit 725962a9f4c050b21488edd58d317e87c76d6f66
Author:     Mark Johnston <[email protected]>
AuthorDate: 2023-11-06 19:57:56 +0000
Commit:     Mark Johnston <[email protected]>
CommitDate: 2023-11-06 19:57:56 +0000

    e6000sw: Fix locking in miibus_{read,write}reg implementations
    
    Commit 469290648005e13b819a19353032ca53dda4378f made e6000sw's
    implementation of miibus_(read|write)reg assume that the softc lock is
    held.  I presume that is to avoid lock recursion in e6000sw_attach() ->
    e6000sw_attach_miibus() -> mii_attach() -> MIIBUS_READREG().
    
    However, the lock assertion in e6000sw_readphy_locked() can fail if a
    different driver uses the interface to probe registers.  Work around the
    problem by providing implementations which lock the softc if it is not
    already locked.
    
    PR:             274795
    Fixes:          469290648005 ("e6000sw: add readphy and writephy wrappers")
    Reviewed by:    kp, imp
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D42466
---
 sys/dev/etherswitch/e6000sw/e6000sw.c | 31 +++++++++++++++++++------------
 1 file changed, 19 insertions(+), 12 deletions(-)

diff --git a/sys/dev/etherswitch/e6000sw/e6000sw.c 
b/sys/dev/etherswitch/e6000sw/e6000sw.c
index 768d1b927e3e..95f1a2e96db6 100644
--- a/sys/dev/etherswitch/e6000sw/e6000sw.c
+++ b/sys/dev/etherswitch/e6000sw/e6000sw.c
@@ -66,6 +66,7 @@ MALLOC_DEFINE(M_E6000SW, "e6000sw", "e6000sw switch");
 #define        E6000SW_UNLOCK(_sc)             sx_unlock(&(_sc)->sx)
 #define        E6000SW_LOCK_ASSERT(_sc, _what) sx_assert(&(_sc)->sx, (_what))
 #define        E6000SW_TRYLOCK(_sc)            sx_tryxlock(&(_sc)->sx)
+#define        E6000SW_LOCKED(_sc)             sx_xlocked(&(_sc)->sx)
 #define        E6000SW_WAITREADY(_sc, _reg, _bit)                              
\
     e6000sw_waitready((_sc), REG_GLOBAL, (_reg), (_bit))
 #define        E6000SW_WAITREADY2(_sc, _reg, _bit)                             
\
@@ -169,8 +170,8 @@ static device_method_t e6000sw_methods[] = {
        DEVMETHOD(bus_add_child,                device_add_child_ordered),
 
        /* mii interface */
-       DEVMETHOD(miibus_readreg,               e6000sw_readphy_locked),
-       DEVMETHOD(miibus_writereg,              e6000sw_writephy_locked),
+       DEVMETHOD(miibus_readreg,               e6000sw_readphy),
+       DEVMETHOD(miibus_writereg,              e6000sw_writephy),
 
        /* etherswitch interface */
        DEVMETHOD(etherswitch_getinfo,          e6000sw_getinfo),
@@ -744,17 +745,20 @@ e6000sw_write_xmdio(device_t dev, int phy, int devaddr, 
int devreg, int val)
        return (0);
 }
 
-static int e6000sw_readphy(device_t dev, int phy, int reg)
+static int
+e6000sw_readphy(device_t dev, int phy, int reg)
 {
        e6000sw_softc_t *sc;
-       int ret;
+       int locked, ret;
 
        sc = device_get_softc(dev);
-       E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
 
-       E6000SW_LOCK(sc);
+       locked = E6000SW_LOCKED(sc);
+       if (!locked)
+               E6000SW_LOCK(sc);
        ret = e6000sw_readphy_locked(dev, phy, reg);
-       E6000SW_UNLOCK(sc);
+       if (!locked)
+               E6000SW_UNLOCK(sc);
 
        return (ret);
 }
@@ -795,17 +799,20 @@ e6000sw_readphy_locked(device_t dev, int phy, int reg)
        return (val & PHY_DATA_MASK);
 }
 
-static int e6000sw_writephy(device_t dev, int phy, int reg, int data)
+static int
+e6000sw_writephy(device_t dev, int phy, int reg, int data)
 {
        e6000sw_softc_t *sc;
-       int ret;
+       int locked, ret;
 
        sc = device_get_softc(dev);
-       E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
 
-       E6000SW_LOCK(sc);
+       locked = E6000SW_LOCKED(sc);
+       if (!locked)
+               E6000SW_LOCK(sc);
        ret = e6000sw_writephy_locked(dev, phy, reg, data);
-       E6000SW_UNLOCK(sc);
+       if (!locked)
+               E6000SW_UNLOCK(sc);
 
        return (ret);
 }

Reply via email to