[ros-diffs] [janderwald] 55799: [USBUHCI] - Sync shared parts with usbohci driver - Fixes memory bug, includes data toggle support, device cleanup etc...

janderwald at svn.reactos.org janderwald at svn.reactos.org
Tue Feb 21 23:18:46 UTC 2012


Author: janderwald
Date: Tue Feb 21 23:18:46 2012
New Revision: 55799

URL: http://svn.reactos.org/svn/reactos?rev=55799&view=rev
Log:
[USBUHCI]
- Sync shared parts with usbohci driver
- Fixes memory bug, includes data toggle support, device cleanup etc...

Modified:
    trunk/reactos/drivers/usb/usbuhci/hcd_controller.cpp
    trunk/reactos/drivers/usb/usbuhci/hub_controller.cpp
    trunk/reactos/drivers/usb/usbuhci/interfaces.h
    trunk/reactos/drivers/usb/usbuhci/memory_manager.cpp
    trunk/reactos/drivers/usb/usbuhci/usb_device.cpp
    trunk/reactos/drivers/usb/usbuhci/usb_queue.cpp
    trunk/reactos/drivers/usb/usbuhci/usb_request.cpp
    trunk/reactos/drivers/usb/usbuhci/usbuhci.h

Modified: trunk/reactos/drivers/usb/usbuhci/hcd_controller.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hcd_controller.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/hcd_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/hcd_controller.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -234,7 +234,7 @@
     //
     PC_ASSERT(DeviceExtension->IsFDO);
 
