]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/3.1.1/iwlagn-do-not-use-interruptible-waits.patch
5.1-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 3.1.1 / iwlagn-do-not-use-interruptible-waits.patch
1 From effd4d9aece9184f526e6556786a94d335e38b71 Mon Sep 17 00:00:00 2001
2 From: Johannes Berg <johannes.berg@intel.com>
3 Date: Thu, 15 Sep 2011 11:46:52 -0700
4 Subject: iwlagn: do not use interruptible waits
5
6 From: Johannes Berg <johannes.berg@intel.com>
7
8 commit effd4d9aece9184f526e6556786a94d335e38b71 upstream.
9
10 Since the dawn of its time, iwlwifi has used
11 interruptible waits to wait for synchronous
12 commands and firmware loading.
13
14 This leads to "interesting" bugs, because it
15 can't actually handle the interruptions; for
16 example when a command sending is interrupted
17 it will assume the command completed fully,
18 and then leave it pending, which leads to all
19 kinds of trouble when the command finishes
20 later.
21
22 Since there's no easy way to gracefully deal
23 with interruptions, fix the driver to not use
24 interruptible waits.
25
26 This at least fixes the error
27 iwlagn 0000:02:00.0: Error: Response NULL in 'REPLY_SCAN_ABORT_CMD'
28
29 I have seen in P2P testing, but it is likely
30 that there are other errors caused by this.
31
32 Cc: Stanislaw Gruszka <sgruszka@redhat.com>
33 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
34 Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
35 Signed-off-by: John W. Linville <linville@tuxdriver.com>
36
37
38 ---
39 drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 9 ++-------
40 drivers/net/wireless/iwlwifi/iwl-core.c | 4 ++--
41 drivers/net/wireless/iwlwifi/iwl-rx.c | 2 +-
42 drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c | 2 +-
43 drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c | 4 ++--
44 5 files changed, 8 insertions(+), 13 deletions(-)
45
46 --- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
47 +++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
48 @@ -113,13 +113,8 @@ static int iwlagn_load_section(struct iw
49 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
50
51 IWL_DEBUG_FW(priv, "%s uCode section being loaded...\n", name);
52 - ret = wait_event_interruptible_timeout(priv->wait_command_queue,
53 - priv->ucode_write_complete, 5 * HZ);
54 - if (ret == -ERESTARTSYS) {
55 - IWL_ERR(priv, "Could not load the %s uCode section due "
56 - "to interrupt\n", name);
57 - return ret;
58 - }
59 + ret = wait_event_timeout(priv->wait_command_queue,
60 + priv->ucode_write_complete, 5 * HZ);
61 if (!ret) {
62 IWL_ERR(priv, "Could not load the %s uCode section\n",
63 name);
64 --- a/drivers/net/wireless/iwlwifi/iwl-core.c
65 +++ b/drivers/net/wireless/iwlwifi/iwl-core.c
66 @@ -867,7 +867,7 @@ void iwlagn_fw_error(struct iwl_priv *pr
67 * commands by clearing the ready bit */
68 clear_bit(STATUS_READY, &priv->status);
69
70 - wake_up_interruptible(&priv->wait_command_queue);
71 + wake_up(&priv->wait_command_queue);
72
73 if (!ondemand) {
74 /*
75 @@ -918,7 +918,7 @@ void iwl_irq_handle_error(struct iwl_pri
76 */
77 clear_bit(STATUS_READY, &priv->status);
78 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
79 - wake_up_interruptible(&priv->wait_command_queue);
80 + wake_up(&priv->wait_command_queue);
81 IWL_ERR(priv, "RF is used by WiMAX\n");
82 return;
83 }
84 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c
85 +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
86 @@ -561,7 +561,7 @@ static void iwl_rx_card_state_notif(stru
87 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
88 test_bit(STATUS_RF_KILL_HW, &priv->status));
89 else
90 - wake_up_interruptible(&priv->wait_command_queue);
91 + wake_up(&priv->wait_command_queue);
92 }
93
94 static void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
95 --- a/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
96 +++ b/drivers/net/wireless/iwlwifi/iwl-trans-rx-pcie.c
97 @@ -671,7 +671,7 @@ void iwl_irq_tasklet(struct iwl_priv *pr
98 handled |= CSR_INT_BIT_FH_TX;
99 /* Wake up uCode load routine, now that load is complete */
100 priv->ucode_write_complete = 1;
101 - wake_up_interruptible(&priv->wait_command_queue);
102 + wake_up(&priv->wait_command_queue);
103 }
104
105 if (inta & ~handled) {
106 --- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
107 +++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
108 @@ -790,7 +790,7 @@ void iwl_tx_cmd_complete(struct iwl_priv
109 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
110 IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s\n",
111 get_cmd_string(cmd->hdr.cmd));
112 - wake_up_interruptible(&priv->wait_command_queue);
113 + wake_up(&priv->wait_command_queue);
114 }
115
116 meta->flags = 0;
117 @@ -957,7 +957,7 @@ static int iwl_send_cmd_sync(struct iwl_
118 return ret;
119 }
120
121 - ret = wait_event_interruptible_timeout(priv->wait_command_queue,
122 + ret = wait_event_timeout(priv->wait_command_queue,
123 !test_bit(STATUS_HCMD_ACTIVE, &priv->status),
124 HOST_COMPLETE_TIMEOUT);
125 if (!ret) {