]> err.no Git - linux-2.6/commitdiff
iwlwifi: Fix synchronous host command
authorTomas Winkler <tomas.winkler@intel.com>
Fri, 28 Mar 2008 23:21:12 +0000 (16:21 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 1 Apr 2008 21:13:19 +0000 (17:13 -0400)
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>
drivers/net/wireless/iwlwifi/iwl-3945.h
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-4965.h
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-hcmd.c
drivers/net/wireless/iwlwifi/iwl3945-base.c

index d7ccf13b875d6211a0527b3f73af59488393d3bb..ac1226946aa69b5e8a1893947552b7c495d92e4f 100644 (file)
@@ -401,23 +401,24 @@ struct iwl3945_rx_queue {
 #define MIN_B_CHANNELS  1
 
 #define STATUS_HCMD_ACTIVE     0       /* host command in progress */
-#define STATUS_INT_ENABLED     1
-#define STATUS_RF_KILL_HW      2
-#define STATUS_RF_KILL_SW      3
-#define STATUS_INIT            4
-#define STATUS_ALIVE           5
-#define STATUS_READY           6
-#define STATUS_TEMPERATURE     7
-#define STATUS_GEO_CONFIGURED  8
-#define STATUS_EXIT_PENDING    9
-#define STATUS_IN_SUSPEND      10
-#define STATUS_STATISTICS      11
-#define STATUS_SCANNING                12
-#define STATUS_SCAN_ABORTING   13
-#define STATUS_SCAN_HW         14
-#define STATUS_POWER_PMI       15
-#define STATUS_FW_ERROR                16
-#define STATUS_CONF_PENDING    17
+#define STATUS_HCMD_SYNC_ACTIVE        1       /* sync host command in progress */
+#define STATUS_INT_ENABLED     2
+#define STATUS_RF_KILL_HW      3
+#define STATUS_RF_KILL_SW      4
+#define STATUS_INIT            5
+#define STATUS_ALIVE           6
+#define STATUS_READY           7
+#define STATUS_TEMPERATURE     8
+#define STATUS_GEO_CONFIGURED  9
+#define STATUS_EXIT_PENDING    10
+#define STATUS_IN_SUSPEND      11
+#define STATUS_STATISTICS      12
+#define STATUS_SCANNING                13
+#define STATUS_SCAN_ABORTING   14
+#define STATUS_SCAN_HW         15
+#define STATUS_POWER_PMI       16
+#define STATUS_FW_ERROR                17
+#define STATUS_CONF_PENDING    18
 
 #define MAX_TID_COUNT        9
 
index add6311393d38b9142b6b69493b6554679e9530b..51a144914cfa58b24abd4329501f642c89d692e2 100644 (file)
@@ -1314,8 +1314,8 @@ void iwl4965_chain_noise_reset(struct iwl_priv *priv)
                cmd.diff_gain_a = 0;
                cmd.diff_gain_b = 0;
                cmd.diff_gain_c = 0;
-               iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
-                                sizeof(cmd), &cmd);
+               iwl_send_cmd_pdu_async(priv, REPLY_PHY_CALIBRATION_CMD,
+                                sizeof(cmd), &cmd, NULL);
                msleep(4);
                data->state = IWL_CHAIN_NOISE_ACCUMULATE;
                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)
        /* Update the rate scaling for control frame Tx to AP */
        link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_setting.bcast_sta_id;
 
-       iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD, sizeof(link_cmd),
-                        &link_cmd);
+       iwl_send_cmd_pdu_async(priv, REPLY_TX_LINK_QUALITY_CMD,
+                              sizeof(link_cmd), &link_cmd, NULL);
 }
 
 #ifdef CONFIG_IWL4965_HT
