Author: cgutman
Date: Sun Feb 19 22:22:45 2012
New Revision: 55725
URL:
http://svn.reactos.org/svn/reactos?rev=55725&view=rev
Log:
[USBEHCI]
- Try to fix reset bugs in my code and remove hacks
- Don't clear extra bits when acknowledging a port connect status change
[USBOHCI]
- Code cleanup
- No functional change
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] Sun Feb 19 22:22:45 2012
@@ -124,7 +124,6 @@
BOOLEAN m_DoorBellRingInProgress; //
door bell ring in progress
WORK_QUEUE_ITEM m_StatusChangeWorkItem; //
work item for status change callback
ULONG m_SyncFramePhysAddr; //
periodic frame list physical address
- BOOLEAN m_ResetInProgress[16]; //
set when a reset is in progress
BUS_INTERFACE_STANDARD m_BusInterface; //
pci bus interface
// read register
@@ -957,6 +956,7 @@
return STATUS_UNSUCCESSFUL;
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
+
//
// check slow speed line before reset
//
@@ -977,37 +977,10 @@
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
//
- // Wait for reset to start
- //
- KeStallExecutionProcessor(100);
-
- //
- // Clear reset
- //
- PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
- PortStatus &= ~EHCI_PRT_RESET;
- EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
-
- do
- {
- //
- // wait
- //
- KeStallExecutionProcessor(100);
-
- //
- // Check that the port reset
- //
- PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
- if (!(PortStatus & EHCI_PRT_RESET))
- break;
- } while (TRUE);
-
- //
- // delay is 10 ms
- //
- Timeout.QuadPart = 10;
- DPRINT1("Waiting %d milliseconds for port to recover after reset\n",
Timeout.LowPart);
+ // 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)
@@ -1018,37 +991,6 @@
// 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");
- EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex),
EHCI_PRT_RELEASEOWNERSHIP);
- return STATUS_DEVICE_NOT_CONNECTED;
- }
-
- //
- // 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;
}
@@ -1110,18 +1052,17 @@
Status |= USB_PORT_STATUS_OVER_CURRENT;
// In a reset state?
- if ((Value & EHCI_PRT_RESET) || m_ResetInProgress[PortId])
+ if (Value & EHCI_PRT_RESET)
{
Status |= USB_PORT_STATUS_RESET;
Change |= USB_PORT_STATUS_RESET;
}
- //
- // FIXME: Is the Change here correct?
- //
+ // This indicates a connect or disconnect
if (Value & EHCI_PRT_CONNECTSTATUSCHANGE)
Change |= USB_PORT_STATUS_CONNECT;
+ // This is set to indicate a critical port error
if (Value & EHCI_PRT_ENABLEDSTATUSCHANGE)
Change |= USB_PORT_STATUS_ENABLE;
@@ -1137,36 +1078,42 @@
ULONG Status)
{
ULONG Value;
+ LARGE_INTEGER Timeout;
DPRINT("CUSBHardwareDevice::ClearPortStatus PortId %x Feature %x\n",
PortId, Status);
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)
{
//
- // update port status
- //
- m_ResetInProgress[PortId] = FALSE;
- }
-
- if (Status == C_PORT_CONNECTION && (Value & EHCI_PRT_CONNECTED))
- {
- LARGE_INTEGER Timeout;
-
- //
- // delay is 100 ms
- //
- Timeout.QuadPart = 100;
- DPRINT1("Waiting %d milliseconds for port to stabilize after
connection\n", Timeout.LowPart);
+ // Clear reset
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ Value &= ~EHCI_PRT_RESET;
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+
+ do
+ {
+ //
+ // wait
+ //
+ KeStallExecutionProcessor(100);
+
+ //
+ // Check that the port reset
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ if (!(Value & EHCI_PRT_RESET))
+ 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)
@@ -1177,6 +1124,64 @@
// perform the wait
//
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+
+ //
+ // check slow speed line after reset
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ if (Value & EHCI_PRT_SLOWSPEEDLINE)
+ {
+ DPRINT1("Non HighSpeed device. Releasing Ownership\n");
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId),
EHCI_PRT_RELEASEOWNERSHIP);
+ return STATUS_DEVICE_NOT_CONNECTED;
+ }
+
+ //
+ // this will be enabled now since we're high-speed
+ //
+ do
+ {
+ //
+ // wait
+ //
+ KeStallExecutionProcessor(100);
+
+ //
+ // Check that the port is enabled
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ if (Value & EHCI_PRT_ENABLED)
+ break;
+ } while (TRUE);
+
+ DPRINT1("Port is back up after reset\n");
+ }
+ else if (Status == C_PORT_CONNECTION)
+ {
+ //
+ // reset status change bits
+ //
+ Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
+ EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
+
+ if (Value & EHCI_PRT_CONNECTED)
+ {
+ //
+ // 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;
@@ -1207,12 +1212,10 @@
if (Feature == PORT_RESET)
{
+ //
+ // call the helper
+ //
ResetPort(PortId);
-
- //
- // update cached settings
- //
- m_ResetInProgress[PortId] = TRUE;
//
// is there a status change callback
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] Sun Feb 19 22:22:45 2012
@@ -1138,7 +1138,13 @@
// connected
if (Value & OHCI_RH_PORTSTATUS_CCS)
+ {
*PortStatus |= USB_PORT_STATUS_CONNECT;
+
+ // low speed device
+ if (Value & OHCI_RH_PORTSTATUS_LSDA)
+ *PortStatus |= USB_PORT_STATUS_LOW_SPEED;
+ }
// did a device connect?
if (Value & OHCI_RH_PORTSTATUS_CSC)
@@ -1170,10 +1176,6 @@
// port reset ended (change bit only set at completion)
if (Value & OHCI_RH_PORTSTATUS_PRSC)
*PortChange |= USB_PORT_STATUS_RESET;
-
- // low speed device
- if (Value & OHCI_RH_PORTSTATUS_LSDA)
- *PortStatus |= USB_PORT_STATUS_LOW_SPEED;
return STATUS_SUCCESS;
}
@@ -1352,7 +1354,7 @@
// wait a bit
//
KeStallExecutionProcessor(100);
- }while(TRUE);
+ } while(TRUE);
if (m_SCECallBack != NULL)
{