-    DPRINT1("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n",
+    DPRINT("HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n",
         IoStack->Parameters.DeviceIoControl.IoControlCode,
         IoStack->Parameters.DeviceIoControl.InputBufferLength,
         IoStack->Parameters.DeviceIoControl.OutputBufferLength);
@@ -394,7 +394,7 @@
     {
         case IRP_MN_START_DEVICE:
         {
-            DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO\n");
+            DPRINT("CHCDController::HandlePnp IRP_MN_START FDO\n");
 
             //
             // first start lower device object
@@ -423,12 +423,12 @@
                 Status = SetSymbolicLink(TRUE);
             }
 
-            DPRINT1("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status);
+            DPRINT("CHCDController::HandlePnp IRP_MN_START FDO: Status %x\n", Status);
             break;
         }
         case IRP_MN_QUERY_DEVICE_RELATIONS:
         {
-            DPRINT1("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type);
+            DPRINT("CHCDController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", IoStack->Parameters.QueryDeviceRelations.Type);
 
             if (m_HubController == NULL)
             {
@@ -502,14 +502,13 @@
                 //
                 // not supported
                 //
-                PC_ASSERT(0);
                 Status = STATUS_NOT_SUPPORTED;
             }
             break;
         }
         case IRP_MN_STOP_DEVICE:
         {
-            DPRINT1("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n");
+            DPRINT("CHCDController::HandlePnp IRP_MN_STOP_DEVICE\n");
 
             if (m_Hardware)
             {
@@ -535,9 +534,34 @@
             }
             break;
         }
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        case IRP_MN_QUERY_STOP_DEVICE:
+        {
+            //
+            // sure
+            //
+            Irp->IoStatus.Status = STATUS_SUCCESS;
+
+            //
+            // forward irp to next device object
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            return IoCallDriver(m_NextDeviceObject, Irp);
+        }
         case IRP_MN_REMOVE_DEVICE:
         {
-            DPRINT1("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n");
+            DPRINT("CHCDController::HandlePnp IRP_MN_REMOVE_DEVICE FDO\n");
+
+            //
+            // delete the symbolic link
+            //
+            SetSymbolicLink(FALSE);
+
+            //
+            // forward irp to next device object
+            //
+            IoSkipCurrentIrpStackLocation(Irp);
+            IoCallDriver(m_NextDeviceObject, Irp);
 
             //
             // detach device from device stack
@@ -549,8 +573,7 @@
             //
             IoDeleteDevice(m_FunctionalDeviceObject);
 
-            Status = STATUS_SUCCESS;
-            break;
+            return STATUS_SUCCESS;
         }
         default:
         {
@@ -650,7 +673,7 @@
     //
     m_FDODeviceNumber = UsbDeviceNumber;
 
-    DPRINT1("CreateFDO: DeviceName %wZ\n", &DeviceName);
+    DPRINT("CreateFDO: DeviceName %wZ\n", &DeviceName);
 
     /* done */
     return Status;

Modified: trunk/reactos/drivers/usb/usbuhci/hub_controller.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/hub_controller.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/hub_controller.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/hub_controller.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -70,6 +70,9 @@
     NTSTATUS HandleClassEndpoint(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleBulkOrInterruptTransfer(IN OUT PIRP Irp, PURB Urb);
     NTSTATUS HandleIsochronousTransfer(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleClearStall(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleSyncResetAndClearStall(IN OUT PIRP Irp, PURB Urb);
+    NTSTATUS HandleAbortPipe(IN OUT PIRP Irp, PURB Urb);
 
     friend VOID StatusChangeEndpointCallBack(PVOID Context);
 
@@ -190,7 +193,7 @@
     USHORT VendorID, DeviceID;
     ULONG Dummy1;
 
-    DPRINT1("CHubController::Initialize\n");
+    DPRINT("CHubController::Initialize\n");
 
     //
     // initialize members
@@ -305,7 +308,7 @@
     // Get the number of ports and check each one for device connected
     //
     m_Hardware->GetDeviceDetails(NULL, NULL, &PortCount, NULL);
-    DPRINT1("SCE Request %p TransferBufferLength %lu Flags %x MDL %p\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength, Urb->UrbBulkOrInterruptTransfer.TransferFlags, Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
+    DPRINT("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;
 
@@ -316,7 +319,7 @@
     {
         m_Hardware->GetPortStatus(PortId, &PortStatus, &PortChange);
 
-        DPRINT1("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
+        DPRINT("Port %d: Status %x, Change %x\n", PortId, PortStatus, PortChange);
 
 
         //
@@ -427,16 +430,25 @@
     {
         case IRP_MN_START_DEVICE:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_START_DEVICE\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_START_DEVICE\n");
             //
             // register device interface 
             //
             Status = SetDeviceInterface(TRUE);
             break;
         }
+        case IRP_MN_QUERY_STOP_DEVICE:
+        case IRP_MN_QUERY_REMOVE_DEVICE:
+        {
+            //
+            // sure
+            //
+            Status = STATUS_SUCCESS;
+            break;
+        }
         case IRP_MN_QUERY_ID:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
+            DPRINT("CHubController::HandlePnp IRP_MN_QUERY_ID Type %x\n", IoStack->Parameters.QueryId.IdType);
 
             if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID)
             {
@@ -462,7 +474,7 @@
                         swprintf(Buffer, L"USB\\ROOT_HUB");
                     }
 
-                    DPRINT1("Name %S\n", Buffer);
+                    DPRINT("Name %S\n", Buffer);
 
                     //
                     // calculate length
@@ -539,7 +551,7 @@
                    Index++;
 
 
-                    DPRINT1("Name %S\n", Buffer);
+                    DPRINT("Name %S\n", Buffer);
 
                     //
                     // allocate buffer
@@ -573,7 +585,7 @@
         }
         case IRP_MN_QUERY_CAPABILITIES:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_QUERY_CAPABILITIES\n");
 
             DeviceCapabilities = (PDEVICE_CAPABILITIES)IoStack->Parameters.DeviceCapabilities.Capabilities;
 
@@ -593,7 +605,7 @@
             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;
@@ -605,7 +617,7 @@
         }
         case IRP_MN_QUERY_INTERFACE:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_QUERY_INTERFACE\n");
 
             //
             // handle device interface requests
@@ -615,7 +627,7 @@
         }
         case IRP_MN_REMOVE_DEVICE:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_REMOVE_DEVICE\n");
 
             //
             // deactivate device interface for BUS PDO
@@ -645,7 +657,7 @@
         }
         case IRP_MN_QUERY_DEVICE_RELATIONS:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack->Parameters.QueryDeviceRelations.Type);
+            DPRINT("CHubController::HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %x\n", IoStack->Parameters.QueryDeviceRelations.Type);
 
             if (IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
             {
@@ -686,7 +698,7 @@
         }
         case IRP_MN_QUERY_BUS_INFORMATION:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_QUERY_BUS_INFORMATION\n");
 
             //
             // allocate buffer for bus information
@@ -719,7 +731,7 @@
         }
         case IRP_MN_STOP_DEVICE:
         {
-            DPRINT1("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n");
+            DPRINT("CHubController::HandlePnp IRP_MN_STOP_DEVICE\n");
             //
             // stop device
             //
@@ -790,7 +802,15 @@
     //
     // check if this is a valid usb device handle
     //
-    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    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
@@ -827,7 +847,7 @@
         //
         // Else pend the IRP, to be completed when a device connects or disconnects.
         //
-        DPRINT1("Pending SCE Irp\n");;
+        DPRINT("Pending SCE Irp\n");;
         m_PendingSCEIrp = Irp;
         IoMarkIrpPending(Irp);
         return STATUS_PENDING;
@@ -847,7 +867,15 @@
     //
     // check if this is a valid usb device handle
     //
-    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleBuldOrInterruptTransfer invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
 
     //
     // get device
@@ -984,7 +1012,6 @@
                     // reset port feature
                     //
                     Status = m_Hardware->SetPortFeature(PortId, PORT_RESET);
-                    PC_ASSERT(Status == STATUS_SUCCESS);
                     break;
                 }
                 default:
@@ -1057,7 +1084,15 @@
         //
         // 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
@@ -1099,7 +1134,15 @@
         //
         // 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
@@ -1149,7 +1192,15 @@
     //
     // check if this is a valid usb device handle
     //
-    ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    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
@@ -1172,7 +1223,7 @@
     //
     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);
+    DPRINT("CHubController::HandleGetStatusFromDevice Status %x Length %lu DeviceStatus %x\n", Status, Urb->UrbControlDescriptorRequest.TransferBufferLength, *DeviceStatus);
 
     //
     // done
@@ -1205,7 +1256,15 @@
             //
             // check if this is a valid usb device handle
             //
-            ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+            if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+            {
+                DPRINT1("USB_REQUEST_GET_STATUS invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                //
+                // invalid device handle
+                //
+                return STATUS_DEVICE_NOT_CONNECTED;
+            }
 
             //
             // get device
@@ -1311,7 +1370,15 @@
     //
     // check if this is a valid usb device handle
     //
-    ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    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
@@ -1381,7 +1448,15 @@
                 //
                 // 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
@@ -1452,7 +1527,15 @@
                 //
                 // 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
@@ -1494,11 +1577,18 @@
             PC_ASSERT(Urb->UrbControlDescriptorRequest.TransferBuffer);
             PC_ASSERT(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_STRING_DESCRIPTOR_TYPE invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+                //
+                // invalid device handle
+                //
+                return STATUS_DEVICE_NOT_CONNECTED;
+            }
 
             //
             // get device
@@ -1552,7 +1642,15 @@
     //
     // 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
@@ -1573,12 +1671,21 @@
     //
     // initialize setup packet
     //
-    CtrlSetup.bmRequestType.B = 0xa2; //FIXME: Const.
+    CtrlSetup.bmRequestType.B = 0x22; //FIXME: Const.
     CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
     CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
     CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
     CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
 
+    if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+    {
+        //
+        // data direction is device to host
+        //
+        CtrlSetup.bmRequestType.B |= 0x80;
+    }
+
+
     //
     // issue request
     //
@@ -1595,6 +1702,196 @@
     //
     return Status;
 }
+
+NTSTATUS
+CHubController::HandleSyncResetAndClearStall(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PUSB_ENDPOINT EndpointDescriptor;
+    ULONG Type;
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // abort pipe
+    //
+    Status = HandleAbortPipe(Irp, Urb);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // abort pipe failed
+        //
+        DPRINT1("[USBOHCI] AbortPipe failed with %x\n", Status);
+    }
+
+    //
+    // get type
+    //
+    Type = (EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK);
+    if (Type != USB_ENDPOINT_TYPE_ISOCHRONOUS)
+    {
+        //
+        // clear stall
+        //
+        Status = HandleClearStall(Irp, Urb);
+    }
+    DPRINT1("URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL Status %x\n", Status);
+
+    //
+    // reset data toggle
+    //
+    EndpointDescriptor->DataToggle = 0;
+
+    //
+    // done
+    //
+    return Status;
+}
+
+NTSTATUS
+CHubController::HandleAbortPipe(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT EndpointDescriptor;
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleAbortPipe invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->AbortPipe(EndpointDescriptor);
+    DPRINT1("URB_FUNCTION_ABORT_PIPE Status %x\n", Status);
+
+    //
+    // done
+    //
+    return Status;
+}
+
+
+//-----------------------------------------------------------------------------------------
+NTSTATUS
+CHubController::HandleClearStall(
+    IN OUT PIRP Irp,
+    IN OUT PURB Urb)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    PUSBDEVICE UsbDevice;
+    PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(Urb->UrbHeader.UsbdDeviceHandle);
+    PC_ASSERT(Urb->UrbHeader.Length == sizeof(struct _URB_PIPE_REQUEST));
+    PC_ASSERT(Urb->UrbPipeRequest.PipeHandle);
+
+    //
+    // check if this is a valid usb device handle
+    //
+    if (!ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)))
+    {
+        DPRINT1("HandleClearStall invalid device handle %p\n", Urb->UrbHeader.UsbdDeviceHandle);
+
+        //
+        // invalid device handle
+        //
+        return STATUS_DEVICE_NOT_CONNECTED;
+    }
+
+    //
+    // get endpoint descriptor
+    //
+    EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbPipeRequest.PipeHandle;
+
+    //
+    // get device
+    //
+    UsbDevice = PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle);
+    DPRINT1("URB_FUNCTION_SYNC_CLEAR_STALL\n");
+
+    //
+    // initialize setup packet
+    //
+    CtrlSetup.bmRequestType.B = 0x02;
+    CtrlSetup.bRequest = USB_REQUEST_CLEAR_FEATURE;
+    CtrlSetup.wValue.W = USB_FEATURE_ENDPOINT_STALL;
+    CtrlSetup.wIndex.W = EndpointDescriptor->bEndpointAddress;
+    CtrlSetup.wLength = 0;
+    CtrlSetup.wValue.W = 0;
+
+    //
+    // issue request
+    //
+    Status = UsbDevice->SubmitSetupPacket(&CtrlSetup, 0, 0);
+
+    DPRINT1("URB_FUNCTION_CLEAR_STALL Status %x\n", Status);
+
+    //
+    // done
+    //
+    return Status;
+}
+
 
 //-----------------------------------------------------------------------------------------
 NTSTATUS
@@ -1616,7 +1913,15 @@
     //
     // check if this is a valid usb device handle
     //
-    PC_ASSERT(ValidateUsbDevice(PUSBDEVICE(Urb->UrbHeader.UsbdDeviceHandle)));
+    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
@@ -1634,21 +1939,23 @@
     DPRINT1("Value %x\n", Urb->UrbControlVendorClassRequest.Value);
     DPRINT1("Index %x\n", Urb->UrbControlVendorClassRequest.Index);
 
