summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2011-08-02 08:54:48 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2011-08-02 08:54:48 -0700
commite2cab6c9f6c3a46e171dc6a70b89d45698a42987 (patch)
tree22ee0a9c959df51d3cbce285d6ef48dccb20d398
parent81311522ced1545a68c63b78770be406316b1f02 (diff)
downloadstable-queue-e2cab6c9f6c3a46e171dc6a70b89d45698a42987.tar.gz
3.0 patches
-rw-r--r--queue-3.0/arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch37
-rw-r--r--queue-3.0/drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch36
-rw-r--r--queue-3.0/rtc-fix-hrtimer-deadlock.patch130
-rw-r--r--queue-3.0/rtc-handle-errors-correctly-in-rtc_irq_set_state.patch46
-rw-r--r--queue-3.0/rtc-limit-frequency.patch38
-rw-r--r--queue-3.0/series14
-rw-r--r--queue-3.0/staging-comedi-fix-infoleak-to-userspace.patch33
-rw-r--r--queue-3.0/staging-hv-netvsc-increase-the-timeout-value-in-the.patch76
-rw-r--r--queue-3.0/staging-hv-storvsc-increase-the-timeout-value-in-the.patch77
-rw-r--r--queue-3.0/staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch61
-rw-r--r--queue-3.0/staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch44
-rw-r--r--queue-3.0/staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch44
-rw-r--r--queue-3.0/usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch213
-rw-r--r--queue-3.0/usb-musb-restore-index-register-in-resume-path.patch32
-rw-r--r--queue-3.0/usb-ohci-fix-another-regression-for-nvidia-controllers.patch84
15 files changed, 965 insertions, 0 deletions
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
index 0000000000..4476201fc0
--- /dev/null
+++ b/queue-3.0/arm-pxa-cm-x300-fix-v3020-rtc-functionality.patch
@@ -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
index 0000000000..254d5c2d4a
--- /dev/null
+++ b/queue-3.0/drivers-rtc-rtc-tegra.c-properly-initialize-spinlock.patch
@@ -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
index 0000000000..56a4eb719a
--- /dev/null
+++ b/queue-3.0/rtc-fix-hrtimer-deadlock.patch
@@ -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
index 0000000000..098595db64
--- /dev/null
+++ b/queue-3.0/rtc-handle-errors-correctly-in-rtc_irq_set_state.patch
@@ -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
index 0000000000..c4254d0005
--- /dev/null
+++ b/queue-3.0/rtc-limit-frequency.patch
@@ -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);
diff --git a/queue-3.0/series b/queue-3.0/series
index 24f09b3418..230ac3fc2b 100644
--- a/queue-3.0/series
+++ b/queue-3.0/series
@@ -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
index 0000000000..1ae74ca3aa
--- /dev/null
+++ b/queue-3.0/staging-comedi-fix-infoleak-to-userspace.patch
@@ -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
index 0000000000..e2fae6e838
--- /dev/null
+++ b/queue-3.0/staging-hv-netvsc-increase-the-timeout-value-in-the.patch
@@ -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
index 0000000000..194973f9bc
--- /dev/null
+++ b/queue-3.0/staging-hv-storvsc-increase-the-timeout-value-in-the.patch
@@ -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
index 0000000000..0bddaa19c7
--- /dev/null
+++ b/queue-3.0/staging-hv-vmbus-increase-the-timeout-value-in-the-vmbus.patch
@@ -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
index 0000000000..501296b21f
--- /dev/null
+++ b/queue-3.0/staging-r8192e_pci-handle-duplicate-pci-id-0x10ec-0x8192.patch
@@ -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
index 0000000000..44768d44b1
--- /dev/null
+++ b/queue-3.0/staging-usbip-vhci-hcd-do-not-kill-already-dead-rx-tx-kthread.patch
@@ -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
index 0000000000..c12652a76e
--- /dev/null
+++ b/queue-3.0/usb-ehci-go-back-to-using-the-system-clock-for-qh-unlinks.patch
@@ -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
index 0000000000..e7b74a2a8a
--- /dev/null
+++ b/queue-3.0/usb-musb-restore-index-register-in-resume-path.patch
@@ -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
index 0000000000..0db0e776d8
--- /dev/null
+++ b/queue-3.0/usb-ohci-fix-another-regression-for-nvidia-controllers.patch
@@ -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