p54: Fix potential concurrent access to private data
authorLarry Finger <Larry.Finger@lwfinger.net>
Sun, 3 Aug 2008 22:58:36 +0000 (17:58 -0500)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 4 Aug 2008 19:09:12 +0000 (15:09 -0400)
Experience with the rtl8187 driver has shown that mac80211 can make
calls to the config callback routine in rapid succession. This patch
creates a mutex that protects the private data in several of the routines
called by mac80211.

Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/p54/p54.h
drivers/net/wireless/p54/p54common.c

index c6f27b9..cac9a51 100644 (file)
@@ -52,6 +52,7 @@ struct p54_common {
        int (*open)(struct ieee80211_hw *dev);
        void (*stop)(struct ieee80211_hw *dev);
        int mode;
+       struct mutex conf_mutex;
        u8 mac_addr[ETH_ALEN];
        u8 bssid[ETH_ALEN];
        struct pda_iq_autocal_entry *iq_autocal;
index ffaf7a6..4da89ea 100644 (file)
@@ -886,9 +886,12 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
 static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
 {
        int ret;
+       struct p54_common *priv = dev->priv;
 
+       mutex_lock(&priv->conf_mutex);
        ret = p54_set_freq(dev, cpu_to_le16(conf->channel->center_freq));
        p54_set_vdcf(dev);
+       mutex_unlock(&priv->conf_mutex);
        return ret;
 }
 
@@ -898,10 +901,12 @@ static int p54_config_interface(struct ieee80211_hw *dev,
 {
        struct p54_common *priv = dev->priv;
 
+       mutex_lock(&priv->conf_mutex);
        p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 0, 1, 0, 0xF642);
        p54_set_filter(dev, 0, priv->mac_addr, conf->bssid, 2, 0, 0, 0);
        p54_set_leds(dev, 1, !is_multicast_ether_addr(conf->bssid), 0);
        memcpy(priv->bssid, conf->bssid, ETH_ALEN);
+       mutex_unlock(&priv->conf_mutex);
        return 0;
 }
 
@@ -1009,6 +1014,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
        }
 
        p54_init_vdcf(dev);
+       mutex_init(&priv->conf_mutex);
 
        return dev;
 }