Author: janderwald
Date: Tue Apr 19 18:35:40 2011
New Revision: 51406

URL: http://svn.reactos.org/svn/reactos?rev=51406&view=rev
Log:
[USBEHCI_NEW]
- Fix warning because comparing signed vs unsigned
- Implement function for retrieving the device descriptor
- Implement function for retrieving a configuration descriptor (including 
contained interface descriptor and endpoint descriptor)
- Cleanup interface for IUSBRequest:
- When caller initializes IUSBRequest with an IRP, then the operation mode is 
asynchronously. Therefore when the request is completed, 
IUSBRequest::ShouldReleaseRequestAfterCompletion will return true, which makes 
IUSBQueue call Release on IUSBRequest
- When the caller initializes IUSBRequest with an setup packet, the operation 
mode is synchronously. After submitting the IUSBRequest to queue, the caller 
should call IUSBRequest::GetResultStatus. This function will then block untill 
the operation has been completed. However, the caller needs to call Release() 
as those requests are not cleaned up by the IUSBQueue


Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
    branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp?rev=51406&r1=51405&r2=51406&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hub_controller.cpp 
[iso-8859-1] Tue Apr 19 18:35:40 2011
@@ -288,7 +288,7 @@
         return STATUS_UNSUCCESSFUL;
     }
 
-    if (BufferLength < m_HubDeviceInterfaceString.Length - 8)
+    if (BufferLength < (ULONG)m_HubDeviceInterfaceString.Length - 8)
     {
         //
         // buffer too small
@@ -774,7 +774,7 @@
     //
     // sanity check
     //
-    PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < NumPort);
+    PC_ASSERT(Urb->UrbControlVendorClassRequest.Index - 1 < (USHORT)NumPort);
 
     //
     // port range reported start from 1 -n
@@ -1882,7 +1882,8 @@
     //
     // submit urb
     //
-    Status = UsbDevice->SubmitUrb(Urb);
+    //Status = UsbDevice->SubmitUrb(Urb);
+    UNIMPLEMENTED
 
     if (NT_SUCCESS(Status))
     {

Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h?rev=51406&r1=51405&r2=51406&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h [iso-8859-1] Tue 
Apr 19 18:35:40 2011
@@ -171,6 +171,15 @@
 // Do not call Initialize on IUSBQueue, the object is already initialized
 
     virtual NTSTATUS GetUSBQueue(OUT struct IUSBQueue **OutUsbQueue) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// GetDMA
+//
+// Description: returns the DMA object which can be used to allocate memory 
from the common buffer
+
+    virtual NTSTATUS GetDMA(OUT struct IDMAMemoryManager 
**OutDMAMemoryManager) = 0;
+
 
 
//-----------------------------------------------------------------------------------------
 //
@@ -363,40 +372,33 @@
 // The irp contains an URB block which contains all necessary information
 
     virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, 
-                                       IN OUT PIRP Irp);
-
-//-----------------------------------------------------------------------------------------
-//
-// SetCompletionEvent
-//
-// Description: sets up completion event which is signaled when the
-// request is completed or cancelled
-
-    virtual NTSTATUS SetCompletionEvent(IN PKEVENT Event) = 0;
+                                       IN OUT PIRP Irp) = 0;
 
 
//-----------------------------------------------------------------------------------------
 //
 // CompletionCallback
 //
 // Description: called when request has been completed. It is called when
-// IUSBQueue completes the request
+// IUSBQueue completes a queue head
 
     virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode,
-                                   IN ULONG UrbStatusCode) = 0;
+                                    IN ULONG UrbStatusCode,
+                                    IN struct _QUEUE_HEAD *QueueHead) = 0;
 
 
//-----------------------------------------------------------------------------------------
 //
 // CancelCallback
 //
-// Description: called when request is cancelled. Called by IUSBQueue
-
-    virtual VOID CancelCallback(IN NTSTATUS NtStatusCode) = 0;
+// Description: called when the queue head is cancelled
+
+    virtual VOID CancelCallback(IN NTSTATUS NtStatusCode,
+                                IN struct _QUEUE_HEAD *QueueHead) = 0;
 
 
//-----------------------------------------------------------------------------------------
 //
 //  GetQueueHead
 //
-// Description: returns an initialized queue head with contains the all 
transfer descriptors
+// Description: returns an initialized queue head which contains all transfer 
descriptors
 
     virtual NTSTATUS GetQueueHead(struct _QUEUE_HEAD ** OutHead) = 0;
 
@@ -406,6 +408,9 @@
 //
 // Description: returns true when the request has been completed
 // Should be called after the CompletionCallback has been invoked
+// This function is called by IUSBQueue after queue head has been completed
+// If the function returns true, IUSBQueue will then call 
ShouldReleaseRequestAfterCompletion
+// If that function returns also true, it calls Release() to delete the 
IUSBRequest
 
     virtual BOOLEAN IsRequestComplete() = 0;
 
