Author: cgutman
Date: Fri Jan 27 06:27:12 2012
New Revision: 55232
URL:
http://svn.reactos.org/svn/reactos?rev=55232&view=rev
Log:
[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
Modified:
branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp
Modified: branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/u…
==============================================================================
--- branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1]
(original)
+++ branches/usb-bringup-trunk/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] Fri Jan
27 06:27:12 2012
@@ -525,39 +525,10 @@
StopController();
//
- // Reset the device. Bit is set to 0 on completion.
- //
- GetCommandRegister(&UsbCmd);
- UsbCmd.HCReset = TRUE;
- 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);
+ // 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);
//
// Assign the AsyncList Register
@@ -574,18 +545,10 @@
//
GetCommandRegister(&UsbCmd);
UsbCmd.PeriodicEnable = TRUE;
- UsbCmd.AsyncEnable = TRUE; //FIXME: Need USB Memory Manager
-
UsbCmd.IntThreshold = 1;
- // FIXME: Set framelistsize when periodic is implemented.
SetCommandRegister(&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);
-
+ GetCommandRegister(&UsbCmd);
UsbCmd.Run = TRUE;
SetCommandRegister(&UsbCmd);
@@ -613,6 +576,14 @@
// Set port routing to EHCI controller
//
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");
return STATUS_SUCCESS;
@@ -669,6 +640,9 @@
return STATUS_UNSUCCESSFUL;
PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
+ //
+ // check slow speed line before reset
+ //
if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
{
DPRINT1("Non HighSpeed device. Releasing Ownership\n");
@@ -676,6 +650,8 @@
return STATUS_DEVICE_NOT_CONNECTED;
}
+ ASSERT(PortStatus & EHCI_PRT_CONNECTED);
+
//
// Reset and clean enable
//
@@ -692,17 +668,35 @@
PortStatus &= ~EHCI_PRT_RESET;
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex), PortStatus);
- KeStallExecutionProcessor(100);
-
- //
- // Check that the port reset
- //
- PortStatus = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortIndex));
- if (PortStatus & EHCI_PRT_RESET)
- {
- DPRINT1("Port did not reset\n");
- return STATUS_RETRY;
- }
+ 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 slow speed line after reset
+ //
+ if (PortStatus & EHCI_PRT_SLOWSPEEDLINE)
+ {
+ DPRINT1("Non HighSpeed device. Releasing Ownership\n");
+ 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;
}
@@ -739,15 +733,17 @@
}
}
- // 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
if (Value & EHCI_PRT_CONNECTED)
+ {
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
if (Value & EHCI_PRT_ENABLED)
@@ -795,30 +791,17 @@
if (PortId > m_Capabilities.HCSParams.PortCount)
return STATUS_UNSUCCESSFUL;
- Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
-
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);
- }
-
+ //
+ // update port status
+ //
+ m_ResetInProgress[PortId] = FALSE;
+ }
+
+ if (Status == C_PORT_CONNECTION)
+ {
Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId));
- //
- // update port status
- //
- m_ResetInProgress[PortId] = FALSE;
- if (!(Value & EHCI_PRT_ENABLED))
- {
- DPRINT1("Port is not enabled.\n");
- }
- }
-
- if (Status == C_PORT_CONNECTION)
- {
Value |= EHCI_PRT_CONNECTSTATUSCHANGE | EHCI_PRT_ENABLEDSTATUSCHANGE;
EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId), Value);
}
@@ -851,11 +834,6 @@
if (Feature == PORT_RESET)
{
- if (Value & EHCI_PRT_SLOWSPEEDLINE)
- {
- DPRINT1("Non HighSpeed device. Releasing Ownership\n");
- }
-
ResetPort(PortId);
//