]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.0 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Aug 2011 15:54:48 +0000 (08:54 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 2 Aug 2011 15:54:48 +0000 (08:54 -0700)
15 files changed:
queue-3.0/arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch [new file with mode: 0644]
queue-3.0/drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch [new file with mode: 0644]
queue-3.0/rtc-fix-hrtimer-deadlock.patch [new file with mode: 0644]
queue-3.0/rtc-handle-errors-correctly-in-rtc_irq_set_state.patch [new file with mode: 0644]
queue-3.0/rtc-limit-frequency.patch [new file with mode: 0644]
queue-3.0/series
queue-3.0/staging-comedi-fix-infoleak-to-userspace.patch [new file with mode: 0644]
queue-3.0/staging-hv-netvsc-increase-the-timeout-value-in-the.patch [new file with mode: 0644]
queue-3.0/staging-hv-storvsc-increase-the-timeout-value-in-the.patch [new file with mode: 0644]
queue-3.0/staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch [new file with mode: 0644]
queue-3.0/staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch [new file with mode: 0644]
queue-3.0/staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch [new file with mode: 0644]
queue-3.0/usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch [new file with mode: 0644]
queue-3.0/usb-musb-restore-index-register-in-resume-path.patch [new file with mode: 0644]
queue-3.0/usb-ohci-fix-another-regression-for-nvidia-controllers.patch [new file with mode: 0644]

diff --git a/queue-3.0/arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch b/queue-3.0/arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch
new file mode 100644 (file)
index 0000000..4476201
--- /dev/null
@@ -0,0 +1,37 @@
+From 6c7b3ea52e345ab614edb91d3f0e9f3bb3713871 Mon Sep 17 00:00:00 2001
+From: Igor Grinberg <grinberg@compulab.co.il>
+Date: Mon, 9 May 2011 14:41:46 +0300
+Subject: ARM: pxa/cm-x300: fix V3020 RTC functionality
+
+From: Igor Grinberg <grinberg@compulab.co.il>
+
+commit 6c7b3ea52e345ab614edb91d3f0e9f3bb3713871 upstream.
+
+While in sleep mode the CS# and other V3020 RTC GPIOs must be driven
+high, otherwise V3020 RTC fails to keep the right time in sleep mode.
+
+Signed-off-by: Igor Grinberg <grinberg@compulab.co.il>
+Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/mach-pxa/cm-x300.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/arm/mach-pxa/cm-x300.c
++++ b/arch/arm/mach-pxa/cm-x300.c
+@@ -161,10 +161,10 @@ static mfp_cfg_t cm_x3xx_mfp_cfg[] __ini
+       GPIO99_GPIO,                    /* Ethernet IRQ */
+       /* RTC GPIOs */
+-      GPIO95_GPIO,                    /* RTC CS */
+-      GPIO96_GPIO,                    /* RTC WR */
+-      GPIO97_GPIO,                    /* RTC RD */
+-      GPIO98_GPIO,                    /* RTC IO */
++      GPIO95_GPIO | MFP_LPM_DRIVE_HIGH,       /* RTC CS */
++      GPIO96_GPIO | MFP_LPM_DRIVE_HIGH,       /* RTC WR */
++      GPIO97_GPIO | MFP_LPM_DRIVE_HIGH,       /* RTC RD */
++      GPIO98_GPIO,                            /* RTC IO */
+       /* Standard I2C */
+       GPIO21_I2C_SCL,
diff --git a/queue-3.0/drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch b/queue-3.0/drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch
new file mode 100644 (file)
index 0000000..254d5c2
--- /dev/null
@@ -0,0 +1,36 @@
+From e57ee01750c4954fd0b5e3c6109cd4b870880eb9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+Date: Mon, 25 Jul 2011 17:13:34 -0700
+Subject: drivers/rtc/rtc-tegra.c: properly initialize spinlock
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= <u.kleine-koenig@pengutronix.de>
+
+commit e57ee01750c4954fd0b5e3c6109cd4b870880eb9 upstream.
+
+Using __SPIN_LOCK_UNLOCKED for a dynamically allocated lock is wrong and
+breaks the build with PREEMPT_RT_FULL.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Cc: Andrew Chew <achew@nvidia.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/rtc/rtc-tegra.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/rtc/rtc-tegra.c
++++ b/drivers/rtc/rtc-tegra.c
+@@ -343,7 +343,7 @@ static int __devinit tegra_rtc_probe(str
+       /* set context info. */
+       info->pdev = pdev;
+-      info->tegra_rtc_lock = __SPIN_LOCK_UNLOCKED(info->tegra_rtc_lock);
++      spin_lock_init(&info->tegra_rtc_lock);
+       platform_set_drvdata(pdev, info);
diff --git a/queue-3.0/rtc-fix-hrtimer-deadlock.patch b/queue-3.0/rtc-fix-hrtimer-deadlock.patch
new file mode 100644 (file)
index 0000000..56a4eb7
--- /dev/null
@@ -0,0 +1,130 @@
+From b830ac1d9a2262093bb0f3f6a2fd2a1c8278daf5 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 26 Jul 2011 16:08:20 -0700
+Subject: rtc: fix hrtimer deadlock
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit b830ac1d9a2262093bb0f3f6a2fd2a1c8278daf5 upstream.
+
+Ben reported a lockup related to rtc. The lockup happens due to:
+
+CPU0                                        CPU1
+
+rtc_irq_set_state()                        __run_hrtimer()
+  spin_lock_irqsave(&rtc->irq_task_lock)    rtc_handle_legacy_irq();
+                                             spin_lock(&rtc->irq_task_lock);
+  hrtimer_cancel()
+    while (callback_running);
+
+So the running callback never finishes as it's blocked on
+rtc->irq_task_lock.
+
+Use hrtimer_try_to_cancel() instead and drop rtc->irq_task_lock while
+waiting for the callback.  Fix this for both rtc_irq_set_state() and
+rtc_irq_set_freq().
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reported-by: Ben Greear <greearb@candelatech.com>
+Cc: John Stultz <john.stultz@linaro.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/rtc/interface.c |   56 +++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 37 insertions(+), 19 deletions(-)
+
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -636,6 +636,29 @@ void rtc_irq_unregister(struct rtc_devic
+ }
+ EXPORT_SYMBOL_GPL(rtc_irq_unregister);
++static int rtc_update_hrtimer(struct rtc_device *rtc, int enabled)
++{
++      /*
++       * We unconditionally cancel the timer here, because otherwise
++       * we could run into BUG_ON(timer->state != HRTIMER_STATE_CALLBACK);
++       * when we manage to start the timer before the callback
++       * returns HRTIMER_RESTART.
++       *
++       * We cannot use hrtimer_cancel() here as a running callback
++       * could be blocked on rtc->irq_task_lock and hrtimer_cancel()
++       * would spin forever.
++       */
++      if (hrtimer_try_to_cancel(&rtc->pie_timer) < 0)
++              return -1;
++
++      if (enabled) {
++              ktime_t period = ktime_set(0, NSEC_PER_SEC / rtc->irq_freq);
++
++              hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
++      }
++      return 0;
++}
++
+ /**
+  * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
+  * @rtc: the rtc device
+@@ -651,24 +674,21 @@ int rtc_irq_set_state(struct rtc_device
+       int err = 0;
+       unsigned long flags;
++retry:
+       spin_lock_irqsave(&rtc->irq_task_lock, flags);
+       if (rtc->irq_task != NULL && task == NULL)
+               err = -EBUSY;
+       if (rtc->irq_task != task)
+               err = -EACCES;
+-      if (err)
+-              goto out;
+-
+-      if (enabled) {
+-              ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
+-              hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL);
+-      } else {
+-              hrtimer_cancel(&rtc->pie_timer);
++      if (!err) {
++              if (rtc_update_hrtimer(rtc, enabled) < 0) {
++                      spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
++                      cpu_relax();
++                      goto retry;
++              }
++              rtc->pie_enabled = enabled;
+       }
+-      rtc->pie_enabled = enabled;
+-out:
+       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+-
+       return err;
+ }
+ EXPORT_SYMBOL_GPL(rtc_irq_set_state);
+@@ -690,20 +710,18 @@ int rtc_irq_set_freq(struct rtc_device *
+       if (freq <= 0)
+               return -EINVAL;
+-
++retry:
+       spin_lock_irqsave(&rtc->irq_task_lock, flags);
+       if (rtc->irq_task != NULL && task == NULL)
+               err = -EBUSY;
+       if (rtc->irq_task != task)
+               err = -EACCES;
+-      if (err == 0) {
++      if (!err) {
+               rtc->irq_freq = freq;
+-              if (rtc->pie_enabled) {
+-                      ktime_t period;
+-                      hrtimer_cancel(&rtc->pie_timer);
+-                      period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
+-                      hrtimer_start(&rtc->pie_timer, period,
+-                                      HRTIMER_MODE_REL);
++              if (rtc->pie_enabled && rtc_update_hrtimer(rtc, 1) < 0) {
++                      spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
++                      cpu_relax();
++                      goto retry;
+               }
+       }
+       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
diff --git a/queue-3.0/rtc-handle-errors-correctly-in-rtc_irq_set_state.patch b/queue-3.0/rtc-handle-errors-correctly-in-rtc_irq_set_state.patch
new file mode 100644 (file)
index 0000000..098595d
--- /dev/null
@@ -0,0 +1,46 @@
+From 2c4f57d12df7696d65b0247bfd57fd082a7719e6 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 26 Jul 2011 16:08:18 -0700
+Subject: rtc: handle errors correctly in rtc_irq_set_state()
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 2c4f57d12df7696d65b0247bfd57fd082a7719e6 upstream.
+
+The code checks the correctness of the parameters, but unconditionally
+arms/disarms the hrtimer.
+
+The result is that a random task might arm/disarm rtc timer and surprise
+the real owner by either generating events or by stopping them.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: John Stultz <john.stultz@linaro.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/rtc/interface.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -656,6 +656,8 @@ int rtc_irq_set_state(struct rtc_device
+               err = -EBUSY;
+       if (rtc->irq_task != task)
+               err = -EACCES;
++      if (err)
++              goto out;
+       if (enabled) {
+               ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq);
+@@ -664,6 +666,7 @@ int rtc_irq_set_state(struct rtc_device
+               hrtimer_cancel(&rtc->pie_timer);
+       }
+       rtc->pie_enabled = enabled;
++out:
+       spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
+       return err;
diff --git a/queue-3.0/rtc-limit-frequency.patch b/queue-3.0/rtc-limit-frequency.patch
new file mode 100644 (file)
index 0000000..c4254d0
--- /dev/null
@@ -0,0 +1,38 @@
+From 431e2bcc371016824f419baa745f82388258f3ee Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Tue, 26 Jul 2011 16:08:19 -0700
+Subject: rtc: limit frequency
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit 431e2bcc371016824f419baa745f82388258f3ee upstream.
+
+Due to the hrtimer self rearming mode a user can DoS the machine simply
+because it's starved by hrtimer events.
+
+The RTC hrtimer is self rearming.  We really need to limit the frequency
+to something sensible.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: John Stultz <john.stultz@linaro.org>
+Cc: Ingo Molnar <mingo@elte.hu>
+Cc: Ben Greear <greearb@candelatech.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/rtc/interface.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/rtc/interface.c
++++ b/drivers/rtc/interface.c
+@@ -708,7 +708,7 @@ int rtc_irq_set_freq(struct rtc_device *
+       int err = 0;
+       unsigned long flags;
+-      if (freq <= 0)
++      if (freq <= 0 || freq > 5000)
+               return -EINVAL;
+ retry:
+       spin_lock_irqsave(&rtc->irq_task_lock, flags);
index 24f09b3418c9effa9ffc71041e59f9900dba4e35..230ac3fc2ba9fc4f6a747aab3ad76c1e79f3d10d 100644 (file)
@@ -3,3 +3,17 @@ mmc-added-quirks-for-ricoh-1180-e823-lower-base-clock.patch
 mmc-sdhci-esdhc-imx-sdhci_card_present-does-not-get.patch
 bridge-send-proper-message_age-in-config-bpdu.patch
 gro-only-reset-frag0-when-skb-can-be-pulled.patch
+staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch
+staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch
+staging-comedi-fix-infoleak-to-userspace.patch
+staging-hv-storvsc-increase-the-timeout-value-in-the.patch
+staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch
+staging-hv-netvsc-increase-the-timeout-value-in-the.patch
+usb-ohci-fix-another-regression-for-nvidia-controllers.patch
+usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch
+usb-musb-restore-index-register-in-resume-path.patch
+rtc-handle-errors-correctly-in-rtc_irq_set_state.patch
+rtc-fix-hrtimer-deadlock.patch
+rtc-limit-frequency.patch
+drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch
+arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch
diff --git a/queue-3.0/staging-comedi-fix-infoleak-to-userspace.patch b/queue-3.0/staging-comedi-fix-infoleak-to-userspace.patch
new file mode 100644 (file)
index 0000000..1ae74ca
--- /dev/null
@@ -0,0 +1,33 @@
+From 819cbb120eaec7e014e5abd029260db1ca8c5735 Mon Sep 17 00:00:00 2001
+From: Vasiliy Kulikov <segoon@openwall.com>
+Date: Sun, 26 Jun 2011 12:56:22 +0400
+Subject: staging: comedi: fix infoleak to userspace
+
+From: Vasiliy Kulikov <segoon@openwall.com>
+
+commit 819cbb120eaec7e014e5abd029260db1ca8c5735 upstream.
+
+driver_name and board_name are pointers to strings, not buffers of size
+COMEDI_NAMELEN.  Copying COMEDI_NAMELEN bytes of a string containing
+less than COMEDI_NAMELEN-1 bytes would leak some unrelated bytes.
+
+Signed-off-by: Vasiliy Kulikov <segoon@openwall.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/comedi/comedi_fops.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/comedi/comedi_fops.c
++++ b/drivers/staging/comedi/comedi_fops.c
+@@ -383,8 +383,8 @@ static int do_devinfo_ioctl(struct comed
+       /* fill devinfo structure */
+       devinfo.version_code = COMEDI_VERSION_CODE;
+       devinfo.n_subdevs = dev->n_subdevices;
+-      memcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
+-      memcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
++      strlcpy(devinfo.driver_name, dev->driver->driver_name, COMEDI_NAMELEN);
++      strlcpy(devinfo.board_name, dev->board_name, COMEDI_NAMELEN);
+       if (read_subdev)
+               devinfo.read_subdevice = read_subdev - dev->subdevices;
diff --git a/queue-3.0/staging-hv-netvsc-increase-the-timeout-value-in-the.patch b/queue-3.0/staging-hv-netvsc-increase-the-timeout-value-in-the.patch
new file mode 100644 (file)
index 0000000..e2fae6e
--- /dev/null
@@ -0,0 +1,76 @@
+From 5c5781b3f88567211ecaaada13431af15c8c6003 Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 16 Jun 2011 13:16:35 -0700
+Subject: Staging: hv: netvsc: Increase the timeout value in the
+ netvsc driver
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 5c5781b3f88567211ecaaada13431af15c8c6003 upstream.
+
+On some loaded windows hosts, we have discovered that the host may not
+respond to guest requests within the specified time (one second)
+as evidenced by the guest timing out. Fix this problem by increasing
+the timeout to 5 seconds.
+
+It may be useful to apply this patch to the 3.0 kernel as well.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/netvsc.c       |    4 ++--
+ drivers/staging/hv/rndis_filter.c |    6 +++---
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/hv/netvsc.c
++++ b/drivers/staging/hv/netvsc.c
+@@ -270,7 +270,7 @@ static int netvsc_init_recv_buf(struct h
+               goto cleanup;
+       }
+-      t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
++      t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+       BUG_ON(t == 0);
+@@ -513,7 +513,7 @@ static int netvsc_connect_vsp(struct hv_
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
++      t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+--- a/drivers/staging/hv/rndis_filter.c
++++ b/drivers/staging/hv/rndis_filter.c
+@@ -467,7 +467,7 @@ static int rndis_filter_query_device(str
+       if (ret != 0)
+               goto Cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto Cleanup;
+@@ -543,7 +543,7 @@ static int rndis_filter_set_packet_filte
+       if (ret != 0)
+               goto Cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -1;
+@@ -600,7 +600,7 @@ static int rndis_filter_init_device(stru
+       }
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
diff --git a/queue-3.0/staging-hv-storvsc-increase-the-timeout-value-in-the.patch b/queue-3.0/staging-hv-storvsc-increase-the-timeout-value-in-the.patch
new file mode 100644 (file)
index 0000000..194973f
--- /dev/null
@@ -0,0 +1,77 @@
+From 46d2eb6d82ef44be58ae192c35e8cd52485f02eb Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 16 Jun 2011 13:16:36 -0700
+Subject: Staging: hv: storvsc: Increase the timeout value in the
+ storvsc driver
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 46d2eb6d82ef44be58ae192c35e8cd52485f02eb upstream.
+
+On some loaded windows hosts, we have discovered that the host may not
+respond to guest requests within the specified time (one second)
+as evidenced by the guest timing out. Fix this problem by increasing
+the timeout to 5 seconds.
+
+It may be useful to apply this patch to the 3.0 kernel as well.
+the 3.0 kernel as well.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/storvsc.c     |    8 ++++----
+ drivers/staging/hv/storvsc_drv.c |    2 +-
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/hv/storvsc.c
++++ b/drivers/staging/hv/storvsc.c
+@@ -135,7 +135,7 @@ static int storvsc_channel_init(struct h
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
+@@ -163,7 +163,7 @@ static int storvsc_channel_init(struct h
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
+@@ -192,7 +192,7 @@ static int storvsc_channel_init(struct h
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
+@@ -222,7 +222,7 @@ static int storvsc_channel_init(struct h
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
+--- a/drivers/staging/hv/storvsc_drv.c
++++ b/drivers/staging/hv/storvsc_drv.c
+@@ -393,7 +393,7 @@ static int storvsc_host_reset(struct hv_
+       if (ret != 0)
+               goto cleanup;
+-      t = wait_for_completion_timeout(&request->wait_event, HZ);
++      t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
diff --git a/queue-3.0/staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch b/queue-3.0/staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch
new file mode 100644 (file)
index 0000000..0bddaa1
--- /dev/null
@@ -0,0 +1,61 @@
+From 2dfde9644fe8c4a77f9c73f95b25d6300ca23b5d Mon Sep 17 00:00:00 2001
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+Date: Thu, 16 Jun 2011 13:16:34 -0700
+Subject: Staging: hv: vmbus: Increase the timeout value in the vmbus
+ driver
+
+From: "K. Y. Srinivasan" <kys@microsoft.com>
+
+commit 2dfde9644fe8c4a77f9c73f95b25d6300ca23b5d upstream.
+
+On some loaded windows hosts, we have discovered that the host may not
+respond to guest requests within the specified time (one second)
+as evidenced by the guest timing out. Fix this problem by increasing
+the timeout to 5 seconds.
+
+It may be useful to apply this patch to the 3.0 kernel as well.
+
+Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Signed-off-by: Hank Janssen <hjanssen@microsoft.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/hv/channel.c      |    2 +-
+ drivers/staging/hv/channel_mgmt.c |    2 +-
+ drivers/staging/hv/connection.c   |    2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/hv/channel.c
++++ b/drivers/staging/hv/channel.c
+@@ -212,7 +212,7 @@ int vmbus_open(struct vmbus_channel *new
+       if (ret != 0)
+               goto Cleanup;
+-      t = wait_for_completion_timeout(&openInfo->waitevent, HZ);
++      t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ);
+       if (t == 0) {
+               err = -ETIMEDOUT;
+               goto errorout;
+--- a/drivers/staging/hv/channel_mgmt.c
++++ b/drivers/staging/hv/channel_mgmt.c
+@@ -773,7 +773,7 @@ int vmbus_request_offers(void)
+               goto cleanup;
+       }
+-      t = wait_for_completion_timeout(&msginfo->waitevent, HZ);
++      t = wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
+       if (t == 0) {
+               ret = -ETIMEDOUT;
+               goto cleanup;
+--- a/drivers/staging/hv/connection.c
++++ b/drivers/staging/hv/connection.c
+@@ -135,7 +135,7 @@ int vmbus_connect(void)
+       }
+       /* Wait for the connection response */
+-      t =  wait_for_completion_timeout(&msginfo->waitevent, HZ);
++      t =  wait_for_completion_timeout(&msginfo->waitevent, 5*HZ);
+       if (t == 0) {
+               spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
+                               flags);
diff --git a/queue-3.0/staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch b/queue-3.0/staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch
new file mode 100644 (file)
index 0000000..501296b
--- /dev/null
@@ -0,0 +1,44 @@
+From 1c50bf7e415cf6ce9545dbecc2ac0d89d3916c53 Mon Sep 17 00:00:00 2001
+From: Larry Finger <Larry.Finger@lwfinger.net>
+Date: Sat, 18 Jun 2011 22:34:34 -0500
+Subject: staging: r8192e_pci: Handle duplicate PCI ID 0x10ec:0x8192
+ conflict with rtl8192se
+
+From: Larry Finger <Larry.Finger@lwfinger.net>
+
+commit 1c50bf7e415cf6ce9545dbecc2ac0d89d3916c53 upstream.
+
+There are two devices with PCI ID 0x10ec:0x8192, namely RTL8192E and
+RTL8192SE. The method of distinguishing them is by the revision ID
+at offset 0x8 of the PCI configuration space. If the value is 0x10,
+then the device uses rtl8192se for a driver.
+
+Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/rtl8192e/r8192E_core.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/staging/rtl8192e/r8192E_core.c
++++ b/drivers/staging/rtl8192e/r8192E_core.c
+@@ -4532,6 +4532,7 @@ static int __devinit rtl8192_pci_probe(s
+       u8 unit = 0;
+       int ret = -ENODEV;
+       unsigned long pmem_start, pmem_len, pmem_flags;
++      u8 revisionid;
+       RT_TRACE(COMP_INIT,"Configuring chip resources\n");
+@@ -4592,6 +4593,11 @@ static int __devinit rtl8192_pci_probe(s
+          pci_write_config_byte(pdev, 0x41, 0x00);
++      pci_read_config_byte(pdev, 0x08, &revisionid);
++      /* If the revisionid is 0x10, the device uses rtl8192se. */
++      if (pdev->device == 0x8192 && revisionid == 0x10)
++              goto fail1;
++
+       pci_read_config_byte(pdev, 0x05, &unit);
+       pci_write_config_byte(pdev, 0x05, unit & (~0x04));
diff --git a/queue-3.0/staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch b/queue-3.0/staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch
new file mode 100644 (file)
index 0000000..44768d4
--- /dev/null
@@ -0,0 +1,44 @@
+From 8547d4cc2b616e4f1dafebe2c673fc986422b506 Mon Sep 17 00:00:00 2001
+From: Tobias Klauser <tklauser@distanz.ch>
+Date: Fri, 24 Jun 2011 15:48:47 +0200
+Subject: Staging: usbip: vhci-hcd: Do not kill already dead RX/TX kthread
+
+From: Tobias Klauser <tklauser@distanz.ch>
+
+commit 8547d4cc2b616e4f1dafebe2c673fc986422b506 upstream.
+
+When unbinding a device on the host which was still attached on the
+client, I got a NULL pointer dereference on the client. This turned out
+to be due to kthread_stop() being called on an already dead kthread.
+
+Here is how I was able to reproduce the problem:
+
+ server:# usbip bind -b 1-2
+                                client:# usbip attach -h server -b 1-2
+ server:# usbip unbind -b 1-2
+
+This patch fixes the problem by checking the kthread before attempting
+to kill it, as it is done on the opposite side in
+stub_shutdown_connection().
+
+Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/staging/usbip/vhci_hcd.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/usbip/vhci_hcd.c
++++ b/drivers/staging/usbip/vhci_hcd.c
+@@ -846,9 +846,9 @@ static void vhci_shutdown_connection(str
+       }
+       /* kill threads related to this sdev, if v.c. exists */
+-      if (vdev->ud.tcp_rx)
++      if (vdev->ud.tcp_rx && !task_is_dead(vdev->ud.tcp_rx))
+               kthread_stop(vdev->ud.tcp_rx);
+-      if (vdev->ud.tcp_tx)
++      if (vdev->ud.tcp_tx && !task_is_dead(vdev->ud.tcp_tx))
+               kthread_stop(vdev->ud.tcp_tx);
+       pr_info("stop threads\n");
diff --git a/queue-3.0/usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch b/queue-3.0/usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch
new file mode 100644 (file)
index 0000000..c12652a
--- /dev/null
@@ -0,0 +1,213 @@
+From 004c19682884d4f40000ce1ded53f4a1d0b18206 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 5 Jul 2011 12:34:05 -0400
+Subject: USB: EHCI: go back to using the system clock for QH unlinks
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 004c19682884d4f40000ce1ded53f4a1d0b18206 upstream.
+
+This patch (as1477) fixes a problem affecting a few types of EHCI
+controller.  Contrary to what one might expect, these controllers
+automatically stop their internal frame counter when no ports are
+enabled.  Since ehci-hcd currently relies on the frame counter for
+determining when it should unlink QHs from the async schedule, those
+controllers run into trouble: The frame counter stops and the QHs
+never get unlinked.
+
+Some systems have also experienced other problems traced back to
+commit b963801164618e25fbdc0cd452ce49c3628b46c8 (USB: ehci-hcd unlink
+speedups), which made the original switch from using the system clock
+to using the frame counter.  It never became clear what the reason was
+for these problems, but evidently it is related to use of the frame
+counter.
+
+To fix all these problems, this patch more or less reverts that commit
+and goes back to using the system clock.  But this can't be done
+cleanly because other changes have since been made to the scan_async()
+subroutine.  One of these changes involved the tricky logic that tries
+to avoid rescanning QHs that have already been seen when the scanning
+loop is restarted, which happens whenever an URB is given back.
+Switching back to clock-based unlinks would make this logic even more
+complicated.
+
+Therefore the new code doesn't rescan the entire async list whenever a
+giveback occurs.  Instead it rescans only the current QH and continues
+on from there.  This requires the use of a separate pointer to keep
+track of the next QH to scan, since the current QH may be unlinked
+while the scanning is in progress.  That new pointer must be global,
+so that it can be adjusted forward whenever the _next_ QH gets
+unlinked.  (uhci-hcd uses this same trick.)
+
+Simplification of the scanning loop removes a level of indentation,
+which accounts for the size of the patch.  The amount of code changed
+is relatively small, and it isn't exactly a reversion of the
+b963801164 commit.
+
+This fixes Bugzilla #32432.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Matej Kenda <matejken@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hcd.c |    8 +---
+ drivers/usb/host/ehci-q.c   |   86 +++++++++++++++++++++-----------------------
+ drivers/usb/host/ehci.h     |    3 +
+ 3 files changed, 47 insertions(+), 50 deletions(-)
+
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -94,7 +94,8 @@ static const char    hcd_name [] = "ehci_hc
+ #define EHCI_IAA_MSECS                10              /* arbitrary */
+ #define EHCI_IO_JIFFIES               (HZ/10)         /* io watchdog > irq_thresh */
+ #define EHCI_ASYNC_JIFFIES    (HZ/20)         /* async idle timeout */
+-#define EHCI_SHRINK_FRAMES    5               /* async qh unlink delay */
++#define EHCI_SHRINK_JIFFIES   (DIV_ROUND_UP(HZ, 200) + 1)
++                                              /* 200-ms async qh unlink delay */
+ /* Initial IRQ latency:  faster than hw default */
+ static int log2_irq_thresh = 0;               // 0 to 6
+@@ -152,10 +153,7 @@ timer_action(struct ehci_hcd *ehci, enum
+                       break;
+               /* case TIMER_ASYNC_SHRINK: */
+               default:
+-                      /* add a jiffie since we synch against the
+-                       * 8 KHz uframe counter.
+-                       */
+-                      t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1;
++                      t = EHCI_SHRINK_JIFFIES;
+                       break;
+               }
+               mod_timer(&ehci->watchdog, t + jiffies);
+--- a/drivers/usb/host/ehci-q.c
++++ b/drivers/usb/host/ehci-q.c
+@@ -1231,6 +1231,8 @@ static void start_unlink_async (struct e
+       prev->hw->hw_next = qh->hw->hw_next;
+       prev->qh_next = qh->qh_next;
++      if (ehci->qh_scan_next == qh)
++              ehci->qh_scan_next = qh->qh_next.qh;
+       wmb ();
+       /* If the controller isn't running, we don't have to wait for it */
+@@ -1256,53 +1258,49 @@ static void scan_async (struct ehci_hcd
+       struct ehci_qh          *qh;
+       enum ehci_timer_action  action = TIMER_IO_WATCHDOG;
+-      ehci->stamp = ehci_readl(ehci, &ehci->regs->frame_index);
+       timer_action_done (ehci, TIMER_ASYNC_SHRINK);
+-rescan:
+       stopped = !HC_IS_RUNNING(ehci_to_hcd(ehci)->state);
+-      qh = ehci->async->qh_next.qh;
+-      if (likely (qh != NULL)) {
+-              do {
+-                      /* clean any finished work for this qh */
+-                      if (!list_empty(&qh->qtd_list) && (stopped ||
+-                                      qh->stamp != ehci->stamp)) {
+-                              int temp;
+-
+-                              /* unlinks could happen here; completion
+-                               * reporting drops the lock.  rescan using
+-                               * the latest schedule, but don't rescan
+-                               * qhs we already finished (no looping)
+-                               * unless the controller is stopped.
+-                               */
+-                              qh = qh_get (qh);
+-                              qh->stamp = ehci->stamp;
+-                              temp = qh_completions (ehci, qh);
+-                              if (qh->needs_rescan)
+-                                      unlink_async(ehci, qh);
+-                              qh_put (qh);
+-                              if (temp != 0) {
+-                                      goto rescan;
+-                              }
+-                      }
+-
+-                      /* unlink idle entries, reducing DMA usage as well
+-                       * as HCD schedule-scanning costs.  delay for any qh
+-                       * we just scanned, there's a not-unusual case that it
+-                       * doesn't stay idle for long.
+-                       * (plus, avoids some kind of re-activation race.)
+-                       */
+-                      if (list_empty(&qh->qtd_list)
+-                                      && qh->qh_state == QH_STATE_LINKED) {
+-                              if (!ehci->reclaim && (stopped ||
+-                                      ((ehci->stamp - qh->stamp) & 0x1fff)
+-                                              >= EHCI_SHRINK_FRAMES * 8))
+-                                      start_unlink_async(ehci, qh);
+-                              else
+-                                      action = TIMER_ASYNC_SHRINK;
+-                      }
+-                      qh = qh->qh_next.qh;
+-              } while (qh);
++      ehci->qh_scan_next = ehci->async->qh_next.qh;
++      while (ehci->qh_scan_next) {
++              qh = ehci->qh_scan_next;
++              ehci->qh_scan_next = qh->qh_next.qh;
++ rescan:
++              /* clean any finished work for this qh */
++              if (!list_empty(&qh->qtd_list)) {
++                      int temp;
++
++                      /*
++                       * Unlinks could happen here; completion reporting
++                       * drops the lock.  That's why ehci->qh_scan_next
++                       * always holds the next qh to scan; if the next qh
++                       * gets unlinked then ehci->qh_scan_next is adjusted
++                       * in start_unlink_async().
++                       */
++                      qh = qh_get(qh);
++                      temp = qh_completions(ehci, qh);
++                      if (qh->needs_rescan)
++                              unlink_async(ehci, qh);
++                      qh->unlink_time = jiffies + EHCI_SHRINK_JIFFIES;
++                      qh_put(qh);
++                      if (temp != 0)
++                              goto rescan;
++              }
++
++              /* unlink idle entries, reducing DMA usage as well
++               * as HCD schedule-scanning costs.  delay for any qh
++               * we just scanned, there's a not-unusual case that it
++               * doesn't stay idle for long.
++               * (plus, avoids some kind of re-activation race.)
++               */
++              if (list_empty(&qh->qtd_list)
++                              && qh->qh_state == QH_STATE_LINKED) {
++                      if (!ehci->reclaim && (stopped ||
++                                      time_after_eq(jiffies, qh->unlink_time)))
++                              start_unlink_async(ehci, qh);
++                      else
++                              action = TIMER_ASYNC_SHRINK;
++              }
+       }
+       if (action == TIMER_ASYNC_SHRINK)
+               timer_action (ehci, TIMER_ASYNC_SHRINK);
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -75,6 +75,7 @@ struct ehci_hcd {                    /* one per controlle
+       struct ehci_qh          *async;
+       struct ehci_qh          *dummy;         /* For AMD quirk use */
+       struct ehci_qh          *reclaim;
++      struct ehci_qh          *qh_scan_next;
+       unsigned                scanning : 1;
+       /* periodic schedule support */
+@@ -117,7 +118,6 @@ struct ehci_hcd {                  /* one per controlle
+       struct timer_list       iaa_watchdog;
+       struct timer_list       watchdog;
+       unsigned long           actions;
+-      unsigned                stamp;
+       unsigned                periodic_stamp;
+       unsigned                random_frame;
+       unsigned long           next_statechange;
+@@ -343,6 +343,7 @@ struct ehci_qh {
+       struct ehci_qh          *reclaim;       /* next to reclaim */
+       struct ehci_hcd         *ehci;
++      unsigned long           unlink_time;
+       /*
+        * Do NOT use atomic operations for QH refcounting. On some CPUs
diff --git a/queue-3.0/usb-musb-restore-index-register-in-resume-path.patch b/queue-3.0/usb-musb-restore-index-register-in-resume-path.patch
new file mode 100644 (file)
index 0000000..e7b74a2
--- /dev/null
@@ -0,0 +1,32 @@
+From 3c5fec75e121b21a2eb35e5a6b44291509abba6f Mon Sep 17 00:00:00 2001
+From: Ajay Kumar Gupta <ajay.gupta@ti.com>
+Date: Fri, 8 Jul 2011 15:06:13 +0530
+Subject: usb: musb: restore INDEX register in resume path
+
+From: Ajay Kumar Gupta <ajay.gupta@ti.com>
+
+commit 3c5fec75e121b21a2eb35e5a6b44291509abba6f upstream.
+
+Restoring the missing INDEX register value in musb_restore_context().
+Without this suspend resume functionality is broken with offmode
+enabled.
+
+Acked-by: Anand Gadiyar <gadiyar@ti.com>
+Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
+Signed-off-by: Felipe Balbi <balbi@ti.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2329,6 +2329,7 @@ static void musb_restore_context(struct
+                               musb->context.index_regs[i].rxhubport);
+               }
+       }
++      musb_writeb(musb_base, MUSB_INDEX, musb->context.index);
+ }
+ static int musb_suspend(struct device *dev)
diff --git a/queue-3.0/usb-ohci-fix-another-regression-for-nvidia-controllers.patch b/queue-3.0/usb-ohci-fix-another-regression-for-nvidia-controllers.patch
new file mode 100644 (file)
index 0000000..0db0e77
--- /dev/null
@@ -0,0 +1,84 @@
+From 6ea12a04d295235ed67010a09fdea58c949e3eb0 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 15 Jul 2011 17:22:15 -0400
+Subject: USB: OHCI: fix another regression for NVIDIA controllers
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 6ea12a04d295235ed67010a09fdea58c949e3eb0 upstream.
+
+The NVIDIA series of OHCI controllers continues to be troublesome.  A
+few people using the MCP67 chipset have reported that even with the
+most recent kernels, the OHCI controller fails to handle new
+connections and spams the system log with "unable to enumerate USB
+port" messages.  This is different from the other problems previously
+reported for NVIDIA OHCI controllers, although it is probably related.
+
+It turns out that the MCP67 controller does not like to be kept in the
+RESET state very long.  After only a few seconds, it decides not to
+work any more.  This patch (as1479) changes the PCI initialization
+quirk code so that NVIDIA controllers are switched into the SUSPEND
+state after 50 ms of RESET.  With no interrupts enabled and all the
+downstream devices reset, and thus unable to send wakeup requests,
+this should be perfectly safe (even for non-NVIDIA hardware).
+
+The removal code in ohci-hcd hasn't been changed; it will still leave
+the controller in the RESET state.  As a result, if someone unloads
+ohci-hcd and then reloads it, the controller won't work again until
+the system is rebooted.  If anybody complains about this, the removal
+code can be updated similarly.
+
+This fixes Bugzilla #22052.
+
+Tested-by: Larry Finger <Larry.Finger@lwfinger.net>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/pci-quirks.c |   28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/drivers/usb/host/pci-quirks.c
++++ b/drivers/usb/host/pci-quirks.c
+@@ -35,6 +35,8 @@
+ #define OHCI_INTRSTATUS               0x0c
+ #define OHCI_INTRENABLE               0x10
+ #define OHCI_INTRDISABLE      0x14
++#define OHCI_FMINTERVAL               0x34
++#define OHCI_HCR              (1 << 0)        /* host controller reset */
+ #define OHCI_OCR              (1 << 3)        /* ownership change request */
+ #define OHCI_CTRL_RWC         (1 << 9)        /* remote wakeup connected */
+ #define OHCI_CTRL_IR          (1 << 8)        /* interrupt routing */
+@@ -497,6 +499,32 @@ static void __devinit quirk_usb_handoff_
+       /* reset controller, preserving RWC (and possibly IR) */
+       writel(control & OHCI_CTRL_MASK, base + OHCI_CONTROL);
++      readl(base + OHCI_CONTROL);
++
++      /* Some NVIDIA controllers stop working if kept in RESET for too long */
++      if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
++              u32 fminterval;
++              int cnt;
++
++              /* drive reset for at least 50 ms (7.1.7.5) */
++              msleep(50);
++
++              /* software reset of the controller, preserving HcFmInterval */
++              fminterval = readl(base + OHCI_FMINTERVAL);
++              writel(OHCI_HCR, base + OHCI_CMDSTATUS);
++
++              /* reset requires max 10 us delay */
++              for (cnt = 30; cnt > 0; --cnt) {        /* ... allow extra time */
++                      if ((readl(base + OHCI_CMDSTATUS) & OHCI_HCR) == 0)
++                              break;
++                      udelay(1);
++              }
++              writel(fminterval, base + OHCI_FMINTERVAL);
++
++              /* Now we're in the SUSPEND state with all devices reset
++               * and wakeups and interrupts disabled
++               */
++      }
+       /*
+        * disable interrupts