aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/cfg80211.c
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2013-05-17 20:50:20 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-05-22 15:08:49 -0400
commit75ab753d7704f0bd34e09d5e4081bc73fdddd775 (patch)
tree834f7906f5eff6acfc31568d3930b87e3487798b /drivers/net/wireless/mwifiex/cfg80211.c
parent06041118ef0908b9cae7657a7b734699bcf61a6c (diff)
mwifiex: remove global user_scan_cfg variable
As the variable is used only for preparation of internal scan commands, we don't need to keep it allocated until the entire scan completes. We will define it as a local variable and free immediately after it's use. New flag 'scan_aborting' is added to handle race between mwifiex_close() and scan handler. Previously user_scan_cfg pointer used to take care of this. This patch fixes a memory leak in mwifiex_cfg80211_scan after running "iwlist mlan0 scan & sleep 1; rmmod mwifiex_sdio". Reported-by: Daniel Drake <dsd@laptop.org> Tested-by: Daniel Drake <dsd@laptop.org> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/cfg80211.c')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index d3c8ece980d8..fcd293c64118 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1859,6 +1859,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1859 int i, offset, ret; 1859 int i, offset, ret;
1860 struct ieee80211_channel *chan; 1860 struct ieee80211_channel *chan;
1861 struct ieee_types_header *ie; 1861 struct ieee_types_header *ie;
1862 struct mwifiex_user_scan_cfg *user_scan_cfg;
1862 1863
1863 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1864 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1864 1865
@@ -1869,20 +1870,22 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1869 return -EBUSY; 1870 return -EBUSY;
1870 } 1871 }
1871 1872
1872 if (priv->user_scan_cfg) { 1873 /* Block scan request if scan operation or scan cleanup when interface
1874 * is disabled is in process
1875 */
1876 if (priv->scan_request || priv->scan_aborting) {
1873 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n"); 1877 dev_err(priv->adapter->dev, "cmd: Scan already in process..\n");
1874 return -EBUSY; 1878 return -EBUSY;
1875 } 1879 }
1876 1880
1877 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), 1881 user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
1878 GFP_KERNEL); 1882 if (!user_scan_cfg)
1879 if (!priv->user_scan_cfg)
1880 return -ENOMEM; 1883 return -ENOMEM;
1881 1884
1882 priv->scan_request = request; 1885 priv->scan_request = request;
1883 1886
1884 priv->user_scan_cfg->num_ssids = request->n_ssids; 1887 user_scan_cfg->num_ssids = request->n_ssids;
1885 priv->user_scan_cfg->ssid_list = request->ssids; 1888 user_scan_cfg->ssid_list = request->ssids;
1886 1889
1887 if (request->ie && request->ie_len) { 1890 if (request->ie && request->ie_len) {
1888 offset = 0; 1891 offset = 0;
@@ -1902,25 +1905,25 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1902 for (i = 0; i < min_t(u32, request->n_channels, 1905 for (i = 0; i < min_t(u32, request->n_channels,
1903 MWIFIEX_USER_SCAN_CHAN_MAX); i++) { 1906 MWIFIEX_USER_SCAN_CHAN_MAX); i++) {
1904 chan = request->channels[i]; 1907 chan = request->channels[i];
1905 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1908 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1906 priv->user_scan_cfg->chan_list[i].radio_type = chan->band; 1909 user_scan_cfg->chan_list[i].radio_type = chan->band;
1907 1910
1908 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) 1911 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
1909 priv->user_scan_cfg->chan_list[i].scan_type = 1912 user_scan_cfg->chan_list[i].scan_type =
1910 MWIFIEX_SCAN_TYPE_PASSIVE; 1913 MWIFIEX_SCAN_TYPE_PASSIVE;
1911 else 1914 else
1912 priv->user_scan_cfg->chan_list[i].scan_type = 1915 user_scan_cfg->chan_list[i].scan_type =
1913 MWIFIEX_SCAN_TYPE_ACTIVE; 1916 MWIFIEX_SCAN_TYPE_ACTIVE;
1914 1917
1915 priv->user_scan_cfg->chan_list[i].scan_time = 0; 1918 user_scan_cfg->chan_list[i].scan_time = 0;
1916 } 1919 }
1917 1920
1918 ret = mwifiex_scan_networks(priv, priv->user_scan_cfg); 1921 ret = mwifiex_scan_networks(priv, user_scan_cfg);
1922 kfree(user_scan_cfg);
1919 if (ret) { 1923 if (ret) {
1920 dev_err(priv->adapter->dev, "scan failed: %d\n", ret); 1924 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1925 priv->scan_aborting = false;
1921 priv->scan_request = NULL; 1926 priv->scan_request = NULL;
1922 kfree(priv->user_scan_cfg);
1923 priv->user_scan_cfg = NULL;
1924 return ret; 1927 return ret;
1925 } 1928 }
1926 1929