aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorTomas Winkler <tomas.winkler@intel.com>2008-03-28 19:21:12 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-04-01 17:13:19 -0400
commite5472978ef16051337913f57b2f22982f3e9e4c2 (patch)
tree9ae5dd96bfe7bf2fbc989dd4429b08d879f294ef /drivers
parenta571ea4eb34adbf33bbaf4bdc6db6037b1a93e0f (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.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c8
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
140const char *get_cmd_string(u8 cmd); 140const char *get_cmd_string(u8 cmd);
141int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd); 141int __must_check iwl_send_cmd_sync(struct iwl_priv *priv,
142 struct iwl_host_cmd *cmd);
142int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); 143int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
143int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data); 144int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
145 u16 len, const void *data);
144int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, 146int 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 }
233out: 233out:
234 atomic_set(&entry, 0); 234 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
235 return ret; 235 return ret;
236} 236}
237EXPORT_SYMBOL(iwl_send_cmd_sync); 237EXPORT_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 }
815out: 815out:
816 atomic_set(&entry, 0); 816 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
817 return ret; 817 return ret;
818} 818}
819 819