[USBCCG]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 3 Mar 2012 15:08:28 +0000 (15:08 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sat, 3 Mar 2012 15:08:28 +0000 (15:08 +0000)
- Remove hacks
- Include alternate interface descriptors in the configuration descriptor

svn path=/trunk/; revision=55966

reactos/drivers/usb/usbccgp/descriptor.c
reactos/drivers/usb/usbccgp/function.c
reactos/drivers/usb/usbccgp/pdo.c

index 2a9e495..5841dd3 100644 (file)
@@ -220,76 +220,32 @@ USBCCGP_GetDescriptors(
      return Status;
 }
 
-ULONG
-CountInterfaceDescriptors(
-    IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor)
-{
-    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
-    PVOID CurrentPosition;
-    ULONG Count = 0;
-
-    //
-    // enumerate all interfaces
-    //
-    CurrentPosition = ConfigurationDescriptor;
-    do
-    {
-        //
-        // find next descriptor
-        //
-        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, CurrentPosition, -1, -1, -1, -1, -1);
-        if (!InterfaceDescriptor)
-            break;
-
-        //
-        // advance to next descriptor
-        //
-        CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
-
-        //
-        // increment descriptor count
-        //
-        Count++;
-
-    }while(TRUE);
-
-    //
-    // done
-    //
-    return Count;
-}
-
 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);
+    Array = AllocateItem(NonPagedPool, sizeof(PUSB_INTERFACE_DESCRIPTOR) * ConfigurationDescriptor->bNumInterfaces);
     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);
+        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(ConfigurationDescriptor, ConfigurationDescriptor, Count, 0, -1, -1, -1);
         if (!InterfaceDescriptor)
             break;
 
@@ -299,11 +255,6 @@ AllocateInterfaceDescriptorsArray(
         Array[Count] = InterfaceDescriptor;
         Count++;
 
-        //
-        // advance to next descriptor
-        //
-        CurrentPosition = (PVOID)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
-
     }while(TRUE);
 
     //
index 2526cb0..2c2f8c9 100644 (file)
@@ -711,7 +711,6 @@ USBCCGP_EnumWithAudioLegacy(
     PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor, FirstDescriptor = NULL;
     PFDO_DEVICE_EXTENSION FDODeviceExtension;
     NTSTATUS Status = STATUS_SUCCESS;
-    PVOID StartPosition;
 
     //
     // get device extension
@@ -723,21 +722,15 @@ USBCCGP_EnumWithAudioLegacy(
     //
     // first check if all interfaces belong to the same audio class
     //
-    StartPosition = FDODeviceExtension->ConfigurationDescriptor;
-    for(Index = 0; Index < CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor); Index++)
+    for(Index = 0; Index < FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces; Index++)
     {
         //
         // get interface descriptor
         //
-        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, StartPosition, -1, -1, -1, -1, -1);
+        InterfaceDescriptor = USBD_ParseConfigurationDescriptorEx(FDODeviceExtension->ConfigurationDescriptor, FDODeviceExtension->ConfigurationDescriptor, Index, 0, -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)
         {
             //
@@ -816,7 +809,7 @@ USBCCGP_EnumWithAudioLegacy(
     //
     // number of interfaces
     //
-    FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = CountInterfaceDescriptors(FDODeviceExtension->ConfigurationDescriptor);
+    FDODeviceExtension->FunctionDescriptor[0].NumberOfInterfaces = FDODeviceExtension->ConfigurationDescriptor->bNumInterfaces;
 
     //
     // store function count
index e7a52b8..2c24772 100644 (file)
@@ -460,6 +460,7 @@ USBCCGP_BuildConfigurationDescriptor(
     PURB Urb;
     PVOID Buffer;
     PUCHAR BufferPtr;
+    UCHAR InterfaceNumber;
 
     //
     // get current stack location
@@ -489,6 +490,7 @@ USBCCGP_BuildConfigurationDescriptor(
         // get current interface descriptor
         //
         InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
+        InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
 
         //
         // add to size and move to next descriptor
@@ -513,10 +515,17 @@ USBCCGP_BuildConfigurationDescriptor(
             {
                 if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
                 {
+                    if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
+                    {
+                        //
+                        // reached next descriptor
+                        //
+                        break;
+                    }
+
                     //
-                    // reached next descriptor
+                    // include alternate descriptor
                     //
-                    break;
                 }
 
                 //
@@ -557,6 +566,7 @@ USBCCGP_BuildConfigurationDescriptor(
         // get current interface descriptor
         //
         InterfaceDescriptor = PDODeviceExtension->FunctionDescriptor->InterfaceDescriptorList[Index];
+        InterfaceNumber = InterfaceDescriptor->bInterfaceNumber;
 
         //
         // copy descriptor and move to next descriptor
@@ -582,10 +592,18 @@ USBCCGP_BuildConfigurationDescriptor(
             {
                 if (InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE)
                 {
+                    if (InterfaceNumber != InterfaceDescriptor->bInterfaceNumber)
+                    {
+                        //
+                        // reached next descriptor
+                        //
+                        break;
+                    }
+
                     //
-                    // reached next descriptor
+                    // include alternate descriptor
                     //
-                    break;
+                    DPRINT("InterfaceDescriptor %p Alternate %x InterfaceNumber %x\n", InterfaceDescriptor, InterfaceDescriptor->bAlternateSetting, InterfaceDescriptor->bInterfaceNumber);
                 }
 
                 //
@@ -645,7 +663,7 @@ USBCCGP_PDOSelectConfiguration(
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
     PURB Urb, NewUrb;
     PUSBD_INTERFACE_INFORMATION InterfaceInformation;
-    ULONG InterfaceInformationCount, Index, InterfaceIndex;
+    ULONG InterfaceIndex, Length;
     PUSBD_INTERFACE_LIST_ENTRY Entry;
     ULONG NeedSelect, FoundInterface;
     NTSTATUS Status;
@@ -677,28 +695,25 @@ USBCCGP_PDOSelectConfiguration(
         return STATUS_SUCCESS;
     }
 
-    //
-    // count interface information
-    //
-    InterfaceInformationCount = 0;
-    InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
-    do
-    {
-        InterfaceInformationCount++;
-        InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
-    }while((ULONG_PTR)InterfaceInformation < (ULONG_PTR)Urb + Urb->UrbSelectConfiguration.Hdr.Length);
+    // sanity checks
+    //C_ASSERT(sizeof(struct _URB_HEADER) == 16);
+    //C_ASSERT(FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length) == 24);
+    //C_ASSERT(sizeof(USBD_INTERFACE_INFORMATION) == 36);
+    //C_ASSERT(sizeof(struct _URB_SELECT_CONFIGURATION) == 0x3C);
+
+    // available buffer length
+    Length = Urb->UrbSelectConfiguration.Hdr.Length - FIELD_OFFSET(struct _URB_SELECT_CONFIGURATION, Interface.Length);
 
     //
     // check all interfaces
     //
     InterfaceInformation = &Urb->UrbSelectConfiguration.Interface;
-    Index = 0;
+
     Entry = NULL;
-    DPRINT("Count %x\n", InterfaceInformationCount);
     do
     {
-        DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
-
+        DPRINT1("[USBCCGP] SelectConfiguration Function %x InterfaceNumber %x Alternative %x Length %lu InterfaceInformation->Length %lu\n", PDODeviceExtension->FunctionDescriptor->FunctionNumber, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, Length, InterfaceInformation->Length);
+        ASSERT(InterfaceInformation->Length);
         //
         // search for the interface in the local interface list
         //
@@ -778,7 +793,19 @@ USBCCGP_PDOSelectConfiguration(
             //
             // interface is already selected
             //
-            RtlCopyMemory(InterfaceInformation, Entry->Interface, min(InterfaceInformation->Length, Entry->Interface->Length));
+            ASSERT(Length >= Entry->Interface->Length);
+            RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+
+            //
+            // adjust remaining buffer size
+            //
+            ASSERT(Entry->Interface->Length);
+            Length -= Entry->Interface->Length;
+
+            //
+            // move to next output interface information
+            //
+            InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
         }
         else
         {
@@ -811,23 +838,37 @@ USBCCGP_PDOSelectConfiguration(
             Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
             DPRINT1("SelectInterface Status %x\n", Status);
 
+            if (!NT_SUCCESS(Status))
+            {
+                 //
+                 // failed
+                 //
+                 break;
+            }
+
             //
-            // did it succeeed
+            // update configuration info
             //
-            if (NT_SUCCESS(Status))
-            {
-                //
-                // update configuration info
-                //
-                ASSERT(Entry->Interface->Length == NewUrb->UrbSelectInterface.Interface.Length);
-                ASSERT(InterfaceInformation->Length == NewUrb->UrbSelectInterface.Interface.Length);
-                RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
+            ASSERT(Entry->Interface->Length >= NewUrb->UrbSelectInterface.Interface.Length);
+            ASSERT(Length >= NewUrb->UrbSelectInterface.Interface.Length);
+            RtlCopyMemory(Entry->Interface, &NewUrb->UrbSelectInterface.Interface, NewUrb->UrbSelectInterface.Interface.Length);
 
-                //
-                // update provided interface information
-                //
-                RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
-            }
+            //
+            // update provided interface information
+            //
+            ASSERT(Length >= Entry->Interface->Length);
+            RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+
+            //
+            // decrement remaining buffer size
+            //
+            ASSERT(Entry->Interface->Length);
+            Length -= Entry->Interface->Length;
+
+            //
+            // adjust output buffer offset
+            //
+            InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + Entry->Interface->Length);
 
             //
             // free urb
@@ -835,12 +876,7 @@ USBCCGP_PDOSelectConfiguration(
             FreeItem(NewUrb);
         }
 
-        //
-        // move to next information
-        //
-        InterfaceInformation = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)InterfaceInformation + InterfaceInformation->Length);
-        Index++;
-    }while(Index < InterfaceInformationCount);
+    }while(Length);
 
     //
     // store configuration handle