diff options
author | Stanislaw Gruszka <sgruszka@redhat.com> | 2011-03-31 11:36:27 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-04-07 15:34:11 -0400 |
commit | dc1a4068fce2657991c5c3b1f6849f7fc466c69f (patch) | |
tree | 8463f06bbbc582f7afa6d8869350dc1f67f8732e /drivers/net/wireless | |
parent | 3598e1774c94e55c71b585340e7dc4538f310e3f (diff) |
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 <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | 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 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) | |||
483 | container_of(work, struct iwl_priv, bt_full_concurrency); | 483 | container_of(work, struct iwl_priv, bt_full_concurrency); |
484 | struct iwl_rxon_context *ctx; | 484 | struct iwl_rxon_context *ctx; |
485 | 485 | ||
486 | mutex_lock(&priv->mutex); | ||
487 | |||
486 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 488 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
487 | return; | 489 | goto out; |
488 | 490 | ||
489 | /* dont send host command if rf-kill is on */ | 491 | /* dont send host command if rf-kill is on */ |
490 | if (!iwl_is_ready_rf(priv)) | 492 | if (!iwl_is_ready_rf(priv)) |
491 | return; | 493 | goto out; |
492 | 494 | ||
493 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", | 495 | IWL_DEBUG_INFO(priv, "BT coex in %s mode\n", |
494 | priv->bt_full_concurrent ? | 496 | priv->bt_full_concurrent ? |
@@ -498,15 +500,15 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
498 | * LQ & RXON updated cmds must be sent before BT Config cmd | 500 | * LQ & RXON updated cmds must be sent before BT Config cmd |
499 | * to avoid 3-wire collisions | 501 | * to avoid 3-wire collisions |
500 | */ | 502 | */ |
501 | mutex_lock(&priv->mutex); | ||
502 | for_each_context(priv, ctx) { | 503 | for_each_context(priv, ctx) { |
503 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 504 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
504 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); | 505 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); |
505 | iwlcore_commit_rxon(priv, ctx); | 506 | iwlcore_commit_rxon(priv, ctx); |
506 | } | 507 | } |
507 | mutex_unlock(&priv->mutex); | ||
508 | 508 | ||
509 | priv->cfg->ops->hcmd->send_bt_config(priv); | 509 | priv->cfg->ops->hcmd->send_bt_config(priv); |
510 | out: | ||
511 | mutex_unlock(&priv->mutex); | ||
510 | } | 512 | } |
511 | 513 | ||
512 | /** | 514 | /** |
@@ -2620,10 +2622,13 @@ static void iwl_bg_init_alive_start(struct work_struct *data) | |||
2620 | struct iwl_priv *priv = | 2622 | struct iwl_priv *priv = |
2621 | container_of(data, struct iwl_priv, init_alive_start.work); | 2623 | container_of(data, struct iwl_priv, init_alive_start.work); |
2622 | 2624 | ||
2623 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2625 | mutex_lock(&priv->mutex); |
2626 | |||
2627 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||
2628 | mutex_unlock(&priv->mutex); | ||
2624 | return; | 2629 | return; |
2630 | } | ||
2625 | 2631 | ||
2626 | mutex_lock(&priv->mutex); | ||
2627 | priv->cfg->ops->lib->init_alive_start(priv); | 2632 | priv->cfg->ops->lib->init_alive_start(priv); |
2628 | mutex_unlock(&priv->mutex); | 2633 | mutex_unlock(&priv->mutex); |
2629 | } | 2634 | } |
@@ -2633,15 +2638,16 @@ static void iwl_bg_alive_start(struct work_struct *data) | |||
2633 | struct iwl_priv *priv = | 2638 | struct iwl_priv *priv = |
2634 | container_of(data, struct iwl_priv, alive_start.work); | 2639 | container_of(data, struct iwl_priv, alive_start.work); |
2635 | 2640 | ||
2641 | mutex_lock(&priv->mutex); | ||
2636 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 2642 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
2637 | return; | 2643 | goto unlock; |
2638 | 2644 | ||
2639 | /* enable dram interrupt */ | 2645 | /* enable dram interrupt */ |
2640 | if (priv->cfg->ops->lib->isr_ops.reset) | 2646 | if (priv->cfg->ops->lib->isr_ops.reset) |
2641 | priv->cfg->ops->lib->isr_ops.reset(priv); | 2647 | priv->cfg->ops->lib->isr_ops.reset(priv); |
2642 | 2648 | ||
2643 | mutex_lock(&priv->mutex); | ||
2644 | iwl_alive_start(priv); | 2649 | iwl_alive_start(priv); |
2650 | unlock: | ||
2645 | mutex_unlock(&priv->mutex); | 2651 | mutex_unlock(&priv->mutex); |
2646 | } | 2652 | } |
2647 | 2653 | ||
@@ -3267,21 +3273,22 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
3267 | 3273 | ||
3268 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 3274 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
3269 | 3275 | ||
3276 | mutex_lock(&priv->mutex); | ||
3277 | |||
3270 | if (iwl_is_rfkill(priv)) | 3278 | if (iwl_is_rfkill(priv)) |
3271 | goto out_exit; | 3279 | goto out; |
3272 | 3280 | ||
3273 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 3281 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
3274 | test_bit(STATUS_SCANNING, &priv->status)) | 3282 | test_bit(STATUS_SCANNING, &priv->status)) |
3275 | goto out_exit; | 3283 | goto out; |
3276 | 3284 | ||
3277 | if (!iwl_is_associated_ctx(ctx)) | 3285 | if (!iwl_is_associated_ctx(ctx)) |
3278 | goto out_exit; | 3286 | goto out; |
3279 | 3287 | ||
3280 | /* channel switch in progress */ | 3288 | /* channel switch in progress */ |
3281 | if (priv->switch_rxon.switch_in_progress == true) | 3289 | if (priv->switch_rxon.switch_in_progress == true) |
3282 | goto out_exit; | 3290 | goto out; |
3283 | 3291 | ||
3284 | mutex_lock(&priv->mutex); | ||
3285 | if (priv->cfg->ops->lib->set_channel_switch) { | 3292 | if (priv->cfg->ops->lib->set_channel_switch) { |
3286 | 3293 | ||
3287 | ch = channel->hw_value; | 3294 | ch = channel->hw_value; |
@@ -3337,7 +3344,6 @@ void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
3337 | } | 3344 | } |
3338 | out: | 3345 | out: |
3339 | mutex_unlock(&priv->mutex); | 3346 | mutex_unlock(&priv->mutex); |
3340 | out_exit: | ||
3341 | if (!priv->switch_rxon.switch_in_progress) | 3347 | if (!priv->switch_rxon.switch_in_progress) |
3342 | ieee80211_chswitch_done(ctx->vif, false); | 3348 | ieee80211_chswitch_done(ctx->vif, false); |
3343 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 3349 | IWL_DEBUG_MAC80211(priv, "leave\n"); |