-    if (Urb->UrbControlVendorClassRequest.TransferBufferLength == 0)
-    {
-        DPRINT1("Invalid request length\n");
-        return STATUS_SUCCESS;
-    }
-
     //
     // initialize setup packet
     //
-    CtrlSetup.bmRequestType.B = 0xa1;
+    CtrlSetup.bmRequestType.B = 0x21;
     CtrlSetup.bRequest = Urb->UrbControlVendorClassRequest.Request;
     CtrlSetup.wValue.W = Urb->UrbControlVendorClassRequest.Value;
     CtrlSetup.wIndex.W = Urb->UrbControlVendorClassRequest.Index;
     CtrlSetup.wLength = Urb->UrbControlVendorClassRequest.TransferBufferLength;
 
+    if (Urb->UrbControlVendorClassRequest.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
+    {
+        //
+        // data direction is device to host
+        //
+        CtrlSetup.bmRequestType.B |= 0x80;
+    }
+
     //
     // issue request
     //
@@ -1657,8 +1964,13 @@
     //
     // assert on failure
     //
-    PC_ASSERT(NT_SUCCESS(Status));
-
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // display error
+        //
+        DPRINT1("URB_FUNCTION_CLASS_INTERFACE failed with Urb Status %x\n", Urb->UrbHeader.Status);
+    }
 
     //
     // done
@@ -1702,6 +2014,16 @@
 
             switch (Urb->UrbHeader.Function)
             {
+                case URB_FUNCTION_SYNC_RESET_PIPE:
+                case URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL:
+                    Status = HandleSyncResetAndClearStall(Irp, Urb);
+                    break;
+                case URB_FUNCTION_ABORT_PIPE:
+                    Status = HandleAbortPipe(Irp, Urb);
+                    break;
+                case URB_FUNCTION_SYNC_CLEAR_STALL:
+                    Status = HandleClearStall(Irp, Urb);
+                    break;
                 case URB_FUNCTION_GET_DESCRIPTOR_FROM_INTERFACE:
                     Status = HandleGetDescriptorFromInterface(Irp, Urb);
                     break;
@@ -2132,7 +2454,7 @@
 {
     CHubController * Controller = (CHubController*)BusContext;
 
-    DPRINT1("USBH_InterfaceReference\n");
+    DPRINT("USBH_InterfaceReference\n");
 
     //
     // add reference
@@ -2147,7 +2469,7 @@
 {
     CHubController * Controller = (CHubController*)BusContext;
 
-    DPRINT1("USBH_InterfaceDereference\n");
+    DPRINT("USBH_InterfaceDereference\n");
 
     //
     // release
@@ -2171,7 +2493,7 @@
     CHubController * Controller;
     NTSTATUS Status;
 
-    DPRINT1("USBHI_CreateUsbDevice\n");
+    DPRINT("USBHI_CreateUsbDevice PortStatus %x\n", PortStatus);
 
     //
     // first get hub controller
@@ -2261,7 +2583,7 @@
     NTSTATUS Status;
     ULONG Index = 0;
 
-    DPRINT1("USBHI_InitializeUsbDevice\n");
+    DPRINT("USBHI_InitializeUsbDevice\n");
 
     //
     // first get controller
@@ -2357,7 +2679,7 @@
     PUSBDEVICE UsbDevice;
     CHubController * Controller;
 
-    DPRINT1("USBHI_GetUsbDescriptors\n");
+    DPRINT("USBHI_GetUsbDescriptors\n");
 
     //
     // sanity check
@@ -2426,7 +2748,7 @@
     CHubController * Controller;
     NTSTATUS Status;
 
-    DPRINT1("USBHI_RemoveUsbDevice\n");
+    DPRINT("USBHI_RemoveUsbDevice\n");
 
     //
     // first get controller
@@ -2499,7 +2821,7 @@
     PUSBDEVICE OldUsbDevice, NewUsbDevice;
     CHubController * Controller;
 
-    DPRINT1("USBHI_RestoreUsbDevice\n");
+    DPRINT("USBHI_RestoreUsbDevice\n");
 
     //
     // first get controller
@@ -2521,8 +2843,8 @@
     PC_ASSERT(Controller->ValidateUsbDevice(NewUsbDevice));
     PC_ASSERT(Controller->ValidateUsbDevice(OldUsbDevice));
 
-    DPRINT1("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress());
-    DPRINT1("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress());
+    DPRINT("NewUsbDevice: DeviceAddress %x\n", NewUsbDevice->GetDeviceAddress());
+    DPRINT("OldUsbDevice: DeviceAddress %x\n", OldUsbDevice->GetDeviceAddress());
 
     //
     // remove old device handle
@@ -2545,7 +2867,7 @@
     PUSBDEVICE UsbDevice;
     CHubController * Controller;
 
-    DPRINT1("USBHI_QueryDeviceInformation %p\n", BusContext);
+    DPRINT("USBHI_QueryDeviceInformation %p\n", BusContext);
 
     //
     // sanity check
@@ -2667,7 +2989,7 @@
 {
     PUSB_CONTROLLER_INFORMATION_0 ControllerInfo;
 
-    DPRINT1("USBHI_GetControllerInformation\n");
+    DPRINT("USBHI_GetControllerInformation\n");
 
     //
     // sanity checks
@@ -2730,7 +3052,7 @@
     USHORT Dummy1;
     NTSTATUS Status;
 
-    DPRINT1("USBHI_GetExtendedHubInformation\n");
+    DPRINT("USBHI_GetExtendedHubInformation\n");
 
     //
     // sanity checks
@@ -2909,7 +3231,7 @@
         // looks like we need apply a dragon voodoo to fixup the device stack
         // otherwise usbhub will cause a bugcheck
         //
-        DPRINT1("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
+        DPRINT("USBHI_SetDeviceHandleData %p\n", UsbDevicePdo);
 
         //
         // sanity check
@@ -2946,7 +3268,7 @@
     ULONG Speed, Dummy2;
     USHORT Dummy1;
 
-    DPRINT1("USBDI_GetUSBDIVersion\n");
+    DPRINT("USBDI_GetUSBDIVersion\n");
 
     //
     // get controller
@@ -3026,7 +3348,7 @@
     ULONG Speed, Dummy2;
     USHORT Dummy1;
 
-    DPRINT1("USBDI_IsDeviceHighSpeed\n");
+    DPRINT("USBDI_IsDeviceHighSpeed\n");
 
     //
     // get controller
@@ -3287,7 +3609,7 @@
     //
     // done
     //
-    return Status;
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS
@@ -3349,7 +3671,7 @@
         }
     }
 
-    DPRINT1("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
+    DPRINT("CHubController::CreatePDO: DeviceName %wZ\n", &DeviceName);
 
     //
     // fixup device stack voodoo part #1
@@ -3407,7 +3729,7 @@
     Irp = This->m_PendingSCEIrp;
     if (!Irp)
     {
-        DPRINT1("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n");
+        DPRINT("There was no pending IRP for SCE. Did the usb hub 2.0 driver (usbhub2) load?\n");
         return;
     }
 

Modified: trunk/reactos/drivers/usb/usbuhci/interfaces.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/interfaces.h?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/interfaces.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/interfaces.h [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -38,6 +38,7 @@
 // a list of registered controllers and provides support functions for the host controllers
 
 struct IHCDController;
+struct _USB_ENDPOINT;
 
 DECLARE_INTERFACE_(IRootHCDController, IUnknown)
 {
@@ -359,8 +360,8 @@
     virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager,
                                                IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
                                                IN UCHAR DeviceAddress,
+                                               IN OPTIONAL struct _USB_ENDPOINT *EndpointDescriptor,
                                                IN USB_DEVICE_SPEED DeviceSpeed,
-                                               IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
                                                IN OUT ULONG TransferBufferLength,
                                                IN OUT PMDL TransferBuffer) = 0;
 
@@ -436,7 +437,6 @@
 // Description: returns device speed
 
     virtual USB_DEVICE_SPEED GetDeviceSpeed() = 0;
-
 };
 
 
@@ -496,6 +496,15 @@
 // Description: creates an usb request
 
     virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest) = 0;
+
+
+//-----------------------------------------------------------------------------------------
+//
+// AbortDevicePipe
+//
+// Description: aborts all pending requsts of an device
+
+    virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor) = 0;
 
 };
 
@@ -750,6 +759,16 @@
 
     virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
                                      IN OUT PUSBD_INTERFACE_INFORMATION Interface) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// AbortPipe
+//
+// Description: aborts all pending requsts of an device
+
+    virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor) = 0;
+
+
 };
 
 typedef IUSBDevice *PUSBDEVICE;

