Author: cgutman
Date: Fri Jan 27 05:20:37 2012
New Revision: 55231

URL: http://svn.reactos.org/svn/reactos?rev=55231&view=rev
Log:
[USBOHCI]
- Attempt to fix reset race conditions

Modified:
    branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.cpp

Modified: branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.cpp?rev=55231&r1=55230&r2=55231&view=diff
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbohci/hardware.cpp [iso-8859-1] 
Fri Jan 27 05:20:37 2012
@@ -1172,6 +1172,119 @@
 
     if (Status == C_PORT_RESET)
     {
+        //
+        // sanity checks
+        //
+        ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC));
+
+        //
+        // clear reset bit complete
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
+
+        //
+        // sanity check
+        //
+        ASSERT((Value & OHCI_RH_PORTSTATUS_PES));
+    }
+
+    if (Status == C_PORT_CONNECTION || Status == C_PORT_ENABLE)
+    {
+        //
+        // clear bits
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_CSC | OHCI_RH_PORTSTATUS_PESC);
+    }
+
+    //
+    // re-enable root hub change
+    //
+    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
+
+    return STATUS_SUCCESS;
+}
+
+
+NTSTATUS
+CUSBHardwareDevice::SetPortFeature(
+    ULONG PortId,
+    ULONG Feature)
+{
+    ULONG Value;
+
+    DPRINT1("CUSBHardwareDevice::SetPortFeature PortId %x Feature %x\n", 
PortId, Feature);
+
+    //
+    // read port status
+    //
+    Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)));
+
+
+    if (Feature == PORT_ENABLE)
+    {
+        //
+        // enable port
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PES);
+        return STATUS_SUCCESS;
+    }
+    else if (Feature == PORT_POWER)
+    {
+        LARGE_INTEGER Timeout;
+
+        //
+        // enable power
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PPS);
+
+        //
+        // read descriptor A for the delay data
+        //
+        Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_DESCRIPTOR_A_OFFSET));
+
+        //
+        // compute the delay
+        //
+        Timeout.QuadPart = OHCI_RH_GET_POWER_ON_TO_POWER_GOOD_TIME(Value);
+
+        //
+        // delay is multiplied by 2 ms
+        //
+        Timeout.QuadPart *= 2;
+        DPRINT1("Waiting %d milliseconds for port power up\n", 
Timeout.LowPart);
+
+        //
+        // convert to 100 ns units (absolute)
+        //
+        Timeout.QuadPart *= -10000;
+
+        //
+        // perform the wait
+        //
+        KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
+        return STATUS_SUCCESS;
+    }
+    else if (Feature == PORT_SUSPEND)
+    {
+        //
+        // enable port
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PSS);
+        return STATUS_SUCCESS;
+    }
+    else if (Feature == PORT_RESET)
+    {
+        //
+        // assert
+        //
+        ASSERT((Value & OHCI_RH_PORTSTATUS_CCS));
+
+        //
+        // reset port
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRS);
+
         do
         {
            //
@@ -1191,151 +1304,14 @@
            // wait a bit
            //
            KeStallExecutionProcessor(100);
-
-           //DPRINT1("Value %x Index %lu\n", Value, Index);
-
         }while(TRUE);
 
         //
-        // check if reset bit is still set
-        //
-        if (Value & OHCI_RH_PORTSTATUS_PRS)
-        {
-            //
-            // reset failed
-            //
-            DPRINT1("PortId %lu Reset failed\n", PortId);
-            return STATUS_UNSUCCESSFUL;
-        }
-
-        //
-        // sanity checks
-        //
-        ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC));
-
-        //
-        // clear reset bit complete
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
-
-        //
-        // sanity check
-        //
-        ASSERT((Value & OHCI_RH_PORTSTATUS_PES));
-    }
-
-    if (Status == C_PORT_CONNECTION || Status == C_PORT_ENABLE)
-    {
-        //
-        // clear bits
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_CSC | OHCI_RH_PORTSTATUS_PESC);
-    }
-
-    //
-    // re-enable root hub change
-    //
-    WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
-
-    return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-CUSBHardwareDevice::SetPortFeature(
-    ULONG PortId,
-    ULONG Feature)
-{
-    ULONG Value;
-
-    DPRINT1("CUSBHardwareDevice::SetPortFeature PortId %x Feature %x\n", 
PortId, Feature);
-
-    //
-    // read port status
-    //
-    Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)));
-
-
-    if (Feature == PORT_ENABLE)
-    {
-        //
-        // enable port
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PES);
+        // trigger the status change interrupt
+        //
+        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
+
         return STATUS_SUCCESS;
-    }
-    else if (Feature == PORT_POWER)
-    {
-        LARGE_INTEGER Timeout;
-
-        //
-        // enable power
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PPS);
-
-        //
-        // read descriptor A for the delay data
-        //
-        Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_DESCRIPTOR_A_OFFSET));
-
-        //
-        // compute the delay
-        //
-        Timeout.QuadPart = OHCI_RH_GET_POWER_ON_TO_POWER_GOOD_TIME(Value);
-
-        //
-        // delay is multiplied by 2 ms
-        //
-        Timeout.QuadPart *= 2;
-        DPRINT1("Waiting %d milliseconds for port power up\n", 
Timeout.LowPart);
-
-        //
-        // convert to 100 ns units (absolute)
-        //
-        Timeout.QuadPart *= -10000;
-
-        //
-        // perform the wait
-        //
-        KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
-
-        return STATUS_SUCCESS;
-    }
-    else if (Feature == PORT_SUSPEND)
-    {
-        //
-        // enable port
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PSS);
-        return STATUS_SUCCESS;
-    }
-    else if (Feature == PORT_RESET)
-    {
-        //
-        // assert
-        //
-        ASSERT((Value & OHCI_RH_PORTSTATUS_CCS));
-
-        //
-        // reset port
-        //
-        WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 
OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRS);
-
-        //
-        // wait 
-        //
-        KeStallExecutionProcessor(100);
-
-        //
-        // is there a status change callback
-        //
-        if (m_SCECallBack != NULL)
-        {
-            //
-            // issue callback
-            //
-            m_SCECallBack(m_SCEContext);
-        }
     }
     return STATUS_SUCCESS;
 }


Reply via email to