[USBOHCI]

- Enable global power mode
- Wait untill reset is complete
- Clear reset complete bit when reset is done
- Enable port
- Reset port now works
- USBOHCI still hangs after adding first control request, needs more investigation

svn path=/branches/usb-bringup/; revision=51883
This commit is contained in:
Johannes Anderwald 2011-05-24 12:51:03 +00:00
parent f75cb3d51d
commit b275073474
3 changed files with 94 additions and 23 deletions

View file

@ -489,7 +489,7 @@ CUSBHardwareDevice::GetUSBQueue(
NTSTATUS
CUSBHardwareDevice::StartController(void)
{
ULONG Control, NumberOfPorts, Index, Descriptor;
ULONG Control, NumberOfPorts, Index, Descriptor, FrameInterval, Periodic, IntervalValue;
//
// first write address of HCCA
@ -541,6 +541,48 @@ CUSBHardwareDevice::StartController(void)
//
ASSERT((Control & OHCI_HC_FUNCTIONAL_STATE_MASK) == OHCI_HC_FUNCTIONAL_STATE_OPERATIONAL);
//
// get frame interval
//
//FrameInterval = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_FRAME_INTERVAL_OFFSET)) & OHCI_FRAME_INTERVAL_TOGGLE) ^ OHCI_FRAME_INTERVAL_TOGGLE;
//FrameInterval |= OHCI_FSMPS(IntervalValue) | IntervalValue;
//
// write frame interval
//
//WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_FRAME_INTERVAL_OFFSET), FrameInterval);
// 90% periodic
//Periodic = OHCI_PERIODIC(intervalValue);
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + 0x40 /*OHCI_PERIODIC_START_OFFSET*/), 0x3E67);
//
// read descriptor
//
Descriptor = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET));
//
// no over current protection
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor | OHCI_RH_NO_OVER_CURRENT_PROTECTION);
//
// enable power on all ports
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_STATUS_OFFSET), OHCI_RH_LOCAL_POWER_STATUS_CHANGE);
//
// wait a bit
//
KeStallExecutionProcessor(10);
//
// write descriptor
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor);
//
// retrieve number of ports
//
@ -913,19 +955,11 @@ CUSBHardwareDevice::ClearPortStatus(
if (PortId > m_NumberOfPorts)
return STATUS_UNSUCCESSFUL;
//
// read port status
//
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)));
KeStallExecutionProcessor(100);
if (Status == C_PORT_RESET)
{
//
// complete reset
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
do
{
//
@ -945,15 +979,44 @@ CUSBHardwareDevice::ClearPortStatus(
// wait a bit
//
KeStallExecutionProcessor(100);
DPRINT1("Wait...\n");
}while(Index++ < 10);
//DPRINT1("Value %x Index %lu\n", Value, Index);
if ((Value & OHCI_RH_PORTSTATUS_PRS))
}while(TRUE);
//
// check if reset bit is still set
//
if (Value & OHCI_RH_PORTSTATUS_PRS)
{
DPRINT1("Failed to reset\n");
//
// reset failed
//
DPRINT1("PortId %lu Reset failed\n", PortId);
return STATUS_UNSUCCESSFUL;
}
//
// sanity checks
//
ASSERT((Value & OHCI_RH_PORTSTATUS_PRS) == 0);
ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC));
//
// clear reset bit complete
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)), OHCI_RH_PORTSTATUS_PRSC);
//
// read status register
//
Value = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_PORT_STATUS(PortId)));
//
// reset complete bit should be cleared
//
ASSERT((Value & OHCI_RH_PORTSTATUS_PRSC) == 0);
//
// update port status
//
@ -964,13 +1027,15 @@ CUSBHardwareDevice::ClearPortStatus(
//
ASSERT((Value & OHCI_RH_PORTSTATUS_PES));
if (Value & OHCI_RH_PORTSTATUS_PES)
{
//
// port is enabled
//
m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
}
//
// port is enabled
//
m_PortStatus[PortId].PortStatus |= USB_PORT_STATUS_ENABLE;
//
// re-enable root hub change
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_INTERRUPT_ENABLE_OFFSET), OHCI_ROOT_HUB_STATUS_CHANGE);
}
if (Status == C_PORT_CONNECTION)
@ -1276,6 +1341,12 @@ OhciDefferedRoutine(
//
DPRINT1("New device arrival at Port %d LowSpeed %x\n", Index, (PortStatus & OHCI_RH_PORTSTATUS_LSDA));
//
// enable port
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)This->m_Base + OHCI_RH_PORT_STATUS(Index)), OHCI_RH_PORTSTATUS_PES);
//
// store change
//

View file

@ -100,7 +100,7 @@
//
// Root Hub status register (section 7.4.3)
//
#define OHCI_RH_STATUS 0x50
#define OHCI_RH_STATUS_OFFSET 0x50
#define OHCI_RH_LOCAL_POWER_STATUS 0x00000001
#define OHCI_RH_OVER_CURRENT_INDICATOR 0x00000002
#define OHCI_RH_DEVICE_REMOTE_WAKEUP_ENABLE 0x00008000

View file

@ -922,9 +922,9 @@ CHubController::HandleClassOther(
case PORT_ENABLE:
{
//
// port enable is a no-op for OHCI
// port enable
//
Status = STATUS_SUCCESS;
Status = m_Hardware->SetPortFeature(PortId, PORT_ENABLE);
break;
}