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/hardwar... ============================================================================== --- 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/hardwar... ============================================================================== --- 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; + } }
//