From dc1a4068fce2657991c5c3b1f6849f7fc466c69f Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 31 Mar 2011 17:36:27 +0200 Subject: iwlwifi: more priv->mutex serialization Check status bits with mutex taken, because when we wait for mutex unlock, status can change. Patch should also make remaining sync commands be send with priv->mutex taken. That will prevent execute these commands when we are currently reset firmware, what could possibly cause troubles. Signed-off-by: Stanislaw Gruszka Acked-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/iwlwifi') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 28ac0d44555e..70428e9b9f76 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -483,12 +483,14 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) container_of(work, struct iwl_priv, bt_full_concurrency); struct iwl_rxon_context *ctx; + mutex_lock(&priv->mutex); + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; + goto out; /* dont send host command if rf-kill is on */ if (!iwl_is_ready_rf(priv)) - return; + goto out; IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", priv->bt_full_concurrent ? @@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) * LQ & RXON updated cmds must be sent before BT Config cmd * to avoid 3-wire collisions */ - mutex_lock(&priv->mutex); for_each_context(priv, ctx) { if (priv->cfg->ops->hcmd->set_rxon_chain) priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); iwlcore_commit_rxon(priv, ctx); } - mutex_unlock(&priv->mutex); priv->cfg->ops->hcmd->send_bt_config(priv); +out: + mutex_unlock(&priv->mutex); } /** @@ -2620,10 +2622,13 @@ static void iwl_bg_init_alive_start(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, init_alive_start.work); - if (test_bit(STATUS_EXIT_PENDING, &priv->status)) + mutex_lock(&priv->mutex); + + if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { + mutex_unlock(&priv->mutex); return; + } - mutex_lock(&priv->mutex); priv->cfg->ops->lib->init_alive_start(priv); mutex_unlock(&priv->mutex); } @@ -2633,15 +2638,16 @@ static void iwl_bg_alive_start(struct work_struct *data) struct iwl_priv *priv = container_of(data, struct iwl_priv, alive_start.work); + mutex_lock(&priv->mutex); if (test_bit(STATUS_EXIT_PENDING, &priv->status)) - return; + goto unlock; /* enable dram interrupt */ if (priv->cfg->ops->lib->isr_ops.reset) priv->cfg->ops->lib->isr_ops.reset(priv); - mutex_lock(&priv->mutex); iwl_alive_start(priv); +unlock: mutex_unlock(&priv->mutex); } @@ -3267,21 +3273,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, IWL_DEBUG_MAC80211(priv, "enter\n"); + mutex_lock(&priv->mutex); + if (iwl_is_rfkill(priv)) - goto out_exit; + goto out; if (test_bit(STATUS_EXIT_PENDING, &priv->status) || test_bit(STATUS_SCANNING, &priv->status)) - goto out_exit; + goto out; if (!iwl_is_associated_ctx(ctx)) - goto out_exit; + goto out; /* channel switch in progress */ if (priv->switch_rxon.switch_in_progress == true) - goto out_exit; + goto out; - mutex_lock(&priv->mutex); if (priv->cfg->ops->lib->set_channel_switch) { ch = channel->hw_value; @@ -3337,7 +3344,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, } out: mutex_unlock(&priv->mutex); -out_exit: if (!priv->switch_rxon.switch_in_progress) ieee80211_chswitch_done(ctx->vif, false); IWL_DEBUG_MAC80211(priv, "leave\n"); -- cgit v1.2.2