Author: janderwald Date: Fri Jan 27 20:58:58 2012 New Revision: 55261
URL: http://svn.reactos.org/svn/reactos?rev=55261&view=rev Log: [USBCCGP] - Implement counting of all interface descriptors - Store device descriptor and configuration descriptor in pdo device extension - Store all interface descriptors for an composite audio device - Implement parsing and constructing a special configuration descriptor for each individual device function - Implement URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE for device descriptor and configuration descriptor - USBGCCGP now receives select configuration request - Tested in XP + Ros USB Stack + USB Audio Device
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/descriptor.c [iso-8859-1] Fri Jan 27 20:58:58 2012 @@ -202,6 +202,66 @@ }
NTSTATUS +AllocateInterfaceDescriptorsArray( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + OUT PUSB_INTERFACE_DESCRIPTOR **OutArray) +{ + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + PVOID CurrentPosition; + ULONG Count = 0; + PUSB_INTERFACE_DESCRIPTOR *Array; + + Count = CountInterfaceDescriptors(ConfigurationDescriptor); + ASSERT(Count); + + // + // allocate array + // + Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * Count); + if (!Array) + return STATUS_INSUFFICIENT_RESOURCES; + + // + // enumerate all interfaces + // + CurrentPosition = ConfigurationDescriptor; + Count = 0; + do + { + // + // find next descriptor + // + InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1); + if (!InterfaceDescriptor) + break; + + // + // store descriptor + // + Array[Count] = InterfaceDescriptor; + Count++; + + // + // advance to next descriptor + // + CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + + }while(TRUE); + + // + // store result + // + *OutArray = Array; + + // + // done + // + return STATUS_SUCCESS; +} + + + +NTSTATUS NTAPI USBCCGP_ScanConfigurationDescriptor( IN OUT PFDO_DEVICE_EXTENSION FDODeviceExtension,
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/fdo.c [iso-8859-1] Fri Jan 27 20:58:58 2012 @@ -279,7 +279,9 @@ PDODeviceExtension->FunctionDescriptor = &FDODeviceExtension->FunctionDescriptor[Index]; PDODeviceExtension->NextDeviceObject = DeviceObject; PDODeviceExtension->FunctionIndex = Index; + PDODeviceExtension->ConfigurationDescriptor = FDODeviceExtension->ConfigurationDescriptor; RtlCopyMemory(&PDODeviceExtension->Capabilities, &FDODeviceExtension->Capabilities, sizeof(DEVICE_CAPABILITIES)); + RtlCopyMemory(&PDODeviceExtension->DeviceDescriptor, &FDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
// // patch the stack size
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/function.c [iso-8859-1] Fri Jan 27 20:58:58 2012 @@ -787,22 +787,17 @@ FDODeviceExtension->FunctionDescriptor[0].FunctionNumber = 0;
// - // FIXME: how many interfaces should be stored? - // - - FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * 1); - if (!FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList) - { - // - // no memory - // - return STATUS_INSUFFICIENT_RESOURCES; - } - - // - // store interface descriptor - // - FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList[0] = InterfaceDescriptor; + // store interfaces + // + Status = AllocateInterfaceDescriptorsArray(FDODeviceExtension->ConfigurationDescriptor, &FDODeviceExtension->FunctionDescriptor[0].InterfaceDescriptorList); + if (!NT_SUCCESS(Status)) + { + // + // failed to allocate descriptor array + // + DPRINT1("[USBCCGP] Failed to allocate descriptor array %x\n", Status); + return Status; + }
// // now init the device ids @@ -818,6 +813,11 @@ }
// + // number of interfaces + // + FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor); + + // // store function count // FDODeviceExtension->FunctionDescriptorCount = 1;
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/pdo.c [iso-8859-1] Fri Jan 27 20:58:58 2012 @@ -323,6 +323,280 @@
}
+NTSTATUS +USBCCGP_BuildConfigurationDescriptor( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; + PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor; + ULONG TotalSize, Index; + PURB Urb; + PVOID Buffer; + PUCHAR BufferPtr; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT1("USBCCGP_BuildConfigurationDescriptor\n"); + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + // + // get configuration descriptor + // + ConfigurationDescriptor = PDODeviceExtension->ConfigurationDescriptor; + + // + // calculate size of configuration descriptor + // + TotalSize = sizeof(USB_CONFIGURATION_DESCRIPTOR); + + for(Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++) + { + // + // get current interface descriptor + // + InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index]; + + // + // add to size and move to next descriptor + // + TotalSize += InterfaceDescriptor->bLength; + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + + do + { + if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) + { + // + // reached end of configuration descriptor + // + break; + } + + // + // association descriptors are removed + // + if (InterfaceDescriptor->bDescriptorType != USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE) + { + if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + { + // + // reached next descriptor + // + break; + } + + // + // append size + // + TotalSize += InterfaceDescriptor->bLength; + } + + // + // move to next descriptor + // + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + }while(TRUE); + } + + // + // now allocate temporary buffer for the configuration descriptor + // + Buffer = AllocateItem(NonPagedPool, TotalSize); + if (!Buffer) + { + // + // failed to allocate buffer + // + DPRINT1("[USBCCGP] Failed to allocate %lu Bytes\n", TotalSize); + return STATUS_INSUFFICIENT_RESOURCES; + } + + // + // first copy the configuration descriptor + // + RtlCopyMemory(Buffer, ConfigurationDescriptor, sizeof(USB_CONFIGURATION_DESCRIPTOR)); + BufferPtr = (PUCHAR)((ULONG_PTR)Buffer + ConfigurationDescriptor->bLength); + + for(Index = 0; Index < PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; Index++) + { + // + // get current interface descriptor + // + InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index]; + + // + // copy descriptor and move to next descriptor + // + RtlCopyMemory(BufferPtr, InterfaceDescriptor, InterfaceDescriptor->bLength); + BufferPtr += InterfaceDescriptor->bLength; + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + + do + { + if ((ULONG_PTR)InterfaceDescriptor >= ((ULONG_PTR)ConfigurationDescriptor + ConfigurationDescriptor->wTotalLength)) + { + // + // reached end of configuration descriptor + // + break; + } + + // + // association descriptors are removed + // + if (InterfaceDescriptor->bDescriptorType != USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE) + { + if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) + { + // + // reached next descriptor + // + break; + } + + // + // copy descriptor + // + RtlCopyMemory(BufferPtr, InterfaceDescriptor, InterfaceDescriptor->bLength); + BufferPtr += InterfaceDescriptor->bLength; + } + + // + // move to next descriptor + // + InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength); + }while(TRUE); + } + + // + // modify configuration descriptor + // + ConfigurationDescriptor = Buffer; + ConfigurationDescriptor->wTotalLength = TotalSize; + ConfigurationDescriptor->bNumInterfaces = PDODeviceExtension->FunctionDescriptor->NumberOfInterfaces; + + // + // get urb + // + Urb = (PURB)IoStack->Parameters.Others.Argument1; + ASSERT(Urb); + + // + // copy descriptor + // + RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, Buffer, min(TotalSize, Urb->UrbControlDescriptorRequest.TransferBufferLength)); + + // + // store final size + // + Urb->UrbControlDescriptorRequest.TransferBufferLength = TotalSize; + + // + // free buffer + // + FreeItem(Buffer); + + // + // done + // + return STATUS_SUCCESS; +} + +NTSTATUS +PDO_HandleInternalDeviceControl( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PPDO_DEVICE_EXTENSION PDODeviceExtension; + NTSTATUS Status; + PURB Urb; + + // + // get current stack location + // + IoStack = IoGetCurrentIrpStackLocation(Irp); + + // + // get device extension + // + PDODeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension; + + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB) + { + // + // get urb + // + Urb = (PURB)IoStack->Parameters.Others.Argument1; + ASSERT(Urb); + + if (Urb->UrbHeader.Function == URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE) + { + DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function); + + if(Urb->UrbControlDescriptorRequest.DescriptorType == USB_DEVICE_DESCRIPTOR_TYPE) + { + // + // is the buffer big enough + // + if (Urb->UrbControlDescriptorRequest.TransferBufferLength < sizeof(USB_DEVICE_DESCRIPTOR)) + { + // + // invalid buffer size + // + DPRINT1("[USBCCGP] invalid device descriptor size %lu\n", Urb->UrbControlDescriptorRequest.TransferBufferLength); + Urb->UrbControlDescriptorRequest.TransferBufferLength = sizeof(USB_DEVICE_DESCRIPTOR); + Irp->IoStatus.Status = STATUS_INVALID_BUFFER_SIZE; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INVALID_BUFFER_SIZE; + } + + // + // copy device descriptor + // + ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer); + RtlCopyMemory(Urb->UrbControlDescriptorRequest.TransferBuffer, &PDODeviceExtension->DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR)); + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + else if (Urb->UrbControlDescriptorRequest.DescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE) + { + // + // build configuration descriptor + // + Status = USBCCGP_BuildConfigurationDescriptor(DeviceObject, Irp); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + } + } + + + + DPRINT1("IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); + DPRINT1("InputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.InputBufferLength); + DPRINT1("OutputBufferLength %lu\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength); + DPRINT1("Type3InputBuffer %p\n", IoStack->Parameters.DeviceIoControl.Type3InputBuffer); + + ASSERT(FALSE); + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} +
NTSTATUS PDO_Dispatch( @@ -339,6 +613,8 @@ { case IRP_MJ_PNP: return PDO_HandlePnp(DeviceObject, Irp); + case IRP_MJ_INTERNAL_DEVICE_CONTROL: + return PDO_HandleInternalDeviceControl(DeviceObject, Irp); default: DPRINT1("PDO_Dispatch Function %x not implemented\n", IoStack->MajorFunction); ASSERT(FALSE);
Modified: branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup-trunk/drivers/usb/us... ============================================================================== --- branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] (original) +++ branches/usb-bringup-trunk/drivers/usb/usbccgp/usbccgp.h [iso-8859-1] Fri Jan 27 20:58:58 2012 @@ -50,6 +50,8 @@ PDEVICE_OBJECT NextDeviceObject; // next device object DEVICE_CAPABILITIES Capabilities; // device capabilities ULONG FunctionIndex; // function index + USB_DEVICE_DESCRIPTOR DeviceDescriptor; // usb device descriptor + PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor; // usb configuration descriptor }PDO_DEVICE_EXTENSION, *PPDO_DEVICE_EXTENSION;
/* descriptor.c */ @@ -72,6 +74,15 @@ IN UCHAR DescriptorIndex, IN LANGID LanguageId, OUT PVOID *OutDescriptor); + +ULONG +CountInterfaceDescriptors( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor); + +NTSTATUS +AllocateInterfaceDescriptorsArray( + IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, + OUT PUSB_INTERFACE_DESCRIPTOR **OutArray);
/* misc.c */