Author: janderwald
Date: Fri May 20 14:47:15 2011
New Revision: 51826

URL: http://svn.reactos.org/svn/reactos?rev=51826&view=rev
Log:
[USBEHCI]
- Pass memory manager to USBQueue object
- Fix bug in memory manager which did not check if an allocation equals page 
size
- Implement interrupt queue head array with frequencys of 1ms up to 32ms
- Store queue heads in the sync schedule array
- WIP

Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
    branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
    branches/usb-bringup/drivers/usb/usbehci_new/usb_queue.cpp

Modified: branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp?rev=51826&r1=51825&r2=51826&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] 
(original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/hardware.cpp [iso-8859-1] Fri 
May 20 14:47:15 2011
@@ -437,7 +437,7 @@
     //
     // Initialize the UsbQueue now that we have an AdapterObject.
     //
-    Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, NULL);
+    Status = m_UsbQueue->Initialize(PUSBHARDWAREDEVICE(this), m_Adapter, 
m_MemoryManager, NULL);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Failed to Initialize the UsbQueue\n");

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=51826&r1=51825&r2=51826&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] Fri 
May 20 14:47:15 2011
@@ -525,7 +525,8 @@
 // Description: initializes the object
 
     virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware,
-                                PDMA_ADAPTER AdapterObject,
+                                IN PDMA_ADAPTER AdapterObject,
+                                IN PDMAMEMORYMANAGER MemManager,
                                 IN OPTIONAL PKSPIN_LOCK Lock) = 0;
 
 
//-----------------------------------------------------------------------------------------

Modified: branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
URL: 
http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp?rev=51826&r1=51825&r2=51826&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp 
[iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp 
[iso-8859-1] Fri May 20 14:47:15 2011
@@ -131,11 +131,12 @@
 {
     ULONG Length, BlockCount, FreeIndex, StartPage, EndPage;
     KIRQL OldLevel;
+    ULONG BlocksPerPage;
 
     //
     // sanity checks
     //
-    ASSERT(Size < PAGE_SIZE);
+    ASSERT(Size <= PAGE_SIZE);
     //ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
 
     //
@@ -157,6 +158,11 @@
     // acquire lock
     //
     KeAcquireSpinLock(m_Lock, &OldLevel);
+
+    //
+    // helper variable
+    //
+    BlocksPerPage = PAGE_SIZE / m_BlockSize;
 
     //
     // start search
@@ -202,6 +208,19 @@
             //
             break;
         }
+        else if ((BlockCount == BlocksPerPage) && (FreeIndex % BlocksPerPage 
== 0))
+        {
+            //
+            // the request equals PAGE_SIZE and is aligned at page boundary
+            // reserve block
+            //
+            RtlSetBits(&m_Bitmap, FreeIndex, BlockCount);
+
+            //
+            // reserve block
+            //
+            break;
+        }
         else
         {
             //

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=51826&r1=51825&r2=51826&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] Fri 
May 20 14:47:15 2011
@@ -33,7 +33,7 @@
         return m_Ref;
     }
 
-    virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER 
AdapterObject, IN OPTIONAL PKSPIN_LOCK Lock);
+    virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Hardware, PDMA_ADAPTER 
AdapterObject, IN PDMAMEMORYMANAGER MemManager, IN OPTIONAL PKSPIN_LOCK Lock);
     virtual ULONG GetPendingRequestCount();
     virtual NTSTATUS AddUSBRequest(PURB Urb);
     virtual NTSTATUS AddUSBRequest(IUSBRequest * Request);
@@ -47,13 +47,18 @@
     virtual ~CUSBQueue(){}
 
 protected:
-    LONG m_Ref;
-    KSPIN_LOCK m_Lock;
-    PDMA_ADAPTER m_Adapter;
-    PQUEUE_HEAD AsyncListQueueHead;
-    LIST_ENTRY m_CompletedRequestAsyncList;
-    LIST_ENTRY m_PendingRequestAsyncList;
-
+    LONG m_Ref;                                                                
         // reference count
+    KSPIN_LOCK m_Lock;                                                         
         // list lock
+    PDMA_ADAPTER m_Adapter;                                                    
         // dma adapter
+    PUSBHARDWAREDEVICE m_Hardware;                                             
         // stores hardware object
+    PQUEUE_HEAD AsyncListQueueHead;                                            
         // async queue head
+    LIST_ENTRY m_CompletedRequestAsyncList;                                    
         // completed async request list
+    LIST_ENTRY m_PendingRequestAsyncList;                                      
         // pending async request list
+    ULONG m_MaxPeriodicListEntries;                                            
         // max perdiodic list entries
+    ULONG m_MaxPollingInterval;                                                
         // max polling interval
+    PHYSICAL_ADDRESS m_SyncFrameListAddr;                                      
         // physical address of sync frame list
+    PULONG m_SyncFrameList;                                                    
         // virtual address of sync frame list
+    PQUEUE_HEAD * m_SyncFrameListQueueHeads;                                   
         // stores the frame list of queue head
 
     // queue head manipulation functions
     VOID LinkQueueHead(PQUEUE_HEAD HeadQueueHead, PQUEUE_HEAD NewQueueHead);
