if (Status == C_PORT_RESET)
{
- do
- {
- //
- // read port status
- //
- Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)));
-
- if ((Value & OHCI_RH_PORTSTATUS_PRS) == 0)
- {
- //
- // reset is complete
- //
- break;
- }
-
- //
- // wait a bit
- //
- KeStallExecutionProcessor(100);
-
- //DPRINT1("Value %x Index %lu\n", Value, Index);
-
- }while(TRUE);
-
- //
- // check if reset bit is still set
- //
- if (Value & OHCI_RH_PORTSTATUS_PRS)
- {
- //
- // reset failed
- //
- DPRINT1("PortId %lu Reset failed\n", PortId);
- return STATUS_UNSUCCESSFUL;
- }
-
//
// sanity checks
//
if (Status == C_PORT_CONNECTION || Status == C_PORT_ENABLE)
{
//
- // clear bits
+ // clear change bits
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_CSC | OHCI_RH_PORTSTATUS_PESC);
+
+ //
+ // wait for port to stabilize
+ //
+ if (Status == C_PORT_CONNECTION)
+ {
+ LARGE_INTEGER Timeout;
+
+ //
+ // delay is 100 ms
+ //
+ Timeout.QuadPart = 100;
+ DPRINT1("Waiting %d milliseconds for port to stabilize after connection\n", Timeout.LowPart);
+
+ //
+ // convert to 100 ns units (absolute)
+ //
+ Timeout.QuadPart *= -10000;
+
+ //
+ // perform the wait
+ //
+ KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+ }
}
//
}
else if (Feature == PORT_RESET)
{
+ LARGE_INTEGER Timeout;
+
//
// assert
//
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRS);
+ do
+ {
+ //
+ // read port status
+ //
+ Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)));
+
+ if ((Value & OHCI_RH_PORTSTATUS_PRS) == 0)
+ {
+ //
+ // reset is complete
+ //
+ break;
+ }
+
+ //
+ // wait a bit
+ //
+ KeStallExecutionProcessor(100);
+ }while(TRUE);
+
//
- // wait
+ // delay is 10 ms
//
- KeStallExecutionProcessor(100);
+ Timeout.QuadPart = 10;
+ DPRINT1("Waiting %d milliseconds for port to recover after reset\n", Timeout.LowPart);
+
+ //
+ // convert to 100 ns units (absolute)
+ //
+ Timeout.QuadPart *= -10000;
+
+ //
+ // perform the wait
+ //
+ KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
//
// is there a status change callback
//
m_SCECallBack(m_SCEContext);
}
+ return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
}
// the interrupt was not caused by DoneHead update
// check if something important happened
//
+ DPRINT1("InterruptStatus %x InterruptEnable %x\n", READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)),
+ READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_ENABLE_OFFSET)));
Status = READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_STATUS_OFFSET)) & READ_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_INTERRUPT_ENABLE_OFFSET)) & (~OHCI_WRITEBACK_DONE_HEAD);
if (Status == 0)
{