mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[USBEHCI]
- Fix initialization bugs for EHCI controllers - Try again to release ownership of low-speed devices after reset - Wait for the port reset to complete svn path=/branches/usb-bringup-trunk/; revision=55232
This commit is contained in:
parent
9b540bf8a8
commit
6f54b01f29
1 changed files with 50 additions and 72 deletions
|
@ -525,39 +525,10 @@ CUSBHardwareDevice::StartController(void)
|
||||||
StopController();
|
StopController();
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reset the device. Bit is set to 0 on completion.
|
// Enable Interrupts and start execution
|
||||||
//
|
//
|
||||||
GetCommandRegister(&UsbCmd);
|
EHCI_WRITE_REGISTER_ULONG(EHCI_USBINTR, EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
|
||||||
UsbCmd.HCReset = TRUE;
|
/*| EHCI_USBINTR_FLROVR*/ | EHCI_USBINTR_PC);
|
||||||
SetCommandRegister(&UsbCmd);
|
|
||||||
|
|
||||||
//
|
|
||||||
// Check that the controller reset
|
|
||||||
//
|
|
||||||
for (FailSafe = 100; FailSafe > 1; FailSafe--)
|
|
||||||
{
|
|
||||||
KeStallExecutionProcessor(10);
|
|
||||||
GetCommandRegister(&UsbCmd);
|
|
||||||
if (!UsbCmd.HCReset)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the controller did not reset then fail
|
|
||||||
//
|
|
||||||
if (UsbCmd.HCReset)
|
|
||||||
{
|
|
||||||
DPRINT1("EHCI ERROR: Controller failed to reset. Hardware problem!\n");
|
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Disable Interrupts and clear status
|
|
||||||
//
|
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_USBINTR, 0);
|
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_USBSTS, 0x0000001f);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Assign the AsyncList Register
|
// Assign the AsyncList Register
|
||||||
|
@ -574,18 +545,10 @@ CUSBHardwareDevice::StartController(void)
|
||||||
//
|
//
|
||||||
GetCommandRegister(&UsbCmd);
|
GetCommandRegister(&UsbCmd);
|
||||||
UsbCmd.PeriodicEnable = TRUE;
|
UsbCmd.PeriodicEnable = TRUE;
|
||||||
UsbCmd.AsyncEnable = TRUE; //FIXME: Need USB Memory Manager
|
|
||||||
|
|
||||||
UsbCmd.IntThreshold = 1;
|
UsbCmd.IntThreshold = 1;
|
||||||
// FIXME: Set framelistsize when periodic is implemented.
|
|
||||||
SetCommandRegister(&UsbCmd);
|
SetCommandRegister(&UsbCmd);
|
||||||
|
|
||||||
//
|
GetCommandRegister(&UsbCmd);
|
||||||
// Enable Interrupts and start execution
|
|
||||||
//
|
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_USBINTR, EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR
|
|
||||||
/*| EHCI_USBINTR_FLROVR*/ | EHCI_USBINTR_PC);
|
|
||||||
|
|
||||||
UsbCmd.Run = TRUE;
|
UsbCmd.Run = TRUE;
|
||||||
SetCommandRegister(&UsbCmd);
|
SetCommandRegister(&UsbCmd);
|
||||||
|
|
||||||
|
@ -614,6 +577,14 @@ CUSBHardwareDevice::StartController(void)
|
||||||
//
|
//
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_CONFIGFLAG, 1);
|
EHCI_WRITE_REGISTER_ULONG(EHCI_CONFIGFLAG, 1);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enable async
|
||||||
|
//
|
||||||
|
GetCommandRegister(&UsbCmd);
|
||||||
|
UsbCmd.AsyncEnable = TRUE; //FIXME: Need USB Memory Manager
|
||||||
|
// FIXME: Set framelistsize when periodic is implemented.
|
||||||
|
SetCommandRegister(&UsbCmd);
|
||||||
|
|
||||||
DPRINT1("EHCI Started!\n");
|
DPRINT1("EHCI Started!\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -669,6 +640,9 @@ CUSBHardwareDevice::ResetPort(
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
|
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
|
||||||
|
//
|
||||||
|
// check slow speed line before reset
|
||||||
|
//
|
||||||
if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
|
if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
|
||||||
{
|
{
|
||||||
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
|
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
|
||||||
|
@ -676,6 +650,8 @@ CUSBHardwareDevice::ResetPort(
|
||||||
return STATUS_DEVICE_NOT_CONNECTED;
|
return STATUS_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ASSERT(PortStatus & EHCI_PRT_CONNECTED);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reset and clean enable
|
// Reset and clean enable
|
||||||
//
|
//
|
||||||
|
@ -692,18 +668,36 @@ CUSBHardwareDevice::ResetPort(
|
||||||
PortStatus &= ~EHCI_PRT_RESET;
|
PortStatus &= ~EHCI_PRT_RESET;
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
|
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
|
||||||
|
|
||||||
KeStallExecutionProcessor(100);
|
do
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// wait
|
||||||
|
//
|
||||||
|
KeStallExecutionProcessor(100);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check that the port reset
|
||||||
|
//
|
||||||
|
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
|
||||||
|
if (!(PortStatus & EHCI_PRT_RESET))
|
||||||
|
break;
|
||||||
|
} while (TRUE);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Check that the port reset
|
// check slow speed line after reset
|
||||||
//
|
//
|
||||||
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
|
if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
|
||||||
if (PortStatus & EHCI_PRT_RESET)
|
|
||||||
{
|
{
|
||||||
DPRINT1("Port did not reset\n");
|
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
|
||||||
return STATUS_RETRY;
|
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), EHCI_PRT_RELEASEOWNERSHIP);
|
||||||
|
return STATUS_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// this must be enabled now
|
||||||
|
//
|
||||||
|
ASSERT(PortStatus & EHCI_PRT_ENABLED);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -739,16 +733,18 @@ CUSBHardwareDevice::GetPortStatus(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get Speed. If SlowSpeedLine flag is there then its a slow speed device
|
|
||||||
if (Value & EHCI_PRT_SLOWSPEEDLINE)
|
|
||||||
Status |= USB_PORT_STATUS_LOW_SPEED;
|
|
||||||
else
|
|
||||||
Status |= USB_PORT_STATUS_HIGH_SPEED;
|
|
||||||
|
|
||||||
// Get Connected Status
|
// Get Connected Status
|
||||||
if (Value & EHCI_PRT_CONNECTED)
|
if (Value & EHCI_PRT_CONNECTED)
|
||||||
|
{
|
||||||
Status |= USB_PORT_STATUS_CONNECT;
|
Status |= USB_PORT_STATUS_CONNECT;
|
||||||
|
|
||||||
|
// Get Speed. If SlowSpeedLine flag is there then its a slow speed device
|
||||||
|
if (Value & EHCI_PRT_SLOWSPEEDLINE)
|
||||||
|
Status |= USB_PORT_STATUS_LOW_SPEED;
|
||||||
|
else
|
||||||
|
Status |= USB_PORT_STATUS_HIGH_SPEED;
|
||||||
|
}
|
||||||
|
|
||||||
// Get Enabled Status
|
// Get Enabled Status
|
||||||
if (Value & EHCI_PRT_ENABLED)
|
if (Value & EHCI_PRT_ENABLED)
|
||||||
Status |= USB_PORT_STATUS_ENABLE;
|
Status |= USB_PORT_STATUS_ENABLE;
|
||||||
|
@ -795,30 +791,17 @@ CUSBHardwareDevice::ClearPortStatus(
|
||||||
if (PortId > m_Capabilities.HCSParams.PortCount)
|
if (PortId > m_Capabilities.HCSParams.PortCount)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
|
|
||||||
|
|
||||||
if (Status == C_PORT_RESET)
|
if (Status == C_PORT_RESET)
|
||||||
{
|
{
|
||||||
if (Value & EHCI_PRT_RESET)
|
|
||||||
{
|
|
||||||
Value &= ~EHCI_PRT_RESET;
|
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
|
|
||||||
KeStallExecutionProcessor(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
|
|
||||||
//
|
//
|
||||||
// update port status
|
// update port status
|
||||||
//
|
//
|
||||||
m_ResetInProgress[PortId] = FALSE;
|
m_ResetInProgress[PortId] = FALSE;
|
||||||
if (!(Value & EHCI_PRT_ENABLED))
|
|
||||||
{
|
|
||||||
DPRINT1("Port is not enabled.\n");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Status == C_PORT_CONNECTION)
|
if (Status == C_PORT_CONNECTION)
|
||||||
{
|
{
|
||||||
|
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
|
||||||
Value |= EHCI_PRT_CONNECTSTATUSCHANGE | EHCI_PRT_ENABLEDSTATUSCHANGE;
|
Value |= EHCI_PRT_CONNECTSTATUSCHANGE | EHCI_PRT_ENABLEDSTATUSCHANGE;
|
||||||
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
|
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
|
||||||
}
|
}
|
||||||
|
@ -851,11 +834,6 @@ CUSBHardwareDevice::SetPortFeature(
|
||||||
|
|
||||||
if (Feature == PORT_RESET)
|
if (Feature == PORT_RESET)
|
||||||
{
|
{
|
||||||
if (Value & EHCI_PRT_SLOWSPEEDLINE)
|
|
||||||
{
|
|
||||||
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetPort(PortId);
|
ResetPort(PortId);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in a new issue