index ca864fa65ca443b2233630b12a5b703945e91a9a..8c14e9a87c142fbedd52f15d34b6b6d2b5ce44bc 100644 (file)
@@ -415,23 +415,24 @@ struct iwl4965_rx_queue {
 #define MIN_B_CHANNELS  1
 
 #define STATUS_HCMD_ACTIVE     0       /* host command in progress */
-#define STATUS_INT_ENABLED     1
-#define STATUS_RF_KILL_HW      2
-#define STATUS_RF_KILL_SW      3
-#define STATUS_INIT            4
-#define STATUS_ALIVE           5
-#define STATUS_READY           6
-#define STATUS_TEMPERATURE     7
-#define STATUS_GEO_CONFIGURED  8
-#define STATUS_EXIT_PENDING    9
-#define STATUS_IN_SUSPEND      10
-#define STATUS_STATISTICS      11
-#define STATUS_SCANNING                12
-#define STATUS_SCAN_ABORTING   13
-#define STATUS_SCAN_HW         14
-#define STATUS_POWER_PMI       15
-#define STATUS_FW_ERROR                16
-#define STATUS_CONF_PENDING    17
+#define STATUS_HCMD_SYNC_ACTIVE        1       /* sync host command in progress */
+#define STATUS_INT_ENABLED     2
+#define STATUS_RF_KILL_HW      3
+#define STATUS_RF_KILL_SW      4
+#define STATUS_INIT            5
+#define STATUS_ALIVE           6
+#define STATUS_READY           7
+#define STATUS_TEMPERATURE     8
+#define STATUS_GEO_CONFIGURED  9
+#define STATUS_EXIT_PENDING    10
+#define STATUS_IN_SUSPEND      11
+#define STATUS_STATISTICS      12
+#define STATUS_SCANNING                13
+#define STATUS_SCAN_ABORTING   14
+#define STATUS_SCAN_HW         15
+#define STATUS_POWER_PMI       16
+#define STATUS_FW_ERROR                17
+#define STATUS_CONF_PENDING    18
 
 #define MAX_TID_COUNT        9
 
index 5efafe1a1d860c85527806547106533d1c4108a3..64f4df53986c8d66bb9b8e78633543dac7bd6912 100644 (file)
@@ -138,9 +138,11 @@ int iwl_setup(struct iwl_priv *priv);
  *****************************************************/
 
 const char *get_cmd_string(u8 cmd);
-int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
+int __must_check iwl_send_cmd_sync(struct iwl_priv *priv,
+                                  struct iwl_host_cmd *cmd);
 int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
-int iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len, const void *data);
+int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
+                                 u16 len, const void *data);
 int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
                           const void *data,
                           int (*callback)(struct iwl_priv *priv,
index 51c9949633e3186d06c410ff5b06f94819e35fe9..1f8c2999805b85f3825f410d738c56d2fa461f7d 100644 (file)
@@ -151,17 +151,17 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 {
        int cmd_idx;
        int ret;
-       static atomic_t entry = ATOMIC_INIT(0); /* reentrance protection */
 
        BUG_ON(cmd->meta.flags & CMD_ASYNC);
 
         /* A synchronous command can not have a callback set. */
        BUG_ON(cmd->meta.u.callback != NULL);
 
-       if (atomic_xchg(&entry, 1)) {
+       if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
                IWL_ERROR("Error sending %s: Already sending a host command\n",
                          get_cmd_string(cmd->id));
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out;
        }
 
        set_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -231,7 +231,7 @@ fail:
                cmd->meta.u.skb = NULL;
        }
 out:
-       atomic_set(&entry, 0);
+       clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
        return ret;
 }
 EXPORT_SYMBOL(iwl_send_cmd_sync);
index 8c2036850c89ee93e18bd0548134d7762c0620a4..51480a4920e89c1755937eb5a2c1f515afbd1fa6 100644 (file)
@@ -733,17 +733,17 @@ static int iwl3945_send_cmd_sync(struct iwl3945_priv *priv, struct iwl3945_host_
 {
        int cmd_idx;
        int ret;
-       static atomic_t entry = ATOMIC_INIT(0); /* reentrance protection */
 
        BUG_ON(cmd->meta.flags & CMD_ASYNC);
 
         /* A synchronous command can not have a callback set. */
        BUG_ON(cmd->meta.u.callback != NULL);
 
-       if (atomic_xchg(&entry, 1)) {
+       if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
                IWL_ERROR("Error sending %s: Already sending a host command\n",
                          get_cmd_string(cmd->id));
-               return -EBUSY;
+               ret = -EBUSY;
+               goto out;
        }
 
        set_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -813,7 +813,7 @@ fail:
                cmd->meta.u.skb = NULL;
        }
 out:
-       atomic_set(&entry, 0);
+       clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
        return ret;
 }