diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2010-10-26 07:24:38 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-11-15 13:25:19 -0500 |
commit | b739a42c921dcb0ae92cc14032b7f75dcba88e3b (patch) | |
tree | 85cc1cf771a013f2e040c1edcb90b4fe315e3df7 /drivers/net/wireless/wl12xx | |
parent | fb2382c75b1292aff0ebc8e209b0cb9ba70bb2cf (diff) |
wl1271: Fix scan failure detection
In scan_complete_work, because the mutex is released before accessing the
scan->failed flag, it is possible for unfounded hardware recovery rounds
to be executed.
Fix this.
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Luciano Coelho <luciano.coelho@nokia.com>
Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_main.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1271_scan.c | 5 |
2 files changed, 17 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c index 63036b53f9e..bec2b3d7878 100644 --- a/drivers/net/wireless/wl12xx/wl1271_main.c +++ b/drivers/net/wireless/wl12xx/wl1271_main.c | |||
@@ -1056,6 +1056,7 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl) | |||
1056 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 1056 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
1057 | kfree(wl->scan.scanned_ch); | 1057 | kfree(wl->scan.scanned_ch); |
1058 | wl->scan.scanned_ch = NULL; | 1058 | wl->scan.scanned_ch = NULL; |
1059 | wl->scan.req = NULL; | ||
1059 | ieee80211_scan_completed(wl->hw, true); | 1060 | ieee80211_scan_completed(wl->hw, true); |
1060 | } | 1061 | } |
1061 | 1062 | ||
@@ -1676,6 +1677,16 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw, | |||
1676 | 1677 | ||
1677 | mutex_lock(&wl->mutex); | 1678 | mutex_lock(&wl->mutex); |
1678 | 1679 | ||
1680 | if (wl->state == WL1271_STATE_OFF) { | ||
1681 | /* | ||
1682 | * We cannot return -EBUSY here because cfg80211 will expect | ||
1683 | * a call to ieee80211_scan_completed if we do - in this case | ||
1684 | * there won't be any call. | ||
1685 | */ | ||
1686 | ret = -EAGAIN; | ||
1687 | goto out; | ||
1688 | } | ||
1689 | |||
1679 | ret = wl1271_ps_elp_wakeup(wl, false); | 1690 | ret = wl1271_ps_elp_wakeup(wl, false); |
1680 | if (ret < 0) | 1691 | if (ret < 0) |
1681 | goto out; | 1692 | goto out; |
@@ -2093,14 +2104,14 @@ static int wl1271_op_get_survey(struct ieee80211_hw *hw, int idx, | |||
2093 | { | 2104 | { |
2094 | struct wl1271 *wl = hw->priv; | 2105 | struct wl1271 *wl = hw->priv; |
2095 | struct ieee80211_conf *conf = &hw->conf; | 2106 | struct ieee80211_conf *conf = &hw->conf; |
2096 | 2107 | ||
2097 | if (idx != 0) | 2108 | if (idx != 0) |
2098 | return -ENOENT; | 2109 | return -ENOENT; |
2099 | 2110 | ||
2100 | survey->channel = conf->channel; | 2111 | survey->channel = conf->channel; |
2101 | survey->filled = SURVEY_INFO_NOISE_DBM; | 2112 | survey->filled = SURVEY_INFO_NOISE_DBM; |
2102 | survey->noise = wl->noise; | 2113 | survey->noise = wl->noise; |
2103 | 2114 | ||
2104 | return 0; | 2115 | return 0; |
2105 | } | 2116 | } |
2106 | 2117 | ||
diff --git a/drivers/net/wireless/wl12xx/wl1271_scan.c b/drivers/net/wireless/wl12xx/wl1271_scan.c index 909bb47995b..e0661a543a3 100644 --- a/drivers/net/wireless/wl12xx/wl1271_scan.c +++ b/drivers/net/wireless/wl12xx/wl1271_scan.c | |||
@@ -48,14 +48,15 @@ void wl1271_scan_complete_work(struct work_struct *work) | |||
48 | wl->scan.state = WL1271_SCAN_STATE_IDLE; | 48 | wl->scan.state = WL1271_SCAN_STATE_IDLE; |
49 | kfree(wl->scan.scanned_ch); | 49 | kfree(wl->scan.scanned_ch); |
50 | wl->scan.scanned_ch = NULL; | 50 | wl->scan.scanned_ch = NULL; |
51 | mutex_unlock(&wl->mutex); | 51 | wl->scan.req = NULL; |
52 | |||
53 | ieee80211_scan_completed(wl->hw, false); | 52 | ieee80211_scan_completed(wl->hw, false); |
54 | 53 | ||
55 | if (wl->scan.failed) { | 54 | if (wl->scan.failed) { |
56 | wl1271_info("Scan completed due to error."); | 55 | wl1271_info("Scan completed due to error."); |
57 | ieee80211_queue_work(wl->hw, &wl->recovery_work); | 56 | ieee80211_queue_work(wl->hw, &wl->recovery_work); |
58 | } | 57 | } |
58 | mutex_unlock(&wl->mutex); | ||
59 | |||
59 | } | 60 | } |
60 | 61 | ||
61 | 62 | ||