Author: janderwald
Date: Sat Apr 23 19:36:23 2011
New Revision: 51440
URL:
http://svn.reactos.org/svn/reactos?rev=51440&view=rev
Log:
[USBEHCI_NEW]
- Create member for storing the request object
- Add interface function which is invoked when the queue head should be freed
- Add support functions which deal with completed queue heads
Modified:
branches/usb-bringup/drivers/usb/usbehci_new/hardware.h
branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp
branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hardware.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hardware.h [iso-8859-1] Sat Apr 23
19:36:23 2011
@@ -194,6 +194,7 @@
PIRP IrpToComplete;
PMDL Mdl;
PKEVENT Event;
+ PVOID Request;
} QUEUE_HEAD, *PQUEUE_HEAD;
//
Modified: branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- 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] Sat Apr 23
19:36:23 2011
@@ -474,6 +474,14 @@
// If the request was initialized with an setup packet, it will return false
virtual BOOLEAN ShouldReleaseRequestAfterCompletion() = 0;
+
+//----------------------------------------------------------------------------------------
+//
+// FreeQueueHead
+//
+// Description: frees the queue head with the associated transfer descriptors
+
+ virtual VOID FreeQueueHead(struct _QUEUE_HEAD * QueueHead) = 0;
};
typedef IUSBRequest *PUSBREQUEST;
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp [iso-8859-1] Sat Apr 23
19:36:23 2011
@@ -51,10 +51,17 @@
PQUEUE_HEAD AsyncListQueueHead;
PQUEUE_HEAD PendingListQueueHead;
+ // queue head manipulation functions
VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
VOID UnlinkQueueHead(PQUEUE_HEAD QueueHead);
VOID LinkQueueHeadChain(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
PQUEUE_HEAD UnlinkQueueHeadChain(PQUEUE_HEAD HeadQueueHead, ULONG Count);
+
+ // called for each completed queue head
+ NTSTATUS QueueHeadCompletion(PQUEUE_HEAD QueueHead, NTSTATUS Status);
+
+ // called when the completion queue is cleaned up
+ VOID QueueHeadCleanup(PQUEUE_HEAD QueueHead);
};
//=================================================================================================
@@ -141,6 +148,11 @@
// Add it to the pending list
//
LinkQueueHead(PendingListQueueHead, QueueHead);
+
+ //
+ // add extra reference which is released when the request is completed
+ //
+ Request->AddRef();
return STATUS_SUCCESS;
}
@@ -315,6 +327,154 @@
}
NTSTATUS
+CUSBQueue::QueueHeadCompletion(
+ PQUEUE_HEAD CurrentQH,
+ NTSTATUS Status)
+{
+ IUSBRequest *Request;
+ USBD_STATUS UrbStatus;
+ PQUEUE_HEAD NewQueueHead;
+
+ //
+ // this function is called when a queue head has been completed
+ //
+ PC_ASSERT(CurrentQH->Token.Bits.Active == 0);
+
+ //
+ // get contained usb request
+ //
+ Request = (IUSBRequest*)CurrentQH->Request;
+
+ //
+ // sanity check
+ //
+ PC_ASSERT(Request);
+
+ //
+ // check if the queue head was completed with errors
+ //
+ if (CurrentQH->Token.Bits.Halted)
+ {
+ if (CurrentQH->Token.Bits.DataBufferError)
+ {
+ //
+ // data buffer error
+ //
+ UrbStatus = USBD_STATUS_DATA_BUFFER_ERROR;
+ }
+ else if (CurrentQH->Token.Bits.BabbleDetected)
+ {
+ //
+ // babble detected
+ //
+ UrbStatus = USBD_STATUS_BABBLE_DETECTED;
+ }
+ else
+ {
+ //
+ // stall pid
+ //
+ UrbStatus = USBD_STATUS_STALL_PID;
+ }
+ }
+ else
+ {
+ //
+ // well done ;)
+ //
+ UrbStatus = USBD_STATUS_SUCCESS;
+ }
+
+ //
+ // notify request that a queue head has been completed
+ //
+ Request->CompletionCallback(Status, UrbStatus, CurrentQH);
+
+ //
+ // now unlink the queue head
+ // FIXME: implement chained queue heads
+ //
+ UnlinkQueueHead(CurrentQH);
+
+ //
+ // check if the request is complete
+ //
+ if (Request->IsRequestComplete() == FALSE)
+ {
+ //
+ // request is still in complete
+ // get new queue head
+ //
+ Status = Request->GetQueueHead(&NewQueueHead);
+
+ //
+ // add to pending list
+ //
+ LinkQueueHead(PendingListQueueHead, NewQueueHead);
+ }
+ else
+ {
+ //
+ // FIXME: put queue head into completed queue head list
+ //
+ }
+
+ //
+ // done
+ //
+ return STATUS_SUCCESS;
+}
+
+VOID
+CUSBQueue::QueueHeadCleanup(
+ PQUEUE_HEAD CurrentQH)
+{
+ IUSBRequest * Request;
+ BOOLEAN ShouldReleaseWhenDone;
+
+ //
+ // sanity checks
+ //
+ PC_ASSERT(CurrentQH->Token.Bits.Active == 0);
+ PC_ASSERT(CurrentQH->Request);
+
+ //
+ // get request
+ //
+ Request = (IUSBRequest*)CurrentQH->Request;
+
+ //
+ // let IUSBRequest free the queue head
+ //
+ Request->FreeQueueHead(CurrentQH);
+
+ //
+ // check if we should release request when done
+ //
+ ShouldReleaseWhenDone = Request->ShouldReleaseRequestAfterCompletion();
+
+ //
+ // release reference when the request was added
+ //
+ Request->Release();
+
+ //
+ // check if the operation was asynchronous
+ //
+ if (ShouldReleaseWhenDone)
+ {
+ //
+ // release outstanding reference count
+ //
+ Request->Release();
+ }
+
+ //
+ // request is now released
+ //
+}
+
+NTSTATUS
CreateUSBQueue(
PUSBQUEUE *OutUsbQueue)
{
Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_request.cpp
URL:
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci…
==============================================================================
--- 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] Sat Apr 23
19:36:23 2011
@@ -46,6 +46,7 @@
virtual VOID GetResultStatus(OUT OPTIONAL NTSTATUS *NtStatusCode, OUT OPTIONAL PULONG
UrbStatusCode);
virtual BOOLEAN IsRequestInitialized();
virtual BOOLEAN ShouldReleaseRequestAfterCompletion();
+ virtual VOID FreeQueueHead(struct _QUEUE_HEAD * QueueHead);
// local functions
ULONG InternalGetTransferType();
@@ -416,6 +417,11 @@
// store queue head
//
m_QueueHead = *OutHead;
+
+ //
+ // store request object
+ //
+ (*OutHead)->Request = PVOID(this);
}
//
@@ -936,6 +942,58 @@
}
}
+//-----------------------------------------------------------------------------------------
+VOID
+CUSBRequest::FreeQueueHead(
+ IN struct _QUEUE_HEAD * QueueHead)
+{
+ //
+ // FIXME: support chained queue heads
+ //
+ PC_ASSERT(QueueHead == m_QueueHead);
+
+ //
+ // release queue head
+ //
+ m_DmaManager->Release(QueueHead, sizeof(QUEUE_HEAD));
+
+ //
+ // nullify pointer
+ //
+ m_QueueHead = 0;
+
+ //
+ // release transfer descriptors
+ //
+
+ if (m_TransferDescriptors[0])
+ {
+ //
+ // release transfer descriptors
+ //
+ m_DmaManager->Release(m_TransferDescriptors[0],
sizeof(QUEUE_TRANSFER_DESCRIPTOR));
+ m_TransferDescriptors[0] = 0;
+ }
+
+ if (m_TransferDescriptors[1])
+ {
+ //
+ // release transfer descriptors
+ //
+ m_DmaManager->Release(m_TransferDescriptors[1],
sizeof(QUEUE_TRANSFER_DESCRIPTOR));
+ m_TransferDescriptors[1] = 0;
+ }
+
+ if (m_TransferDescriptors[2])
+ {
+ //
+ // release transfer descriptors
+ //
+ m_DmaManager->Release(m_TransferDescriptors[2],
sizeof(QUEUE_TRANSFER_DESCRIPTOR));
+ m_TransferDescriptors[2] = 0;
+ }
+}
+
NTSTATUS
InternalCreateUSBRequest(
PUSBREQUEST *OutRequest)