]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iwlagn: do not use interruptible waits
authorJohannes Berg <johannes.berg@intel.com>
Thu, 15 Sep 2011 18:46:52 +0000 (11:46 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 11 Nov 2011 17:43:34 +0000 (09:43 -0800)
commit effd4d9aece9184f526e6556786a94d335e38b71 upstream.

Since the dawn of its time, iwlwifi has used
interruptible waits to wait for synchronous
commands and firmware loading.

This leads to "interesting" bugs, because it
can't actually handle the interruptions; for
example when a command sending is interrupted
it will assume the command completed fully,
and then leave it pending, which leads to all
kinds of trouble when the command finishes
later.

Since there's no easy way to gracefully deal
with interruptions, fix the driver to not use
interruptible waits.

This at least fixes the error
iwlagn 0000:02:00.0: Error: Response NULL in  'REPLY_SCAN_ABORT_CMD'

I have seen in P2P testing, but it is likely
that there are other errors caused by this.

Cc: Stanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c

index 56211006a182900cf56fc6a013893299a28795e5..a5c5a0accd5e6fc5614fcc737e2aba007947802b 100644 (file)
@@ -113,13 +113,8 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name,
                FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
 
        IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name);
-       ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-                                       priv->ucode_write_complete, 5 * HZ);
-       if (ret == -ERESTARTSYS) {
-               IWL_ERR(priv, "Could not load the %s uCode section due "
-                       "to interrupt\n", name);
-               return ret;
-       }
+       ret = wait_event_timeout(priv->wait_command_queue,
+                                priv->ucode_write_complete, 5 * HZ);
        if (!ret) {
                IWL_ERR(priv, "Could not load the %s uCode section\n",
                        name);
index cf376f62b2f6b3d5dea8c7d13d61a4a313fd3957..d652778253a46c9fa999b0eea6401c83dc20741a 100644 (file)
@@ -867,7 +867,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
         * commands by clearing the ready bit */
        clear_bit(STATUS_READY, &priv->status);
 
-       wake_up_interruptible(&priv->wait_command_queue);
+       wake_up(&priv->wait_command_queue);
 
        if (!ondemand) {
                /*
@@ -918,7 +918,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
                 */
                clear_bit(STATUS_READY, &priv->status);
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
-               wake_up_interruptible(&priv->wait_command_queue);
+               wake_up(&priv->wait_command_queue);
                IWL_ERR(priv, "RF is used by WiMAX\n");
                return;
        }
index 8e314003b63ac67a5412f03ed4d6332b5ae9de86..732f01b565deddfe81a2f9dbaa3c012164dc9e88 100644 (file)
@@ -561,7 +561,7 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
                wiphy_rfkill_set_hw_state(priv->hw->wiphy,
                        test_bit(STATUS_RF_KILL_HW, &priv->status));
        else
-               wake_up_interruptible(&priv->wait_command_queue);
+               wake_up(&priv->wait_command_queue);
 }
 
 static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
index 474860290404d2805657562c5f56dcc9629aca16..f9f0df0cecbfc260f2c4042317c9d2641ed3ccb5 100644 (file)
@@ -671,7 +671,7 @@ void iwl_irq_tasklet(struct iwl_priv *priv)
                handled |= CSR_INT_BIT_FH_TX;
                /* Wake up uCode load routine, now that load is complete */
                priv->ucode_write_complete = 1;
-               wake_up_interruptible(&priv->wait_command_queue);
+               wake_up(&priv->wait_command_queue);
        }
 
        if (inta & ~handled) {
index 222d410c586e4e481a8c474471ed8702e41aac90..2bf3107be930af4040ba8e033c8f280959853aee 100644 (file)
@@ -790,7 +790,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
                clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
                IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
                               get_cmd_string(cmd->hdr.cmd));
-               wake_up_interruptible(&priv->wait_command_queue);
+               wake_up(&priv->wait_command_queue);
        }
 
        meta->flags = 0;
@@ -957,7 +957,7 @@ static int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
                return ret;
        }
 
-       ret = wait_event_interruptible_timeout(priv->wait_command_queue,
+       ret = wait_event_timeout(priv->wait_command_queue,
                        !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
                        HOST_COMPLETE_TIMEOUT);
        if (!ret) {