[USBOHCI]

- Fix various initialization bugs

svn path=/trunk/; revision=55844
This commit is contained in:
Cameron Gutman 2012-02-24 23:05:22 +00:00
parent d9f4f1b411
commit 17b865ebc2

View file

@ -517,7 +517,7 @@ CUSBHardwareDevice::GetUSBQueue(
NTSTATUS NTSTATUS
CUSBHardwareDevice::StartController(void) CUSBHardwareDevice::StartController(void)
{ {
ULONG Control, NumberOfPorts, Index, Descriptor, FrameInterval, Periodic; ULONG Control, Descriptor, FrameInterval, Periodic;
// //
// lets write physical address of dummy control endpoint descriptor // lets write physical address of dummy control endpoint descriptor
@ -529,6 +529,42 @@ CUSBHardwareDevice::StartController(void)
// //
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_BULK_HEAD_ED_OFFSET), m_BulkEndpointDescriptor->PhysicalAddress.LowPart); WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_BULK_HEAD_ED_OFFSET), m_BulkEndpointDescriptor->PhysicalAddress.LowPart);
//
// read descriptor
//
Descriptor = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET));
//
// get port count
//
m_NumberOfPorts = OHCI_RH_GET_PORT_COUNT(Descriptor);
DPRINT1("NumberOfPorts %lu\n", m_NumberOfPorts);
ASSERT(m_NumberOfPorts < OHCI_MAX_PORT_COUNT);
//
// no over current protection
//
Descriptor |= OHCI_RH_NO_OVER_CURRENT_PROTECTION;
//
// power switching on
//
Descriptor &= ~OHCI_RH_NO_POWER_SWITCHING;
//
// control each port power independently (disabled until it's supported correctly)
//
#if 0
Descriptor |= OHCI_RH_POWER_SWITCHING_MODE;
#else
Descriptor &= ~OHCI_RH_POWER_SWITCHING_MODE;
#endif
//
// write the configuration back
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor);
// //
// get frame interval // get frame interval
// //
@ -546,6 +582,14 @@ CUSBHardwareDevice::StartController(void)
// //
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_FRAME_INTERVAL_OFFSET), FrameInterval); WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_FRAME_INTERVAL_OFFSET), FrameInterval);
//
// HCCA alignment check
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_HCCA_OFFSET), 0xFFFFFFFF);
KeStallExecutionProcessor(10);
Control = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_HCCA_OFFSET));
ASSERT((m_HCCAPhysicalAddress.LowPart & Control) == Control);
// //
// write address of HCCA // write address of HCCA
// //
@ -590,96 +634,15 @@ CUSBHardwareDevice::StartController(void)
ASSERT((Control & OHCI_ENABLE_LIST) == OHCI_ENABLE_LIST); ASSERT((Control & OHCI_ENABLE_LIST) == OHCI_ENABLE_LIST);
DPRINT1("Control %x\n", Control); DPRINT1("Control %x\n", Control);
//
// read descriptor
//
Descriptor = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET));
//
// no over current protection
//
Descriptor |= OHCI_RH_NO_OVER_CURRENT_PROTECTION;
//
// power switching on
//
Descriptor &= ~OHCI_RH_NO_POWER_SWITCHING;
//
// control each port power independently (disabled until it's supported correctly)
//
#if 0
Descriptor |= OHCI_RH_POWER_SWITCHING_MODE;
#else
Descriptor &= ~OHCI_RH_POWER_SWITCHING_MODE;
#endif
//
// write the configuration back
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET), Descriptor);
// //
// enable power on all ports // enable power on all ports
// //
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_STATUS_OFFSET), OHCI_RH_LOCAL_POWER_STATUS_CHANGE); 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
//
for(Index = 0; Index < 10; Index++)
{
//
// wait a bit
//
KeStallExecutionProcessor(10);
//
// read descriptor
//
Descriptor = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_RH_DESCRIPTOR_A_OFFSET));
//
// get number of ports
//
NumberOfPorts = OHCI_RH_GET_PORT_COUNT(Descriptor);
//
// check if we have received the ports
//
if (NumberOfPorts)
break;
}
//
// sanity check
//
ASSERT(NumberOfPorts < OHCI_MAX_PORT_COUNT);
//
// store number of ports
//
m_NumberOfPorts = NumberOfPorts;
//
// print out number ports
//
DPRINT1("NumberOfPorts %lu\n", m_NumberOfPorts);
// //
// done // done
// //
DPRINT1("OHCI controller is operational\n");
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -912,17 +875,9 @@ CUSBHardwareDevice::InitializeController()
NTSTATUS NTSTATUS
CUSBHardwareDevice::StopController(void) CUSBHardwareDevice::StopController(void)
{ {
ULONG Control, Reset, Status; ULONG Control, Reset;
ULONG Index, FrameInterval; ULONG Index, FrameInterval;
//
// alignment check
//
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_HCCA_OFFSET), 0xFFFFFFFF);
Control = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_HCCA_OFFSET));
//ASSERT((m_HCCAPhysicalAddress.QuadPart & Control) == Control);
// //
// check context // check context
// //
@ -930,15 +885,10 @@ CUSBHardwareDevice::StopController(void)
if ((Control & OHCI_INTERRUPT_ROUTING)) if ((Control & OHCI_INTERRUPT_ROUTING))
{ {
//
// read command status
//
Status = READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET));
// //
// change ownership // change ownership
// //
WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), Status | OHCI_OWNERSHIP_CHANGE_REQUEST); WRITE_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_COMMAND_STATUS_OFFSET), OHCI_OWNERSHIP_CHANGE_REQUEST);
for(Index = 0; Index < 100; Index++) for(Index = 0; Index < 100; Index++)
{ {
// //
@ -1002,7 +952,7 @@ CUSBHardwareDevice::StopController(void)
// check control register // check control register
// //
Control = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET)) & OHCI_HC_FUNCTIONAL_STATE_MASK); Control = (READ_REGISTER_ULONG((PULONG)((PUCHAR)m_Base + OHCI_CONTROL_OFFSET)) & OHCI_HC_FUNCTIONAL_STATE_MASK);
if (Control & OHCI_HC_FUNCTIONAL_STATE_RESUME) if (Control == OHCI_HC_FUNCTIONAL_STATE_RESUME)
{ {
// //
// it has resumed // it has resumed
@ -1086,7 +1036,7 @@ CUSBHardwareDevice::StopController(void)
// //
// reset time is 10ms // reset time is 10ms
// //
for(Index = 0; Index < 10; Index++) for(Index = 0; Index < 100; Index++)
{ {
// //
// wait a bit // wait a bit