mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
[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 svn path=/trunk/; revision=55662
This commit is contained in:
parent
c1c3ea3ac8
commit
075cf8cdc9
2 changed files with 43 additions and 57 deletions
|
@ -977,20 +977,9 @@ CUSBHardwareDevice::ResetPort(
|
|||
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
|
||||
|
||||
//
|
||||
// delay is 20 ms for port reset as per USB 2.0 spec
|
||||
// Wait for reset to start
|
||||
//
|
||||
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);
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
//
|
||||
// Clear reset
|
||||
|
@ -1042,13 +1031,24 @@ CUSBHardwareDevice::ResetPort(
|
|||
}
|
||||
|
||||
//
|
||||
// this must be enabled now
|
||||
// this will be enabled now since we're high-speed
|
||||
//
|
||||
if (PortStatus & EHCI_PRT_ENABLED)
|
||||
do
|
||||
{
|
||||
DPRINT1("Port is not enabled after reset\n");
|
||||
//ASSERT(FALSE);
|
||||
}
|
||||
//
|
||||
// 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 @@ CUSBHardwareDevice::ClearPortStatus(
|
|||
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,17 +1158,10 @@ CUSBHardwareDevice::ClearPortStatus(
|
|||
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
|
||||
//
|
||||
|
|
|
@ -1193,7 +1193,6 @@ CUSBHardwareDevice::ClearPortStatus(
|
|||
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 @@ CUSBHardwareDevice::ClearPortStatus(
|
|||
//
|
||||
// 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 @@ CUSBHardwareDevice::ClearPortStatus(
|
|||
//
|
||||
// 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 @@ CUSBHardwareDevice::SetPortFeature(
|
|||
}
|
||||
else if (Feature == PORT_RESET)
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
//
|
||||
// assert
|
||||
//
|
||||
|
@ -1343,7 +1341,8 @@ CUSBHardwareDevice::SetPortFeature(
|
|||
//
|
||||
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 @@ 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);
|
||||
|
||||
//
|
||||
// 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 @@ InterruptServiceRoutine(
|
|||
//
|
||||
// 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 @@ OhciDefferedRoutine(
|
|||
//
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue