Author: mjmartin
Date: Mon Apr 18 11:34:02 2011
New Revision: 51390

URL: http://svn.reactos.org/svn/reactos?rev=51390&view=rev
Log:
[USBEHCI_NEW]
- Use PQUEUE_HEAD as the Head of pending list  and Async (Active) list vice 
using PLIST_ENTRY.
- Implement linking/unlinking a QueueHead to these Head QueueHeads.
- Implement chain linking/unlinking of QueueHeads. Thr plan being to used these 
functions during DMA operations to pull a number of QueueHeads from the pending 
list to place into the Async list for execution. 
- Will look for optimization in these functions later.

Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp?rev=51390&r1=51389&r2=51390&view=diff
==============================================================================
--- 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] Mon 
Apr 18 11:34:02 2011
@@ -50,12 +50,16 @@
     PDMA_ADAPTER m_Adapter;
     PVOID VirtualBase;
     PHYSICAL_ADDRESS PhysicalAddress;
-    PLIST_ENTRY ExecutingList;
-    PLIST_ENTRY PendingList;
+    PQUEUE_HEAD AsyncQueueHead;
+    PQUEUE_HEAD PendingQueueHead;
     IDMAMemoryManager *m_MemoryManager;
 
     PQUEUE_HEAD CreateQueueHead();
     PQUEUE_TRANSFER_DESCRIPTOR CreateDescriptor(UCHAR PIDCode, ULONG 
TotalBytesToTransfer);
+    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);
 };
 
 
//=================================================================================================
@@ -84,7 +88,6 @@
     IN OPTIONAL PKSPIN_LOCK Lock)
 {
     NTSTATUS Status;
-    PQUEUE_HEAD HeadQueueHead;
 
     DPRINT1("CUSBQueue::Initialize()\n");
 
@@ -130,33 +133,28 @@
     }
 
     //
-    // Create a dead QueueHead for use in Async Register
-    //
-    HeadQueueHead = CreateQueueHead();
-    HeadQueueHead->HorizontalLinkPointer = HeadQueueHead->PhysicalAddr | 
QH_TYPE_QH;
-    HeadQueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
-    HeadQueueHead->Token.Bits.InterruptOnComplete = FALSE;
-    HeadQueueHead->EndPointCharacteristics.HeadOfReclamation = TRUE;
-    HeadQueueHead->Token.Bits.Halted = TRUE;
+    // Create a QueueHead for use in Async Register
+    //
+    AsyncQueueHead = CreateQueueHead();
+    AsyncQueueHead->HorizontalLinkPointer = AsyncQueueHead->PhysicalAddr | 
QH_TYPE_QH;
+    AsyncQueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
+    AsyncQueueHead->Token.Bits.InterruptOnComplete = FALSE;
+    AsyncQueueHead->EndPointCharacteristics.HeadOfReclamation = TRUE;
+    AsyncQueueHead->Token.Bits.Halted = TRUE;
     
-    Hardware->SetAsyncListRegister(HeadQueueHead->PhysicalAddr);
-
-    //
-    // Set ExecutingList and create PendingList
-    //
-    ExecutingList = &HeadQueueHead->LinkedQueueHeads;
-    PendingList = (PLIST_ENTRY) ExAllocatePool(NonPagedPool, 
sizeof(LIST_ENTRY));
-    if (!PendingList)
-    {
-        DPRINT1("Pool allocation failed\n");
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    //
-    // Initialize ListHeads
-    //
-    InitializeListHead(ExecutingList);
-    InitializeListHead(PendingList);
+    Hardware->SetAsyncListRegister(AsyncQueueHead->PhysicalAddr);
+
+    //
+    // Create a Unused QueueHead to hold pending QueueHeads
+    //
+    PendingQueueHead = CreateQueueHead();
+    PendingQueueHead->Token.Bits.Halted = TRUE;
+
+    //
+    // Initialize ListHead in QueueHeads
+    //
+    InitializeListHead(&AsyncQueueHead->LinkedQueueHeads);
+    InitializeListHead(&PendingQueueHead->LinkedQueueHeads);
 
     return STATUS_SUCCESS;
 }
@@ -262,6 +260,9 @@
     if (!NT_SUCCESS(Status))
         return NULL;
 
+    //
+    // Set default values
+    //
     Descriptor->NextPointer = TERMINATE_POINTER;
     Descriptor->AlternateNextPointer = TERMINATE_POINTER;
     Descriptor->Token.Bits.DataToggle = TRUE;
@@ -270,7 +271,144 @@
     Descriptor->Token.Bits.PIDCode = PIDCode;
     Descriptor->Token.Bits.TotalBytesToTransfer = TotalBytesToTransfer;
     Descriptor->PhysicalAddr = PhysicalAddress.LowPart;
+
     return Descriptor;