@@ -69,6 +74,9 @@
 
     // called when the completion queue is cleaned up
     VOID QueueHeadCleanup(PQUEUE_HEAD QueueHead);
+
+    // intializes the sync schedule
+    NTSTATUS InitializeSyncSchedule(IN PUSBHARDWAREDEVICE Hardware, IN 
PDMAMEMORYMANAGER MemManager);
 };
 
 
//=================================================================================================
@@ -93,7 +101,8 @@
 NTSTATUS
 CUSBQueue::Initialize(
     IN PUSBHARDWAREDEVICE Hardware,
-    PDMA_ADAPTER AdapterObject,
+    IN PDMA_ADAPTER AdapterObject,
+    IN PDMAMEMORYMANAGER MemManager,
     IN OPTIONAL PKSPIN_LOCK Lock)
 {
     NTSTATUS Status = STATUS_SUCCESS;
@@ -127,7 +136,139 @@
     //
     InitializeListHead(&m_PendingRequestAsyncList);
 
+    //
+    // now initialize sync schedule
+    //
+    Status = InitializeSyncSchedule(Hardware, MemManager);
+
     return Status;
+}
+
+NTSTATUS
+CUSBQueue::InitializeSyncSchedule(
+    IN PUSBHARDWAREDEVICE Hardware,
+    IN PDMAMEMORYMANAGER MemManager)
+{
+    PHYSICAL_ADDRESS QueueHeadPhysAddr;
+    NTSTATUS Status;
+    ULONG Index;
+    PQUEUE_HEAD QueueHead;
+
+    //
+    // FIXME: check if smaller list sizes are supported
+    //
+    m_MaxPeriodicListEntries = 1024;
+
+    //
+    // use polling scheme of 32ms
+    //
+    m_MaxPollingInterval = 32;
+
+    //
+    // allocate dummy frame list array
+    //
+    m_SyncFrameListQueueHeads = (PQUEUE_HEAD*)ExAllocatePool(NonPagedPool, 
m_MaxPollingInterval * sizeof(PQUEUE_HEAD));
+    if (!m_SyncFrameListQueueHeads)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+  
+    //
+    // first allocate a page to hold the queue array
+    //
+    Status = MemManager->Allocate(m_MaxPeriodicListEntries * sizeof(PVOID), 
(PVOID*)&m_SyncFrameList, &m_SyncFrameListAddr);
+    if (!NT_SUCCESS(Status))
+    {
+        //
+        // failed to allocate sync frame list array
+        //
+        DPRINT1("Failed to allocate sync frame list\n");
+        ExFreePool(m_SyncFrameListQueueHeads);
+        ASSERT(FALSE);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // now allocate queue head descriptors for the polling interval
+    //
+    for(Index = 0; Index < m_MaxPeriodicListEntries; Index++)
+    {
+        //
+        // check if is inside our polling interrupt frequency window
+        //
+        if (Index < m_MaxPollingInterval)
+        {
+            //
+            // allocate queue head
+            //
+            Status = MemManager->Allocate(sizeof(QUEUE_HEAD), 
(PVOID*)&QueueHead, &QueueHeadPhysAddr);
+
+            //
+            // initialize queue head
+            //
+            QueueHead->HorizontalLinkPointer = TERMINATE_POINTER;
+            QueueHead->AlternateNextPointer = TERMINATE_POINTER;
+            QueueHead->NextPointer = TERMINATE_POINTER;
+
+            //
+            // 1 for non high speed, 0 for high speed device
+            //
+            QueueHead->EndPointCharacteristics.ControlEndPointFlag = 0;
+            QueueHead->EndPointCharacteristics.HeadOfReclamation = FALSE;
+            QueueHead->EndPointCharacteristics.MaximumPacketLength = 64;
+
+            //
+            // Set NakCountReload to max value possible
+            //
+            QueueHead->EndPointCharacteristics.NakCountReload = 0xF;
+
+            //
+            // Get the Initial Data Toggle from the QEDT
+            //
+            QueueHead->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
+
+            //
+            // FIXME: check if High Speed Device
+            //
+            QueueHead->EndPointCharacteristics.EndPointSpeed = 
QH_ENDPOINT_HIGHSPEED;
+            QueueHead->EndPointCapabilities.NumberOfTransactionPerFrame = 0x03;
+            QueueHead->Token.DWord = 0;
+            QueueHead->Token.Bits.InterruptOnComplete = FALSE;
+            QueueHead->PhysicalAddr = QueueHeadPhysAddr.LowPart;
+
+
+            //
+            // store in queue head array
+            //
+            m_SyncFrameListQueueHeads[Index] = QueueHead;
+        }
+        else
+        {
+            //
+            // get cached entry
+            //
+            QueueHead = m_SyncFrameListQueueHeads[m_MaxPeriodicListEntries % 
m_MaxPollingInterval];
+        }
+
+        //
+        // store entry
+        //
+        m_SyncFrameList[Index] = (QueueHead->PhysicalAddr | 0x2);
+    }
+
+    //
+    // now set the sync base
+    //
+    Hardware->SetPeriodicListRegister(m_SyncFrameListAddr.LowPart);
+
+    //
+    // sync frame list initialized
+    //
+    return STATUS_SUCCESS;
 }
 
 ULONG


Reply via email to