summaryrefslogtreecommitdiffstats
path: root/ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch
diff options
context:
space:
mode:
Diffstat (limited to 'ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch')
-rw-r--r--ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch69
1 files changed, 69 insertions, 0 deletions
diff --git a/ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch b/ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch
new file mode 100644
index 000000000..3b7451f9f
--- /dev/null
+++ b/ipw2200-Fix-race-condition-in-the-command-completion-acknowledge.patch
@@ -0,0 +1,69 @@
+Driver incorrectly validates command completion: instead of waiting
+for a command to be acknowledged it continues execution. Most of the
+time driver gets acknowledge of the command completion in a tasklet
+before it executes the next one. But sometimes it sends the next
+command before it gets acknowledge for the previous one. In such a
+case one of the following error messages appear in the log:
+
+Failed to send SYSTEM_CONFIG: Already sending a command.
+Failed to send ASSOCIATE: Already sending a command.
+Failed to send TX_POWER: Already sending a command.
+
+After that you need to reload the driver to get it working again.
+
+This bug occurs during roammaping (reported by Sam Varshavchik)
+https://bugzilla.redhat.com/show_bug.cgi?id=738508
+and machine booting (reported by Tom Gundersen and Mads Kiilerich)
+https://bugs.archlinux.org/task/28097
+https://bugzilla.redhat.com/show_bug.cgi?id=802106
+
+This patch doesn't fix the delay issue during firmware load.
+But at least device now works as usual after boot.
+
+Cc: stable@kernel.org
+Signed-off-by: Stanislav Yakovlev <stas.yakovlev@gmail.com>
+---
+ drivers/net/wireless/ipw2x00/ipw2200.c | 13 ++++++++++++-
+ 1 files changed, 12 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
+index 4130802..8cbafa5 100644
+--- a/drivers/net/wireless/ipw2x00/ipw2200.c
++++ b/drivers/net/wireless/ipw2x00/ipw2200.c
+@@ -2192,6 +2192,7 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
+ {
+ int rc = 0;
+ unsigned long flags;
++ unsigned long now, end;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->status & STATUS_HCMD_ACTIVE) {
+@@ -2233,10 +2234,20 @@ static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
+ }
+ spin_unlock_irqrestore(&priv->lock, flags);
+
++ now = jiffies;
++ end = now + HOST_COMPLETE_TIMEOUT;
++again:
+ rc = wait_event_interruptible_timeout(priv->wait_command_queue,
+ !(priv->
+ status & STATUS_HCMD_ACTIVE),
+- HOST_COMPLETE_TIMEOUT);
++ end - now);
++ if (rc < 0) {
++ now = jiffies;
++ if (time_before(now, end))
++ goto again;
++ rc = 0;
++ }
++
+ if (rc == 0) {
+ spin_lock_irqsave(&priv->lock, flags);
+ if (priv->status & STATUS_HCMD_ACTIVE) {
+--
+1.7.2.5
+
+--
+To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
+the body of a message to majordomo@vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html \ No newline at end of file