[SDK][USB] Delete old USB drivers and libusb
[reactos.git] / drivers / usb / usbuhci / usb_request.cpp
diff --git a/drivers/usb/usbuhci/usb_request.cpp b/drivers/usb/usbuhci/usb_request.cpp
deleted file mode 100644 (file)
index 0b667b6..0000000
+++ /dev/null
@@ -1,1446 +0,0 @@
-/*
- * PROJECT:     ReactOS Universal Serial Bus Host Controller Interface
- * LICENSE:     GPL - See COPYING in the top level directory
- * FILE:        drivers/usb/usbuhci/usb_request.cpp
- * PURPOSE:     USB UHCI device driver.
- * PROGRAMMERS:
- *              Michael Martin (michael.martin@reactos.org)
- *              Johannes Anderwald (johannes.anderwald@reactos.org)
- */
-
-#include "usbuhci.h"
-
-#define NDEBUG
-#include <debug.h>
-
-class CUSBRequest : public IUHCIRequest
-{
-public:
-    STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
-
-    STDMETHODIMP_(ULONG) AddRef()
-    {
-        InterlockedIncrement(&m_Ref);
-        return m_Ref;
-    }
-    STDMETHODIMP_(ULONG) Release()
-    {
-        InterlockedDecrement(&m_Ref);
-
-        if (!m_Ref)
-        {
-            delete this;
-            return 0;
-        }
-        return m_Ref;
-    }
-
-    // com
-    IMP_IUSBREQUEST
-    IMP_IUHCIREQUEST
-
-    // local functions
-    ULONG InternalGetTransferType();
-    UCHAR InternalGetPidDirection();
-    UCHAR GetDeviceAddress();
-    NTSTATUS BuildSetupPacket();
-    NTSTATUS BuildSetupPacketFromURB();
-    UCHAR GetEndpointAddress();
-    USHORT GetMaxPacketSize();
-    NTSTATUS CreateDescriptor(PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor, IN UCHAR PidCode, ULONG BufferLength);
-    NTSTATUS BuildControlTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
-    NTSTATUS BuildBulkInterruptTransferDescriptor(IN PUHCI_QUEUE_HEAD * OutQueueHead);
-    NTSTATUS BuildQueueHead(OUT PUHCI_QUEUE_HEAD *OutQueueHead);
-    VOID FreeDescriptor(IN PUHCI_TRANSFER_DESCRIPTOR Descriptor);
-    NTSTATUS BuildTransferDescriptorChain(IN PVOID TransferBuffer, IN ULONG TransferBufferLength, IN UCHAR PidCode, IN UCHAR InitialDataToggle, OUT PUHCI_TRANSFER_DESCRIPTOR * OutFirstDescriptor, OUT PUHCI_TRANSFER_DESCRIPTOR * OutLastDescriptor, OUT PULONG OutTransferBufferOffset, OUT PUCHAR OutDataToggle);
-
-    // constructor / destructor
-    CUSBRequest(IUnknown *OuterUnknown);
-    virtual ~CUSBRequest();
-
-protected:
-    LONG m_Ref;
-
-    //
-    // memory manager for allocating setup packet / queue head / transfer descriptors
-    //
-    PDMAMEMORYMANAGER m_DmaManager;
-
-    //
-    // caller provided irp packet containing URB request
-    //
-    PIRP m_Irp;
-
-    //
-    // transfer buffer length
-    //
-    ULONG m_TransferBufferLength;
-
-    //
-    // current transfer length
-    //
-    ULONG m_TransferBufferLengthCompleted;
-
-    //
-    // Total Transfer Length
-    //
-    ULONG m_TotalBytesTransferred;
-
-    //
-    // transfer buffer MDL
-    //
-    PMDL m_TransferBufferMDL;
-
-    //
-    // caller provided setup packet
-    //
-    PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket;
-
-    //
-    // completion event for callers who initialized request with setup packet
-    //
-    PKEVENT m_CompletionEvent;
-
-    //
-    // device address for callers who initialized it with device address
-    //
-    UCHAR m_DeviceAddress;
-
-    //
-    // store end point address
-    //
-    PUSB_ENDPOINT m_EndpointDescriptor;
-
-    //
-    // allocated setup packet from the DMA pool
-    //
-    PUSB_DEFAULT_PIPE_SETUP_PACKET m_DescriptorPacket;
-    PHYSICAL_ADDRESS m_DescriptorSetupPacket;
-
-    //
-    // stores the result of the operation
-    //
-    NTSTATUS m_NtStatusCode;
-    ULONG m_UrbStatusCode;
-
-    //
-    // store device speed
-    //
-    USB_DEVICE_SPEED m_DeviceSpeed;
-
-    // base
-    PVOID m_Base;
-
-};
-
-//----------------------------------------------------------------------------------------
-CUSBRequest::CUSBRequest(IUnknown *OuterUnknown) :
-    m_CompletionEvent(NULL)
-{
-    UNREFERENCED_PARAMETER(OuterUnknown);
-}
-
-//----------------------------------------------------------------------------------------
-CUSBRequest::~CUSBRequest()
-{
-    if (m_CompletionEvent != NULL)
-    {
-        ExFreePoolWithTag(m_CompletionEvent, TAG_USBUHCI);
-    }
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-STDMETHODCALLTYPE
-CUSBRequest::QueryInterface(
-    IN  REFIID refiid,
-    OUT PVOID* Output)
-{
-    return STATUS_UNSUCCESSFUL;
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBRequest::InitializeWithSetupPacket(
-    IN PDMAMEMORYMANAGER DmaManager,
-    IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket,
-    IN PUSBDEVICE Device,
-    IN OPTIONAL struct _USB_ENDPOINT * EndpointDescriptor,
-    IN OUT ULONG TransferBufferLength,
-    IN OUT PMDL TransferBuffer)
-{
-    //
-    // sanity checks
-    //
-    PC_ASSERT(DmaManager);
-    PC_ASSERT(SetupPacket);
-
-    //
-    // initialize packet
-    //
-    m_DmaManager = DmaManager;
-    m_SetupPacket = SetupPacket;
-    m_TransferBufferLength = TransferBufferLength;
-    m_TransferBufferMDL = TransferBuffer;
-    m_DeviceAddress = Device->GetDeviceAddress();
-    m_EndpointDescriptor = EndpointDescriptor;
-    m_TotalBytesTransferred = 0;
-    m_DeviceSpeed = Device->GetSpeed();
-
-    //
-    // Set Length Completed to 0
-    //
-    m_TransferBufferLengthCompleted = 0;
-
-    //
-    // allocate completion event
-    //
-    m_CompletionEvent = (PKEVENT)ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_USBUHCI);
-    if (!m_CompletionEvent)
-    {
-        //
-        // failed to allocate completion event
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // initialize completion event
-    //
-    KeInitializeEvent(m_CompletionEvent, NotificationEvent, FALSE);
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBRequest::InitializeWithIrp(
-    IN PDMAMEMORYMANAGER DmaManager,
-    IN PUSBDEVICE Device,
-    IN OUT PIRP Irp)
-{
-    PIO_STACK_LOCATION IoStack;
-    PURB Urb;
-
-    //
-    // sanity checks
-    //
-    PC_ASSERT(DmaManager);
-    PC_ASSERT(Irp);
-
-    m_DmaManager = DmaManager;
-    m_TotalBytesTransferred = 0;
-    m_DeviceSpeed = Device->GetSpeed();
-
-    //
-    // get current irp stack location
-    //
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
-
-    //
-    // sanity check
-    //
-    PC_ASSERT(IoStack->MajorFunction == IRP_MJ_INTERNAL_DEVICE_CONTROL);
-    PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_INTERNAL_USB_SUBMIT_URB);
-    PC_ASSERT(IoStack->Parameters.Others.Argument1 != 0);
-
-    //
-    // get urb
-    //
-    Urb = (PURB)IoStack->Parameters.Others.Argument1;
-
-    //
-    // store irp
-    //
-    m_Irp = Irp;
-
-    //
-    // check function type
-    //
-    switch (Urb->UrbHeader.Function)
-    {
-        case URB_FUNCTION_ISOCH_TRANSFER:
-        {
-            //
-            // there must be at least one packet
-            //
-            ASSERT(Urb->UrbIsochronousTransfer.NumberOfPackets);
-
-            //
-            // is there data to be transferred
-            //
-            if (Urb->UrbIsochronousTransfer.TransferBufferLength)
-            {
-                //
-                // Check if there is a MDL
-                //
-                if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
-                {
-                    //
-                    // sanity check
-                    //
-                    PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
-
-                    //
-                    // Create one using TransferBuffer
-                    //
-                    DPRINT("Creating Mdl from Urb Buffer %p Length %lu\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
-                    m_TransferBufferMDL = IoAllocateMdl(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
-                                                        Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
-                                                        FALSE,
-                                                        FALSE,
-                                                        NULL);
-
-                    if (!m_TransferBufferMDL)
-                    {
-                        //
-                        // failed to allocate mdl
-                        //
-                        return STATUS_INSUFFICIENT_RESOURCES;
-                    }
-
-                    //
-                    // build mdl for non paged pool
-                    // FIXME: Does hub driver already do this when passing MDL?
-                    //
-                    MmBuildMdlForNonPagedPool(m_TransferBufferMDL);
-                }
-                else
-                {
-                    //
-                    // use provided mdl
-                    //
-                    m_TransferBufferMDL = Urb->UrbIsochronousTransfer.TransferBufferMDL;
-                }
-            }
-            //
-            // save buffer length
-            //
-            m_TransferBufferLength = Urb->UrbIsochronousTransfer.TransferBufferLength;
-
-            //
-            // Set Length Completed to 0
-            //
-            m_TransferBufferLengthCompleted = 0;
-
-            //
-            // get endpoint descriptor
-            //
-            m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbIsochronousTransfer.PipeHandle;
-
-            //
-            // completed initialization
-            //
-            break;
-        }
-        //
-        // luckily those request have the same structure layout
-        //
-        case URB_FUNCTION_CLASS_INTERFACE:
-        case URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE:
-        case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER:
-        {
-            //
-            // bulk interrupt transfer
-            //
-            if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
-            {
-                //
-                // Check if there is a MDL
-                //
-                if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
-                {
-                    //
-                    // sanity check
-                    //
-                    PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBuffer);
-
-                    //
-                    // Create one using TransferBuffer
-                    //
-                    DPRINT("Creating Mdl from Urb Buffer %p Length %lu\n", Urb->UrbBulkOrInterruptTransfer.TransferBuffer, Urb->UrbBulkOrInterruptTransfer.TransferBufferLength);
-                    m_TransferBufferMDL = IoAllocateMdl(Urb->UrbBulkOrInterruptTransfer.TransferBuffer,
-                                                        Urb->UrbBulkOrInterruptTransfer.TransferBufferLength,
-                                                        FALSE,
-                                                        FALSE,
-                                                        NULL);
-
-                    if (!m_TransferBufferMDL)
-                    {
-                        //
-                        // failed to allocate mdl
-                        //
-                        return STATUS_INSUFFICIENT_RESOURCES;
-                    }
-
-                    //
-                    // build mdl for non paged pool
-                    // FIXME: Does hub driver already do this when passing MDL?
-                    //
-                    MmBuildMdlForNonPagedPool(m_TransferBufferMDL);
-
-                    //
-                    // Keep that ehci created the MDL and needs to free it.
-                    //
-                }
-                else
-                {
-                    m_TransferBufferMDL = Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL;
-                }
-
-                //
-                // save buffer length
-                //
-                m_TransferBufferLength = Urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
-
-                //
-                // Set Length Completed to 0
-                //
-                m_TransferBufferLengthCompleted = 0;
-
-                //
-                // get endpoint descriptor
-                //
-                m_EndpointDescriptor = (PUSB_ENDPOINT)Urb->UrbBulkOrInterruptTransfer.PipeHandle;
-
-            }
-            break;
-        }
-        default:
-            DPRINT1("URB Function: not supported %x\n", Urb->UrbHeader.Function);
-            PC_ASSERT(FALSE);
-    }
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-
-}
-
-//----------------------------------------------------------------------------------------
-BOOLEAN
-CUSBRequest::IsRequestComplete()
-{
-    //
-    // FIXME: check if request was split
-    //
-
-    //
-    // Check if the transfer was completed, only valid for Bulk Transfers
-    //
-    if ((m_TransferBufferLengthCompleted < m_TransferBufferLength)
-        && (GetTransferType() == USB_ENDPOINT_TYPE_BULK))
-    {
-        //
-        // Transfer not completed
-        //
-        return FALSE;
-    }
-    return TRUE;
-}
-//----------------------------------------------------------------------------------------
-ULONG
-CUSBRequest::GetTransferType()
-{
-    //
-    // call internal implementation
-    //
-    return InternalGetTransferType();
-}
-
-USHORT
-CUSBRequest::GetMaxPacketSize()
-{
-    if (!m_EndpointDescriptor)
-    {
-        //
-        // control request
-        //
-        return 0;
-    }
-
-    ASSERT(m_Irp);
-    ASSERT(m_EndpointDescriptor);
-
-    //
-    // return max packet size
-    //
-    return m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
-}
-
-UCHAR
-CUSBRequest::GetInterval()
-{
-    ASSERT(m_EndpointDescriptor);
-    ASSERT((m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_INTERRUPT);
-
-    //
-    // return interrupt interval
-    //
-    return m_EndpointDescriptor->EndPointDescriptor.bInterval;
-}
-
-UCHAR
-CUSBRequest::GetEndpointAddress()
-{
-    if (!m_EndpointDescriptor)
-    {
-        //
-        // control request
-        //
-        return 0;
-    }
-
-    ASSERT(m_Irp);
-    ASSERT(m_EndpointDescriptor);
-
-    //
-    // endpoint number is between 1-15
-    //
-    return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & 0xF);
-}
-
-//----------------------------------------------------------------------------------------
-ULONG
-CUSBRequest::InternalGetTransferType()
-{
-    ULONG TransferType;
-
-    //
-    // check if an irp is provided
-    //
-    if (m_Irp)
-    {
-        ASSERT(m_EndpointDescriptor);
-
-        //
-        // end point is defined in the low byte of bmAttributes
-        //
-        TransferType = (m_EndpointDescriptor->EndPointDescriptor.bmAttributes & USB_ENDPOINT_TYPE_MASK);
-    }
-    else
-    {
-        //
-        // initialized with setup packet, must be a control transfer
-        //
-        TransferType = USB_ENDPOINT_TYPE_CONTROL;
-    }
-
-    //
-    // done
-    //
-    return TransferType;
-}
-
-UCHAR
-CUSBRequest::InternalGetPidDirection()
-{
-    if (m_EndpointDescriptor)
-    {
-        //
-        // end point direction is highest bit in bEndpointAddress
-        //
-        return (m_EndpointDescriptor->EndPointDescriptor.bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK) >> 7;
-    }
-    else
-    {
-        //
-        // request arrives on the control pipe, extract direction from setup packet
-        //
-        ASSERT(m_SetupPacket);
-        return (m_SetupPacket->bmRequestType.B >> 7);
-    }
-}
-
-
-//----------------------------------------------------------------------------------------
-UCHAR
-CUSBRequest::GetDeviceAddress()
-{
-    PIO_STACK_LOCATION IoStack;
-    PURB Urb;
-    PUSBDEVICE UsbDevice;
-
-    //
-    // check if there is an irp provided
-    //
-    if (!m_Irp)
-    {
-        //
-        // used provided address
-        //
-        return m_DeviceAddress;
-    }
-
-    //
-    // get current stack location
-    //
-    IoStack = IoGetCurrentIrpStackLocation(m_Irp);
-
-    //
-    // get contained urb
-    //
-    Urb = (PURB)IoStack->Parameters.Others.Argument1;
-
-    //
-    // check if there is a pipe handle provided
-    //
-    if (Urb->UrbHeader.UsbdDeviceHandle)
-    {
-        //
-        // there is a device handle provided
-        //
-        UsbDevice = (PUSBDEVICE)Urb->UrbHeader.UsbdDeviceHandle;
-
-        //
-        // return device address
-        //
-        return UsbDevice->GetDeviceAddress();
-    }
-
-    //
-    // no device handle provided, it is the host root bus
-    //
-    return 0;
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBRequest::GetEndpointDescriptor(
-    struct _UHCI_QUEUE_HEAD ** OutQueueHead)
-{
-    NTSTATUS Status = STATUS_UNSUCCESSFUL;
-    ULONG TransferType;
-
-    // get transfer type
-    TransferType = InternalGetTransferType();
-
-    if (TransferType == USB_ENDPOINT_TYPE_CONTROL)
-    {
-        //
-        // build queue head
-        //
-        Status = BuildControlTransferDescriptor(OutQueueHead);
-    }
-    else if (TransferType == USB_ENDPOINT_TYPE_INTERRUPT || TransferType == USB_ENDPOINT_TYPE_BULK)
-    {
-        //
-        // build queue head
-        //
-        Status = BuildBulkInterruptTransferDescriptor(OutQueueHead);
-    }
-
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed
-        //
-        return Status;
-    }
-
-    //
-    // store result
-    //
-    (*OutQueueHead)->Request = PVOID(this);
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}
-
-//----------------------------------------------------------------------------------------
-VOID
-CUSBRequest::GetResultStatus(
-    OUT OPTIONAL NTSTATUS * NtStatusCode,
-    OUT OPTIONAL PULONG UrbStatusCode)
-{
-    //
-    // sanity check
-    //
-    PC_ASSERT(m_CompletionEvent);
-
-    //
-    // wait for the operation to complete
-    //
-    KeWaitForSingleObject(m_CompletionEvent, Executive, KernelMode, FALSE, NULL);
-
-    //
-    // copy status
-    //
-    if (NtStatusCode)
-    {
-        *NtStatusCode = m_NtStatusCode;
-    }
-
-    //
-    // copy urb status
-    //
-    if (UrbStatusCode)
-    {
-        *UrbStatusCode = m_UrbStatusCode;
-    }
-
-}
-
-//-----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBRequest::CreateDescriptor(
-    OUT PUHCI_TRANSFER_DESCRIPTOR *OutDescriptor,
-    IN UCHAR PidCode,
-    ULONG BufferLength)
-{
-    PUHCI_TRANSFER_DESCRIPTOR Descriptor;
-    PHYSICAL_ADDRESS Address;
-    NTSTATUS Status;
-
-    //
-    // allocate descriptor
-    //
-    Status = m_DmaManager->Allocate(sizeof(UHCI_TRANSFER_DESCRIPTOR), (PVOID*)&Descriptor, &Address);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("[USBUHCI] Failed to allocate descriptor\n");
-        return Status;
-    }
-
-    //
-    // init descriptor
-    //
-    Descriptor->PhysicalAddress = Address.LowPart;
-    Descriptor->Status = TD_STATUS_ACTIVE;
-
-    if (InternalGetTransferType() == USB_ENDPOINT_TYPE_ISOCHRONOUS)
-    {
-        //
-        // isochronous transfer descriptor
-        //
-        Descriptor->Status |= TD_CONTROL_ISOCHRONOUS;
-    }
-    else
-    {
-        //
-        // error count
-        //
-        Descriptor->Status |= TD_CONTROL_3_ERRORS;
-
-        if (PidCode == TD_TOKEN_IN && (InternalGetTransferType() != USB_ENDPOINT_TYPE_CONTROL))
-        {
-            //
-            // enable short packet detect for bulk & interrupt
-            //
-            Descriptor->Status |= TD_CONTROL_SPD;
-        }
-    }
-
-    //
-    // is it low speed device
-    //
-    if (m_DeviceSpeed == UsbLowSpeed)
-    {
-        //
-        // low speed device
-        //
-        Descriptor->Status |= TD_CONTROL_LOWSPEED;
-    }
-
-    //
-    // store buffer size
-    //
-    Descriptor->BufferSize = BufferLength;
-
-    //
-    // is there a buffer
-    //
-    if(BufferLength)
-    {
-        //
-        // store buffer length
-        //
-        Descriptor->Token = (BufferLength - 1) << TD_TOKEN_MAXLEN_SHIFT;
-    }
-    else
-    {
-        //
-        // no buffer magic constant
-        //
-        Descriptor->Token = TD_TOKEN_NULL_DATA;
-    }
-
-    //
-    // store address & endpoint number
-    //
-    Descriptor->Token |= GetEndpointAddress() << TD_TOKEN_ENDPTADDR_SHIFT;
-    Descriptor->Token |= GetDeviceAddress() << TD_TOKEN_DEVADDR_SHIFT | PidCode;
-
-    if (BufferLength)
-    {
-        //
-        // allocate buffer for descriptor
-        //
-        Status = m_DmaManager->Allocate(BufferLength, (PVOID*)&Descriptor->BufferLogical, &Address);
-        if (!NT_SUCCESS(Status))
-        {
-            DPRINT1("[USBUHCI] Failed to allocate descriptor buffer length %lu\n", BufferLength);
-            m_DmaManager->Release(Descriptor, sizeof(UHCI_TRANSFER_DESCRIPTOR));
-            return Status;
-        }
-
-        //
-        // store address
-        //
-        Descriptor->BufferPhysical = Address.LowPart;
-    }
-
-    //
-    // done
-    //
-    *OutDescriptor = Descriptor;
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-CUSBRequest::BuildTransferDescriptorChain(
-    IN PVOID TransferBuffer, 
-    IN ULONG TransferBufferLength, 
-    IN UCHAR PidCode,
-    IN UCHAR InitialDataToggle,
-    OUT PUHCI_TRANSFER_DESCRIPTOR * OutFirstDescriptor, 
-    OUT PUHCI_TRANSFER_DESCRIPTOR * OutLastDescriptor, 
-    OUT PULONG OutTransferBufferOffset,
-    OUT PUCHAR OutDataToggle)
-{
-    PUHCI_TRANSFER_DESCRIPTOR FirstDescriptor = NULL, CurrentDescriptor, LastDescriptor = NULL;
-    ULONG TransferBufferOffset = 0;
-    NTSTATUS Status;
-    ULONG MaxPacketSize, CurrentBufferSize;
-
-    //
-    // FIXME FIXME FIXME FIXME FIXME 
-    //
-    if (GetDeviceSpeed() == UsbLowSpeed)
-    {
-        //
-        // low speed use max 8 bytes
-        //
-        MaxPacketSize = 8;
-    }
-    else
-    {
-        if (m_EndpointDescriptor)
-        {
-            //
-            // use endpoint size
-            //
-            MaxPacketSize = m_EndpointDescriptor->EndPointDescriptor.wMaxPacketSize;
-        }
-        else
-        {
-            //
-            // use max 64 bytes
-            //
-            MaxPacketSize = 64;
-        }
-    }
-
-    do
-    {
-        //
-        // determine current packet size
-        //
-        CurrentBufferSize = min(MaxPacketSize, TransferBufferLength - TransferBufferOffset);
-
-        //
-        // allocate descriptor
-        //
-        Status = CreateDescriptor(&CurrentDescriptor, PidCode, CurrentBufferSize);
-        if (!NT_SUCCESS(Status))
-        {
-            //
-            // failed to allocate queue head
-            //
-            DPRINT1("[UHCI] Failed to create descriptor\n");
-            ASSERT(FALSE);
-            return Status;
-        }
-
-        if (PidCode == TD_TOKEN_OUT)
-        {
-             //
-             // copy buffer
-             //
-             RtlCopyMemory(CurrentDescriptor->BufferLogical, (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset), CurrentBufferSize);
-        }
-        else
-        {
-            //
-            // store user buffer
-            //
-            CurrentDescriptor->UserBuffer = (PVOID)((ULONG_PTR)TransferBuffer + TransferBufferOffset);
-        }
-
-        if (!FirstDescriptor)
-        {
-            //
-            // first descriptor
-            //
-            FirstDescriptor = CurrentDescriptor;
-        }
-        else
-        {
-            //
-            // link descriptor
-            //
-            LastDescriptor->LinkPhysical = CurrentDescriptor->PhysicalAddress | TD_DEPTH_FIRST;
-            LastDescriptor->NextLogicalDescriptor = (PVOID)CurrentDescriptor;
-        }
-
-        if (InitialDataToggle)
-        {
-            //
-            // apply data toggle
-            //
-            CurrentDescriptor->Token |= TD_TOKEN_DATA1;
-        }
-
-        //
-        // re-run
-        //
-        LastDescriptor = CurrentDescriptor;
-        TransferBufferOffset += CurrentBufferSize;
-        InitialDataToggle = !InitialDataToggle;
-
-    }while(TransferBufferOffset < TransferBufferLength);
-
-    if (OutTransferBufferOffset)
-    {
-        //
-        // store transfer buffer length
-        //
-        *OutTransferBufferOffset = TransferBufferOffset;
-    }
-
-    if (OutFirstDescriptor)
-    {
-        //
-        // store first descriptor
-        //
-        *OutFirstDescriptor = FirstDescriptor;
-    }
-
-    if (OutLastDescriptor)
-    {
-        //
-        // store last descriptor
-        //
-        *OutLastDescriptor = CurrentDescriptor;
-    }
-
-    if (OutDataToggle)
-    {
-        //
-        // store data toggle
-        //
-        *OutDataToggle = InitialDataToggle;
-    }
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}
-
-NTSTATUS
-CUSBRequest::BuildQueueHead(
-    OUT PUHCI_QUEUE_HEAD *OutQueueHead)
-{
-    PUHCI_QUEUE_HEAD QueueHead;
-    NTSTATUS Status;
-    PHYSICAL_ADDRESS Address;
-
-    //
-    // allocate queue head
-    //
-    Status = m_DmaManager->Allocate(sizeof(UHCI_QUEUE_HEAD), (PVOID*)&QueueHead, &Address);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to allocate queue head
-        //
-        DPRINT1("[UHCI] Failed to create queue head\n");
-        return Status;
-    }
-
-    //
-    // store address
-    //
-    QueueHead->PhysicalAddress = Address.LowPart;
-    QueueHead->ElementPhysical = Address.LowPart;
-
-    //
-    // store result
-    //
-    *OutQueueHead = QueueHead;
-    return STATUS_SUCCESS;
-}
-
-VOID
-CUSBRequest::FreeDescriptor(
-    IN PUHCI_TRANSFER_DESCRIPTOR Descriptor)
-{
-    if (Descriptor->BufferLogical)
-    {
-        //
-        // free buffer
-        //
-        m_DmaManager->Release(Descriptor->BufferLogical, Descriptor->BufferSize);
-    }
-
-    //
-    // free descriptors
-    //
-    m_DmaManager->Release(Descriptor, sizeof(UHCI_TRANSFER_DESCRIPTOR));
-}
-
-NTSTATUS
-CUSBRequest::BuildBulkInterruptTransferDescriptor(
-    IN PUHCI_QUEUE_HEAD * OutQueueHead)
-{
-    NTSTATUS Status;
-    PUHCI_QUEUE_HEAD QueueHead;
-    PUHCI_TRANSFER_DESCRIPTOR FirstDescriptor, LastDescriptor;
-    ULONG ChainDescriptorLength;
-    BOOLEAN Direction;
-    PVOID Buffer;
-    ULONG BufferSize;
-
-    // create queue head
-    Status = BuildQueueHead(&QueueHead);
-    if (!NT_SUCCESS(Status))
-    {
-        // failed to allocate queue head
-        DPRINT1("[UHCI] Failed to create queue head\n");
-        return Status;
-    }
-
-    // get direction
-    Direction = InternalGetPidDirection();
-
-    if (!m_Base)
-    {
-        // get buffer base
-        m_Base = MmGetMdlVirtualAddress(m_TransferBufferMDL);
-
-        // sanity check
-        ASSERT(m_Base != NULL);
-    }
-
-    // get new buffer offset
-    Buffer = (PVOID)((ULONG_PTR)m_Base + m_TransferBufferLengthCompleted);
-
-    // FIXME determine buffer limit
-    BufferSize = min(m_TransferBufferLength - m_TransferBufferLengthCompleted, PAGE_SIZE);
-
-    // create descriptor chain
-    Status = BuildTransferDescriptorChain(Buffer,
-                                          BufferSize,
-                                          Direction ? TD_TOKEN_IN : TD_TOKEN_OUT,
-                                          m_EndpointDescriptor->DataToggle,
-                                          &FirstDescriptor,
-                                          &LastDescriptor,
-                                          &ChainDescriptorLength,
-                                           NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to allocate descriptor
-        //
-        DPRINT1("[UHCI] Failed to create descriptor chain\n");
-        m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
-        return Status;
-    }
-
-    // adjust buffer offset
-    m_TransferBufferLengthCompleted += ChainDescriptorLength;
-
-    // fire interrupt when the last descriptor is complete
-    LastDescriptor->Status |= TD_CONTROL_IOC;
-    LastDescriptor->LinkPhysical = TD_TERMINATE;
-    LastDescriptor->NextLogicalDescriptor = NULL;
-
-    // link queue head with first data descriptor descriptor
-    QueueHead->NextElementDescriptor = (PVOID)FirstDescriptor;
-    QueueHead->ElementPhysical = FirstDescriptor->PhysicalAddress;
-
-    // store result
-    *OutQueueHead = QueueHead;
-    return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-CUSBRequest::BuildControlTransferDescriptor(
-    IN PUHCI_QUEUE_HEAD * OutQueueHead)
-{
-    PUHCI_TRANSFER_DESCRIPTOR SetupDescriptor, StatusDescriptor, FirstDescriptor, LastDescriptor;
-    PUHCI_QUEUE_HEAD QueueHead;
-    BOOLEAN Direction;
-    NTSTATUS Status;
-    ULONG ChainDescriptorLength;
-
-    //
-    // create queue head
-    //
-    Status = BuildQueueHead(&QueueHead);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to allocate queue head
-        //
-        DPRINT1("[UHCI] Failed to create queue head\n");
-        return Status;
-    }
-
-    //
-    // get direction
-    //
-    Direction = InternalGetPidDirection();
-
-    //
-    // build setup descriptor
-    //
-    Status = CreateDescriptor(&SetupDescriptor,
-                              TD_TOKEN_SETUP,
-                              sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to allocate descriptor
-        //
-        DPRINT1("[UHCI] Failed to create setup descriptor\n");
-        m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
-        return Status;
-    }
-
-    //
-    // build status descriptor
-    //
-    Status = CreateDescriptor(&StatusDescriptor,
-                              Direction ? TD_TOKEN_OUT : TD_TOKEN_IN,
-                              0);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to allocate descriptor
-        //
-        DPRINT1("[UHCI] Failed to create status descriptor\n");
-        FreeDescriptor(SetupDescriptor);
-        m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
-        return Status;
-    }
-
-    if (m_SetupPacket)
-    {
-        //
-        // copy setup packet
-        //
-        RtlCopyMemory(SetupDescriptor->BufferLogical, m_SetupPacket, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-    }
-    else
-    {
-        //
-        // generate setup packet from urb
-        //
-        ASSERT(FALSE);
-    }
-
-    //
-    // init status descriptor
-    //
-    StatusDescriptor->Status |= TD_CONTROL_IOC;
-    StatusDescriptor->Token |= TD_TOKEN_DATA1;
-    StatusDescriptor->LinkPhysical = TD_TERMINATE;
-    StatusDescriptor->NextLogicalDescriptor = NULL;
-
-    if (m_TransferBufferLength)
-    {
-        //
-        // create descriptor chain
-        //
-        Status = BuildTransferDescriptorChain(MmGetMdlVirtualAddress(m_TransferBufferMDL),
-                                              m_TransferBufferLength,
-                                              Direction ? TD_TOKEN_IN : TD_TOKEN_OUT,
-                                              TRUE,
-                                              &FirstDescriptor,
-                                              &LastDescriptor,
-                                              &ChainDescriptorLength,
-                                              NULL);
-        if (!NT_SUCCESS(Status))
-        {
-            //
-            // failed to allocate descriptor
-            //
-            DPRINT1("[UHCI] Failed to create descriptor chain\n");
-            FreeDescriptor(SetupDescriptor);
-            FreeDescriptor(StatusDescriptor);
-            m_DmaManager->Release(QueueHead, sizeof(UHCI_QUEUE_HEAD));
-            return Status;
-        }
-
-        //
-        // link setup descriptor to first data descriptor
-        //
-        SetupDescriptor->LinkPhysical = FirstDescriptor->PhysicalAddress | TD_DEPTH_FIRST;
-        SetupDescriptor->NextLogicalDescriptor = (PVOID)FirstDescriptor;
-
-        //
-        // link last data descriptor to status descriptor
-        //
-        LastDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress | TD_DEPTH_FIRST;
-        LastDescriptor->NextLogicalDescriptor = (PVOID)StatusDescriptor;
-    }
-    else
-    {
-        //
-        // directly link setup to status descriptor
-        //
-        SetupDescriptor->LinkPhysical = StatusDescriptor->PhysicalAddress | TD_DEPTH_FIRST;
-        SetupDescriptor->NextLogicalDescriptor = (PVOID)StatusDescriptor;
-    }
-
-    //
-    // link queue head with setup descriptor
-    //
-    QueueHead->NextElementDescriptor = (PVOID)SetupDescriptor;
-    QueueHead->ElementPhysical = SetupDescriptor->PhysicalAddress;
-
-    //
-    // store result
-    //
-    *OutQueueHead = QueueHead;
-    return STATUS_SUCCESS;
-}
-USB_DEVICE_SPEED
-CUSBRequest::GetDeviceSpeed()
-{
-    return m_DeviceSpeed;
-}
-
-VOID
-CUSBRequest::FreeEndpointDescriptor(
-     struct _UHCI_QUEUE_HEAD * OutDescriptor)
-{
-    PUHCI_TRANSFER_DESCRIPTOR Descriptor, NextDescriptor;
-    ULONG ErrorCount;
-    UCHAR DataToggle = 0;
-    ULONG Index = 0;
-
-    //
-    // grab first transfer descriptor
-    //
-    Descriptor = (PUHCI_TRANSFER_DESCRIPTOR)OutDescriptor->NextElementDescriptor;
-    while(Descriptor)
-    {
-        // get data toggle
-        DataToggle = (Descriptor->Token >> TD_TOKEN_DATA_TOGGLE_SHIFT) & 0x01;
-
-        if (Descriptor->Status & TD_ERROR_MASK)
-        {
-            //
-            // error happened
-            //
-            DPRINT1("[USBUHCI] Error detected at descriptor %p Physical %x\n", Descriptor, Descriptor->PhysicalAddress);
-
-            //
-            // get error count
-            //
-            ErrorCount = (Descriptor->Status >> TD_ERROR_COUNT_SHIFT) & TD_ERROR_COUNT_MASK;
-            if (ErrorCount == 0)
-            {
-                 //
-                 // error retry count elapsed
-                 //
-                 m_NtStatusCode = STATUS_UNSUCCESSFUL;
-
-                 if (Descriptor->Status & TD_STATUS_ERROR_BUFFER)
-                 {
-                     DPRINT1("[USBUHCI] Buffer Error detected in descriptor %p Index %lu\n", Descriptor, Index);
-                     m_UrbStatusCode = USBD_STATUS_DATA_BUFFER_ERROR;
-                 }
-                 else if (Descriptor->Status & TD_STATUS_ERROR_TIMEOUT)
-                 {
-                     DPRINT1("[USBUHCI] Timeout detected in descriptor %p Index %lu\n", Descriptor, Index);
-                     m_UrbStatusCode = USBD_STATUS_TIMEOUT;
-                 }
-                 else if (Descriptor->Status & TD_STATUS_ERROR_NAK)
-                 {
-                     DPRINT1("[USBUHCI] Unexpected pid detected in descriptor %p Index %lu\n", Descriptor, Index);
-                     m_UrbStatusCode = USBD_STATUS_UNEXPECTED_PID;
-                 }
-                 else if (Descriptor->Status & TD_STATUS_ERROR_BITSTUFF)
-                 {
-                     DPRINT1("[USBUHCI] BitStuff detected in descriptor %p Index %lu\n", Descriptor, Index);
-                     m_UrbStatusCode = USBD_STATUS_BTSTUFF;
-                 }
-            }
-            else if (Descriptor->Status & TD_STATUS_ERROR_BABBLE)
-            {
-                 //
-                 // babble error
-                 //
-                 DPRINT1("[USBUHCI] Babble detected in descriptor %p Index %lu\n", Descriptor, Index);
-                 m_UrbStatusCode = USBD_STATUS_BABBLE_DETECTED;
-            }
-            else
-            {
-                //
-                // stall detected
-                //
-                DPRINT1("[USBUHCI] Stall detected Descriptor %p Index %lu\n", Descriptor, Index);
-                m_UrbStatusCode = USBD_STATUS_STALL_PID;
-            }
-        }
-        else
-        {
-            //
-            // FIXME detect actual length
-            //
-            if (Descriptor->UserBuffer)
-            {
-                //
-                // copy contents back
-                //
-                RtlCopyMemory(Descriptor->UserBuffer, Descriptor->BufferLogical, Descriptor->BufferSize);
-            }
-        }
-        //
-        // move to next descriptor
-        //
-        NextDescriptor = (PUHCI_TRANSFER_DESCRIPTOR)Descriptor->NextLogicalDescriptor;
-
-        //
-        // free endpoint descriptor
-        //
-        FreeDescriptor(Descriptor);
-
-        //
-        // move to next
-        //
-        Descriptor = NextDescriptor;
-        Index++;
-    }
-
-    //
-    // now free queue head
-    //
-    m_DmaManager->Release(OutDescriptor, sizeof(UHCI_QUEUE_HEAD));
-
-    // is there an endpoint descriptor
-    if (m_EndpointDescriptor)
-    {
-        // invert last data toggle
-        m_EndpointDescriptor->DataToggle = (DataToggle == 0);
-    }
-}
-
-VOID
-CUSBRequest::CompletionCallback()
-{
-    PIO_STACK_LOCATION IoStack;
-    PURB Urb;
-
-    DPRINT("CUSBRequest::CompletionCallback\n");
-
-    if (m_Irp)
-    {
-        //
-        // set irp completion status
-        //
-        m_Irp->IoStatus.Status = m_NtStatusCode;
-
-        //
-        // get current irp stack location
-        //
-        IoStack = IoGetCurrentIrpStackLocation(m_Irp);
-
-        //
-        // get urb
-        //
-        Urb = (PURB)IoStack->Parameters.Others.Argument1;
-
-        //
-        // store urb status
-        //
-        Urb->UrbHeader.Status = m_UrbStatusCode;
-
-        //
-        // Check if the MDL was created
-        //
-        if (!Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL)
-        {
-            //
-            // Free Mdl
-            //
-            IoFreeMdl(m_TransferBufferMDL);
-        }
-
-        //
-        // FIXME calculate length
-        //
-
-        //
-        // complete request
-        //
-        IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
-    }
-    else
-    {
-        //
-        // signal completion event
-        //
-        PC_ASSERT(m_CompletionEvent);
-        KeSetEvent(m_CompletionEvent, 0, FALSE);
-    }
-
-}
-
-
-//-----------------------------------------------------------------------------------------
-NTSTATUS
-NTAPI
-InternalCreateUSBRequest(
-    PUSBREQUEST *OutRequest)
-{
-    PUSBREQUEST This;
-
-    //
-    // allocate requests
-    //
-    This = new(NonPagedPool, TAG_USBUHCI) CUSBRequest(0);
-    if (!This)
-    {
-        //
-        // failed to allocate
-        //
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // add reference count
-    //
-    This->AddRef();
-
-    //
-    // return result
-    //
-    *OutRequest = (PUSBREQUEST)This;
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}