Modified: trunk/reactos/drivers/usb/usbuhci/memory_manager.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/memory_manager.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/memory_manager.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/memory_manager.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -271,7 +271,7 @@
     IN ULONG Size)
 {
     KIRQL OldLevel;
-    ULONG BlockOffset = 0, BlockLength;
+    ULONG BlockOffset = 0, BlockLength, BlockCount;
 
     //
     // sanity checks
@@ -302,14 +302,25 @@
     Size = (Size + m_BlockSize - 1) & ~(m_BlockSize - 1);
 
     //
+    // convert to blocks
+    //
+    BlockCount = Size / m_BlockSize;
+    ASSERT(BlockCount);
+
+    //
     // acquire lock
     //
     KeAcquireSpinLock(m_Lock, &OldLevel);
 
     //
+    // sanity check
+    //
+    ASSERT(RtlAreBitsSet(&m_Bitmap, BlockOffset, BlockCount));
+
+    //
     // release buffer
     //
-    RtlClearBits(&m_Bitmap, BlockOffset, Size);
+    RtlClearBits(&m_Bitmap, BlockOffset, BlockCount);
 
     //
     // release lock

Modified: trunk/reactos/drivers/usb/usbuhci/usb_device.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usb_device.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/usb_device.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/usb_device.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -52,18 +52,20 @@
     virtual NTSTATUS SubmitSetupPacket(IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, OUT ULONG BufferLength, OUT PVOID Buffer);
     virtual NTSTATUS SelectConfiguration(IN PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor, IN PUSBD_INTERFACE_INFORMATION Interface, OUT USBD_CONFIGURATION_HANDLE *ConfigurationHandle);
     virtual NTSTATUS SelectInterface(IN USBD_CONFIGURATION_HANDLE ConfigurationHandle, IN OUT PUSBD_INTERFACE_INFORMATION Interface);
+    virtual NTSTATUS AbortPipe(IN struct _USB_ENDPOINT * EndpointDescriptor);
+
 
     // local function
     virtual NTSTATUS CommitIrp(PIRP Irp);
-    virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
-    virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
+    virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor, IN ULONG BufferLength, IN OUT PMDL Mdl);
+    virtual NTSTATUS CreateConfigurationDescriptor(UCHAR ConfigurationIndex);
     virtual NTSTATUS CreateDeviceDescriptor();
     virtual VOID DumpDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
     virtual VOID DumpConfigurationDescriptor(PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor);
 
     // constructor / destructor
     CUSBDevice(IUnknown *OuterUnknown){}
-    virtual ~CUSBDevice(){}
+    virtual ~CUSBDevice();
 
 protected:
     LONG m_Ref;
@@ -79,8 +81,76 @@
     ULONG m_PortStatus;
     PUSBQUEUE m_Queue;
     PDMAMEMORYMANAGER m_DmaManager;
-    PUSB_CONFIGURATION_DESCRIPTOR *m_ConfigurationDescriptors;
+
+    PUSB_CONFIGURATION m_ConfigurationDescriptors;
 };
+
+CUSBDevice::~CUSBDevice()
+{
+    ULONG Index, InterfaceIndex, EndpointIndex;
+    //NTSTATUS Status;
+
+   if (!m_ConfigurationDescriptors)
+   {
+       //
+       // nothing to do
+       //
+       return;
+   }
+
+
+    //
+    // clean up resources
+    //
+    for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++)
+    {
+        for(InterfaceIndex = 0; InterfaceIndex < m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
+        {
+            //
+            // are there any endpoint descriptors
+            //
+            for(EndpointIndex = 0; EndpointIndex < m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints; EndpointIndex++)
+            {
+                //
+                // abort pipe
+                //
+                //Status = AbortPipe((PUSB_ENDPOINT_DESCRIPTOR)&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndpointIndex]);
+                //DPRINT1("[USBOHCI] Deleting Device Abort Pipe Status %x\n", Status);
+            }
+
+            if (m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints)
+            {
+                //
+                // free endpoints
+                //
+                ExFreePool(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints);
+            }
+        }
+
+        if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor->bNumInterfaces)
+        {
+            //
+            // free interface descriptors
+            //
+            ExFreePool(m_ConfigurationDescriptors[Index].Interfaces);
+        }
+
+        if (m_ConfigurationDescriptors[Index].ConfigurationDescriptor)
+        {
+            //
+            // free configuration descriptor
+            //
+            ExFreePool(m_ConfigurationDescriptors[Index].ConfigurationDescriptor);
+        }
+    }
+
+    //
+    // free configuration descriptor
+    //
+    ExFreePool(m_ConfigurationDescriptors);
+}
+
+
 
 //----------------------------------------------------------------------------------------
 NTSTATUS
@@ -267,7 +337,7 @@
     }
 
     DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n", m_DeviceDescriptor.bcdUSB);
-    PC_ASSERT(FALSE);
+    //PC_ASSERT(FALSE);
 
     return Usb11Device;
 }
@@ -299,7 +369,7 @@
     PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     NTSTATUS Status;
     UCHAR OldAddress;
-    ULONG Index;
+    UCHAR Index;
 
     DPRINT1("CUSBDevice::SetDeviceAddress Address %d\n", DeviceAddress);
 
@@ -381,12 +451,12 @@
     //
     // allocate configuration descriptor
     //
-    m_ConfigurationDescriptors = (PUSB_CONFIGURATION_DESCRIPTOR*) ExAllocatePoolWithTag(NonPagedPool, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) * m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI);
+    m_ConfigurationDescriptors = (PUSB_CONFIGURATION) ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations, TAG_USBOHCI);
 
     //
     // zero configuration descriptor
     //
-    RtlZeroMemory(m_ConfigurationDescriptors, sizeof(PUSB_CONFIGURATION_DESCRIPTOR) * m_DeviceDescriptor.bNumConfigurations);
+    RtlZeroMemory(m_ConfigurationDescriptors, sizeof(USB_CONFIGURATION) * m_DeviceDescriptor.bNumConfigurations);
 
     //
     // retrieve the configuration descriptors
