- Split retrieving the full configuration descriptor into 2 steps
- Fixes errors while initializing usb devices on UHCI controller
- Tested in VmWare / VBox and real hardware

svn path=/trunk/; revision=55942
This commit is contained in:
Johannes Anderwald 2012-03-01 14:16:33 +00:00
parent 348d7d4625
commit d431e272f8
2 changed files with 80 additions and 49 deletions

View file

@ -1111,7 +1111,7 @@ CUSBRequest::BuildControlTransferDescriptor(
// //
// failed to allocate descriptor // failed to allocate descriptor
// //
DPRINT1("[UHCI] Failed to create setup descriptor\n"); DPRINT1("[UHCI] Failed to create status descriptor\n");
FreeDescriptor(SetupDescriptor); FreeDescriptor(SetupDescriptor);
m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD)); m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
return Status; return Status;

View file

@ -63,6 +63,7 @@ public:
virtual NTSTATUS CreateDeviceDescriptor(); virtual NTSTATUS CreateDeviceDescriptor();
virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor); virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
virtual NTSTATUS GetConfigurationDescriptor(UCHAR ConfigurationIndex, USHORT BufferSize, PVOID Buffer);
// constructor / destructor // constructor / destructor
CUSBDevice(IUnknown *OuterUnknown){} CUSBDevice(IUnknown *OuterUnknown){}
@ -370,6 +371,7 @@ CUSBDevice::SetDeviceAddress(
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve configuration %lu\n", Index); DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve configuration %lu\n", Index);
ASSERT(FALSE);
break; break;
} }
} }
@ -651,13 +653,69 @@ CUSBDevice::CreateDeviceDescriptor()
//---------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------
NTSTATUS NTSTATUS
CUSBDevice::CreateConfigurationDescriptor( CUSBDevice::GetConfigurationDescriptor(
UCHAR Index) IN UCHAR ConfigurationIndex,
IN USHORT BufferSize,
IN PVOID Buffer)
{ {
PVOID Buffer;
USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup; USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
NTSTATUS Status; NTSTATUS Status;
PMDL Mdl; PMDL Mdl;
//
// now build MDL describing the buffer
//
Mdl = IoAllocateMdl(Buffer, BufferSize, FALSE, FALSE, 0);
if (!Mdl)
{
//
// failed to allocate mdl
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// build mdl for non paged pool
//
MmBuildMdlForNonPagedPool(Mdl);
//
// build setup packet
//
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
CtrlSetup.bmRequestType._BM.Reserved = 0;
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
CtrlSetup.wValue.LowByte = ConfigurationIndex;
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = BufferSize;
//
// commit packet
//
Status = CommitSetupPacket(&CtrlSetup, 0, BufferSize, Mdl);
//
// free mdl
//
IoFreeMdl(Mdl);
//
// done
//
return Status;
}
//----------------------------------------------------------------------------------------
NTSTATUS
CUSBDevice::CreateConfigurationDescriptor(
UCHAR Index)
{
NTSTATUS Status;
PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
// //
@ -668,8 +726,8 @@ CUSBDevice::CreateConfigurationDescriptor(
// //
// first allocate a buffer which should be enough to store all different interfaces and endpoints // first allocate a buffer which should be enough to store all different interfaces and endpoints
// //
Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, TAG_USBLIB); ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, TAG_USBLIB);
if (!Buffer) if (!ConfigurationDescriptor)
{ {
// //
// failed to allocate buffer // failed to allocate buffer
@ -678,59 +736,32 @@ CUSBDevice::CreateConfigurationDescriptor(
} }
// //
// build setup packet // get partial configuration descriptor
// //
CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE; Status = GetConfigurationDescriptor(Index, sizeof(USB_CONFIGURATION_DESCRIPTOR), ConfigurationDescriptor);
CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
CtrlSetup.bmRequestType._BM.Reserved = 0;
CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
CtrlSetup.wValue.LowByte = Index;
CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
CtrlSetup.wIndex.W = 0;
CtrlSetup.wLength = PAGE_SIZE;
//
// now build MDL describing the buffer
//
Mdl = IoAllocateMdl(Buffer, PAGE_SIZE, FALSE, FALSE, 0);
if (!Mdl)
{
//
// failed to allocate mdl
//
ExFreePoolWithTag(Buffer, TAG_USBLIB);
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// build mdl for non paged pool
//
MmBuildMdlForNonPagedPool(Mdl);
//
// commit packet
//
Status = CommitSetupPacket(&CtrlSetup, 0, PAGE_SIZE, Mdl);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
// //
// failed to issue request, cleanup // failed to get partial configuration descriptor
// //
IoFreeMdl(Mdl); DPRINT1("[USBLIB] Failed to get partial configuration descriptor Status %x Index %x\n", Status, Index);
ExFreePool(Buffer); ExFreePoolWithTag(ConfigurationDescriptor, TAG_USBLIB);
return Status; return Status;
} }
// //
// now free the mdl // now get full descriptor
// //
IoFreeMdl(Mdl); Status = GetConfigurationDescriptor(Index, ConfigurationDescriptor->wTotalLength, ConfigurationDescriptor);
if (!NT_SUCCESS(Status))
// {
// get configuration descriptor //
// // failed to get full configuration descriptor
ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer; //
DPRINT1("[USBLIB] Failed to get full configuration descriptor Status %x Index %x\n", Status, Index);
ExFreePoolWithTag(ConfigurationDescriptor, TAG_USBLIB);
return Status;
}
// //
// informal debug print // informal debug print