[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#635573: Endless message of "Unable to enumerate usb device on port 5"



severity 635573 important
tags 635573 + upstream
forwarded 635573 https://bugzilla.kernel.org/show_bug.cgi?id=22052
merge 620848 635573
tags 620848 + fixed-upstream
quit

Hi,

Hor Jiun Shyong wrote:

> [Subject: lspci output]

Please keep in mind that this appears as the subject line when these
mails are received by email, so it can be a good place to put valuable
context.

[...]
> 00:02.0 USB Controller: nVidia Corporation MCP67 OHCI USB 1.1 Controller

Yep, this looks like Bug#620848.  Could you test the package from

 http://people.debian.org/~benh/packages/linux-image-2.6.39-3-amd64_2.6.39-4~a.test1_amd64.deb

, the latest upstream snapshot version from kernel.org, or the
following patch?  Instructions for testing a snapshot or a patch are
at <http://kernel-handbook.alioth.debian.org/>.

Thanks,
Jonathan

commit 6ea12a04
Author: Alan Stern <stern@rowland.harvard.edu>
Date:   Fri Jul 15 17:22:15 2011 -0400

    USB: OHCI: fix another regression for NVIDIA controllers
    
    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>
    Cc: stable <stable@kernel.org>
    Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index b5a7304f..a9d31590 100644
--- 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_ohci(struct pci_dev *pdev)
 
 	/* 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



Reply to: