diff options
author | Ido Yariv <ido@wizery.com> | 2012-01-11 02:42:39 -0500 |
---|---|---|
committer | Luciano Coelho <coelho@ti.com> | 2012-02-15 01:38:28 -0500 |
commit | f3df1331f25f782e838a3ecb72cec86b539ac02f (patch) | |
tree | 216aa4589286aec4cfd5878b6607b10ffe5cff4b /drivers | |
parent | 9e0dc890ce23e2b28ce906bb8f466ca66f420911 (diff) |
wl12xx: Acquire lock before stopping plt
__wl1271_plt_stop is called from both wl1271_plt_stop and
wl1271_unregister_hw. While wl1271_plt_stop acquires a mutex,
wl1271_unregister_hw does not.
Fix this by calling wl1271_plt_stop instead of __wl1271_plt_stop from
wl1271_unregister_hw.
Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/wl12xx/main.c | 18 |
1 files changed, 5 insertions, 13 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index f2a958c9537a..ac6866469073 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
@@ -1391,13 +1391,15 @@ out: | |||
1391 | return ret; | 1391 | return ret; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | static int __wl1271_plt_stop(struct wl1271 *wl) | 1394 | int wl1271_plt_stop(struct wl1271 *wl) |
1395 | { | 1395 | { |
1396 | int ret = 0; | 1396 | int ret = 0; |
1397 | 1397 | ||
1398 | wl1271_notice("power down"); | 1398 | wl1271_notice("power down"); |
1399 | 1399 | ||
1400 | mutex_lock(&wl->mutex); | ||
1400 | if (wl->state != WL1271_STATE_PLT) { | 1401 | if (wl->state != WL1271_STATE_PLT) { |
1402 | mutex_unlock(&wl->mutex); | ||
1401 | wl1271_error("cannot power down because not in PLT " | 1403 | wl1271_error("cannot power down because not in PLT " |
1402 | "state: %d", wl->state); | 1404 | "state: %d", wl->state); |
1403 | ret = -EBUSY; | 1405 | ret = -EBUSY; |
@@ -1410,25 +1412,15 @@ static int __wl1271_plt_stop(struct wl1271 *wl) | |||
1410 | wl->rx_counter = 0; | 1412 | wl->rx_counter = 0; |
1411 | 1413 | ||
1412 | mutex_unlock(&wl->mutex); | 1414 | mutex_unlock(&wl->mutex); |
1415 | |||
1413 | wl1271_disable_interrupts(wl); | 1416 | wl1271_disable_interrupts(wl); |
1414 | wl1271_flush_deferred_work(wl); | 1417 | wl1271_flush_deferred_work(wl); |
1415 | cancel_work_sync(&wl->netstack_work); | 1418 | cancel_work_sync(&wl->netstack_work); |
1416 | cancel_work_sync(&wl->recovery_work); | 1419 | cancel_work_sync(&wl->recovery_work); |
1417 | mutex_lock(&wl->mutex); | ||
1418 | out: | 1420 | out: |
1419 | return ret; | 1421 | return ret; |
1420 | } | 1422 | } |
1421 | 1423 | ||
1422 | int wl1271_plt_stop(struct wl1271 *wl) | ||
1423 | { | ||
1424 | int ret; | ||
1425 | |||
1426 | mutex_lock(&wl->mutex); | ||
1427 | ret = __wl1271_plt_stop(wl); | ||
1428 | mutex_unlock(&wl->mutex); | ||
1429 | return ret; | ||
1430 | } | ||
1431 | |||
1432 | static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1424 | static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
1433 | { | 1425 | { |
1434 | struct wl1271 *wl = hw->priv; | 1426 | struct wl1271 *wl = hw->priv; |
@@ -4881,7 +4873,7 @@ static int wl1271_register_hw(struct wl1271 *wl) | |||
4881 | static void wl1271_unregister_hw(struct wl1271 *wl) | 4873 | static void wl1271_unregister_hw(struct wl1271 *wl) |
4882 | { | 4874 | { |
4883 | if (wl->state == WL1271_STATE_PLT) | 4875 | if (wl->state == WL1271_STATE_PLT) |
4884 | __wl1271_plt_stop(wl); | 4876 | wl1271_plt_stop(wl); |
4885 | 4877 | ||
4886 | unregister_netdevice_notifier(&wl1271_dev_notifier); | 4878 | unregister_netdevice_notifier(&wl1271_dev_notifier); |
4887 | ieee80211_unregister_hw(wl->hw); | 4879 | ieee80211_unregister_hw(wl->hw); |