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/usbccgp/descriptor.c?rev=55261&r1=55260&r2=55261&view=diff
==============================================================================
--- 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/usbccgp/fdo.c?rev=55261&r1=55260&r2=55261&view=diff
==============================================================================
--- 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/usbccgp/function.c?rev=55261&r1=55260&r2=55261&view=diff
==============================================================================
--- 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/usbccgp/pdo.c?rev=55261&r1=55260&r2=55261&view=diff
==============================================================================
--- 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/usbccgp/usbccgp.h?rev=55261&r1=55260&r2=55261&view=diff
==============================================================================
--- 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 */
 


Reply via email to