+}
+
+//
+// LinkQueueHead - Links one QueueHead to the end of HeadQueueHead list, 
updating HorizontalLinkPointer.
+//
+VOID
+CUSBQueue::LinkQueueHead(
+    PQUEUE_HEAD HeadQueueHead,
+    PQUEUE_HEAD NewQueueHead)
+{
+    PQUEUE_HEAD LastQueueHead, NextQueueHead;
+    PLIST_ENTRY Entry;
+    ASSERT(HeadQueueHead);
+    ASSERT(NewQueueHead);
+
+    //
+    // Link the LIST_ENTRYs
+    //
+    InsertTailList(&HeadQueueHead->LinkedQueueHeads, 
&NewQueueHead->LinkedQueueHeads);
+
+    //
+    // Update HLP for Previous QueueHead, which should be the last in list.
+    //
+    Entry = NewQueueHead->LinkedQueueHeads.Blink;
+    LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    LastQueueHead->HorizontalLinkPointer = (NewQueueHead->PhysicalAddr | 
QH_TYPE_QH);
+
+    //
+    // Update HLP for NewQueueHead to point to next, which should be the 
HeadQueueHead
+    //
+    Entry = NewQueueHead->LinkedQueueHeads.Flink;
+    NextQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    ASSERT(NextQueueHead == HeadQueueHead);
+    NewQueueHead->HorizontalLinkPointer = NextQueueHead->PhysicalAddr;
+}
+
+//
+// UnlinkQueueHead - Unlinks one QueueHead, updating HorizontalLinkPointer.
+//
+VOID
+CUSBQueue::UnlinkQueueHead(
+    PQUEUE_HEAD QueueHead)
+{
+    PQUEUE_HEAD PreviousQH, NextQH;
+    PLIST_ENTRY Entry;
+
+    Entry = QueueHead->LinkedQueueHeads.Blink;
+    PreviousQH = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    Entry = QueueHead->LinkedQueueHeads.Flink;
+    NextQH = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    ASSERT(QueueHead->HorizontalLinkPointer == (NextQH->PhysicalAddr | 
QH_TYPE_QH));
+    PreviousQH->HorizontalLinkPointer = NextQH->PhysicalAddr | QH_TYPE_QH;
+
+    RemoveEntryList(&QueueHead->LinkedQueueHeads);
+}
+
+//
+// LinkQueueHeadChain - Links a list of QueueHeads to the HeadQueueHead list, 
updating HorizontalLinkPointer.
+//
+VOID
+CUSBQueue::LinkQueueHeadChain(
+    PQUEUE_HEAD HeadQueueHead,
+    PQUEUE_HEAD NewQueueHead)
+{
+    PQUEUE_HEAD LastQueueHead;
+    PLIST_ENTRY Entry;
+    ASSERT(HeadQueueHead);
+    ASSERT(NewQueueHead);
+
+    //
+    // Find the last QueueHead in NewQueueHead
+    //
+    Entry = NewQueueHead->LinkedQueueHeads.Blink;
+    ASSERT(Entry != NewQueueHead->LinkedQueueHeads.Flink);
+    LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+
+    //
+    // Set the LinkPointer and Flink
+    //
+    LastQueueHead->HorizontalLinkPointer = HeadQueueHead->PhysicalAddr | 
QH_TYPE_QH;
+    LastQueueHead->LinkedQueueHeads.Flink = &HeadQueueHead->LinkedQueueHeads;
+
+    //
+    // Fine the last QueueHead in HeadQueueHead
+    //
+    Entry = HeadQueueHead->LinkedQueueHeads.Blink;
+    HeadQueueHead->LinkedQueueHeads.Blink = &LastQueueHead->LinkedQueueHeads;
+    LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    LastQueueHead->LinkedQueueHeads.Flink = &NewQueueHead->LinkedQueueHeads;
+    LastQueueHead->HorizontalLinkPointer = NewQueueHead->PhysicalAddr | 
QH_TYPE_QH;
+}
+
+//
+// UnlinkQueueHeadChain - Unlinks a list number of QueueHeads from 
HeadQueueHead list, updating HorizontalLinkPointer.
+// returns the chain of QueueHeads removed from HeadQueueHead.
+//
+PQUEUE_HEAD
+CUSBQueue::UnlinkQueueHeadChain(
+    PQUEUE_HEAD HeadQueueHead,
+    ULONG Count)
+{
+    PQUEUE_HEAD LastQueueHead, FirstQueueHead;
+    PLIST_ENTRY Entry;
+    ULONG Index;
+
+    //
+    // Find the last QueueHead in NewQueueHead
+    //
+    Entry = &HeadQueueHead->LinkedQueueHeads;
+    FirstQueueHead = CONTAINING_RECORD(Entry->Flink, QUEUE_HEAD, 
LinkedQueueHeads);
+
+    for (Index = 0; Index < Count; Index++)
+    {
+        Entry = Entry->Flink;
+
+        if (Entry == &HeadQueueHead->LinkedQueueHeads)
+        {
+            DPRINT1("Warnnig; Only %d QueueHeads in HeadQueueHead\n", Index);
+            Count = Index + 1;
+            break;
+        }
+    }
+
+    LastQueueHead = CONTAINING_RECORD(Entry, QUEUE_HEAD, LinkedQueueHeads);
+    HeadQueueHead->LinkedQueueHeads.Flink = 
LastQueueHead->LinkedQueueHeads.Flink;
+    if (Count + 1 == Index)
+    {
+        HeadQueueHead->LinkedQueueHeads.Blink = 
&HeadQueueHead->LinkedQueueHeads;
+    }
+    else
+        HeadQueueHead->LinkedQueueHeads.Blink = 
LastQueueHead->LinkedQueueHeads.Flink;
+
+    FirstQueueHead->LinkedQueueHeads.Blink = &LastQueueHead->LinkedQueueHeads;
+    LastQueueHead->LinkedQueueHeads.Flink = &FirstQueueHead->LinkedQueueHeads;
+    LastQueueHead->HorizontalLinkPointer = TERMINATE_POINTER;
+    return FirstQueueHead;
 }
 
 NTSTATUS


Reply via email to