@@ -518,7 +588,7 @@
 NTSTATUS
 CUSBDevice::CommitSetupPacket(
     IN PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
-    IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
+    IN OPTIONAL PUSB_ENDPOINT EndpointDescriptor,
     IN ULONG BufferLength, 
     IN OUT PMDL Mdl)
 {
@@ -550,7 +620,7 @@
     //
     // initialize request
     //
-    Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, GetSpeed(), EndpointDescriptor, BufferLength, Mdl);
+    Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, m_DeviceAddress, (struct _USB_ENDPOINT*)EndpointDescriptor, GetSpeed(), BufferLength, Mdl);
     if (!NT_SUCCESS(Status))
     {
         //
@@ -598,11 +668,24 @@
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     PMDL Mdl;
     NTSTATUS Status;
+    PVOID DeviceDescriptor;
+
+    //
+    // allocate descriptor page aligned
+    //
+    DeviceDescriptor = ExAllocatePool(NonPagedPool, PAGE_SIZE);
+    if (!DeviceDescriptor)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
 
     //
     // zero descriptor
     //
-    RtlZeroMemory(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
+    RtlZeroMemory(DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
     RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
 
     //
@@ -616,7 +699,7 @@
     //
     // allocate mdl describing the device descriptor
     //
-    Mdl = IoAllocateMdl(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR), FALSE, FALSE, 0);
+    Mdl = IoAllocateMdl(DeviceDescriptor, PAGE_SIZE, FALSE, FALSE, 0);
     if (!Mdl)
     {
         //
@@ -645,8 +728,14 @@
         //
         // informal dbg print
         //
+        RtlCopyMemory(&m_DeviceDescriptor, DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR));
         DumpDeviceDescriptor(&m_DeviceDescriptor);
     }
+
+    //
+    // free buffer
+    //
+    ExFreePool(DeviceDescriptor);
 
     //
     // done
@@ -658,13 +747,16 @@
 //----------------------------------------------------------------------------------------
 NTSTATUS
 CUSBDevice::CreateConfigurationDescriptor(
-    ULONG Index)
+    UCHAR Index)
 {
     PVOID Buffer;
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     NTSTATUS Status;
     PMDL Mdl;
+    ULONG InterfaceIndex, EndPointIndex;
     PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
 
 
     //
@@ -683,11 +775,6 @@
         //
         return STATUS_INSUFFICIENT_RESOURCES;
     }
-
-    //
-    // zero buffer
-    //
-    RtlZeroMemory(Buffer, PAGE_SIZE);
 
     //
     // build setup packet
@@ -697,16 +784,12 @@
     CtrlSetup.bmRequestType._BM.Reserved = 0;
     CtrlSetup.bmRequestType._BM.Dir = BMREQUEST_DEVICE_TO_HOST;
     CtrlSetup.bRequest = USB_REQUEST_GET_DESCRIPTOR;
-    CtrlSetup.wValue.LowByte = 0;
+    CtrlSetup.wValue.LowByte = Index;
     CtrlSetup.wValue.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE;
     CtrlSetup.wIndex.W = 0;
     CtrlSetup.wLength = PAGE_SIZE;
 
     //
-    // FIXME: where put configuration index?
-    //
-
-    //
     // now build MDL describing the buffer
     //
     Mdl = IoAllocateMdl(Buffer, PAGE_SIZE, FALSE, FALSE, 0);
@@ -761,9 +844,124 @@
     PC_ASSERT(ConfigurationDescriptor->bNumInterfaces);
 
     //
-    // store configuration descriptor
-    //
-    m_ConfigurationDescriptors[Index] = ConfigurationDescriptor;
+    // request is complete, initialize configuration descriptor
+    //
+    m_ConfigurationDescriptors[Index].ConfigurationDescriptor = ConfigurationDescriptor;
+
+    //
+    // now allocate interface descriptors
+    //
+    m_ConfigurationDescriptors[Index].Interfaces = (PUSB_INTERFACE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces, TAG_USBOHCI);
+    if (!m_ConfigurationDescriptors[Index].Interfaces)
+    {
+        //
+        // failed to allocate interface descriptors
+        //
+        ExFreePool(Buffer);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // zero interface descriptor
+    //
+    RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces, sizeof(USB_INTERFACE) * ConfigurationDescriptor->bNumInterfaces);
+
+    //
+    // get first interface descriptor
+    //
+    InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)(ConfigurationDescriptor + 1);
+
+    //
+    // setup interface descriptors
+    //
+    for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
+    {
+        while(InterfaceDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE && InterfaceDescriptor->bLength != sizeof(USB_INTERFACE_DESCRIPTOR))
+        {
+            //
+            // move to next descriptor
+            //
+            ASSERT(InterfaceDescriptor->bLength);
+            InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)((ULONG_PTR)InterfaceDescriptor + InterfaceDescriptor->bLength);
+        }
+
+        //
+        // sanity checks
+        //
+        ASSERT(InterfaceDescriptor->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE);
+        ASSERT(InterfaceDescriptor->bLength == sizeof(USB_INTERFACE_DESCRIPTOR));
+        ASSERT(InterfaceDescriptor->bNumEndpoints);
+
+        //
+        // copy current interface descriptor
+        //
+        RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].InterfaceDescriptor, InterfaceDescriptor, InterfaceDescriptor->bLength);
+
+        //
+        // allocate end point descriptors
+        //
+        m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints = (PUSB_ENDPOINT)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints, TAG_USBOHCI);
+        if (!m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints)
+        {
+            //
+            // failed to allocate endpoint
+            //
+            Status = STATUS_INSUFFICIENT_RESOURCES;
+            break;
+        }
+
+        //
+        // zero memory
+        //
+        RtlZeroMemory(m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints, sizeof(USB_ENDPOINT) * InterfaceDescriptor->bNumEndpoints);
+
+        //
+        // initialize end point descriptors
+        //
+        EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)(InterfaceDescriptor + 1);
+
+        for(EndPointIndex = 0; EndPointIndex < InterfaceDescriptor->bNumEndpoints; EndPointIndex++)
+        {
+            //
+            // skip other descriptors
+            //
+            while(EndPointDescriptor->bDescriptorType != USB_ENDPOINT_DESCRIPTOR_TYPE && EndPointDescriptor->bLength != sizeof(USB_ENDPOINT_DESCRIPTOR))
+            {
+                //
+                // assert when next interface descriptor is reached before the next endpoint
+                //
+                ASSERT(EndPointDescriptor->bDescriptorType != USB_INTERFACE_DESCRIPTOR_TYPE);
+                ASSERT(EndPointDescriptor->bLength);
+
+                DPRINT1("InterfaceDescriptor  bNumEndpoints %x EndpointIndex %x Skipping Descriptor Type %x\n", InterfaceDescriptor->bNumEndpoints, EndPointIndex, EndPointDescriptor->bDescriptorType);
+                //
+                // move to next descriptor
+                //
+                EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength);
+            }
+
+            //
+            // sanity check
+            //
+            ASSERT(EndPointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
+            ASSERT(EndPointDescriptor->bLength == sizeof(USB_ENDPOINT_DESCRIPTOR));
+
+            //
+            // copy endpoint descriptor
+            //
+            RtlCopyMemory(&m_ConfigurationDescriptors[Index].Interfaces[InterfaceIndex].EndPoints[EndPointIndex].EndPointDescriptor, EndPointDescriptor, EndPointDescriptor->bLength);
+
+            //
+            // move to next offset
+            //
+            EndPointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)((ULONG_PTR)EndPointDescriptor + EndPointDescriptor->bLength);
+        }
+
+        //
+        // update interface descriptor offset
+        //
+        InterfaceDescriptor = (PUSB_INTERFACE_DESCRIPTOR)EndPointDescriptor;
+    }
 
     //
     // done
@@ -797,8 +995,8 @@
     //
     // copy configuration descriptor
     //
