Author: janderwald Date: Sun Jan 29 17:24:41 2012 New Revision: 55291
URL: http://svn.reactos.org/svn/reactos?rev=55291&view=rev Log: [USBEHCI] - Rewrite the init routine of EHCI controller - Implement PORT_POWER
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] Sun Jan 29 17:24:41 2012 @@ -80,6 +80,13 @@
KIRQL AcquireDeviceLock(void); VOID ReleaseDeviceLock(KIRQL OldLevel); + // set command + VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd); + + // get command + VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd); + + // local BOOLEAN InterruptService();
@@ -118,11 +125,6 @@ ULONG m_SyncFramePhysAddr; // periodic frame list physical address BOOLEAN m_ResetInProgress[16]; // set when a reset is in progress
- // set command - VOID SetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd); - - // get command - VOID GetCommandRegister(PEHCI_USBCMD_CONTENT UsbCmd);
// read register ULONG EHCI_READ_REGISTER_ULONG(ULONG Offset); @@ -336,8 +338,13 @@ m_Capabilities.HCSParamsLong = READ_REGISTER_ULONG((PULONG)((ULONG)ResourceBase + 4)); m_Capabilities.HCCParamsLong = READ_REGISTER_ULONG((PULONG)((ULONG)ResourceBase + 8));
+ DPRINT1("Controller has %d Length\n", m_Capabilities.Length); DPRINT1("Controller has %d Ports\n", m_Capabilities.HCSParams.PortCount); DPRINT1("Controller EHCI Version %x\n", m_Capabilities.HCIVersion); + DPRINT1("Controler EHCI Caps HCSParamsLong %x\n", m_Capabilities.HCSParamsLong); + DPRINT1("Controler EHCI Caps HCCParamsLong %x\n", m_Capabilities.HCCParamsLong); + + DPRINT1("Controler EHCI Caps PowerControl %x\n", m_Capabilities.HCSParams.PortPowerControl); if (m_Capabilities.HCSParams.PortRouteRules) { for (Count = 0; Count < m_Capabilities.HCSParams.PortCount; Count++) @@ -518,22 +525,42 @@ ULONG UsbSts, FailSafe;
// + // check caps + // + if (m_Capabilities.HCCParams.CurAddrBits) + { + // + // disable 64-bit addressing + // + EHCI_WRITE_REGISTER_ULONG(EHCI_CTRLDSSEGMENT, 0x0); + } + + +#if 1 + // // Stop the controller if its running // UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); if (!(UsbSts & EHCI_STS_HALT)) + { + DPRINT1("Stopping Controller %x\n", UsbSts); StopController(); + } +#endif
// // 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 - // - EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, AsyncQueueHead->PhysicalAddr); + ULONG Mask = EHCI_USBINTR_INTE | EHCI_USBINTR_ERR | EHCI_USBINTR_ASYNC | EHCI_USBINTR_HSERR | EHCI_USBINTR_PC; + EHCI_WRITE_REGISTER_ULONG(EHCI_USBINTR, Mask); + + KeStallExecutionProcessor(10); + + ULONG Status = EHCI_READ_REGISTER_ULONG(EHCI_USBINTR); + + DPRINT1("Interrupt Mask %x\n", Status); + ASSERT((Status & Mask) == Mask); +
// // Assign the SyncList Register @@ -543,13 +570,12 @@ // // Set Schedules to Enable and Interrupt Threshold to 1ms. // - GetCommandRegister(&UsbCmd); + RtlZeroMemory(&UsbCmd, sizeof(EHCI_USBCMD_CONTENT)); + UsbCmd.PeriodicEnable = TRUE; - UsbCmd.IntThreshold = 1; - SetCommandRegister(&UsbCmd); - - GetCommandRegister(&UsbCmd); + UsbCmd.IntThreshold = 0x8; //1ms UsbCmd.Run = TRUE; + UsbCmd.FrameListSize = 0x0; //1024 SetCommandRegister(&UsbCmd);
// @@ -566,6 +592,7 @@ } }
+ if (UsbSts & EHCI_STS_HALT) { DPRINT1("Could not start execution on the controller\n"); @@ -573,17 +600,62 @@ }
// + // Assign the AsyncList Register + // + EHCI_WRITE_REGISTER_ULONG(EHCI_ASYNCLISTBASE, AsyncQueueHead->PhysicalAddr); + + // + // get command register + // + GetCommandRegister(&UsbCmd); + + // + // preserve bits + // + UsbCmd.AsyncEnable = TRUE; + + // + // enable async + // + SetCommandRegister(&UsbCmd); + + // + // Wait for execution to start + // + for (FailSafe = 100; FailSafe > 1; FailSafe--) + { + KeStallExecutionProcessor(10); + UsbSts = EHCI_READ_REGISTER_ULONG(EHCI_USBSTS); + + if ((UsbSts & EHCI_STS_ASS)) + { + break; + } + } + + if (!(UsbSts & EHCI_STS_ASS)) + { + DPRINT1("Failed to enable async schedule UsbSts %x\n", UsbSts); + ASSERT(FALSE); + return STATUS_UNSUCCESSFUL; + } + + DPRINT1("UsbSts %x\n", UsbSts); + GetCommandRegister(&UsbCmd); + + DPRINT1("UsbCmd.PeriodicEnable %x\n", UsbCmd.PeriodicEnable); + DPRINT1("UsbCmd.AsyncEnable %x\n", UsbCmd.AsyncEnable); + DPRINT1("UsbCmd.IntThreshold %x\n", UsbCmd.IntThreshold); + DPRINT1("UsbCmd.Run %x\n", UsbCmd.Run); + DPRINT1("UsbCmd.FrameListSize %x\n", UsbCmd.FrameListSize); + + // // 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; @@ -854,8 +926,16 @@ }
if (Feature == PORT_POWER) - DPRINT1("PORT_POWER Not implemented\n"); - + { + if (m_Capabilities.HCSParams.PortPowerControl) + { + // + // enable port power + // + ULONG Value = EHCI_READ_REGISTER_ULONG(EHCI_PORTSC + (4 * PortId)) | EHCI_PRT_POWER; + EHCI_WRITE_REGISTER_ULONG(EHCI_PORTSC, Value); + } + } return STATUS_SUCCESS; }
@@ -982,6 +1062,7 @@ This = (CUSBHardwareDevice*) SystemArgument1; CStatus = (ULONG) SystemArgument2;
+ DPRINT1("CStatus %x\n", CStatus);
// // check for completion of async schedule