aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlegacy/iwl-4965.c
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2011-06-08 09:26:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-06-08 14:19:05 -0400
commit51e65257142a87fe46a1ce5c35c86c5baf012614 (patch)
treee5210ffad470c6b7b9c969aac667d5d5b491f76c /drivers/net/wireless/iwlegacy/iwl-4965.c
parentf3209bea110cade12e2b133da8b8499689cb0e2e (diff)
iwlegacy: fix channel switch locking
We use priv->mutex to avoid race conditions between chswitch_done() and mac_channel_switch(), when marking channel switch in progress. But chswitch_done() can be called in atomic context from rx_csa() or with mutex already taken from commit_rxon(). To fix remove mutex from chswitch_done() and use atomic bitops for marking channel switch pending. Cc: stable@kernel.org # 2.6.39+ Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlegacy/iwl-4965.c')
-rw-r--r--drivers/net/wireless/iwlegacy/iwl-4965.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c
index e1b89220c18..facc94e74b0 100644
--- a/drivers/net/wireless/iwlegacy/iwl-4965.c
+++ b/drivers/net/wireless/iwlegacy/iwl-4965.c
@@ -1218,10 +1218,10 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
1218 * receive commit_rxon request 1218 * receive commit_rxon request
1219 * abort any previous channel switch if still in process 1219 * abort any previous channel switch if still in process
1220 */ 1220 */
1221 if (priv->switch_rxon.switch_in_progress && 1221 if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
1222 (priv->switch_rxon.channel != ctx->staging.channel)) { 1222 (priv->switch_channel != ctx->staging.channel)) {
1223 IWL_DEBUG_11H(priv, "abort channel switch on %d\n", 1223 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
1224 le16_to_cpu(priv->switch_rxon.channel)); 1224 le16_to_cpu(priv->switch_channel));
1225 iwl_legacy_chswitch_done(priv, false); 1225 iwl_legacy_chswitch_done(priv, false);
1226 } 1226 }
1227 1227
@@ -1404,9 +1404,6 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1404 return rc; 1404 return rc;
1405 } 1405 }
1406 1406
1407 priv->switch_rxon.channel = cmd.channel;
1408 priv->switch_rxon.switch_in_progress = true;
1409
1410 return iwl_legacy_send_cmd_pdu(priv, 1407 return iwl_legacy_send_cmd_pdu(priv,
1411 REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd); 1408 REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1412} 1409}