Author: cgutman Date: Thu Feb 23 05:27:24 2012 New Revision: 55832
URL: http://svn.reactos.org/svn/reactos?rev=55832&view=rev Log: [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
Modified: trunk/reactos/drivers/usb/usbuhci/hardware.cpp
Modified: trunk/reactos/drivers/usb/usbuhci/hardware.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hardwar... ============================================================================== --- trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] (original) +++ trunk/reactos/drivers/usb/usbuhci/hardware.cpp [iso-8859-1] Thu Feb 23 05:27:24 2012 @@ -499,7 +499,7 @@ // 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 @@ VOID CUSBHardwareDevice::GlobalReset() { + LARGE_INTEGER Timeout; + // // back up start of modify register // @@ -586,10 +588,25 @@ // 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 @@ // // wait a bit // - KeStallExecutionProcessor(10); + KeStallExecutionProcessor(100);
// // get status @@ -893,7 +910,7 @@ // 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 @@ ULONG Port; USHORT Status; ULONG Index; + LARGE_INTEGER Timeout;
DPRINT1("[UHCI] ResetPort Id %lu\n", PortIndex);
@@ -937,32 +955,43 @@ WriteRegister16(Port, Status | UHCI_PORTSC_RESET);
// + // delay is 20 ms for port reset + // + 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 + // + Status = ReadRegister16(Port); + + // + // remove unwanted bits + // + Status &= UHCI_PORTSC_DATAMASK; + + // + // clear reset port + // + WriteRegister16(Port, (Status & ~UHCI_PORTSC_RESET)); + + + // // now wait a bit // - KeStallExecutionProcessor(250); - - // - // re-read status - // - Status = ReadRegister16(Port); - - // - // remove unwanted bits - // - Status &= UHCI_PORTSC_DATAMASK; - - // - // clear reset port - // - WriteRegister16(Port, (Status & ~UHCI_PORTSC_RESET)); - - - // - // now wait a bit - // KeStallExecutionProcessor(10);
- for (Index = 0; Index < 10; Index++) + for (Index = 0; Index < 100; Index++) { // read port status Status = ReadRegister16(Port); @@ -994,8 +1023,7 @@ { // 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 @@ 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 @@ // 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 @@ // m_PortResetChange &= ~(1 << PortId); } - else if (Feature == C_PORT_CONNECTION) - { - // - // clear connection status - // - WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_STATCHA); - } - else if (Feature == C_PORT_ENABLE) - { - // - // enable port - // - WriteRegister16(PortRegister, PortStatus | UHCI_PORTSC_ENABCHA); + else if (Feature == C_PORT_CONNECTION || Feature == C_PORT_ENABLE) + { + // + // clear port status changes + // + WriteRegister16(PortRegister, PortStatus); }
return STATUS_SUCCESS;