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/us... ============================================================================== --- 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);
//