-    RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0], min(m_ConfigurationDescriptors[0]->wTotalLength, BufferLength));
-    *OutBufferLength = m_ConfigurationDescriptors[0]->wTotalLength;
+    RtlCopyMemory(ConfigDescriptorBuffer, m_ConfigurationDescriptors[0].ConfigurationDescriptor, min(m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength, BufferLength));
+    *OutBufferLength = m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength;
 }
 
 //----------------------------------------------------------------------------------------
@@ -809,11 +1007,7 @@
     // FIXME: support multiple configurations
     //
     PC_ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
-
-    ASSERT(m_ConfigurationDescriptors[0]);
-    ASSERT(m_ConfigurationDescriptors[0]->wTotalLength);
-
-    return m_ConfigurationDescriptors[0]->wTotalLength;
+    return m_ConfigurationDescriptors[0].ConfigurationDescriptor->wTotalLength;
 }
 //----------------------------------------------------------------------------------------
 VOID
@@ -858,27 +1052,40 @@
     OUT PVOID Buffer)
 {
     NTSTATUS Status;
-    PMDL Mdl;
-
-    //
-    // allocate mdl
-    //
-    Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0);
-
-    //
-    // HACK HACK HACK: assume the buffer is build from non paged pool
-    //
-    MmBuildMdlForNonPagedPool(Mdl);
+    PMDL Mdl = NULL;
+
+    if (BufferLength)
+    {
+        //
+        // allocate mdl
+        //
+        Mdl = IoAllocateMdl(Buffer, BufferLength, FALSE, FALSE, 0);
+        if (!Mdl)
+        {
+            //
+            // no memory
+            //
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        //
+        // HACK HACK HACK: assume the buffer is build from non paged pool
+        //
+        MmBuildMdlForNonPagedPool(Mdl);
+    }
 
     //
     // commit setup packet
     //
     Status = CommitSetupPacket(SetupPacket, 0, BufferLength, Mdl);
 
-    //
-    // free mdl
-    //
-    IoFreeMdl(Mdl);
+    if (Mdl != NULL)
+    {
+        //
+        // free mdl
+        //
+        IoFreeMdl(Mdl);
+    }
 
     //
     // done
@@ -896,25 +1103,70 @@
     ULONG InterfaceIndex, PipeIndex;
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     NTSTATUS Status;
-    PUSB_CONFIGURATION_DESCRIPTOR CurrentConfigurationDescriptor;
-    PUSB_INTERFACE_DESCRIPTOR CurrentInterfaceDescriptor;
-    PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor;
-    PVOID StartPosition;
-
-    //
-    // FIXME: support multiple configurations
-    //
-    ASSERT(m_DeviceDescriptor.bNumConfigurations == 1);
-    ASSERT(m_ConfigurationDescriptors[0]);
-    CurrentConfigurationDescriptor = m_ConfigurationDescriptors[0];
-
-    //
-    // sanity check
-    //
-    PC_ASSERT(ConfigurationDescriptor->iConfiguration == CurrentConfigurationDescriptor->iConfiguration);
-    PC_ASSERT(ConfigurationDescriptor->bNumInterfaces <= CurrentConfigurationDescriptor->bNumInterfaces);
-    DPRINT1("CUSBDevice::SelectConfiguration NumInterfaces %lu\n", ConfigurationDescriptor->bNumInterfaces);
-
+    UCHAR bConfigurationValue = 0;
+
+    if (ConfigurationDescriptor)
+    {
+        //
+        // sanity checks
+        //
+        ASSERT(ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations);
+        ASSERT(ConfigurationDescriptor->iConfiguration == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->iConfiguration);
+
+        //
+        // sanity check
+        //
+        ASSERT(ConfigurationDescriptor->bNumInterfaces <= m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].ConfigurationDescriptor->bNumInterfaces);
+
+        //
+        // get configuration value
+        //
+        bConfigurationValue = ConfigurationDescriptor->bConfigurationValue;
+    }
+
+    //
+    // now build setup packet
+    //
+    RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
+    CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION;
+    CtrlSetup.wValue.W = bConfigurationValue;
+
+    //
+    // select configuration
+    //
+    Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
+
+    if (!ConfigurationDescriptor)
+    {
+        //
+        // unconfigure request
+        //
+        DPRINT1("CUsbDevice::SelectConfiguration Unconfigure Request Status %x\n", Status);
+        m_ConfigurationIndex = 0;
+        return Status;
+    }
+
+    //
+    // informal debug print
+    //
+    DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed
+        //
+        return Status;
+    }
+
+    //
+    // store configuration device index
+    //
+    m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
+
+    //
+    // store configuration handle
+    //
+    *ConfigurationHandle = &m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration];
 
     //
     // copy interface info and pipe info
@@ -922,98 +1174,47 @@
     for(InterfaceIndex = 0; InterfaceIndex < ConfigurationDescriptor->bNumInterfaces; InterfaceIndex++)
     {
         //
-        // find interface descriptor
-        //
-        CurrentInterfaceDescriptor = USBD_ParseConfigurationDescriptor(CurrentConfigurationDescriptor, InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting);
-
-        //
-        // sanity check
-        //
-        ASSERT(CurrentInterfaceDescriptor);
-        ASSERT(CurrentInterfaceDescriptor->bLength != 0);
-        ASSERT(InterfaceInfo->NumberOfPipes == CurrentInterfaceDescriptor->bNumEndpoints);
-        ASSERT(InterfaceInfo->Length != 0);
+        // sanity check: is the info pre-layed out
+        //
+        PC_ASSERT(InterfaceInfo->NumberOfPipes == m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bNumEndpoints);
+        PC_ASSERT(InterfaceInfo->Length != 0);
 #ifdef _MSC_VER
         PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes]));
 #endif
 
-        DPRINT1("CUSBDevice::SelectConfiguration InterfaceNumber %lu AlternativeSetting %lu bNumEndpoints %lu\n", InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting, CurrentInterfaceDescriptor->bNumEndpoints);
-
         //
         // copy interface info
         //
-        InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)CurrentInterfaceDescriptor;
-        InterfaceInfo->Class = CurrentInterfaceDescriptor->bInterfaceClass;
-        InterfaceInfo->SubClass = CurrentInterfaceDescriptor->bInterfaceSubClass;
-        InterfaceInfo->Protocol = CurrentInterfaceDescriptor->bInterfaceProtocol;
+        InterfaceInfo->InterfaceHandle = (USBD_INTERFACE_HANDLE)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex];
+        InterfaceInfo->Class = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceClass;
+        InterfaceInfo->SubClass = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceSubClass;
+        InterfaceInfo->Protocol = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].InterfaceDescriptor.bInterfaceProtocol;
         InterfaceInfo->Reserved = 0;
 
         //
         // copy endpoint info
         //
-        StartPosition = CurrentInterfaceDescriptor;
         for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
         {
             //
-            // find corresponding endpoint descriptor
-            //
-            CurrentEndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(CurrentConfigurationDescriptor, CurrentConfigurationDescriptor->wTotalLength, StartPosition, USB_ENDPOINT_DESCRIPTOR_TYPE);
-
-            //
-            // sanity checks
-            //
-            ASSERT(CurrentEndpointDescriptor);
-            ASSERT(CurrentEndpointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
-
-            //
             // copy pipe info
             //
-            InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = CurrentEndpointDescriptor->wMaxPacketSize;
-            InterfaceInfo->Pipes[PipeIndex].EndpointAddress = CurrentEndpointDescriptor->bEndpointAddress;
-            InterfaceInfo->Pipes[PipeIndex].Interval = CurrentEndpointDescriptor->bInterval;
-            InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes;
-            InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)CurrentEndpointDescriptor;
-
-            //
-            // move start position beyond the current endpoint descriptor
-            //
-            StartPosition = (PVOID)(CurrentEndpointDescriptor + 1);
+            InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.wMaxPacketSize;
+            InterfaceInfo->Pipes[PipeIndex].EndpointAddress = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress;
+            InterfaceInfo->Pipes[PipeIndex].Interval = m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bInterval;
+            InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes;
+            InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)&m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].EndPointDescriptor;
+
+            //
+            // data toggle is reset on configuration requests
+            //
+            m_ConfigurationDescriptors[ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceIndex].EndPoints[PipeIndex].DataToggle = FALSE;
         }
 
         //
         // move offset
         //
         InterfaceInfo = (PUSBD_INTERFACE_INFORMATION)((ULONG_PTR)PtrToUlong(InterfaceInfo) + InterfaceInfo->Length);
