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 //