[PATCH 2/3] iwlwifi: more priv->mutex serialization
From: Stanislaw Gruszka <hidden>
Date: 2011-03-31 15:36:58
Subsystem:
networking drivers (wireless), the rest · Maintainers:
Johannes Berg, Linus Torvalds
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 <redacted> --- drivers/net/wireless/iwlwifi/iwl-agn.c | 34 ++++++++++++++++++------------- 1 files changed, 20 insertions(+), 14 deletions(-)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7adc60e..0c49d1a 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); } /**
@@ -2814,10 +2816,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); }
@@ -2827,15 +2832,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); }
@@ -3457,21 +3463,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;
@@ -3527,7 +3534,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");
--
1.7.1