| From effd4d9aece9184f526e6556786a94d335e38b71 Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Thu, 15 Sep 2011 11:46:52 -0700 |
| Subject: iwlagn: do not use interruptible waits |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| 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 | 9 ++------- |
| drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++-- |
| drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +- |
| drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 2 +- |
| drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 4 ++-- |
| 5 files changed, 8 insertions(+), 13 deletions(-) |
| |
| --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c |
| @@ -113,13 +113,8 @@ static int iwlagn_load_section(struct iw |
| 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); |
| --- a/drivers/net/wireless/iwlwifi/iwl-core.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-core.c |
| @@ -867,7 +867,7 @@ void iwlagn_fw_error(struct iwl_priv *pr |
| * 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_pri |
| */ |
| 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; |
| } |
| --- a/drivers/net/wireless/iwlwifi/iwl-rx.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c |
| @@ -561,7 +561,7 @@ static void iwl_rx_card_state_notif(stru |
| 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, |
| --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c |
| @@ -671,7 +671,7 @@ void iwl_irq_tasklet(struct iwl_priv *pr |
| 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) { |
| --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c |
| +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c |
| @@ -790,7 +790,7 @@ void iwl_tx_cmd_complete(struct iwl_priv |
| 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_ |
| 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) { |