From d7bc9878917c4168becabf984fddf00e2a5a32d1 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 30 Jan 2012 10:41:52 +0000 Subject: [PATCH] [USBCCGP] - Fix bug while scanning configuration descriptor - Store interface list in the PDO device extension - Display interface numbers when dumping function descriptor - Fix a few bugs while selecting the configuration for the PDO svn path=/branches/usb-bringup-trunk/; revision=55325 --- drivers/usb/usbccgp/descriptor.c | 2 +- drivers/usb/usbccgp/fdo.c | 6 ++- drivers/usb/usbccgp/function.c | 17 ++++++-- drivers/usb/usbccgp/misc.c | 9 ++++- drivers/usb/usbccgp/pdo.c | 68 ++++++++++++++++++++++++++------ drivers/usb/usbccgp/usbccgp.c | 1 + 6 files changed, 85 insertions(+), 18 deletions(-) diff --git a/drivers/usb/usbccgp/descriptor.c b/drivers/usb/usbccgp/descriptor.c index fcc504b9744..b7395b54812 100644 --- a/drivers/usb/usbccgp/descriptor.c +++ b/drivers/usb/usbccgp/descriptor.c @@ -301,7 +301,7 @@ USBCCGP_ScanConfigurationDescriptor( // // parse configuration descriptor // - InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1); + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, InterfaceIndex, -1, -1, -1, -1); if (InterfaceDescriptor) { // diff --git a/drivers/usb/usbccgp/fdo.c b/drivers/usb/usbccgp/fdo.c index 65f8fea4013..fe89da13ad0 100644 --- a/drivers/usb/usbccgp/fdo.c +++ b/drivers/usb/usbccgp/fdo.c @@ -277,8 +277,10 @@ FDO_CreateChildPdo( // PDODeviceExtension->Common.IsFDO = FALSE; PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index]; - PDODeviceExtension->NextDeviceObject = DeviceObject; + PDODeviceExtension->NextDeviceObject = FDODeviceExtension->NextDeviceObject; //DeviceObject; HACK PDODeviceExtension->FunctionIndex = Index; + PDODeviceExtension->InterfaceList = FDODeviceExtension->InterfaceList; + PDODeviceExtension->InterfaceListCount = FDODeviceExtension->InterfaceListCount; PDODeviceExtension->ConfigurationHandle = FDODeviceExtension->ConfigurationHandle; PDODeviceExtension->ConfigurationDescriptor = FDODeviceExtension->ConfigurationDescriptor; RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES)); @@ -421,7 +423,7 @@ FDO_HandlePnp( // get stack location IoStack = IoGetCurrentIrpStackLocation(Irp); - + DPRINT1("[USBCCGP] PnP Minor %x\n", IoStack->MinorFunction); switch(IoStack->MinorFunction) { case IRP_MN_START_DEVICE: diff --git a/drivers/usb/usbccgp/function.c b/drivers/usb/usbccgp/function.c index e251a2cafc5..d13c7444b42 100644 --- a/drivers/usb/usbccgp/function.c +++ b/drivers/usb/usbccgp/function.c @@ -650,13 +650,14 @@ USBCCGP_LegacyEnum( for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++) { // get interface descriptor - InterfaceDescriptor = USBD_ParseConfigurationDescriptor(FDODeviceExtension->ConfigurationDescriptor, Index, 0); + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -1, -1, -1); if (InterfaceDescriptor == NULL) { // // failed to find interface descriptor // DPRINT1("[USBCCGP] Failed to find interface descriptor index %lu\n", Index); + ASSERT(FALSE); return STATUS_UNSUCCESSFUL; } @@ -720,6 +721,7 @@ USBCCGP_EnumWithAudioLegacy( PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, FirstDescriptor = NULL; PFDO_DEVICE_EXTENSION FDODeviceExtension; NTSTATUS Status = STATUS_SUCCESS; + PVOID StartPosition; // // get device extension @@ -731,12 +733,21 @@ USBCCGP_EnumWithAudioLegacy( // // first check if all interfaces belong to the same audio class // - for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++) + StartPosition = FDODeviceExtension->ConfigurationDescriptor; + for(Index = 0; Index < CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor); Index++) { // // get interface descriptor // - InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, -1, -1, -1, -1); + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, StartPosition, -1, -1, -1, -1, -1); + DPRINT1("Index %lu Descriptor %p\n", Index, InterfaceDescriptor); + ASSERT(InterfaceDescriptor); + + // + // move to next descriptor + // + StartPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + if (InterfaceDescriptor->bInterfaceClass != 0x1) { // diff --git a/drivers/usb/usbccgp/misc.c b/drivers/usb/usbccgp/misc.c index 62a411b39cd..1cb81f6f020 100644 --- a/drivers/usb/usbccgp/misc.c +++ b/drivers/usb/usbccgp/misc.c @@ -200,7 +200,7 @@ DumpFunctionDescriptor( IN PUSBC_FUNCTION_DESCRIPTOR FunctionDescriptor, IN ULONG FunctionDescriptorCount) { - ULONG Index; + ULONG Index, SubIndex; DPRINT1("FunctionCount %lu\n", FunctionDescriptorCount); @@ -212,6 +212,13 @@ DumpFunctionDescriptor( DPRINT1("CompatibleId %wZ\n", &FunctionDescriptor[Index].CompatibleId); DPRINT1("FunctionDescription %wZ\n", &FunctionDescriptor[Index].FunctionDescription); DPRINT1("NumInterfaces %lu\n", FunctionDescriptor[Index].NumberOfInterfaces); + + for(SubIndex = 0; SubIndex < FunctionDescriptor[Index].NumberOfInterfaces; SubIndex++) + { + DPRINT1(" Interface %p\n", FunctionDescriptor[Index].InterfaceDescriptorList[SubIndex]); + DPRINT1(" Interface InterfaceNumber %x\n", FunctionDescriptor[Index].InterfaceDescriptorList[SubIndex]->bInterfaceNumber); + DPRINT1(" Interface Alternate %x\n", FunctionDescriptor[Index].InterfaceDescriptorList[SubIndex]->bAlternateSetting ); + } } } \ No newline at end of file diff --git a/drivers/usb/usbccgp/pdo.c b/drivers/usb/usbccgp/pdo.c index f44e49f1ad6..ada8a935588 100644 --- a/drivers/usb/usbccgp/pdo.c +++ b/drivers/usb/usbccgp/pdo.c @@ -523,7 +523,7 @@ USBCCGP_PDOSelectConfiguration( PUSBD_INTERFACE_INFORMATION InterfaceInformation; ULONG InterfaceInformationCount, Index, InterfaceIndex; PUSBD_INTERFACE_LIST_ENTRY Entry; - ULONG NeedSelect; + ULONG NeedSelect, FoundInterface; // // get current stack location @@ -569,35 +569,66 @@ USBCCGP_PDOSelectConfiguration( InterfaceInformation = &Urb->UrbSelectConfiguration.Interface; Index = 0; Entry = NULL; - + DPRINT1("Count %x\n", InterfaceInformationCount); do { + DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting); + // - // search for the interface + // search for the interface in the local interface list // + FoundInterface = FALSE; for(InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; InterfaceIndex++) { - if (PDODeviceExtension->InterfaceList[InterfaceIndex].Interface->InterfaceNumber == InterfaceInformation->InterfaceNumber) + if (PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[InterfaceIndex]->bInterfaceNumber == InterfaceInformation->InterfaceNumber) { // found interface entry - Entry = &PDODeviceExtension->InterfaceList[InterfaceIndex]; + FoundInterface = TRUE; break; } } - if (!Entry || Entry->InterfaceDescriptor) + if (!FoundInterface) { // // invalid parameter // + DPRINT1("InterfaceInformation InterfaceNumber %x Alternative %x NumberOfPipes %x not found\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes); ASSERT(FALSE); return STATUS_INVALID_PARAMETER; } + // + // now query the total interface list + // + Entry = NULL; + for(InterfaceIndex = 0; InterfaceIndex < PDODeviceExtension->InterfaceListCount; InterfaceIndex++) + { + if (PDODeviceExtension->InterfaceList[InterfaceIndex].Interface->InterfaceNumber == InterfaceInformation->InterfaceNumber) + { + // + // found entry + // + Entry = &PDODeviceExtension->InterfaceList[InterfaceIndex]; + } + } + + // + // sanity check + // + ASSERT(Entry); + if (!Entry) + { + // + // corruption detected + // + KeBugCheck(0); + } + NeedSelect = FALSE; if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting) { - for(InterfaceIndex = 0; Entry->InterfaceDescriptor->bNumEndpoints; InterfaceIndex++) + for(InterfaceIndex = 0; InterfaceIndex < Entry->InterfaceDescriptor->bNumEndpoints; InterfaceIndex++) { if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize) { @@ -611,7 +642,7 @@ USBCCGP_PDOSelectConfiguration( else { // - // need select + // need select as the interface number differ // NeedSelect = TRUE; } @@ -640,6 +671,16 @@ USBCCGP_PDOSelectConfiguration( Index++; }while(Index < InterfaceInformationCount); + // + // store configuration handle + // + Urb->UrbSelectConfiguration.ConfigurationHandle = PDODeviceExtension->ConfigurationHandle; + + DPRINT1("[USBCCGP] SelectConfiguration Function %x Completed\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber); + + // + // done + // return STATUS_SUCCESS; } @@ -721,9 +762,14 @@ PDO_HandleInternalDeviceControl( return Status; } } - - - + else if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE) + { + DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE\n"); + IoSkipCurrentIrpStackLocation(Irp); + Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp); + DPRINT1("URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE Status %x\n", Status); + return Status; + } } diff --git a/drivers/usb/usbccgp/usbccgp.c b/drivers/usb/usbccgp/usbccgp.c index 7e7cc079393..174612d94bc 100644 --- a/drivers/usb/usbccgp/usbccgp.c +++ b/drivers/usb/usbccgp/usbccgp.c @@ -136,6 +136,7 @@ DriverEntry( { // initialize driver object + DPRINT1("[USBCCGP] DriverEntry\n"); DriverObject->DriverExtension->AddDevice = USBCCGP_AddDevice; DriverObject->MajorFunction[IRP_MJ_CREATE] = USBCCGP_Dispatch; DriverObject->MajorFunction[IRP_MJ_CLOSE] = USBCCGP_Dispatch;