From: Ido Yariv Date: Wed, 11 Jan 2012 07:42:39 +0000 (+0200) Subject: wl12xx: Acquire lock before stopping plt X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=f3df1331f25f782e838a3ecb72cec86b539ac02f;p=linux-beck.git 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 Signed-off-by: Luciano Coelho --- 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: return ret; } -static int __wl1271_plt_stop(struct wl1271 *wl) +int wl1271_plt_stop(struct wl1271 *wl) { int ret = 0; wl1271_notice("power down"); + mutex_lock(&wl->mutex); if (wl->state != WL1271_STATE_PLT) { + mutex_unlock(&wl->mutex); wl1271_error("cannot power down because not in PLT " "state: %d", wl->state); ret = -EBUSY; @@ -1410,25 +1412,15 @@ static int __wl1271_plt_stop(struct wl1271 *wl) wl->rx_counter = 0; mutex_unlock(&wl->mutex); + wl1271_disable_interrupts(wl); wl1271_flush_deferred_work(wl); cancel_work_sync(&wl->netstack_work); cancel_work_sync(&wl->recovery_work); - mutex_lock(&wl->mutex); out: return ret; } -int wl1271_plt_stop(struct wl1271 *wl) -{ - int ret; - - mutex_lock(&wl->mutex); - ret = __wl1271_plt_stop(wl); - mutex_unlock(&wl->mutex); - return ret; -} - static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { struct wl1271 *wl = hw->priv; @@ -4881,7 +4873,7 @@ static int wl1271_register_hw(struct wl1271 *wl) static void wl1271_unregister_hw(struct wl1271 *wl) { if (wl->state == WL1271_STATE_PLT) - __wl1271_plt_stop(wl); + wl1271_plt_stop(wl); unregister_netdevice_notifier(&wl1271_dev_notifier); ieee80211_unregister_hw(wl->hw);