Re: smsc9511: Register access happens after unregistration

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Andrew,

On Fri, Mar 4, 2022 at 11:11 AM Andrew Lunn <andrew@xxxxxxx> wrote:

> I suggest you look at the call sequences. When does phy_stop() and
> phy_disconnect() get called? phylib has a work queue which runs once
> per second to poll the PHY and get its status. That polling is stopped
> by calling phy_stop(). It is also assumed you can still talk to the
> PHY while performing phy_stop().

With this debug patch:

--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1034,6 +1034,8 @@ void phy_stop(struct phy_device *phydev)
 {
        struct net_device *dev = phydev->attached_dev;

+       pr_err("*************** %s\n", __func__);
+
        if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) {
                WARN(1, "called from state %s\n",
                     phy_state_to_str(phydev->state));
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index ce0bb5951b81..e26d9edf32f3 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1108,8 +1108,11 @@ EXPORT_SYMBOL(phy_connect);
  */
 void phy_disconnect(struct phy_device *phydev)
 {
-       if (phy_is_started(phydev))
+       pr_err("*********** %s: 1\n", __func__);
+       if (phy_is_started(phydev)) {
+               pr_err("*********** %s: 2\n", __func__);
                phy_stop(phydev);
+       }

        if (phy_interrupt_is_valid(phydev))
                phy_free_interrupt(phydev);
diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c
index bc1e3dd67c04..6ed674636961 100644
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -1190,6 +1190,7 @@ static void smsc95xx_unbind(struct usbnet *dev,
struct usb_interface *intf)
 {
        struct smsc95xx_priv *pdata = dev->driver_priv;

+       pr_err("*********** %s: calling phy_disconnect\n", __func__);
        phy_disconnect(dev->net->phydev);
        mdiobus_unregister(pdata->mdiobus);
        mdiobus_free(pdata->mdiobus);
@@ -1206,6 +1207,7 @@ static int smsc95xx_start_phy(struct usbnet *dev)

 static int smsc95xx_stop(struct usbnet *dev)
 {
+       pr_err("*********** %s\n", __func__);
        if (dev->net->phydev)
                phy_stop(dev->net->phydev);

The result is:

 # echo -n "2-1" > /sys/bus/usb/drivers/usb/unbind
usb 2-1.1: USB disconnect, device number 3
smsc95xx 2-1.1:1.0 eth1: unregister 'smsc95xx' usb-ci_hdrc.1-1.1,
smsc95xx USB 2.0 Ethernet
smsc95xx 2-1.1:1.0 eth1: Failed to read reg index 0x00000114: -19
smsc95xx 2-1.1:1.0 eth1: Error reading MII_ACCESS
*********** smsc95xx_unbind: calling phy_disconnect
smsc95xx 2-1.1:1.0 eth1: __smsc95xx_mdio_read: MII is busy
libphy: *********** phy_disconnect: 1
libphy: *********** phy_disconnect: 2
*************** phy_stop
smsc95xx 2-1.1:1.0 eth1: Failed to read reg index 0x00000114: -19
smsc95xx 2-1.1:1.0 eth1: Error reading MII_ACCESS
smsc95xx 2-1.1:1.0 eth1: __smsc95xx_mdio_read: MII is busy
smsc95xx 2-1.1:1.0 eth1: Failed to read reg index 0x00000114: -19
smsc95xx 2-1.1:1.0 eth1: Error reading MII_ACCESS
smsc95xx 2-1.1:1.0 eth1: __smsc95xx_mdio_read: MII is busy
*********** smsc95xx_stop
smsc95xx 2-1.1:1.0 eth1: hardware isn't capable of remote wakeup
usb 2-1.4: USB disconnect, device number 4

Maybe the -19 errors should be ignored?



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux