# 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.479   -> 1.480  
#       drivers/usb/host/ohci-hcd.c     1.14    -> 1.15   
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/06/12      [EMAIL PROTECTED]     1.480
# [PATCH] ohci-hcd init err detect
# 
# I tracked down some of those "can't enumerate" problems to a
# chip init problem.  This patch detects and reports that case
# (better than the current nasty failure mode, and worth keeping
# even after we have a fix that works on OPTi/SiS/...) as well as
# doing some other minor cleanup.
# --------------------------------------------
#
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:37 2002
+++ b/drivers/usb/host/ohci-hcd.c       Fri Jun 14 14:15:37 2002
@@ -374,29 +374,35 @@
 
        /* Reset USB (needed by some controllers) */
        writel (0, &ohci->regs->control);
-       
+ 
        /* HC Reset requires max 10 ms delay */
        writel (OHCI_HCR,  &ohci->regs->cmdstatus);
        while ((readl (&ohci->regs->cmdstatus) & OHCI_HCR) != 0) {
                if (--timeout == 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
+        */
        return 0;
 }
 
 /*-------------------------------------------------------------------------*/
 
+#define        FI              0x2edf          /* 12000 bits per frame (-1) */
+#define LSTHRESH       0x628           /* lowspeed bit threshold */
+
 /* Start an OHCI controller, set the BUS operational
  * enable interrupts 
  * connect the virtual root hub
  */
 static int hc_start (struct ohci_hcd *ohci)
 {
-       __u32                   mask;
-       unsigned int            fminterval;
+       u32                     mask;
        struct usb_device       *udev;
 
        spin_lock_init (&ohci->lock);
@@ -405,24 +411,33 @@
 
        /* Tell the controller where the control and bulk lists are
         * The lists are empty now. */
-        
        writel (0, &ohci->regs->ed_controlhead);
        writel (0, &ohci->regs->ed_bulkhead);
-       
+
        /* a reset clears this */
        writel ((u32) ohci->hcca_dma, &ohci->regs->hcca);
-   
-       fminterval = 0x2edf;
-       writel ((fminterval * 9) / 10, &ohci->regs->periodicstart);
-       fminterval |= ((((fminterval - 210) * 6) / 7) << 16); 
-       writel (fminterval, &ohci->regs->fminterval);   
-       writel (0x628, &ohci->regs->lsthresh);
+
+       /* force default fmInterval (we won't adjust it); init thresholds
+        * for last FS and LS packets, reserve 90% for periodic.
+        */
+       writel ((((6 * (FI - 210)) / 7) << 16) | FI, &ohci->regs->fminterval);
+       writel (((9 * FI) / 10) & 0x3fff, &ohci->regs->periodicstart);
+       writel (LSTHRESH, &ohci->regs->lsthresh);
+
+       /* some OHCI implementations are finicky about how they init.
+        * bogus values here mean not even enumeration could work.
+        */
+       if ((readl (&ohci->regs->fminterval) & 0x3fff0000) == 0
+                       || !readl (&ohci->regs->periodicstart)) {
+               err ("%s init err", ohci->hcd.self.bus_name);
+               return -EOVERFLOW;
+       }
 
        /* start controller operations */
        ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
        ohci->disabled = 0;
        writel (ohci->hc_control, &ohci->regs->control);
- 
+
        /* Choose the interrupts we care about now, others later on demand */
        mask = OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_WDH;
        writel (mask, &ohci->regs->intrstatus);
@@ -430,9 +445,10 @@
 
 #ifdef OHCI_USE_NPS
        /* required for AMD-756 and some Mac platforms */
-       writel ((roothub_a (ohci) | RH_A_NPS) & ~RH_A_PSM,
+       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.

_______________________________________________________________

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

Reply via email to