From 5ab8673f32d2f8a0a676b9bebe0e9a61decc04c7 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Wed, 1 Feb 2012 12:16:47 +0000 Subject: [PATCH] [USBEHCI][USBOHCI] - Wait 100 milliseconds for the port power and insertion to stabilize - Wait for the 10 millisecond "recovery" period after reset svn path=/branches/usb-bringup-trunk/; revision=55367 --- drivers/usb/usbehci_new/hardware.cpp | 38 ++++++++++++++++++++++++ drivers/usb/usbohci/hardware.cpp | 44 +++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 1 deletion(-) diff --git a/drivers/usb/usbehci_new/hardware.cpp b/drivers/usb/usbehci_new/hardware.cpp index d4d837a03ff..cdc2bb91790 100644 --- a/drivers/usb/usbehci_new/hardware.cpp +++ b/drivers/usb/usbehci_new/hardware.cpp @@ -798,9 +798,26 @@ CUSBHardwareDevice::ResetPort( 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) + // + Timeout.QuadPart *= -10000; + + // + // 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"); @@ -916,9 +933,30 @@ CUSBHardwareDevice::ClearPortStatus( if (Status == C_PORT_CONNECTION) { + 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 + // + 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; diff --git a/drivers/usb/usbohci/hardware.cpp b/drivers/usb/usbohci/hardware.cpp index efc3bf1b2fa..8e4b9c00e2e 100644 --- a/drivers/usb/usbohci/hardware.cpp +++ b/drivers/usb/usbohci/hardware.cpp @@ -1191,9 +1191,33 @@ CUSBHardwareDevice::ClearPortStatus( if (Status == C_PORT_CONNECTION || Status == C_PORT_ENABLE) { // - // clear bits + // clear change bits // WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_CSC | OHCI_RH_PORTSTATUS_PESC); + + // + // wait for port to stabilize + // + if (Status == C_PORT_CONNECTION) + { + LARGE_INTEGER Timeout; + + // + // 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); + } } // @@ -1275,6 +1299,8 @@ CUSBHardwareDevice::SetPortFeature( } else if (Feature == PORT_RESET) { + LARGE_INTEGER Timeout; + // // assert // @@ -1306,6 +1332,22 @@ CUSBHardwareDevice::SetPortFeature( 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); + // // trigger the status change interrupt //