Author: cgutman
Date: Fri Feb 17 03:45:46 2012
New Revision: 55662
URL:
http://svn.reactos.org/svn/reactos?rev=55662&view=rev
Log:
[USBOHCI]
- Remove massive hacks from our port reset code
- We now wait for the reset complete interrupt instead of stalling 10ms and continuing
- Don't wait for a port to stabilize unless there's actually a device connected
[USBEHCI]
- Fix very long delay between setting the reset bit and clearing it
- Wait for the port to come back enabled before finishing the reset
- Don't wait for a port to stabilize unless there's actually a device connected
Modified:
trunk/reactos/drivers/usb/usbehci/hardware.cpp
trunk/reactos/drivers/usb/usbohci/hardware.cpp
Modified: trunk/reactos/drivers/usb/usbehci/hardware.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbehci/hardwa…
==============================================================================
--- trunk/reactos/drivers/usb/usbehci/hardware.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbehci/hardware.cpp [iso-8859-1] Fri Feb 17 03:45:46 2012
@@ -977,20 +977,9 @@
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
//
- // delay is 20 ms for port reset as per USB 2.0 spec
- //
- 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);
+ // Wait for reset to start
+ //
+ KeStallExecutionProcessor(100);
//
// Clear reset
@@ -1042,13 +1031,24 @@
}
//
- // this must be enabled now
- //
- if (PortStatus & EHCI_PRT_ENABLED)
- {
- DPRINT1("Port is not enabled after reset\n");
- //ASSERT(FALSE);
- }
+ // this will be enabled now since we're high-speed
+ //
+ do
+ {
+ //
+ // wait
+ //
+ KeStallExecutionProcessor(100);
+
+ //
+ // Check that the port is enabled
+ //
+ PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
+ if (PortStatus & EHCI_PRT_ENABLED)
+ break;
+ } while (TRUE);
+
+ DPRINT1("Port is back up after reset\n");
return STATUS_SUCCESS;
}
@@ -1143,6 +1143,13 @@
if (PortId > m_Capabilities.HCSParams.PortCount)
return STATUS_UNSUCCESSFUL;
+ //
+ // 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);
+
if (Status == C_PORT_RESET)
{
//
@@ -1151,16 +1158,9 @@
m_ResetInProgress[PortId] = FALSE;
}
- if (Status == C_PORT_CONNECTION)
+ if (Status == C_PORT_CONNECTION && (Value & EHCI_PRT_CONNECTED))
{
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
Modified: trunk/reactos/drivers/usb/usbohci/hardware.cpp
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbohci/hardwa…
==============================================================================
--- trunk/reactos/drivers/usb/usbohci/hardware.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbohci/hardware.cpp [iso-8859-1] Fri Feb 17 03:45:46 2012
@@ -1193,7 +1193,6 @@
return STATUS_UNSUCCESSFUL;
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)));
- KeStallExecutionProcessor(100);
if (Status == C_PORT_RESET)
{
@@ -1223,7 +1222,7 @@
//
// wait for port to stabilize
//
- if (Status == C_PORT_CONNECTION)
+ if (Status == C_PORT_CONNECTION && (Value & OHCI_RH_PORTSTATUS_CCS))
{
LARGE_INTEGER Timeout;
@@ -1248,6 +1247,7 @@
//
// re-enable root hub change
//
+ DPRINT1("Enabling status change\n");
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET),
OHCI_ROOT_HUB_STATUS_CHANGE);
return STATUS_SUCCESS;
@@ -1324,8 +1324,6 @@
}
else if (Feature == PORT_RESET)
{
- LARGE_INTEGER Timeout;
-
//
// assert
//
@@ -1343,7 +1341,8 @@
//
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base +
OHCI_RH_PORT_STATUS(PortId)));
- if ((Value & OHCI_RH_PORTSTATUS_PRS) == 0)
+ if ((Value & OHCI_RH_PORTSTATUS_PRS) == 0 &&
+ (Value & OHCI_RH_PORTSTATUS_PRSC) != 0)
{
//
// reset is complete
@@ -1357,32 +1356,6 @@
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);
-
- //
- // is there a status change callback
- //
- if (m_SCECallBack != NULL)
- {
- //
- // issue callback
- //
- m_SCECallBack(m_SCEContext);
- }
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
@@ -1552,6 +1525,7 @@
//
// disable interrupt as it will fire untill the port has been reset
//
+ DPRINT1("Disabling status change interrupt\n");
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base +
OHCI_INTERRUPT_DISABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
Acknowledge |= OHCI_ROOT_HUB_STATUS_CHANGE;
}
@@ -1653,6 +1627,18 @@
//
QueueSCEWorkItem = TRUE;
}
+ else if (PortStatus & OHCI_RH_PORTSTATUS_PRSC)
+ {
+ //
+ // This is a port reset complete interrupt
+ //
+ DPRINT1("Port %d completed reset\n", Index);
+
+ //
+ // Queue a work item
+ //
+ QueueSCEWorkItem = TRUE;
+ }
}
//