]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
rtl8187: Fix lockups due to concurrent access to config routine
authorLarry Finger <Larry.Finger@lwfinger.net>
Wed, 6 Aug 2008 04:20:56 +0000 (23:20 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 20 Aug 2008 18:05:10 +0000 (11:05 -0700)
With the rtl8187 driver, the config routine is not protected against
access before a previous call has completed. When this happens, the
TX loopback that is needed to change channels may cause the chip to
be locked with a reset needed to restore communications. This patch
entered mainline as commit 7dcdd073bf78bb6958bbc12a1a47754a0f3c4721.

The problem was found by Herton Ronaldo Krzesinski <herton@mandriva.com.br>,
who also suggested this type of fix.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Acked-by: Herton Ronaldo Krzesinski <herton@mandriva.com.br>
Acked-by: Hin-Tak Leung <htl10@users.sourceforge.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/net/wireless/rtl8187.h
drivers/net/wireless/rtl8187_dev.c

index 076d88b6db0e9f69c23d3e952af95b03097a549f..aefd4f67307c67daf86472a4e0f488e7e8211ca4 100644 (file)
@@ -67,6 +67,10 @@ struct rtl8187_priv {
        const struct rtl818x_rf_ops *rf;
        struct ieee80211_vif *vif;
        int mode;
+       /* The mutex protects the TX loopback state.
+        * Any attempt to set channels concurrently locks the device.
+        */
+       struct mutex conf_mutex;
 
        /* rtl8187 specific */
        struct ieee80211_channel channels[14];
index 9223ada5f00ed2d73ca633793c2b9e646033019a..d49d1c6960a2060d6b584cf419abe41b32f0aeda 100644 (file)
@@ -580,6 +580,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        struct rtl8187_priv *priv = dev->priv;
        u32 reg;
 
+       mutex_lock(&priv->conf_mutex);
        reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
        /* Enable TX loopback on MAC level to avoid TX during channel
         * changes, as this has be seen to causes problems and the
@@ -610,6 +611,7 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
        rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
        rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
+       mutex_unlock(&priv->conf_mutex);
        return 0;
 }
 
@@ -814,6 +816,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
                printk(KERN_ERR "rtl8187: Cannot register device\n");
                goto err_free_dev;
        }
+       mutex_init(&priv->conf_mutex);
 
        printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
               wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),