# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.481 -> 1.482
# drivers/usb/host/ohci-hcd.c 1.15 -> 1.16
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/06/13 [EMAIL PROTECTED] 1.482
# [PATCH] ohci-hcd init err detect
#
# Here's a followup patch, should apply on top of what I sent
# this morning ... please do so! (Sorry, same name but the
# patch is different.)
#
# Along with some cleanups, this actually restores a line that
# was dropped somewhere in 2.5 ... basically, at least SiS and
# OPTi violate the OHCI spec so they don't init "by the book".
# --------------------------------------------
#
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c Fri Jun 14 14:15:33 2002
+++ b/drivers/usb/host/ohci-hcd.c Fri Jun 14 14:15:33 2002
@@ -106,7 +106,6 @@
/*-------------------------------------------------------------------------*/
-#define OHCI_USE_NPS // force NoPowerSwitching mode
// #define OHCI_VERBOSE_DEBUG /* not always helpful */
/* For initializing controller (mask in an HCFS mode too) */
@@ -349,22 +348,23 @@
static int hc_reset (struct ohci_hcd *ohci)
{
- int timeout = 30;
- int smm_timeout = 50; /* 0,5 sec */
-
- if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */
+ u32 temp;
+
+ /* SMM owns the HC? not for long! */
+ if (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
+ temp = 50; /* arbitrary: half second */
writel (OHCI_INTR_OC, &ohci->regs->intrenable);
writel (OHCI_OCR, &ohci->regs->cmdstatus);
dbg ("USB HC TakeOver from SMM");
while (readl (&ohci->regs->control) & OHCI_CTRL_IR) {
wait_ms (10);
- if (--smm_timeout == 0) {
+ if (--temp == 0) {
err ("USB HC TakeOver failed!");
return -1;
}
}
- }
-
+ }
+
/* Disable HC interrupts */
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
@@ -372,22 +372,34 @@
ohci->hcd.self.bus_name,
readl (&ohci->regs->control));
- /* Reset USB (needed by some controllers) */
- writel (0, &ohci->regs->control);
-
- /* HC Reset requires max 10 ms delay */
+ /* Reset USB (needed by some controllers); RemoteWakeupConnected
+ * saved if boot firmware (BIOS/SMM/...) told us it's connected
+ */
+ ohci->hc_control = readl (&ohci->regs->control);
+ ohci->hc_control &= OHCI_CTRL_RWC; /* hcfs 0 = RESET */
+ writel (ohci->hc_control, &ohci->regs->control);
+ wait_ms (50);
+
+ /* HC Reset requires max 10 us delay */
writel (OHCI_HCR, &ohci->regs->cmdstatus);
+ temp = 30; /* ... allow extra time */
while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
- if (--timeout == 0) {
+ if (--temp == 0) {
err ("USB HC reset timed out!");
return -1;
}
udelay (1);
- }
+ }
/* now we're in the SUSPEND state ... must go OPERATIONAL
* within 2msec else HC enters RESUME
+ *
+ * ... 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.
*/
+ writel (ohci->hc_control, &ohci->regs->control);
+
return 0;
}
@@ -434,7 +446,8 @@
}
/* start controller operations */
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ ohci->hc_control &= OHCI_CTRL_RWC;
+ ohci->hc_control |= OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
writel (ohci->hc_control, &ohci->regs->control);
@@ -443,13 +456,11 @@
writel (mask, &ohci->regs->intrstatus);
writel (mask, &ohci->regs->intrenable);
-#ifdef OHCI_USE_NPS
- /* required for AMD-756 and some Mac platforms */
+ /* hub power always on: required for AMD-756 and some Mac platforms */
writel ((roothub_a (ohci) | RH_A_NPS) & ~(RH_A_PSM | RH_A_OCPM),
&ohci->regs->roothub.a);
writel (RH_HS_LPSC, &ohci->regs->roothub.status);
writel (0, &ohci->regs->roothub.b);
-#endif /* OHCI_USE_NPS */
// POTPGT delay is bits 24-31, in 2 ms units.
mdelay ((roothub_a (ohci) >> 23) & 0x1fe);
@@ -458,9 +469,10 @@
ohci->hcd.self.root_hub = udev = usb_alloc_dev (NULL, &ohci->hcd.self);
ohci->hcd.state = USB_STATE_READY;
if (!udev) {
- ohci->disabled = 1;
-// FIXME cleanup
- return -ENOMEM;
+ ohci->disabled = 1;
+ ohci->hc_control &= ~OHCI_CTRL_HCFS;
+ writel (ohci->hc_control, &ohci->regs->control);
+ return -ENOMEM;
}
usb_connect (udev);
@@ -468,10 +480,11 @@
if (usb_register_root_hub (udev, ohci->parent_dev) != 0) {
usb_free_dev (udev);
ohci->disabled = 1;
-// FIXME cleanup
+ ohci->hc_control &= ~OHCI_CTRL_HCFS;
+ writel (ohci->hc_control, &ohci->regs->control);
return -ENODEV;
}
-
+
return 0;
}
_______________________________________________________________
Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -
http://devcon.sprintpcs.com/adp/index.cfm?source=osdntextlink
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel