[USBEHCI][USBOHCI]
authorCameron Gutman <aicommander@gmail.com>
Wed, 1 Feb 2012 12:16:47 +0000 (12:16 +0000)
committerCameron Gutman <aicommander@gmail.com>
Wed, 1 Feb 2012 12:16:47 +0000 (12:16 +0000)
- Wait 100 milliseconds for the port power and insertion to stabilize
- Wait for the 10 millisecond "recovery" period after reset

svn path=/branches/usb-bringup-trunk/; revision=55367

drivers/usb/usbehci_new/hardware.cpp
drivers/usb/usbohci/hardware.cpp

index d4d837a..cdc2bb9 100644 (file)
@@ -798,9 +798,26 @@ CUSBHardwareDevice::ResetPort(
             break;
     } while (TRUE);
 
+    //
+    // delay is 10 ms
+    //
+    Timeout.QuadPart = 10;
+    DPRINT1("Waiting %d milliseconds for port to recover after reset\n", Timeout.LowPart);
+
+    //
+    // convert to 100 ns units (absolute)
+    //
+    Timeout.QuadPart *= -10000;
+
+    //
+    // perform the wait
+    //
+    KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
     //
     // check slow speed line after reset
     //
+    PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
     if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
     {
         DPRINT1("Non HighSpeed device. Releasing Ownership\n");
@@ -916,9 +933,30 @@ CUSBHardwareDevice::ClearPortStatus(
 
     if (Status == C_PORT_CONNECTION)
     {
+        LARGE_INTEGER Timeout;
+
+        //
+        // reset status change bits
+        //
         Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
         Value |= EHCI_PRT_CONNECTSTATUSCHANGE | EHCI_PRT_ENABLEDSTATUSCHANGE;
         EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+
+        //
+        // delay is 100 ms
+        //
+        Timeout.QuadPart = 100;
+        DPRINT1("Waiting %d milliseconds for port to stabilize after connection\n", Timeout.LowPart);
+
+        //
+        // convert to 100 ns units (absolute)
+        //
+        Timeout.QuadPart *= -10000;
+
+        //
+        // perform the wait
+        //
+        KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
     }
 
     return STATUS_SUCCESS;
index efc3bf1..8e4b9c0 100644 (file)
@@ -1191,9 +1191,33 @@ CUSBHardwareDevice::ClearPortStatus(
     if (Status == C_PORT_CONNECTION || Status == C_PORT_ENABLE)
     {
         //
-        // clear bits
+        // clear change bits
         //
         WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_CSC | OHCI_RH_PORTSTATUS_PESC);
+
+        //
+        // wait for port to stabilize
+        //
+        if (Status == C_PORT_CONNECTION)
+        {
+            LARGE_INTEGER Timeout;
+
+            //
+            // delay is 100 ms
+            //
+            Timeout.QuadPart = 100;
+            DPRINT1("Waiting %d milliseconds for port to stabilize after connection\n", Timeout.LowPart);
+
+            //
+            // convert to 100 ns units (absolute)
+            //
+            Timeout.QuadPart *= -10000;
+
+            //
+            // perform the wait
+            //
+            KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+        }
     }
 
     //
@@ -1275,6 +1299,8 @@ CUSBHardwareDevice::SetPortFeature(
     }
     else if (Feature == PORT_RESET)
     {
+        LARGE_INTEGER Timeout;
+
         //
         // assert
         //
@@ -1306,6 +1332,22 @@ CUSBHardwareDevice::SetPortFeature(
            KeStallExecutionProcessor(100);
         }while(TRUE);
 
+        //
+        // delay is 10 ms
+        //
+        Timeout.QuadPart = 10;
+        DPRINT1("Waiting %d milliseconds for port to recover after reset\n", Timeout.LowPart);
+        
+        //
+        // convert to 100 ns units (absolute)
+        //
+        Timeout.QuadPart *= -10000;
+        
+        //
+        // perform the wait
+        //
+        KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
         //
         // trigger the status change interrupt
         //