@@ -417,6 +422,34 @@
 
     virtual ULONG GetTransferType() = 0;
 
+//-----------------------------------------------------------------------------------------
+//
+// GetResultStatus
+//
+// Description: returns the status code of the result
+// Note: this function will block the caller untill the request has been 
completed
+
+    virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS * NtStatusCode,
+                                 OUT OPTIONAL PULONG UrbStatusCode) = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// IsRequestInitialized
+//
+// Description: returns true when the request has been successfully 
initialized using InitializeXXX methods
+
+    virtual BOOLEAN IsRequestInitialized() = 0;
+
+//-----------------------------------------------------------------------------------------
+//
+// ShouldReleaseRequestAfterCompletion
+//
+// Description: this function gets called when the request returns
+// IUSBQueue will then call Release() on the object to release all associated 
memory
+// This function will typically return true when the request has been 
initialized with an irp
+// If the request was initialized with an setup packet, it will return false
+
+    virtual BOOLEAN ShouldReleaseRequestAfterCompletion() = 0;
 };
 
 typedef IUSBRequest *PUSBREQUEST;
@@ -446,7 +479,7 @@
 //
 // GetPendingRequestCount
 //
-// Description: returns the number of pending requests
+// Description: returns the number of pending requests true from 
IsRequestComplete
 
     virtual ULONG GetPendingRequestCount() = 0;
 
@@ -608,7 +641,7 @@
 //
 // Description: gets the device address of the this device
 
-    virtual ULONG GetDeviceAddress() = 0;
+    virtual UCHAR GetDeviceAddress() = 0;
 
 
 
//-----------------------------------------------------------------------------------------
@@ -657,7 +690,7 @@
 //
 // Description: sets device handle data
 
-    virtual NTSTATUS SetDeviceAddress(ULONG DeviceAddress) = 0;
+    virtual NTSTATUS SetDeviceAddress(UCHAR DeviceAddress) = 0;
 
 
//-----------------------------------------------------------------------------------------
 //
@@ -677,11 +710,11 @@
 
 
//-----------------------------------------------------------------------------------------
 //
-// SubmitUrb
-//
-// Description: submits an urb
-
-    virtual NTSTATUS SubmitUrb(PURB Urb) = 0;
+// SubmitIrp
+//
+// Description: submits an irp containing an urb
+
+    virtual NTSTATUS SubmitIrp(PIRP Urb) = 0;
 
 };
 

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp?rev=51406&r1=51405&r2=51406&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_device.cpp [iso-8859-1] 
Tue Apr 19 18:35:40 2011
@@ -11,6 +11,24 @@
 #define INITGUID
 #include "usbehci.h"
 
+typedef struct _USB_ENDPOINT
+{
+    USB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+} USB_ENDPOINT, *PUSB_ENDPOINT;
+
+typedef struct _USB_INTERFACE
+{
+    USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    USB_ENDPOINT *EndPoints;
+} USB_INTERFACE, *PUSB_INTERFACE;
+
+typedef struct _USB_CONFIGURATION
+{
+    USB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+    USB_INTERFACE *Interfaces;
+} USB_CONFIGURATION, *PUSB_CONFIGURATION;
+
+
 class CUSBDevice : public IUSBDevice
 {
 public:
@@ -37,20 +55,22 @@
     virtual NTSTATUS Initialize(IN PHUBCONTROLLER HubController, IN 
PUSBHARDWAREDEVICE Device, IN PVOID Parent, IN ULONG Port, IN ULONG PortStatus);
     virtual BOOLEAN IsHub();
     virtual NTSTATUS GetParent(PVOID * Parent);
-    virtual ULONG GetDeviceAddress();
+    virtual UCHAR GetDeviceAddress();
     virtual ULONG GetPort();
     virtual USB_DEVICE_SPEED GetSpeed();
     virtual USB_DEVICE_TYPE GetType();
     virtual ULONG GetState();
     virtual void SetDeviceHandleData(PVOID Data);
-    virtual NTSTATUS SetDeviceAddress(ULONG DeviceAddress);
+    virtual NTSTATUS SetDeviceAddress(UCHAR DeviceAddress);
     virtual void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR DeviceDescriptor);
     virtual UCHAR GetConfigurationValue();
-    virtual NTSTATUS SubmitUrb(PURB Urb);
+    virtual NTSTATUS SubmitIrp(PIRP Irp);
 
     // local function
-    virtual NTSTATUS CommitUrb(PURB Urb);
-    virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, 
IN ULONG BufferLength, IN OUT PVOID Buffer, IN OPTIONAL PIRP Irp, IN OPTIONAL 
PKEVENT pEvent);
+    virtual NTSTATUS CommitIrp(PIRP Irp);
+    virtual NTSTATUS CommitSetupPacket(PUSB_DEFAULT_PIPE_SETUP_PACKET Packet, 
IN ULONG BufferLength, IN OUT PMDL Mdl);
+    virtual NTSTATUS CreateConfigurationDescriptor(ULONG ConfigurationIndex);
+    virtual NTSTATUS CreateDeviceDescriptor();
 
     // constructor / destructor
     CUSBDevice(IUnknown *OuterUnknown){}
