Re: OHCI_QUIRK_INITRESET (was: 2.6.9-rc2-mm2 ohci_hcd doesn't work)

From: David Brownell
Date: Sat Sep 25 2004 - 18:56:05 EST


On Friday 24 September 2004 9:16 am, Bjorn Helgaas wrote:
>
> The attached patch (which applies on top of Rui's patch for
> ALI M5237) fixes the problem for my DL360.

Hmm, I'd rather avoid needing a quirk table ... especially
when I've always suspected this is some subtle bug in the
way Linux initializes! Does this patch behave too?

- Dave
Cope differently with hardware that doesn't act like we expect:
kick in the "initreset" quirk automatically, so we won't need
to maintain a quirk table.

Signed-off-by: David Brownell <dbrownell@xxxxxxxxxxxxxxxxxxxxx>

--- 1.82/drivers/usb/host/ohci-hcd.c Mon Sep 20 10:31:27 2004
+++ edited/drivers/usb/host/ohci-hcd.c Sat Sep 25 15:53:19 2004
@@ -545,6 +545,7 @@
/* 2msec timelimit here means no irqs/preempt */
spin_lock_irq (&ohci->lock);

+retry:
/* HC Reset requires max 10 us delay */
writel (OHCI_HCR, &ohci->regs->cmdstatus);
temp = 30; /* ... allow extra time */
@@ -563,6 +564,8 @@
* ... but some hardware won't init fmInterval "by the book"
* (SiS, OPTi ...), so reset again instead. SiS doesn't need
* this if we write fmInterval after we're OPERATIONAL.
+ * Unclear about ALi, ServerWorks, and others ... this could
+ * easily be a longstanding bug in chip init on Linux.
*/
if (ohci->flags & OHCI_QUIRK_INITRESET) {
writel (ohci->hc_control, &ohci->regs->control);
@@ -586,6 +589,11 @@
*/
if ((ohci_readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
|| !ohci_readl (&ohci->regs->periodicstart)) {
+ if (!(ohci->flags & OHCI_QUIRK_INITRESET)) {
+ ohci->flags |= OHCI_QUIRK_INITRESET;
+ ohci_dbg (ohci, "enabling initreset quirk\n");
+ goto retry;
+ }
spin_unlock_irq (&ohci->lock);
ohci_err (ohci, "init err (%08x %04x)\n",
ohci_readl (&ohci->regs->fminterval),
--- 1.38/drivers/usb/host/ohci-pci.c Fri Sep 10 17:57:52 2004
+++ edited/drivers/usb/host/ohci-pci.c Sat Sep 25 15:51:41 2004
@@ -69,8 +69,6 @@
&& pdev->device == 0xc861) {
ohci_info (ohci,
"WARNING: OPTi workarounds unavailable\n");
- /* OPTi sometimes acts wierd during init */
- ohci->flags = OHCI_QUIRK_INITRESET;
}

/* Check for NSC87560. We have to look at the bridge (fn1) to
@@ -88,13 +86,6 @@
ohci_info (ohci, "Using NSC SuperIO setup\n");
}
}
-
- /* SiS sometimes acts wierd during init */
- else if (pdev->vendor == PCI_VENDOR_ID_SI) {
- ohci->flags = OHCI_QUIRK_INITRESET;
- ohci_info(ohci, "SiS init quirk\n");
- }
-
}

/* NOTE: there may have already been a first reset, to