-    }
-
-    //
-    // now build setup packet
-    //
-    RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-    CtrlSetup.bRequest = USB_REQUEST_SET_CONFIGURATION;
-    CtrlSetup.wValue.W = ConfigurationDescriptor->bConfigurationValue;
-
-    //
-    // select configuration
-    //
-    Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0);
-
-    //
-    // informal debug print
-    //
-    DPRINT1("CUsbDevice::SelectConfiguration New Configuration %x Old Configuration %x Result %x\n", ConfigurationDescriptor->iConfiguration, m_ConfigurationIndex, Status);
-
-    if (NT_SUCCESS(Status))
-    {
-        //
-        // store configuration device index
-        //
-        m_ConfigurationIndex = ConfigurationDescriptor->iConfiguration;
-
-        //
-        // store configuration handle
-        //
-        *ConfigurationHandle = m_ConfigurationDescriptors[0];
     }
 
     //
@@ -1028,49 +1229,31 @@
     IN USBD_CONFIGURATION_HANDLE ConfigurationHandle,
     IN OUT PUSBD_INTERFACE_INFORMATION InterfaceInfo)
 {
-    PUSB_CONFIGURATION_DESCRIPTOR Configuration;
+    PUSB_CONFIGURATION Configuration;
     ULONG PipeIndex;
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     NTSTATUS Status;
-    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
-    PUSB_ENDPOINT_DESCRIPTOR CurrentEndpointDescriptor;
-    PVOID StartPosition;
-
-    //
-    // FIXME support multiple configurations
-    //
-    PC_ASSERT(m_ConfigurationDescriptors[0] == (PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle);
 
     //
     // get configuration struct
     //
-    Configuration = (PUSB_CONFIGURATION_DESCRIPTOR)ConfigurationHandle;
-
-    //
-    // sanity checks
-    //
-    PC_ASSERT(Configuration->bNumInterfaces > InterfaceInfo->InterfaceNumber);
-#ifdef _MSC_VER
-    //PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes]));
-#endif
-
-    //
-    // FIXME: check bandwidth
-    //
-
-    //
-    // find interface number
-    //
-    InterfaceDescriptor = USBD_ParseConfigurationDescriptor(Configuration, InterfaceInfo->InterfaceNumber, InterfaceInfo->AlternateSetting);
-    ASSERT(InterfaceDescriptor);
+    Configuration = (PUSB_CONFIGURATION)ConfigurationHandle;
+
+    //
+    // sanity check
+    //
+    ASSERT(Configuration->ConfigurationDescriptor->bDescriptorType == USB_CONFIGURATION_DESCRIPTOR_TYPE);
+    ASSERT(Configuration->ConfigurationDescriptor->bLength == sizeof(USB_CONFIGURATION_DESCRIPTOR));
+    ASSERT(Configuration->ConfigurationDescriptor->iConfiguration < m_DeviceDescriptor.bNumConfigurations);
+    ASSERT(&m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration] == Configuration);
 
     //
     // initialize setup packet
     //
     RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
     CtrlSetup.bRequest = USB_REQUEST_SET_INTERFACE;
-    CtrlSetup.wValue.W = InterfaceDescriptor->bAlternateSetting;
-    CtrlSetup.wIndex.W = InterfaceDescriptor->bInterfaceNumber;
+    CtrlSetup.wValue.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bAlternateSetting;
+    CtrlSetup.wIndex.W = Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bInterfaceNumber;
     CtrlSetup.bmRequestType.B = 0x01;
 
     //
@@ -1082,60 +1265,80 @@
     // informal debug print
     //
     DPRINT1("CUSBDevice::SelectInterface AlternateSetting %x InterfaceNumber %x Status %x\n", InterfaceInfo->AlternateSetting, InterfaceInfo->InterfaceNumber, Status);
-    DPRINT1("CUSBDevice::SelectInterface bInterfaceNumber %u bAlternateSetting %u NumberOfPipes %u Length %lu\n", 
-            InterfaceDescriptor->bInterfaceNumber, InterfaceDescriptor->bAlternateSetting, InterfaceInfo->NumberOfPipes, InterfaceInfo->Length);
-    InterfaceInfo->InterfaceHandle =  InterfaceDescriptor;
-    InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints;
-
-    //
-    // are there end points
-    //
-    if (InterfaceDescriptor->bNumEndpoints)
-    {
-        //
-        // sanity check
-        //
-        ASSERT(InterfaceInfo->Length == sizeof(USBD_INTERFACE_INFORMATION) + (InterfaceDescriptor->bNumEndpoints > 1 ? sizeof(USBD_PIPE_INFORMATION) * (InterfaceDescriptor->bNumEndpoints - 1) : 0));
-
-        //
-        // store number of pipes
-        //
-        InterfaceInfo->NumberOfPipes = InterfaceDescriptor->bNumEndpoints;
-
-        StartPosition = InterfaceDescriptor;
-        for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to select interface
+        //
+        return Status;
+    }
+
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(Configuration->ConfigurationDescriptor->bNumInterfaces > InterfaceInfo->InterfaceNumber);
+    PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].InterfaceDescriptor.bNumEndpoints == InterfaceInfo->NumberOfPipes);
+#ifdef _MSC_VER
+    PC_ASSERT(InterfaceInfo->Length == FIELD_OFFSET(USBD_INTERFACE_INFORMATION, Pipes[InterfaceInfo->NumberOfPipes]));
+#endif
+
+    //
+    // copy pipe handles
+    //
+    for(PipeIndex = 0; PipeIndex < InterfaceInfo->NumberOfPipes; PipeIndex++)
+    {
+        //
+        // copy pipe handle
+        //
+        DPRINT1("PipeIndex %lu\n", PipeIndex);
+        DPRINT1("EndpointAddress %x\n", InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+        DPRINT1("Interval %d\n", InterfaceInfo->Pipes[PipeIndex].Interval);
+        DPRINT1("MaximumPacketSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize);
+        DPRINT1("MaximumTransferSize %d\n", InterfaceInfo->Pipes[PipeIndex].MaximumTransferSize);
+        DPRINT1("PipeFlags %d\n", InterfaceInfo->Pipes[PipeIndex].PipeFlags);
+        DPRINT1("PipeType %dd\n", InterfaceInfo->Pipes[PipeIndex].PipeType);
+        DPRINT1("UsbEndPoint %x\n", Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress);
+        PC_ASSERT(Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bEndpointAddress == InterfaceInfo->Pipes[PipeIndex].EndpointAddress);
+
+        InterfaceInfo->Pipes[PipeIndex].PipeHandle = &Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor;
+
+        //
+        // data toggle is reset on select interface requests
+        //
+        m_ConfigurationDescriptors[Configuration->ConfigurationDescriptor->iConfiguration].Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].DataToggle = FALSE;
+
+        if (Configuration->Interfaces[InterfaceInfo->InterfaceNumber].EndPoints[PipeIndex].EndPointDescriptor.bmAttributes & (USB_ENDPOINT_TYPE_ISOCHRONOUS | USB_ENDPOINT_TYPE_INTERRUPT))
         {
             //
-            // find corresponding endpoint descriptor
-            //
-            CurrentEndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)USBD_ParseDescriptors(Configuration, Configuration->wTotalLength, StartPosition, USB_ENDPOINT_DESCRIPTOR_TYPE);
-
-            //
-            // sanity checks
-            //
-            ASSERT(CurrentEndpointDescriptor);
-            ASSERT(CurrentEndpointDescriptor->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE);
-
-            //
-            // copy pipe info
-            //
-            InterfaceInfo->Pipes[PipeIndex].MaximumPacketSize = CurrentEndpointDescriptor->wMaxPacketSize;
-            InterfaceInfo->Pipes[PipeIndex].EndpointAddress = CurrentEndpointDescriptor->bEndpointAddress;
-            InterfaceInfo->Pipes[PipeIndex].Interval = CurrentEndpointDescriptor->bInterval;
-            InterfaceInfo->Pipes[PipeIndex].PipeType = (USBD_PIPE_TYPE)CurrentEndpointDescriptor->bmAttributes;
-            InterfaceInfo->Pipes[PipeIndex].PipeHandle = (PVOID)CurrentEndpointDescriptor;
-
-            //
-            // move start position beyond the current endpoint descriptor
-            //
-            StartPosition = (PVOID)(CurrentEndpointDescriptor + 1);
+            // FIXME: check if enough bandwidth is available
+            //
         }
     }
