[USBCCGP]
[reactos.git] / drivers / usb / usbccgp / pdo.c
index 2d19870..1a2c0be 100644 (file)
@@ -307,6 +307,7 @@ PDO_HandlePnp(
     PIO_STACK_LOCATION IoStack;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
     NTSTATUS Status;
+    ULONG Index;
 
     //
     // get current stack location
@@ -351,15 +352,31 @@ PDO_HandlePnp(
        }
        case IRP_MN_REMOVE_DEVICE:
        {
-           DPRINT1("IRP_MN_REMOVE_DEVICE\n");
+           //
+           // remove us from the fdo's pdo list
+           //
+           for(Index = 0; Index < PDODeviceExtension->FDODeviceExtension->FunctionDescriptorCount; Index++)
+           {
+               if (PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] == DeviceObject)
+               {
+                   //
+                   // remove us
+                   //
+                   PDODeviceExtension->FDODeviceExtension->ChildPDO[Index] = NULL;
+                   break;
+               }
+           }
 
-           /* Complete the IRP */
+           //
+           // Complete the IRP
+           //
            Irp->IoStatus.Status = STATUS_SUCCESS;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
 
-           /* Delete the device object */
+           //
+           // Delete the device object
+           //
            IoDeleteDevice(DeviceObject);
-
            return STATUS_SUCCESS;
        }
        case IRP_MN_QUERY_CAPABILITIES:
@@ -611,11 +628,12 @@ USBCCGP_PDOSelectConfiguration(
 {
     PIO_STACK_LOCATION IoStack;
     PPDO_DEVICE_EXTENSION PDODeviceExtension;
-    PURB Urb;
+    PURB Urb, NewUrb;
     PUSBD_INTERFACE_INFORMATION InterfaceInformation;
     ULONG InterfaceInformationCount, Index, InterfaceIndex;
     PUSBD_INTERFACE_LIST_ENTRY Entry;
     ULONG NeedSelect, FoundInterface;
+    NTSTATUS Status;
 
     //
     // get current stack location
@@ -720,7 +738,8 @@ USBCCGP_PDOSelectConfiguration(
         NeedSelect = FALSE;
         if (Entry->InterfaceDescriptor->bAlternateSetting == InterfaceInformation->AlternateSetting)
         {
-            for(InterfaceIndex = 0; InterfaceIndex < Entry->InterfaceDescriptor->bNumEndpoints; InterfaceIndex++)
+            
+            for(InterfaceIndex = 0; InterfaceIndex < InterfaceInformation->NumberOfPipes; InterfaceIndex++)
             {
                 if (InterfaceInformation->Pipes[InterfaceIndex].MaximumTransferSize != Entry->Interface->Pipes[InterfaceIndex].MaximumTransferSize)
                 {
@@ -744,16 +763,61 @@ USBCCGP_PDOSelectConfiguration(
             //
             // interface is already selected
             //
-            ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
-            RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+            RtlCopyMemory(InterfaceInformation, Entry->Interface, min(InterfaceInformation->Length, Entry->Interface->Length));
         }
         else
         {
             //
-            // FIXME select interface
+            // select interface
             //
-            UNIMPLEMENTED
-            ASSERT(FALSE);
+            DPRINT1("Selecting InterfaceIndex %lu AlternateSetting %lu NumberOfPipes %lu\n", InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting, InterfaceInformation->NumberOfPipes);
+            ASSERT(InterfaceInformation->Length == Entry->Interface->Length);
+
+            //
+            // build urb
+            //
+            NewUrb = AllocateItem(NonPagedPool, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes));
+            if (!NewUrb)
+            {
+                //
+                // no memory
+                //
+                return STATUS_INSUFFICIENT_RESOURCES;
+            }
+
+            //
+            // now prepare interface urb
+            //
+            UsbBuildSelectInterfaceRequest(NewUrb, GET_SELECT_INTERFACE_REQUEST_SIZE(InterfaceInformation->NumberOfPipes), PDODeviceExtension->ConfigurationHandle, InterfaceInformation->InterfaceNumber, InterfaceInformation->AlternateSetting);
+
+            //
+            // now select the interface
+            //
+            Status = USBCCGP_SyncUrbRequest(PDODeviceExtension->NextDeviceObject, NewUrb);
+            DPRINT1("SelectInterface Status %x\n", Status);
+
+            //
+            // did it succeeed
+            //
+            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);
+
+                //
+                // update provided interface information
+                //
+                RtlCopyMemory(InterfaceInformation, Entry->Interface, Entry->Interface->Length);
+            }
+
+            //
+            // free urb
+            //
+            FreeItem(NewUrb);
         }
 
         //
@@ -803,7 +867,7 @@ PDO_HandleInternalDeviceControl(
         //
         Urb = (PURB)IoStack->Parameters.Others.Argument1;
         ASSERT(Urb);
-        DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
+        DPRINT("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x\n", Urb->UrbHeader.Function);
 
         if (Urb->UrbHeader.Function == URB_FUNCTION_SELECT_CONFIGURATION)
         {
@@ -861,6 +925,24 @@ PDO_HandleInternalDeviceControl(
             return Status;
         }
     }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_GET_PORT_STATUS)
+    {
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+        return Status;
+    }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_RESET_PORT)
+    {
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+        return Status;
+    }
+    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_CYCLE_PORT)
+    {
+        IoSkipCurrentIrpStackLocation(Irp);
+        Status = IoCallDriver(PDODeviceExtension->NextDeviceObject, Irp);
+        return Status;
+    }