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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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/u…
==============================================================================
--- 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 */