@@ -62,13 +82,15 @@
     PUSBHARDWAREDEVICE m_Device;
     PVOID m_Parent; 
     ULONG m_Port;
-    ULONG m_DeviceAddress;
+    UCHAR m_DeviceAddress;
     PVOID m_Data;
     KSPIN_LOCK m_Lock;
     USB_DEVICE_DESCRIPTOR m_DeviceDescriptor;
     ULONG m_PortStatus;
     PUSBQUEUE m_Queue;
     PDMAMEMORYMANAGER m_DmaManager;
+
+    PUSB_CONFIGURATION m_ConfigurationDescriptors;
 };
 
 
//----------------------------------------------------------------------------------------
@@ -126,19 +148,445 @@
     }
 
     //
-    // FIXME: get dma manager
-    //
-    //Status = m_Device->GetDMA(&m_DmaManager);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to get usb queue
-        //
-        DPRINT1("CUSBDevice::Initialize GetUsbQueue failed with %x\n", Status);
-        return Status;
-    }
-
-
+    // get dma manager
+    //
+    Status = m_Device->GetDMA(&m_DmaManager);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to get dma manager
+        //
+        DPRINT1("CUSBDevice::Initialize GetDMA failed with %x\n", Status);
+        return Status;
+    }
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(m_DmaManager);
+
+    //
+    // get device descriptor
+    //
+    Status = CreateDeviceDescriptor();
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to get device descriptor
+        //
+        DPRINT1("CUSBDevice::Initialize Failed to get device descriptor with 
%x\n", Status);
+        return Status;
+    }
+
+    //
+    // done
+    //
+    return Status;
+}
+
+//----------------------------------------------------------------------------------------
+BOOLEAN
+CUSBDevice::IsHub()
+{
+    //
+    // USB Standard Device Class see 
http://www.usb.org/developers/defined_class/#BaseClass09h
+    // for details
+    //
+    return (m_DeviceDescriptor.bDeviceClass == 0x09 && 
m_DeviceDescriptor.bDeviceSubClass == 0x00);
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::GetParent(
+    PVOID * Parent)
+{
+    //
+    // returns parent
+    //
+    *Parent = m_Parent;
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+
+//----------------------------------------------------------------------------------------
+UCHAR
+CUSBDevice::GetDeviceAddress()
+{
+    //
+    // get device address
+    //
+    return m_DeviceAddress;
+}
+
+//----------------------------------------------------------------------------------------
+ULONG
+CUSBDevice::GetPort()
+{
+    //
+    // get port to which this device is connected to
+    //
+    return m_Port;
+}
+
+//----------------------------------------------------------------------------------------
+USB_DEVICE_SPEED
+CUSBDevice::GetSpeed()
+{
+    if (m_PortStatus & USB_PORT_STATUS_LOW_SPEED)
+    {
+        //
+        // low speed device
+        //
+        return UsbLowSpeed;
+    }
+    else if (m_PortStatus & USB_PORT_STATUS_HIGH_SPEED)
+    {
+        //
+        // high speed device
+        //
+        return UsbHighSpeed;
+    }
+
+    //
+    // default to full speed
+    //
+    return UsbFullSpeed;
+}
+
+//----------------------------------------------------------------------------------------
+USB_DEVICE_TYPE
+CUSBDevice::GetType()
+{
+    //
+    // device is encoded into bcdUSB
+    //
+    if (m_DeviceDescriptor.bcdUSB == 0x110)
+    {
+        //
+        // USB 1.1 device
+        //
+        return Usb11Device;
+    }
+    else if (m_DeviceDescriptor.bcdUSB == 0x200)
+    {
+        //
+        // USB 2.0 device
+        //
+        return Usb20Device;
+    }
+
+    DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n", 
m_DeviceDescriptor.bcdUSB);
+    PC_ASSERT(FALSE);
+
+    return Usb11Device;
+}
+
+//----------------------------------------------------------------------------------------
+ULONG
+CUSBDevice::GetState()
+{
+    UNIMPLEMENTED
+    return FALSE;
+}
+
+//----------------------------------------------------------------------------------------
+void
+CUSBDevice::SetDeviceHandleData(
+    PVOID Data)
+{
+    //
+    // set device data, for debugging issues
+    //
+    m_Data = Data;
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::SetDeviceAddress(
+    UCHAR DeviceAddress)
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    NTSTATUS Status;
+    UCHAR OldAddress;
+    ULONG Index;
+
+    //
+    // zero request
+    //
+    RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
+
+    //
+    // initialize request
+    //
+    CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
+    CtrlSetup.wValue.W = (USHORT)DeviceAddress;
+
+    //
+    // set device address
+    //
+    Status = CommitSetupPacket(&CtrlSetup, 0, 0);
+
+    //
+    // check for success
+    //
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to set device address
+        //
+        DPRINT1("CUSBDevice::SetDeviceAddress> failed to set device address 
with %x Address %x\n", Status, DeviceAddress);
+        return Status;
+    }
+
+    //
+    // back up old address
+    //
+    OldAddress = m_DeviceAddress;
+
+    //
+    // store new device address
+    //
+    m_DeviceAddress = DeviceAddress;
+
+    //
+    // check that setting device address succeeded by retrieving the device 
descriptor
+    //
+    Status = CreateDeviceDescriptor();
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to retrieve device descriptor
+        //
+        DPRINT1("CUSBbDevice::SetDeviceAddress> failed to set new device 
address %d, falling back to %d Error %x\n", DeviceAddress, OldAddress, Status);
+        m_DeviceAddress = OldAddress;
+
+        //
+        // return error status
+        //
+        return Status;
+    }
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(m_DeviceDescriptor.bNumConfigurations);
+
+    //
+    // allocate configuration descriptor
+    //
+    m_ConfigurationDescriptors = (PUSB_CONFIGURATION) 
ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_CONFIGURATION) * 
m_DeviceDescriptor.bNumConfigurations, TAG_USBEHCI);
+
+    //
+    // zero configuration descriptor
+    //
+    RtlZeroMemory(m_ConfigurationDescriptors, sizeof(USB_CONFIGURATION) * 
m_DeviceDescriptor.bNumConfigurations);
+
+    //
+    // retrieve the configuration descriptors
+    //
+    for(Index = 0; Index < m_DeviceDescriptor.bNumConfigurations; Index++)
+    {
+        //
+        // retrieve configuration descriptors from device
+        //
+        Status = CreateConfigurationDescriptor(Index);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("CUSBDevice::SetDeviceAddress> failed to retrieve 
configuration %lu\n", Index);
+            break;
+        }
+    }
+
+    //
+    // done
+    //
+    return Status;
+
+}
+
+//----------------------------------------------------------------------------------------
+void
+CUSBDevice::GetDeviceDescriptor(
+    PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
+{
+    RtlMoveMemory(DeviceDescriptor, &m_DeviceDescriptor, 
sizeof(USB_DEVICE_DESCRIPTOR));
+}
+
+//----------------------------------------------------------------------------------------
+UCHAR
+CUSBDevice::GetConfigurationValue()
+{
+    UNIMPLEMENTED
+    return 0x1;
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::CommitIrp(
+    PIRP Irp)
+{
+    NTSTATUS Status;
+    PUSBREQUEST Request;
+
+    if (!m_Queue || m_DmaManager)
+    {
+        //
+        // no queue, wtf?
+        //
+        DPRINT1("CUSBDevice::CommitUrb> no queue / dma !!!\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    //
+    // build usb request
+    //
+    Status = m_Queue->CreateUSBRequest(&Request);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to build request
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with 
%x\n", Status);
+        return Status;
+    }
+
+    //
+    // initialize request
+    //
+    Status = Request->InitializeWithIrp(m_DmaManager, Irp);
+
+    //
+    // now add the request
+    //
+    Status = m_Queue->AddUSBRequest(Request);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to add request
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue 
with %x\n", Status);
+        Request->Release();
+        return Status;
+    }
+
+    //
+    // done
+    //
+    return Status;
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::SubmitIrp(
+    PIRP Irp)
+{
+    KIRQL OldLevel;
+    NTSTATUS Status;
+
+    //
+    // acquire device lock
+    //
+    KeAcquireSpinLock(&m_Lock, &OldLevel);
+
+    //
+    // commit urb
+    //
+    Status = CommitIrp(Irp);
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(&m_Lock, OldLevel);
+
+    return Status;
+}
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::CommitSetupPacket(
+    PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
+    IN ULONG BufferLength, 
+    IN OUT PMDL Mdl)
+{
+    NTSTATUS Status;
+    PUSBREQUEST Request;
+
+    if (!m_Queue)
+    {
+        //
+        // no queue, wtf?
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> no queue!!!\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    //
+    // build usb request
+    //
+    Status = m_Queue->CreateUSBRequest(&Request);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to build request
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with 
%x\n", Status);
+        return Status;
+    }
+
+    //
+    // initialize request
+    //
+    Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, 
BufferLength, Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to initialize request
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> failed to initialize  usb 
request with %x\n", Status);
+        Request->Release();
+        return Status;
+    }
+
+
+    //
+    // now add the request
+    //
+    Status = m_Queue->AddUSBRequest(Request);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to add request
+        //
+        DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue 
with %x\n", Status);
+        Request->Release();
+        return Status;
+    }
+
+    //
+    // get the result code when the operation has been finished
+    //
+    Request->GetResultStatus(&Status, NULL);
+
+    //
+    // release request
+    //
+    Request->Release();
+
+    //
+    // done
+    //
+    return Status;
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::CreateDeviceDescriptor()
+{
+    USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
+    PMDL Mdl;
+    NTSTATUS Status;
 
     //
     // zero descriptor
@@ -155,362 +603,239 @@
     CtrlSetup.bmRequestType.B = 0x80;
 
     //
+    // allocate mdl describing the device descriptor
+    //
+    Mdl = IoAllocateMdl(&m_DeviceDescriptor, sizeof(USB_DEVICE_DESCRIPTOR), 
FALSE, FALSE, 0);
+    if (!Mdl)
+    {
+        //
+        // failed to allocate mdl
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // build mdl for non paged pool
+    //
+    MmBuildMdlForNonPagedPool(Mdl);
+
+    //
     // commit setup packet
     //
-    Status = CommitSetupPacket(&CtrlSetup, sizeof(USB_DEVICE_DESCRIPTOR), 
&m_DeviceDescriptor, 0, 0);
-
-    //
-    // check for success
-    //
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("CUSBDevice::Initialize CommitSetupPacket failed with %x\n", 
Status);
-    }
+    Status = CommitSetupPacket(&CtrlSetup, sizeof(USB_DEVICE_DESCRIPTOR), Mdl);
+
+    //
+    // now free the mdl
+    //
+    IoFreeMdl(Mdl);
 
     //
     // done
     //
     return Status;
-}
-
-//----------------------------------------------------------------------------------------
-BOOLEAN
-CUSBDevice::IsHub()
-{
-    //
-    // USB Standard Device Class see 
http://www.usb.org/developers/defined_class/#BaseClass09h
-    // for details
-    //
-    return (m_DeviceDescriptor.bDeviceClass == 0x09 && 
m_DeviceDescriptor.bDeviceSubClass == 0x00);
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBDevice::GetParent(
-    PVOID * Parent)
-{
-    //
-    // returns parent
-    //
-    *Parent = m_Parent;
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}
-
-//----------------------------------------------------------------------------------------
-ULONG
-CUSBDevice::GetDeviceAddress()
-{
-    //
-    // get device address
-    //
-    return m_DeviceAddress;
-}
-
-//----------------------------------------------------------------------------------------
-ULONG
-CUSBDevice::GetPort()
-{
-    //
-    // get port to which this device is connected to
-    //
-    return m_Port;
-}
-
-//----------------------------------------------------------------------------------------
-USB_DEVICE_SPEED
-CUSBDevice::GetSpeed()
-{
-    if (m_PortStatus & USB_PORT_STATUS_LOW_SPEED)
-    {
-        //
-        // low speed device
-        //
-        return UsbLowSpeed;
-    }
-    else if (m_PortStatus & USB_PORT_STATUS_HIGH_SPEED)
-    {
-        //
-        // high speed device
-        //
-        return UsbHighSpeed;
-    }
-
-    //
-    // default to full speed
-    //
-    return UsbFullSpeed;
-}
-
-//----------------------------------------------------------------------------------------
-USB_DEVICE_TYPE
-CUSBDevice::GetType()
-{
-    //
-    // device is encoded into bcdUSB
-    //
-    if (m_DeviceDescriptor.bcdUSB == 0x110)
-    {
-        //
-        // USB 1.1 device
-        //
-        return Usb11Device;
-    }
-    else if (m_DeviceDescriptor.bcdUSB == 0x200)
-    {
-        //
-        // USB 2.0 device
-        //
-        return Usb20Device;
-    }
-
-    DPRINT1("CUSBDevice::GetType Unknown bcdUSB Type %x\n", 
m_DeviceDescriptor.bcdUSB);
-    PC_ASSERT(FALSE);
-
-    return Usb11Device;
-}
-
-//----------------------------------------------------------------------------------------
-ULONG
-CUSBDevice::GetState()
-{
-    UNIMPLEMENTED
-    return FALSE;
-}
-
-//----------------------------------------------------------------------------------------
-void
-CUSBDevice::SetDeviceHandleData(
-    PVOID Data)
-{
-    //
-    // set device data, for debugging issues
-    //
-    m_Data = Data;
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBDevice::SetDeviceAddress(
-    ULONG DeviceAddress)
-{
+
+}
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+CUSBDevice::CreateConfigurationDescriptor(
+    ULONG Index)
+{
+    PVOID Buffer;
     USB_DEFAULT_PIPE_SETUP_PACKET CtrlSetup;
     NTSTATUS Status;
-
-    //
-    // zero request
-    //
-    RtlZeroMemory(&CtrlSetup, sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
-
-    //
-    // initialize request
-    //
-    CtrlSetup.bRequest = USB_REQUEST_SET_ADDRESS;
-    CtrlSetup.wValue.W = (USHORT)DeviceAddress;
-
-    //
-    // set device address
-    //
-    Status = CommitSetupPacket(&CtrlSetup, 0, 0, 0, 0);
-
-    //
-    // check for success
-    //
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to set device address
-        //
-        DPRINT1("CUSBDevice::SetDeviceAddress> failed to set device address 
with %x Address %x\n", Status, DeviceAddress);
-        return Status;
-    }
-
-    //
-    // store device address
-    //
-    m_DeviceAddress = DeviceAddress;
+    PMDL Mdl;
+    ULONG InterfaceIndex, EndPointIndex;
+    PUSB_CONFIGURATION_DESCRIPTOR ConfigurationDescriptor;
+    PUSB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+    PUSB_ENDPOINT_DESCRIPTOR EndPointDescriptor;
+
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(m_ConfigurationDescriptors);
+
+    //
+    // first allocate a buffer which should be enough to store all different 
interfaces and endpoints
+    //
+    Buffer = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, TAG_USBEHCI);
+    if (!Buffer)
+    {
+        //
+        // failed to allocate buffer
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // build setup packet
+    //
+    CtrlSetup.bmRequestType._BM.Recipient = BMREQUEST_TO_DEVICE;
+    CtrlSetup.bmRequestType._BM.Type = BMREQUEST_STANDARD;
+    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.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);
+    if (!Mdl)
+    {
+        //
+        // failed to allocate mdl
+        //
+        ExFreePoolWithTag(Buffer, TAG_USBEHCI);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // build mdl for non paged pool
+    //
+    MmBuildMdlForNonPagedPool(Mdl);
+
+    //
+    // commit packet
+    //
+    Status = CommitSetupPacket(&CtrlSetup, PAGE_SIZE, Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to issue request, cleanup
+        //
+        IoFreeMdl(Mdl);
+        ExFreePool(Buffer);
+        return Status;
+    }
+
+    //
+    // now free the mdl
+    //
+    IoFreeMdl(Mdl);
+
+    //
+    // get configuration descriptor
+    //
+    ConfigurationDescriptor = (PUSB_CONFIGURATION_DESCRIPTOR)Buffer;
+
+    //
+    // sanity check
+    //
+    PC_ASSERT(ConfigurationDescriptor->bLength == 
sizeof(USB_CONFIGURATION_DESCRIPTOR));
+    PC_ASSERT(ConfigurationDescriptor->wTotalLength <= PAGE_SIZE);
+    PC_ASSERT(ConfigurationDescriptor->bNumInterfaces);
+
+    //
+    // request is complete, initialize configuration descriptor
+    //
+    RtlCopyMemory(&m_ConfigurationDescriptors[Index].ConfigurationDescriptor, 
ConfigurationDescriptor, ConfigurationDescriptor->bLength);
+
+    //
+    // now allocate interface descriptors
+    //
+    m_ConfigurationDescriptors[Index].Interfaces = 
(PUSB_INTERFACE)ExAllocatePoolWithTag(NonPagedPool, sizeof(USB_INTERFACE) * 
ConfigurationDescriptor->bNumInterfaces, TAG_USBEHCI);
+    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++)
+    {
+        //
+        // sanity check
+        //
+        PC_ASSERT(InterfaceDescriptor->bLength == 
sizeof(USB_INTERFACE_DESCRIPTOR));
+        PC_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_USBEHCI);
+        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++)
+        {
+            //
+            // sanity check
+            //
+            PC_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;
+    }
+
+    //
+    // free buffer
+    //
+    ExFreePoolWithTag(Buffer, TAG_USBEHCI);
 
     //
     // done
     //
-    return STATUS_SUCCESS;
-}
-
-//----------------------------------------------------------------------------------------
-void
-CUSBDevice::GetDeviceDescriptor(
-    PUSB_DEVICE_DESCRIPTOR DeviceDescriptor)
-{
-    RtlMoveMemory(DeviceDescriptor, &m_DeviceDescriptor, 
sizeof(USB_DEVICE_DESCRIPTOR));
-}
-
-//----------------------------------------------------------------------------------------
-UCHAR
-CUSBDevice::GetConfigurationValue()
-{
-    UNIMPLEMENTED
-    return 0x1;
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBDevice::CommitUrb(
-    PURB Urb)
-{
-    UNIMPLEMENTED
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBDevice::SubmitUrb(
-    PURB Urb)
-{
-    KIRQL OldLevel;
-    NTSTATUS Status;
-
-    //
-    // acquire device lock
-    //
-    KeAcquireSpinLock(&m_Lock, &OldLevel);
-
-    //
-    // commit urb
-    //
-    Status = CommitUrb(Urb);
-
-    //
-    // release lock
-    //
-    KeReleaseSpinLock(&m_Lock, OldLevel);
-
     return Status;
 }
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBDevice::CommitSetupPacket(
-    PUSB_DEFAULT_PIPE_SETUP_PACKET Packet,
-    IN ULONG BufferLength, 
-    IN OUT PVOID Buffer,
-    IN PIRP Irp,
-    IN PKEVENT pEvent)
-{
-    NTSTATUS Status;
-    PUSBREQUEST Request;
-    KEVENT Event;
-    BOOLEAN Wait = FALSE;
-    PMDL Mdl = 0;
-
-
-    if (!m_Queue)
-    {
-        //
-        // no queue, wtf?
-        //
-        DPRINT1("CUSBDevice::CommitSetupPacket> no queue!!!\n");
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    //
-    // build usb request
-    //
-    Status = m_Queue->CreateUSBRequest(&Request);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to build request
-        //
-        DPRINT1("CUSBDevice::CommitSetupPacket> CreateUSBRequest failed with 
%x\n", Status);
-        return Status;
-    }
-
-    /* FIXME build MDL */
-
-    //
-    // initialize request
-    //
-    Status = Request->InitializeWithSetupPacket(m_DmaManager, Packet, 
BufferLength, Mdl);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to initialize request
-        //
-        DPRINT1("CUSBDevice::CommitSetupPacket> failed to initialize  usb 
request with %x\n", Status);
-        Request->Release();
-        return Status;
-    }
-
-    //
-    // is a irp or event provided ?
-    //
-    if (Irp == NULL && pEvent == NULL)
-    {
-        //
-        // no completion details provided, requestor wants synchronized
-        //
-        KeInitializeEvent(&Event, NotificationEvent, FALSE);
-        pEvent = &Event;
-        Wait = TRUE;
-    }
-
-    //
-    // set completion details
-    //
-    Status = Request->SetCompletionEvent(pEvent);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to set completion details
-        //
-        DPRINT1("CUSBDevice::CommitSetupPacket> failed to set completion 
details with %x\n", Status);
-        Request->Release();
-        return Status;
-    }
- 
-    //
-    // now add the request
-    //
-    Status = m_Queue->AddUSBRequest(Request);
-    if (!NT_SUCCESS(Status))
-    {
-        //
-        // failed to add request
-        //
-        DPRINT1("CUSBDevice::CommitSetupPacket> failed add request to queue 
with %x\n", Status);
-        Request->Release();
-        return Status;
-    }
-
-    if (Wait)
-    {
-        //
-        // wait for the operation to complete
-        //
-        KeWaitForSingleObject(pEvent, Executive, KernelMode, FALSE, NULL);
-    }
-
-    //TODO:
-    // Get result code from operation
-    //
-
-    //
-    // returns the result code when the operation has been finished
-    //
-    //Status = Request->GetResultCode();
-
-    //
-    // release request
-    //
-    Request->Release();
-
-    //
-    // done
-    //
-    return Status;
-}
+
 
//----------------------------------------------------------------------------------------
 NTSTATUS
 CreateUSBDevice(

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp?rev=51406&r1=51405&r2=51406&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp [iso-8859-1] 
Tue Apr 19 18:35:40 2011
@@ -38,12 +38,14 @@
     // IUSBRequest interface functions
     virtual NTSTATUS InitializeWithSetupPacket(IN PDMAMEMORYMANAGER 
DmaManager, IN PUSB_DEFAULT_PIPE_SETUP_PACKET SetupPacket, IN OUT ULONG 
TransferBufferLength, IN OUT PMDL TransferBuffer);
     virtual NTSTATUS InitializeWithIrp(IN PDMAMEMORYMANAGER DmaManager, IN OUT 
PIRP Irp);
-    virtual NTSTATUS SetCompletionEvent(IN PKEVENT Event);
-    virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, IN ULONG 
UrbStatusCode);
-    virtual VOID CancelCallback(IN NTSTATUS NtStatusCode);
+    virtual VOID CompletionCallback(IN NTSTATUS NtStatusCode, IN ULONG 
UrbStatusCode, IN struct _QUEUE_HEAD *QueueHead);
+    virtual VOID CancelCallback(IN NTSTATUS NtStatusCode, IN struct 
_QUEUE_HEAD *QueueHead);
     virtual NTSTATUS GetQueueHead(struct _QUEUE_HEAD ** OutHead);
     virtual BOOLEAN IsRequestComplete();
     virtual ULONG GetTransferType();
+    virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT 
OPTIONAL PULONG UrbStatusCode);
+    virtual BOOLEAN IsRequestInitialized();
+    virtual BOOLEAN ShouldReleaseRequestAfterCompletion();
 
     // local functions
     ULONG InternalGetTransferType();
@@ -60,17 +62,60 @@
 
 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;
+
+    //
+    // transfer buffer MDL
+    //
+    PMDL m_TransferBufferMDL;
+
+
+    //
+    // caller provided setup packet
+    //
     PUSB_DEFAULT_PIPE_SETUP_PACKET m_SetupPacket;
-    ULONG m_TransferBufferLength;
-    PMDL m_TransferBufferMDL;
-    PIRP m_Irp;
+
+    //
+    // completion event for callers who initialized request with setup packet
+    //
     PKEVENT m_CompletionEvent;
 
+    //
+    // DMA queue head
+    //
     PQUEUE_HEAD m_QueueHead;
+
+    //
+    // DMA transfer descriptors linked to the queue head
+    //
     PQUEUE_TRANSFER_DESCRIPTOR m_TransferDescriptors[3];
+
+    //
+    // 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;
+
 };
 
 
//----------------------------------------------------------------------------------------
@@ -106,6 +151,23 @@
     m_TransferBufferMDL = TransferBuffer;
 
     //
+    // allocate completion event
+    //
+    m_CompletionEvent = (PKEVENT)ExAllocatePoolWithTag(NonPagedPool, 
sizeof(KEVENT), TAG_USBEHCI);
+    if (!m_CompletionEvent)
+    {
+        //
+        // failed to allocate completion event
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // initialize completion event
+    //
+    KeInitializeEvent(m_CompletionEvent, NotificationEvent, FALSE);
+
+    //
     // done
     //
     return STATUS_SUCCESS;
@@ -166,7 +228,7 @@
             if (Urb->UrbBulkOrInterruptTransfer.TransferBufferLength)
             {
                 //
-                // it must have an MDL
+                // FIXME: it must have an MDL
                 //
                 PC_ASSERT(Urb->UrbBulkOrInterruptTransfer.TransferBufferMDL);
 
@@ -189,38 +251,27 @@
     return STATUS_SUCCESS;
 
 }
-//----------------------------------------------------------------------------------------
-NTSTATUS
-CUSBRequest::SetCompletionEvent(
-    IN PKEVENT Event)
-{
-    if (m_QueueHead)
-    {
-        //
-        // WTF? operation is already in progress
-        //
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    //
-    // store completion event
-    //
-    m_CompletionEvent = Event;
-
-    //
-    // done
-    //
-    return STATUS_SUCCESS;
-}
+
 
//----------------------------------------------------------------------------------------
 VOID
 CUSBRequest::CompletionCallback(
     IN NTSTATUS NtStatusCode,
-    IN ULONG UrbStatusCode)
+    IN ULONG UrbStatusCode,
+    IN struct _QUEUE_HEAD *QueueHead)
 {
     PIO_STACK_LOCATION IoStack;
     PURB Urb;
 
+    //
+    // FIXME: support linked queue heads
+    //
+
+    //
+    // store completion code
+    //
+    m_NtStatusCode = NtStatusCode;
+    m_UrbStatusCode = UrbStatusCode;
+
     if (m_Irp)
     {
         //
@@ -260,23 +311,33 @@
         //
         IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
     }
-
-    if (m_CompletionEvent)
-    {
-        //
-        // FIXME: make sure the request was not split
-        //
+    else
+    {
+        //
+        // signal completion event
+        //
+        PC_ASSERT(m_CompletionEvent);
         KeSetEvent(m_CompletionEvent, 0, FALSE);
     }
 }
 
//----------------------------------------------------------------------------------------
 VOID
 CUSBRequest::CancelCallback(
-    IN NTSTATUS NtStatusCode)
+    IN NTSTATUS NtStatusCode,
+    IN struct _QUEUE_HEAD *QueueHead)
 {
     PIO_STACK_LOCATION IoStack;
     PURB Urb;
 
+    //
+    // FIXME: support linked queue heads
+    //
+
+    //
+    // store cancelleation code
+    //
+    m_NtStatusCode = NtStatusCode;
+
     if (m_Irp)
     {
         //
@@ -306,12 +367,12 @@
         //
         IoCompleteRequest(m_Irp, IO_NO_INCREMENT);
     }
-
-    if (m_CompletionEvent)
-    {
-        //
-        // FIXME: make sure the request was not split
-        //
+    else
+    {
+        //
+        // signal completion event
+        //
+        PC_ASSERT(m_CompletionEvent);
         KeSetEvent(m_CompletionEvent, 0, FALSE);
     }
 }
@@ -370,6 +431,7 @@
     //
     // FIXME: check if request was split
     //
+    UNIMPLEMENTED
     return TRUE;
 }
 
//----------------------------------------------------------------------------------------
@@ -451,7 +513,6 @@
     NTSTATUS Status;
     ULONG NumTransferDescriptors, Index;
     PQUEUE_HEAD QueueHead;
-
 
     //
     // first allocate the queue head
@@ -802,3 +863,75 @@
     return Status;
 }
 
+//----------------------------------------------------------------------------------------
+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;
+    }
+
+}
+
+
+//-----------------------------------------------------------------------------------------
+BOOLEAN
+CUSBRequest::IsRequestInitialized()
+{
+    if (m_Irp || m_SetupPacket)
+    {
+        //
+        // request is initialized
+        //
+        return TRUE;
+    }
+
+    //
+    // request is not initialized
+    //
+    return FALSE;
+}
+
+//-----------------------------------------------------------------------------------------
+BOOLEAN
+CUSBRequest::ShouldReleaseRequestAfterCompletion()
+{
+    if (m_Irp)
+    {
+        //
+        // the request is completed, release it
+        //
+        return TRUE;
+    }
+    else
+    {
+        //
+        // created with an setup packet, don't release
+        //
+        return FALSE;
+    }
+}


Reply via email to