+
+
     //
     // done
     //
     return Status;
 }
+
+NTSTATUS
+CUSBDevice::AbortPipe(
+    IN struct _USB_ENDPOINT *EndpointDescriptor)
+{
+    //
+    // let it handle usb queue
+    //
+    ASSERT(m_Queue);
+    ASSERT(m_DeviceAddress);
+
+    //
+    // done
+    //
+    return m_Queue->AbortDevicePipe(m_DeviceAddress, EndpointDescriptor);
+}
+
 
 //----------------------------------------------------------------------------------------
 NTSTATUS

Modified: trunk/reactos/drivers/usb/usbuhci/usb_queue.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usb_queue.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/usb_queue.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/usb_queue.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -39,6 +39,8 @@
     virtual NTSTATUS AddUSBRequest(IUSBRequest * Request);
     virtual NTSTATUS CancelRequests();
     virtual NTSTATUS CreateUSBRequest(IUSBRequest **OutRequest);
+    virtual NTSTATUS AbortDevicePipe(UCHAR DeviceAddress, IN struct _USB_ENDPOINT * EndpointDescriptor);
+
 
     // local
     VOID LinkQueueHead(PUHCI_QUEUE_HEAD QueueHead, PUHCI_QUEUE_HEAD NextQueueHead);
@@ -204,6 +206,16 @@
 }
 
 NTSTATUS
+CUSBQueue::AbortDevicePipe(
+    IN UCHAR DeviceAddress,
+    IN struct _USB_ENDPOINT *EndpointDescriptor)
+{
+    UNIMPLEMENTED
+    ASSERT(FALSE);
+    return STATUS_NOT_IMPLEMENTED;
+}
+
+NTSTATUS
 CUSBQueue::CreateUSBRequest(
     IUSBRequest **OutRequest)
 {

Modified: trunk/reactos/drivers/usb/usbuhci/usb_request.cpp
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usb_request.cpp?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/usb_request.cpp [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/usb_request.cpp [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -36,7 +36,7 @@
     }
 
     // IUSBRequest interface functions
-    virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN USB_DEVICE_SPEED DeviceSpeed, IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer);
+    virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN UCHAR DeviceAddress, IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor, IN USB_DEVICE_SPEED DeviceSpeed, IN OUT ULONG TransferBufferLength, IN OUT PMDL TransferBuffer);
     virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT PIRP Irp, IN USB_DEVICE_SPEED DeviceSpeed);
     virtual BOOLEAN IsRequestComplete();
     virtual ULONG GetTransferType();
@@ -119,7 +119,7 @@
     //
     // store end point address
     //
-    PUSB_ENDPOINT_DESCRIPTOR m_EndpointDescriptor;
+    PUSB_ENDPOINT m_EndpointDescriptor;
 
     //
     // allocated setup packet from the DMA pool
@@ -156,8 +156,8 @@
     IN PDMAMEMORYMANAGER DmaManager,
     IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
     IN UCHAR DeviceAddress,
+    IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor,
     IN USB_DEVICE_SPEED DeviceSpeed,
-    IN OPTIONAL PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor,
     IN OUT ULONG TransferBufferLength,
     IN OUT PMDL TransferBuffer)
 {
@@ -321,7 +321,7 @@
             //
             // get endpoint descriptor
             //
-            m_EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbIsochronousTransfer.PipeHandle;
+            m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbIsochronousTransfer.PipeHandle;
 
             //
             // completed initialization
@@ -396,7 +396,7 @@
                 //
                 // get endpoint descriptor
                 //
-                m_EndpointDescriptor = (PUSB_ENDPOINT_DESCRIPTOR)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
+                m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
 
             }
             break;
@@ -461,19 +461,19 @@
     //
     // return max packet size
     //
-    return m_EndpointDescriptor->wMaxPacketSize;
+    return m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
 }
 
 UCHAR
 CUSBRequest::GetInterval()
 {
     ASSERT(m_EndpointDescriptor);
-    ASSERT((m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
+    ASSERT((m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
 
     //
     // return interrupt interval
     //
-    return m_EndpointDescriptor->bInterval;
+    return m_EndpointDescriptor->EndPointDescriptor.bInterval;
 }
 
 UCHAR
@@ -493,7 +493,7 @@
     //
     // endpoint number is between 1-15
     //
-    return (m_EndpointDescriptor->bEndpointAddress & 0xF);
+    return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0xF);
 }
 
 //----------------------------------------------------------------------------------------
@@ -512,7 +512,7 @@
         //
         // end point is defined in the low byte of bmAttributes
         //
-        TransferType = (m_EndpointDescriptor->bmAttributes & USB_ENDPOINT_TYPE_MASK);
+        TransferType = (m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK);
     }
     else
     {
@@ -536,7 +536,7 @@
         //
         // end point direction is highest bit in bEndpointAddress
         //
-        return (m_EndpointDescriptor->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
+        return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
     }
     else
     {

Modified: trunk/reactos/drivers/usb/usbuhci/usbuhci.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/usb/usbuhci/usbuhci.h?rev=55799&r1=55798&r2=55799&view=diff
==============================================================================
--- trunk/reactos/drivers/usb/usbuhci/usbuhci.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/usb/usbuhci/usbuhci.h [iso-8859-1] Tue Feb 21 23:18:46 2012
@@ -107,4 +107,26 @@
 //
 NTSTATUS InternalCreateUSBRequest(PUSBREQUEST *OutRequest);
 
+
+typedef struct _USB_ENDPOINT
+{
+    USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+    UCHAR HubAddress;
+    UCHAR HubPort;
+    UCHAR DataToggle;
+} USB_ENDPOINT, *PUSB_ENDPOINT;
+
+typedef struct _USB_INTERFACE
+{
+    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    USB_ENDPOINT *EndPoints;
+} USB_INTERFACE, *PUSB_INTERFACE;
+
+typedef struct _USB_CONFIGURATION
+{
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+    USB_INTERFACE *Interfaces;
+} USB_CONFIGURATION, *PUSB_CONFIGURATION;
+
+
 #endif




More information about the Ros-diffs mailing list