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/hardwa…
==============================================================================
--- 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;