[USBEHCI/USBOHCI]
[reactos.git] / drivers / usb / usbehci_new / hub_controller.cpp
index 5e37d4a..b24ab7d 100644 (file)
@@ -60,14 +60,17 @@ public:
     VOID SetNotification(PVOID CallbackContext, PRH_INIT_CALLBACK CallbackRoutine);
     // internal ioctl routines
     NTSTATUS HandleGetDescriptor(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleGetDescriptorFromInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassDevice(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleGetStatusFromDevice(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleSelectConfiguration(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleSelectInterface(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassOther(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleClassInterface(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
-    
+    NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb);
+
     friend VOID StatusChangeEndpointCallBack(PVOID Context);
 
     // constructor / destructor
@@ -305,31 +308,30 @@ CHubController::QueryStatusChageEndpoint(
     DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
 
     TransferBuffer = (PUCHAR)Urb->UrbBulkOrInterruptTransfer.TransferBuffer;
+
+    //
+    // Loop the ports
+    //
     for (PortId = 0; PortId < PortCount; PortId++)
     {
         m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
 
         DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
 
+
         //
-        // Loop the ports
+        // If theres a flag in PortChange return TRUE so the SCE Irp will be completed
         //
-        if ((PortStatus & USB_PORT_STATUS_CONNECT) && (PortChange & USB_PORT_STATUS_CONNECT))
+        if (PortChange != 0)
         {
-            DPRINT1("Device is connected on port %d\n", PortId);
+            DPRINT1("Change state on port %d\n", PortId);
             // Set the value for the port number
              *TransferBuffer = 1 << ((PortId + 1) & 7);
             Changed = TRUE;
         }
     }
 
-    //
-    // If there were changes then return TRUE
-    //
-    if (Changed != 0)
-        return TRUE;
-
-    return FALSE;
+    return Changed;
 }
 
 //-----------------------------------------------------------------------------------------
@@ -591,7 +593,7 @@ CHubController::HandlePnp(
             DeviceCapabilities->HardwareDisabled = FALSE;
             DeviceCapabilities->NoDisplayInUI = FALSE;
             DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
-            for (Index = 0; Index < PowerSystemMaximum; Index++)
+            for (Index = 1; Index < PowerSystemMaximum; Index++)
                 DeviceCapabilities->DeviceState[Index] = PowerDeviceD3;
             DeviceCapabilities->DeviceWake = PowerDeviceUnspecified;
             DeviceCapabilities->D1Latency = 0;
@@ -757,6 +759,55 @@ CHubController::HandlePower(
     IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_NOT_IMPLEMENTED;
 }
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleIsochronousTransfer(
+    IN OUT PIRP Irp, 
+    PURB Urb)
+{
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndPointDesc = NULL;
+
+    //
+    // Check PipeHandle to determine if this is a Bulk or Interrupt Transfer Request
+    //
+    EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle;
+
+    if (!EndPointDesc)
+    {
+        DPRINT1("No EndpointDesc\n");
+        Urb->UrbIsochronousTransfer.Hdr.Status = USBD_STATUS_INVALID_PIPE_HANDLE;
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    //
+    // sanity checks
+    //
+    ASSERT(EndPointDesc);
+    ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_ISOCHRONOUS);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleIsochronousTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+    return UsbDevice->SubmitIrp(Irp);
+}
+
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleBulkOrInterruptTransfer(
@@ -777,6 +828,7 @@ CHubController::HandleBulkOrInterruptTransfer(
         ASSERT(m_PendingSCEIrp == NULL);
         if (QueryStatusChageEndpoint(Irp))
         {
+            StatusChangeEndpointCallBack(this);
             return STATUS_SUCCESS;
         }
 
@@ -794,27 +846,24 @@ CHubController::HandleBulkOrInterruptTransfer(
     //
     EndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
 
-    switch(EndPointDesc->bmAttributes & 0x0F)
-    {
-        case USB_ENDPOINT_TYPE_CONTROL:
-            DPRINT1("Control Transfer is not expected!!!\n");
-            return STATUS_INVALID_DEVICE_REQUEST;
-        case USB_ENDPOINT_TYPE_BULK:
-            DPRINT("Initiating Bulk Transfer\n");
-            break;
-        case USB_ENDPOINT_TYPE_ISOCHRONOUS:
-        case USB_ENDPOINT_TYPE_INTERRUPT:
-            DPRINT1("Not Supported\n");
-            break;
-        default:
-            DPRINT1("Unknown EndPoint Type!\n");
-            break;
-    }
+    //
+    // sanity checks
+    //
+    ASSERT(EndPointDesc);
+    ASSERT((EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK || (EndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
 
     //
     // check if this is a valid usb device handle
     //
-    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleBulkOrInterruptTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     //
     // get device
@@ -1024,7 +1073,15 @@ CHubController::HandleSelectConfiguration(
         //
         // check if this is a valid usb device handle
         //
-        PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+        if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+        {
+            DPRINT1("HandleSelectConfiguration invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+            //
+            // invalid device handle
+            //
+            return STATUS_DEVICE_NOT_CONNECTED;
+        }
 
         //
         // get device
@@ -1066,7 +1123,15 @@ CHubController::HandleSelectInterface(
         //
         // check if this is a valid usb device handle
         //
-        PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+        if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+        {
+            DPRINT1("HandleSelectInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+            //
+            // invalid device handle
+            //
+            return STATUS_DEVICE_NOT_CONNECTED;
+        }
 
         //
         // get device
@@ -1086,7 +1151,10 @@ CHubController::HandleGetStatusFromDevice(
     IN OUT PIRP Irp, 
     PURB Urb)
 {
-    PUSHORT Status;
+    PUSHORT DeviceStatus;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
 
     //
     // sanity checks
@@ -1094,22 +1162,62 @@ CHubController::HandleGetStatusFromDevice(
     PC_ASSERT(Urb->UrbControlGetStatusRequest.Index == 0);
     PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBufferLength >= sizeof(USHORT));
     PC_ASSERT(Urb->UrbControlGetStatusRequest.TransferBuffer);
-    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle == NULL); 
 
     //
     // get status buffer
     //
-    Status = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
+    DeviceStatus = (PUSHORT)Urb->UrbControlGetStatusRequest.TransferBuffer;
+
+
+    if (Urb->UrbHeader.UsbdDeviceHandle == NULL)
+    {
+        //
+        // FIXME need more flags ?
+        //
+        *DeviceStatus = USB_PORT_STATUS_CONNECT;
+        return STATUS_SUCCESS;
+    }
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleGetStatusFromDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+     //
+     // generate setup packet
+     //
+     CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
+     CtrlSetup.wValue.LowByte = 0;
+     CtrlSetup.wValue.HiByte = 0;
+     CtrlSetup.wIndex.W = Urb->UrbControlGetStatusRequest.Index; 
+     CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
+     CtrlSetup.bmRequestType.B = 0x80;
 
     //
-    // FIXME need more flags ?
+    // submit setup packet
     //
-    *Status = USB_PORT_STATUS_CONNECT;
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+    ASSERT(Status == STATUS_SUCCESS);
+    DPRINT1("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus);
 
     //
     // done
     //
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 //-----------------------------------------------------------------------------------------
@@ -1122,6 +1230,8 @@ CHubController::HandleClassDevice(
     PUSB_HUB_DESCRIPTOR UsbHubDescriptor;
     ULONG PortCount, Dummy2;
     USHORT Dummy1;
+    PUSBDEVICE UsbDevice;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
 
     DPRINT("CHubController::HandleClassDevice Request %x Class %x\n", Urb->UrbControlVendorClassRequest.Request, Urb->UrbControlVendorClassRequest.Value >> 8);
 
@@ -1130,6 +1240,44 @@ CHubController::HandleClassDevice(
     //
     switch(Urb->UrbControlVendorClassRequest.Request)
     {
+        case USB_REQUEST_GET_STATUS:
+        {
+            //
+            // check if this is a valid usb device handle
+            //
+            if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+            {
+                DPRINT1("HandleClassDevice invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                //
+                // invalid device handle
+                //
+                return STATUS_DEVICE_NOT_CONNECTED;
+            }
+
+            //
+            // get device
+            //
+            UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+            //
+            // generate setup packet
+            //
+            CtrlSetup.bRequest = USB_REQUEST_GET_STATUS;
+            CtrlSetup.wValue.LowByte = Urb->UrbControlVendorClassRequest.Index;
+            CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+            CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+            CtrlSetup.wLength = (USHORT)Urb->UrbControlGetStatusRequest.TransferBufferLength;
+            CtrlSetup.bmRequestType.B = 0xA0;
+
+            //
+            // submit setup packet
+            //
+            Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+            ASSERT(Status == STATUS_SUCCESS);
+            break;
+        }
         case USB_REQUEST_GET_DESCRIPTOR:
         {
             switch (Urb->UrbControlVendorClassRequest.Value >> 8)
@@ -1191,6 +1339,63 @@ CHubController::HandleClassDevice(
 
     return Status;
 }
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleGetDescriptorFromInterface(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    PUSBDEVICE UsbDevice;
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+
+    //
+    // sanity check
+    //
+    ASSERT(Urb->UrbControlDescriptorRequest.TransferBufferLength);
+    ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleGetDescriptorFromInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // generate setup packet
+    //
+    CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
+    CtrlSetup.wValue.LowByte = Urb->UrbControlDescriptorRequest.Index;
+    CtrlSetup.wValue.HiByte = Urb->UrbControlDescriptorRequest.DescriptorType;
+    CtrlSetup.wIndex.W = Urb->UrbControlDescriptorRequest.LanguageId;
+    CtrlSetup.wLength = (USHORT)Urb->UrbControlDescriptorRequest.TransferBufferLength;
+    CtrlSetup.bmRequestType.B = 0x81;
+
+    //
+    // submit setup packet
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlDescriptorRequest.TransferBufferLength, Urb->UrbControlDescriptorRequest.TransferBuffer);
+    ASSERT(Status == STATUS_SUCCESS);
+
+    //
+    // done
+    //
+    return Status;
+}
+
 //-----------------------------------------------------------------------------------------
 NTSTATUS
 CHubController::HandleGetDescriptor(
@@ -1232,7 +1437,15 @@ CHubController::HandleGetDescriptor(
                 //
                 // check if this is a valid usb device handle
                 //
-                PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+                if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+                {
+                    DPRINT1("HandleGetDescriptor invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                    //
+                    // invalid device handle
+                    //
+                    return STATUS_DEVICE_NOT_CONNECTED;
+                }
 
                 //
                 // get device
@@ -1300,12 +1513,18 @@ CHubController::HandleGetDescriptor(
             }
             else
             {
-                DPRINT1("Length %u\n", Urb->UrbControlDescriptorRequest.TransferBufferLength);
-
                 //
                 // check if this is a valid usb device handle
                 //
-                PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+                if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+                {
+                    DPRINT1("USB_CONFIGURATION_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                    //
+                    // invalid device handle
+                    //
+                    return STATUS_DEVICE_NOT_CONNECTED;
+                }
 
                 //
                 // get device
@@ -1356,7 +1575,15 @@ CHubController::HandleGetDescriptor(
             //
             // check if this is a valid usb device handle
             //
-            PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+            if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+            {
+                DPRINT1("USB_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                //
+                // invalid device handle
+                //
+                return STATUS_DEVICE_NOT_CONNECTED;
+            }
 
             //
             // get device
@@ -1392,7 +1619,7 @@ CHubController::HandleGetDescriptor(
 
 //-----------------------------------------------------------------------------------------
 NTSTATUS
-CHubController::HandleClassInterface(
+CHubController::HandleClassEndpoint(
     IN OUT PIRP Irp,
     IN OUT PURB Urb)
 {
@@ -1410,7 +1637,87 @@ CHubController::HandleClassInterface(
     //
     // check if this is a valid usb device handle
     //
-    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleClassEndpoint invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+    DPRINT1("URB_FUNCTION_CLASS_ENDPOINT\n");
+    DPRINT1("TransferFlags %x\n", Urb->UrbControlVendorClassRequest.TransferFlags);
+    DPRINT1("TransferBufferLength %x\n", Urb->UrbControlVendorClassRequest.TransferBufferLength);
+    DPRINT1("TransferBuffer %x\n", Urb->UrbControlVendorClassRequest.TransferBuffer);
+    DPRINT1("TransferBufferMDL %x\n", Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+    DPRINT1("RequestTypeReservedBits %x\n", Urb->UrbControlVendorClassRequest.RequestTypeReservedBits);
+    DPRINT1("Request %x\n", Urb->UrbControlVendorClassRequest.Request);
+    DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
+    DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
+
+    //
+    // initialize setup packet
+    //
+    CtrlSetup.bmRequestType.B = 0xa2; //FIXME: Const.
+    CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
+    CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
+    CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
+    CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, Urb->UrbControlVendorClassRequest.TransferBufferLength, Urb->UrbControlVendorClassRequest.TransferBuffer);
+
+    //
+    // assert on failure
+    //
+    PC_ASSERT(NT_SUCCESS(Status));
+
+
+    //
+    // done
+    //
+    return Status;
+}
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClassInterface(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+
+    //
+    // sanity check
+    //
+    //ASSERT(Urb->UrbControlVendorClassRequest.TransferBuffer || Urb->UrbControlVendorClassRequest.TransferBufferMDL);
+    //ASSERT(Urb->UrbControlVendorClassRequest.TransferBufferLength);
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleClassInterface invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     //
     // get device
@@ -1490,6 +1797,9 @@ CHubController::HandleDeviceControl(
 
             switch (Urb->UrbHeader.Function)
             {
+                case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
+                    Status = HandleGetDescriptorFromInterface(Irp, Urb);
+                    break;
                 case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
                     Status = HandleGetDescriptor(Irp, Urb);
                     break;
@@ -1511,9 +1821,15 @@ CHubController::HandleDeviceControl(
                 case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
                     Status = HandleBulkOrInterruptTransfer(Irp, Urb);
                     break;
+                case URB_FUNCTION_ISOCH_TRANSFER:
+                    Status = HandleIsochronousTransfer(Irp, Urb);
+                    break;
                 case URB_FUNCTION_CLASS_INTERFACE:
                     Status = HandleClassInterface(Irp, Urb);
                     break;
+                case URB_FUNCTION_CLASS_ENDPOINT:
+                    Status = HandleClassEndpoint(Irp, Urb);
+                    break;
                 default:
                     DPRINT1("IOCTL_INTERNAL_USB_SUBMIT_URB Function %x NOT IMPLEMENTED\n", Urb->UrbHeader.Function);
                     break;
@@ -2094,7 +2410,7 @@ USBHI_InitializeUsbDevice(
         if (NT_SUCCESS(Status))
             break;
 
-    }while(Index++ < 3 );
+    }while(Index++ < 3    );
 
     //
     // check for failure
@@ -2301,12 +2617,8 @@ USBHI_RestoreUsbDevice(
     PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice));
 
     DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress());
-
-
     DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress());
 
-    PC_ASSERT(FALSE);
-
     //
     // remove old device handle
     //
@@ -2705,11 +3017,6 @@ USBHI_SetDeviceHandleData(
         //
         DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
 
-        //
-        // fixup device stack voodoo part #1
-        //
-        UsbDevicePdo->StackSize++;
-
         //
         // sanity check
         //
@@ -3088,7 +3395,7 @@ CHubController::SetDeviceInterface(
     //
     // done
     //
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -3152,6 +3459,11 @@ CHubController::CreatePDO(
 
     DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
 
+    //
+    // fixup device stack voodoo part #1
+    //
+    (*OutDeviceObject)->StackSize++;
+
     /* done */
     return Status;
 }