mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-09-02 04:13:34 +00:00
[USBUHCI]
- Delay for the correct amount of time when performing a global reset and a port reset - Loosen the loop timings a bit to allow for more time for real hardware to complete start/stop/reset - Clear only the change bits that were set and handle both bits in the either case - Perform a synchronous callback when the reset completes svn path=/trunk/; revision=55832
This commit is contained in:
@@ -499,7 +499,7 @@ CUSBHardwareDevice::StartController(void)
|
||||
//
|
||||
WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) | UHCI_USBCMD_RS);
|
||||
|
||||
for(Index = 0; Index < 10; Index++)
|
||||
for(Index = 0; Index < 100; Index++)
|
||||
{
|
||||
//
|
||||
// wait a bit
|
||||
@@ -576,6 +576,8 @@ CUSBHardwareDevice::StartController(void)
|
||||
VOID
|
||||
CUSBHardwareDevice::GlobalReset()
|
||||
{
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
//
|
||||
// back up start of modify register
|
||||
//
|
||||
@@ -586,10 +588,25 @@ CUSBHardwareDevice::GlobalReset()
|
||||
// perform global reset
|
||||
//
|
||||
WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) | UHCI_USBCMD_GRESET);
|
||||
KeStallExecutionProcessor(20);
|
||||
|
||||
//
|
||||
// clear global reset bit
|
||||
// delay is 10 ms
|
||||
//
|
||||
Timeout.QuadPart = 10;
|
||||
DPRINT1("Waiting %d milliseconds for global reset\n", Timeout.LowPart);
|
||||
|
||||
//
|
||||
// convert to 100 ns units (absolute)
|
||||
//
|
||||
Timeout.QuadPart *= -10000;
|
||||
|
||||
//
|
||||
// perform the wait
|
||||
//
|
||||
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
|
||||
|
||||
//
|
||||
// clear command register
|
||||
//
|
||||
WriteRegister16(UHCI_USBCMD, ReadRegister16(UHCI_USBCMD) & ~UHCI_USBCMD_GRESET);
|
||||
KeStallExecutionProcessor(10);
|
||||
@@ -880,7 +897,7 @@ CUSBHardwareDevice::ResetController(void)
|
||||
//
|
||||
// wait a bit
|
||||
//
|
||||
KeStallExecutionProcessor(10);
|
||||
KeStallExecutionProcessor(100);
|
||||
|
||||
//
|
||||
// get status
|
||||
@@ -893,7 +910,7 @@ CUSBHardwareDevice::ResetController(void)
|
||||
//
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}while(Count++ < 5);
|
||||
}while(Count++ < 100);
|
||||
|
||||
DPRINT1("[USBUHCI] Failed to reset controller Status %x\n", Status);
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
@@ -906,6 +923,7 @@ CUSBHardwareDevice::ResetPort(
|
||||
ULONG Port;
|
||||
USHORT Status;
|
||||
ULONG Index;
|
||||
LARGE_INTEGER Timeout;
|
||||
|
||||
DPRINT1("[UHCI] ResetPort Id %lu\n", PortIndex);
|
||||
|
||||
@@ -937,9 +955,20 @@ CUSBHardwareDevice::ResetPort(
|
||||
WriteRegister16(Port, Status | UHCI_PORTSC_RESET);
|
||||
|
||||
//
|
||||
// now wait a bit
|
||||
// delay is 20 ms for port reset
|
||||
//
|
||||
KeStallExecutionProcessor(250);
|
||||
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);
|
||||
|
||||
//
|
||||
// re-read status
|
||||
@@ -962,7 +991,7 @@ CUSBHardwareDevice::ResetPort(
|
||||
//
|
||||
KeStallExecutionProcessor(10);
|
||||
|
||||
for (Index = 0; Index < 10; Index++)
|
||||
for (Index = 0; Index < 100; Index++)
|
||||
{
|
||||
// read port status
|
||||
Status = ReadRegister16(Port);
|
||||
@@ -994,8 +1023,7 @@ CUSBHardwareDevice::ResetPort(
|
||||
{
|
||||
// port enabled changed or connection status were set.
|
||||
// acknowledge either / both and wait again.
|
||||
Status &= UHCI_PORTSC_DATAMASK;
|
||||
WriteRegister16(Port, Status | UHCI_PORTSC_STATCHA | UHCI_PORTSC_ENABCHA);
|
||||
WriteRegister16(Port, Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1009,6 +1037,16 @@ CUSBHardwareDevice::ResetPort(
|
||||
m_PortResetChange |= (1 << PortIndex);
|
||||
DPRINT1("[USBUhci] Port Index %x Status after reset %x\n", PortIndex, ReadRegister16(Port));
|
||||
|
||||
//
|
||||
// is there a callback
|
||||
//
|
||||
if (m_SCECallBack)
|
||||
{
|
||||
//
|
||||
// issue callback
|
||||
//
|
||||
m_SCECallBack(m_SCEContext);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -1114,7 +1152,7 @@ CUSBHardwareDevice::ClearPortStatus(
|
||||
// read current status
|
||||
//
|
||||
PortRegister = UHCI_PORTSC1 + PortId * 2;
|
||||
PortStatus = ReadRegister16(PortRegister) & UHCI_PORTSC_DATAMASK;
|
||||
PortStatus = ReadRegister16(PortRegister);
|
||||
DPRINT("[UHCI] PortStatus %x\n", PortStatus);
|
||||
|
||||
if (Feature == C_PORT_RESET)
|
||||
@@ -1124,19 +1162,12 @@ CUSBHardwareDevice::ClearPortStatus(
|
||||
//
|
||||
m_PortResetChange &= ~(1 << PortId);
|
||||
}
|
||||
else if (Feature == C_PORT_CONNECTION)
|
||||
else if (Feature == C_PORT_CONNECTION || Feature == C_PORT_ENABLE)
|
||||
{
|
||||
//
|
||||
// clear connection status
|
||||
// clear port status changes
|
||||
//
|
||||
WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_STATCHA);
|
||||
}
|
||||
else if (Feature == C_PORT_ENABLE)
|
||||
{
|
||||
//
|
||||
// enable port
|
||||
//
|
||||
WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_ENABCHA);
|
||||
WriteRegister16(PortRegister, PortStatus);
|
||||
}
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
Reference in New Issue
Block a user