diff options
author | Tomas Winkler <tomas.winkler@intel.com> | 2008-03-28 19:21:12 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-04-01 17:13:19 -0400 |
commit | e5472978ef16051337913f57b2f22982f3e9e4c2 (patch) | |
tree | 9ae5dd96bfe7bf2fbc989dd4429b08d879f294ef /drivers | |
parent | a571ea4eb34adbf33bbaf4bdc6db6037b1a93e0f (diff) |
iwlwifi: Fix synchronous host command
This patch replaces static variable from send_cmd_sync
with flag in priv->status. It was used for reentrance protection
but clearly made it impossible to stuck more cards into the same machine
In addition it force check of return values of synchronous commands
commands that doesn't requires return value async commands have to be used
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Yi Zhu <yi.zhu@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.h | 35 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.h | 35 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-hcmd.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 8 |
6 files changed, 52 insertions, 48 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index d7ccf13b875d..ac1226946aa6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h | |||
@@ -401,23 +401,24 @@ struct iwl3945_rx_queue { | |||
401 | #define MIN_B_CHANNELS 1 | 401 | #define MIN_B_CHANNELS 1 |
402 | 402 | ||
403 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ | 403 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ |
404 | #define STATUS_INT_ENABLED 1 | 404 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
405 | #define STATUS_RF_KILL_HW 2 | 405 | #define STATUS_INT_ENABLED 2 |
406 | #define STATUS_RF_KILL_SW 3 | 406 | #define STATUS_RF_KILL_HW 3 |
407 | #define STATUS_INIT 4 | 407 | #define STATUS_RF_KILL_SW 4 |
408 | #define STATUS_ALIVE 5 | 408 | #define STATUS_INIT 5 |
409 | #define STATUS_READY 6 | 409 | #define STATUS_ALIVE 6 |
410 | #define STATUS_TEMPERATURE 7 | 410 | #define STATUS_READY 7 |
411 | #define STATUS_GEO_CONFIGURED 8 | 411 | #define STATUS_TEMPERATURE 8 |
412 | #define STATUS_EXIT_PENDING 9 | 412 | #define STATUS_GEO_CONFIGURED 9 |
413 | #define STATUS_IN_SUSPEND 10 | 413 | #define STATUS_EXIT_PENDING 10 |
414 | #define STATUS_STATISTICS 11 | 414 | #define STATUS_IN_SUSPEND 11 |
415 | #define STATUS_SCANNING 12 | 415 | #define STATUS_STATISTICS 12 |
416 | #define STATUS_SCAN_ABORTING 13 | 416 | #define STATUS_SCANNING 13 |
417 | #define STATUS_SCAN_HW 14 | 417 | #define STATUS_SCAN_ABORTING 14 |
418 | #define STATUS_POWER_PMI 15 | 418 | #define STATUS_SCAN_HW 15 |
419 | #define STATUS_FW_ERROR 16 | 419 | #define STATUS_POWER_PMI 16 |
420 | #define STATUS_CONF_PENDING 17 | 420 | #define STATUS_FW_ERROR 17 |
421 | #define STATUS_CONF_PENDING 18 | ||
421 | 422 | ||
422 | #define MAX_TID_COUNT 9 | 423 | #define MAX_TID_COUNT 9 |
423 | 424 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index add6311393d3..51a144914cfa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -1314,8 +1314,8 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv) | |||
1314 | cmd.diff_gain_a = 0; | 1314 | cmd.diff_gain_a = 0; |
1315 | cmd.diff_gain_b = 0; | 1315 | cmd.diff_gain_b = 0; |
1316 | cmd.diff_gain_c = 0; | 1316 | cmd.diff_gain_c = 0; |
1317 | iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD, | 1317 | iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD, |
1318 | sizeof(cmd), &cmd); | 1318 | sizeof(cmd), &cmd, NULL); |
1319 | msleep(4); | 1319 | msleep(4); |
1320 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; | 1320 | data->state = IWL_CHAIN_NOISE_ACCUMULATE; |
1321 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); | 1321 | IWL_DEBUG_CALIB("Run chain_noise_calibrate\n"); |
@@ -4563,8 +4563,8 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap) | |||
4563 | /* Update the rate scaling for control frame Tx to AP */ | 4563 | /* Update the rate scaling for control frame Tx to AP */ |
4564 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id; | 4564 | link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id; |
4565 | 4565 | ||
4566 | iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd), | 4566 | iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD, |
4567 | &link_cmd); | 4567 | sizeof(link_cmd), &link_cmd, NULL); |
4568 | } | 4568 | } |
4569 | 4569 | ||
4570 | #ifdef CONFIG_IWL4965_HT | 4570 | #ifdef CONFIG_IWL4965_HT |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h index ca864fa65ca4..8c14e9a87c14 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965.h | |||
@@ -415,23 +415,24 @@ struct iwl4965_rx_queue { | |||
415 | #define MIN_B_CHANNELS 1 | 415 | #define MIN_B_CHANNELS 1 |
416 | 416 | ||
417 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ | 417 | #define STATUS_HCMD_ACTIVE 0 /* host command in progress */ |
418 | #define STATUS_INT_ENABLED 1 | 418 | #define STATUS_HCMD_SYNC_ACTIVE 1 /* sync host command in progress */ |
419 | #define STATUS_RF_KILL_HW 2 | 419 | #define STATUS_INT_ENABLED 2 |
420 | #define STATUS_RF_KILL_SW 3 | 420 | #define STATUS_RF_KILL_HW 3 |
421 | #define STATUS_INIT 4 | 421 | #define STATUS_RF_KILL_SW 4 |
422 | #define STATUS_ALIVE 5 | 422 | #define STATUS_INIT 5 |
423 | #define STATUS_READY 6 | 423 | #define STATUS_ALIVE 6 |
424 | #define STATUS_TEMPERATURE 7 | 424 | #define STATUS_READY 7 |
425 | #define STATUS_GEO_CONFIGURED 8 | 425 | #define STATUS_TEMPERATURE 8 |
426 | #define STATUS_EXIT_PENDING 9 | 426 | #define STATUS_GEO_CONFIGURED 9 |
427 | #define STATUS_IN_SUSPEND 10 | 427 | #define STATUS_EXIT_PENDING 10 |
428 | #define STATUS_STATISTICS 11 | 428 | #define STATUS_IN_SUSPEND 11 |
429 | #define STATUS_SCANNING 12 | 429 | #define STATUS_STATISTICS 12 |
430 | #define STATUS_SCAN_ABORTING 13 | 430 | #define STATUS_SCANNING 13 |
431 | #define STATUS_SCAN_HW 14 | 431 | #define STATUS_SCAN_ABORTING 14 |
432 | #define STATUS_POWER_PMI 15 | 432 | #define STATUS_SCAN_HW 15 |
433 | #define STATUS_FW_ERROR 16 | 433 | #define STATUS_POWER_PMI 16 |
434 | #define STATUS_CONF_PENDING 17 | 434 | #define STATUS_FW_ERROR 17 |
435 | #define STATUS_CONF_PENDING 18 | ||
435 | 436 | ||
436 | #define MAX_TID_COUNT 9 | 437 | #define MAX_TID_COUNT 9 |
437 | 438 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 5efafe1a1d86..64f4df53986c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -138,9 +138,11 @@ int iwl_setup(struct iwl_priv *priv); | |||
138 | *****************************************************/ | 138 | *****************************************************/ |
139 | 139 | ||
140 | const char *get_cmd_string(u8 cmd); | 140 | const char *get_cmd_string(u8 cmd); |
141 | int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 141 | int __must_check iwl_send_cmd_sync(struct iwl_priv *priv, |
142 | struct iwl_host_cmd *cmd); | ||
142 | int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 143 | int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); |
143 | int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data); | 144 | int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, |
145 | u16 len, const void *data); | ||
144 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | 146 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, |
145 | const void *data, | 147 | const void *data, |
146 | int (*callback)(struct iwl_priv *priv, | 148 | int (*callback)(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c index 51c9949633e3..1f8c2999805b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c | |||
@@ -151,17 +151,17 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
151 | { | 151 | { |
152 | int cmd_idx; | 152 | int cmd_idx; |
153 | int ret; | 153 | int ret; |
154 | static atomic_t entry = ATOMIC_INIT(0); /* reentrance protection */ | ||
155 | 154 | ||
156 | BUG_ON(cmd->meta.flags & CMD_ASYNC); | 155 | BUG_ON(cmd->meta.flags & CMD_ASYNC); |
157 | 156 | ||
158 | /* A synchronous command can not have a callback set. */ | 157 | /* A synchronous command can not have a callback set. */ |
159 | BUG_ON(cmd->meta.u.callback != NULL); | 158 | BUG_ON(cmd->meta.u.callback != NULL); |
160 | 159 | ||
161 | if (atomic_xchg(&entry, 1)) { | 160 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { |
162 | IWL_ERROR("Error sending %s: Already sending a host command\n", | 161 | IWL_ERROR("Error sending %s: Already sending a host command\n", |
163 | get_cmd_string(cmd->id)); | 162 | get_cmd_string(cmd->id)); |
164 | return -EBUSY; | 163 | ret = -EBUSY; |
164 | goto out; | ||
165 | } | 165 | } |
166 | 166 | ||
167 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 167 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
@@ -231,7 +231,7 @@ fail: | |||
231 | cmd->meta.u.skb = NULL; | 231 | cmd->meta.u.skb = NULL; |
232 | } | 232 | } |
233 | out: | 233 | out: |
234 | atomic_set(&entry, 0); | 234 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); |
235 | return ret; | 235 | return ret; |
236 | } | 236 | } |
237 | EXPORT_SYMBOL(iwl_send_cmd_sync); | 237 | EXPORT_SYMBOL(iwl_send_cmd_sync); |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 8c2036850c89..51480a4920e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -733,17 +733,17 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_ | |||
733 | { | 733 | { |
734 | int cmd_idx; | 734 | int cmd_idx; |
735 | int ret; | 735 | int ret; |
736 | static atomic_t entry = ATOMIC_INIT(0); /* reentrance protection */ | ||
737 | 736 | ||
738 | BUG_ON(cmd->meta.flags & CMD_ASYNC); | 737 | BUG_ON(cmd->meta.flags & CMD_ASYNC); |
739 | 738 | ||
740 | /* A synchronous command can not have a callback set. */ | 739 | /* A synchronous command can not have a callback set. */ |
741 | BUG_ON(cmd->meta.u.callback != NULL); | 740 | BUG_ON(cmd->meta.u.callback != NULL); |
742 | 741 | ||
743 | if (atomic_xchg(&entry, 1)) { | 742 | if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { |
744 | IWL_ERROR("Error sending %s: Already sending a host command\n", | 743 | IWL_ERROR("Error sending %s: Already sending a host command\n", |
745 | get_cmd_string(cmd->id)); | 744 | get_cmd_string(cmd->id)); |
746 | return -EBUSY; | 745 | ret = -EBUSY; |
746 | goto out; | ||
747 | } | 747 | } |
748 | 748 | ||
749 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); | 749 | set_bit(STATUS_HCMD_ACTIVE, &priv->status); |
@@ -813,7 +813,7 @@ fail: | |||
813 | cmd->meta.u.skb = NULL; | 813 | cmd->meta.u.skb = NULL; |
814 | } | 814 | } |
815 | out: | 815 | out: |
816 | atomic_set(&entry, 0); | 816 | clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); |
817 | return ret; | 817 | return ret; |
818 | } | 818 | } |
819 | 819 | ||