usbnet: add a mutex around phy register access
authorArnd Bergmann <arnd@arndb.de>
Sun, 8 Oct 2006 22:08:02 +0000 (00:08 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 17 Oct 2006 21:46:32 +0000 (14:46 -0700)
When working on the mcs7830, I noticed the need for a mutex in its
mdio_read/mdio_write functions. A related problem seems to be present
in the asix driver in the respective functions.

This introduces a mutex in the common usbnet driver and uses it
from the two hardware specific drivers.

Acked-by: David Hollis <dhollis@davehollis.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/usb/net/asix.c
drivers/usb/net/mcs7830.c
drivers/usb/net/usbnet.c
drivers/usb/net/usbnet.h

index 5edd0534c7abe16685718d95d6c677bc8400f974..881841e600def9f680f58109b30bfb175e4d2118 100644 (file)
@@ -569,10 +569,12 @@ static int asix_mdio_read(struct net_device *netdev, int phy_id, int loc)
        struct usbnet *dev = netdev_priv(netdev);
        u16 res;
 
+       mutex_lock(&dev->phy_mutex);
        asix_set_sw_mii(dev);
        asix_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id,
                                (__u16)loc, 2, (u16 *)&res);
        asix_set_hw_mii(dev);
+       mutex_unlock(&dev->phy_mutex);
 
        devdbg(dev, "asix_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x", phy_id, loc, le16_to_cpu(res & 0xffff));
 
@@ -586,10 +588,12 @@ asix_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
        u16 res = cpu_to_le16(val);
 
        devdbg(dev, "asix_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x", phy_id, loc, val);
+       mutex_lock(&dev->phy_mutex);
        asix_set_sw_mii(dev);
        asix_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id,
                                (__u16)loc, 2, (u16 *)&res);
        asix_set_hw_mii(dev);
+       mutex_unlock(&dev->phy_mutex);
 }
 
 /* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */
index 23a80667f17e56e6f44884a0b211249bfdacb036..6240b978fe3d94ccbe08ebf489ba75b47c042566 100644 (file)
@@ -184,6 +184,7 @@ static int mcs7830_read_phy(struct usbnet *dev, u8 index)
                HIF_REG_PHY_CMD2_PEND_FLAG_BIT | index,
        };
 
+       mutex_lock(&dev->phy_mutex);
        /* write the MII command */
        ret = mcs7830_set_reg(dev, HIF_REG_PHY_CMD1, 2, cmd);
        if (ret < 0)
@@ -208,6 +209,7 @@ static int mcs7830_read_phy(struct usbnet *dev, u8 index)
        dev_dbg(&dev->udev->dev, "read PHY reg %02x: %04x (%d tries)\n",
                index, val, i);
 out:
+       mutex_unlock(&dev->phy_mutex);
        return ret;
 }
 
@@ -222,6 +224,8 @@ static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val)
                HIF_REG_PHY_CMD2_PEND_FLAG_BIT | (index & 0x1F),
        };
 
+       mutex_lock(&dev->phy_mutex);
+
        /* write the new register contents */
        le_val = cpu_to_le16(val);
        ret = mcs7830_set_reg(dev, HIF_REG_PHY_DATA, 2, &le_val);
@@ -248,6 +252,7 @@ static int mcs7830_write_phy(struct usbnet *dev, u8 index, u16 val)
        dev_dbg(&dev->udev->dev, "write PHY reg %02x: %04x (%d tries)\n",
                index, val, i);
 out:
+       mutex_unlock(&dev->phy_mutex);
        return ret;
 }
 
index decc1b179246660a7858674546f43f7295400630..cf3d20eb781cde127e53f1af4c553bea198fa13a 100644 (file)
@@ -1144,6 +1144,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
        dev->delay.function = usbnet_bh;
        dev->delay.data = (unsigned long) dev;
        init_timer (&dev->delay);
+       mutex_init (&dev->phy_mutex);
 
        SET_MODULE_OWNER (net);
        dev->net = net;
index 743947c3fb837d3db4816cfe6b2c3c4884f684a5..07c70abbe0ecaa5c3df76e488239e79e0f7ebbcf 100644 (file)
@@ -30,6 +30,7 @@ struct usbnet {
        struct usb_device       *udev;
        struct driver_info      *driver_info;
        wait_queue_head_t       *wait;
+       struct mutex            phy_mutex;
 
        /* i/o info: pipes etc */
        unsigned                in, out;