Author: cgutman
Date: Thu Feb 23 05:27:24 2012
New Revision: 55832

URL: http://svn.reactos.org/svn/reactos?rev=55832&view=rev
Log:
[USBUHCI]
- Delay for the correct amount of time when performing a global reset and a 
port reset
- Loosen the loop timings a bit to allow for more time for real hardware to 
complete start/stop/reset
- Clear only the change bits that were set and handle both bits in the either 
case
- Perform a synchronous callback when the reset completes

Modified:
    trunk/reactos/drivers/usb/usbuhci/hardware.cpp

Modified: trunk/reactos/drivers/usb/usbuhci/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hardware.cpp?rev=55832&r1=55831&r2=55832&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] Thu Feb 23 
05:27:24 2012
@@ -499,7 +499,7 @@
     //
     WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) | UHCI_USBCMD_RS);
 
-    for(Index = 0; Index < 10; Index++)
+    for(Index = 0; Index < 100; Index++)
     {
         //
         // wait a bit
@@ -576,6 +576,8 @@
 VOID
 CUSBHardwareDevice::GlobalReset()
 {
+    LARGE_INTEGER Timeout;
+
     //
     // back up start of modify register
     //
@@ -586,10 +588,25 @@
     // perform global reset
     //
     WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) | 
UHCI_USBCMD_GRESET);
-    KeStallExecutionProcessor(20);
-
-    //
-    // clear global reset bit
+
+    //
+    // delay is 10 ms
+    //
+    Timeout.QuadPart = 10;
+    DPRINT1("Waiting %d milliseconds for global reset\n", Timeout.LowPart);
+
+    //
+    // convert to 100 ns units (absolute)
+    //
+    Timeout.QuadPart *= -10000;
+
+    //
+    // perform the wait
+    //
+    KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
+    //
+    // clear command register
     //
     WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) & 
~UHCI_USBCMD_GRESET);
     KeStallExecutionProcessor(10);
@@ -880,7 +897,7 @@
         //
         // wait a bit
         //
-        KeStallExecutionProcessor(10);
+        KeStallExecutionProcessor(100);
 
         //
         // get status
@@ -893,7 +910,7 @@
             //
             return STATUS_SUCCESS;
         }
-    }while(Count++ < 5);
+    }while(Count++ < 100);
 
     DPRINT1("[USBUHCI] Failed to reset controller Status %x\n", Status);
     return STATUS_UNSUCCESSFUL;
@@ -906,6 +923,7 @@
     ULONG Port;
     USHORT Status;
     ULONG Index;
+    LARGE_INTEGER Timeout;
 
     DPRINT1("[UHCI] ResetPort Id %lu\n", PortIndex);
 
@@ -937,32 +955,43 @@
     WriteRegister16(Port, Status | UHCI_PORTSC_RESET);
 
     //
+    // delay is 20 ms for port reset
+    //
+    Timeout.QuadPart = 20;
+    DPRINT1("Waiting %d milliseconds for port reset\n", Timeout.LowPart);
+
+    //
+    // convert to 100 ns units (absolute)
+    //
+    Timeout.QuadPart *= -10000;
+
+    //
+    // perform the wait
+    //
+    KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
+    //
+    // re-read status
+    //
+    Status = ReadRegister16(Port);
+
+    //
+    // remove unwanted bits
+    //
+    Status &= UHCI_PORTSC_DATAMASK;
+
+    //
+    // clear reset port 
+    //
+    WriteRegister16(Port, (Status & ~UHCI_PORTSC_RESET));
+
+
+    //
     // now wait a bit
     //
-    KeStallExecutionProcessor(250);
-
-    //
-    // re-read status
-    //
-    Status = ReadRegister16(Port);
-
-    //
-    // remove unwanted bits
-    //
-    Status &= UHCI_PORTSC_DATAMASK;
-
-    //
-    // clear reset port 
-    //
-    WriteRegister16(Port, (Status & ~UHCI_PORTSC_RESET));
-
-
-    //
-    // now wait a bit
-    //
     KeStallExecutionProcessor(10);
 
-    for (Index = 0; Index < 10; Index++) 
+    for (Index = 0; Index < 100; Index++) 
     {
         // read port status
         Status = ReadRegister16(Port);
@@ -994,8 +1023,7 @@
         {
             // port enabled changed or connection status were set.
             // acknowledge either / both and wait again.
-            Status &= UHCI_PORTSC_DATAMASK;
-            WriteRegister16(Port, Status | UHCI_PORTSC_STATCHA | 
UHCI_PORTSC_ENABCHA);
+            WriteRegister16(Port, Status);
             continue;
         }
 
@@ -1009,6 +1037,16 @@
     m_PortResetChange |= (1 << PortIndex);
     DPRINT1("[USBUhci] Port Index %x Status after reset %x\n", PortIndex, 
ReadRegister16(Port));
 
+    //
+    // is there a callback
+    //
+    if (m_SCECallBack)
+    {
+        //
+        // issue callback
+        //
+        m_SCECallBack(m_SCEContext);
+    }
 
     return STATUS_SUCCESS;
 }
@@ -1114,7 +1152,7 @@
     // read current status
     //
     PortRegister = UHCI_PORTSC1 + PortId * 2;
-    PortStatus = ReadRegister16(PortRegister) & UHCI_PORTSC_DATAMASK;
+    PortStatus = ReadRegister16(PortRegister);
     DPRINT("[UHCI] PortStatus %x\n", PortStatus);
 
     if (Feature == C_PORT_RESET)
@@ -1124,19 +1162,12 @@
         //
         m_PortResetChange &= ~(1 << PortId);
     }
-    else if (Feature == C_PORT_CONNECTION)
-    {
-        //
-        // clear connection status
-        //
-        WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_STATCHA);
-    }
-    else if (Feature == C_PORT_ENABLE)
-    {
-        //
-        // enable port
-        //
-        WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_ENABCHA);
+    else if (Feature == C_PORT_CONNECTION || Feature == C_PORT_ENABLE)
+    {
+        //
+        // clear port status changes
+        //
+        WriteRegister16(PortRegister, PortStatus);
     }
 
     return STATUS_SUCCESS;


Reply via email to