[ros-diffs] [janderwald] 51369: [USBEHCI_NEW] - Implement IDMAMemoryManager interface, with IDMAMemoryManager::Allocate, IDMAMemoryManager::Free - Fix interface of IDMAMemoryManager - Will be used by IUSBHardw...

janderwald at svn.reactos.org janderwald at svn.reactos.org
Sat Apr 16 12:26:07 UTC 2011


Author: janderwald
Date: Sat Apr 16 12:26:06 2011
New Revision: 51369

URL: http://svn.reactos.org/svn/reactos?rev=51369&view=rev
Log:
[USBEHCI_NEW]
- Implement IDMAMemoryManager interface, with IDMAMemoryManager::Allocate, IDMAMemoryManager::Free
- Fix interface of IDMAMemoryManager
- Will be used by IUSBHardwareDevice

Added:
    branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp   (with props)
Modified:
    branches/usb-bringup/drivers/usb/usbehci_new/CMakeLists.txt
    branches/usb-bringup/drivers/usb/usbehci_new/interfaces.h
    branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h

Modified: branches/usb-bringup/drivers/usb/usbehci_new/CMakeLists.txt
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/CMakeLists.txt?rev=51369&r1=51368&r2=51369&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/CMakeLists.txt [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/CMakeLists.txt [iso-8859-1] Sat Apr 16 12:26:06 2011
@@ -11,6 +11,7 @@
     misc.cpp
     purecall.cpp
     hub_controller.cpp
+    memory_manager.cpp
     usbehci.rc)
 
 target_link_libraries(usbehci

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=51369&r1=51368&r2=51369&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] Sat Apr 16 12:26:06 2011
@@ -253,7 +253,7 @@
 
     virtual NTSTATUS Allocate(IN ULONG Size,
                               OUT PVOID *OutVirtualBase,
-                              OUT PPHYSICAL_ADDRESS *OutPhysicalAddress) = 0;
+                              OUT PPHYSICAL_ADDRESS OutPhysicalAddress) = 0;
 
 
 //-----------------------------------------------------------------------------------------

Added: 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=51369&view=auto
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp (added)
+++ branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp [iso-8859-1] Sat Apr 16 12:26:06 2011
@@ -1,0 +1,339 @@
+/*
+ * PROJECT:     ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
+ * LICENSE:     GPL - See COPYING in the top level directory
+ * FILE:        drivers/usb/usbehci/memory_manager.cpp
+ * PURPOSE:     USB EHCI device driver.
+ * PROGRAMMERS:
+ *              Michael Martin (michael.martin at reactos.org)
+ *              Johannes Anderwald (johannes.anderwald at reactos.org)
+ */
+
+#include "usbehci.h"
+
+class CDMAMemoryManager : public IDMAMemoryManager
+{
+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;
+    }
+
+    // IDMAMemoryManager interface functions
+    virtual NTSTATUS Initialize(IN PUSBHARDWAREDEVICE Device, IN PKSPIN_LOCK Lock, IN ULONG DmaBufferSize, IN PVOID VirtualBase, IN PHYSICAL_ADDRESS PhysicalAddress, IN ULONG DefaultBlockSize);
+    virtual NTSTATUS Allocate(IN ULONG Size, OUT PVOID *OutVirtualBase, OUT PPHYSICAL_ADDRESS OutPhysicalAddress);
+    virtual NTSTATUS Release(IN PVOID VirtualBase, IN ULONG Size);
+
+    // constructor / destructor
+    CDMAMemoryManager(IUnknown *OuterUnknown){}
+    virtual ~CDMAMemoryManager(){}
+
+protected:
+    LONG m_Ref;
+    PUSBHARDWAREDEVICE m_Device;
+    PKSPIN_LOCK m_Lock;
+    LONG m_DmaBufferSize;
+    PVOID m_VirtualBase;
+    PHYSICAL_ADDRESS m_PhysicalAddress;
+    ULONG m_BlockSize;
+
+    PULONG m_BitmapBuffer;
+    RTL_BITMAP m_Bitmap;
+};
+
+//----------------------------------------------------------------------------------------
+NTSTATUS
+STDMETHODCALLTYPE
+CDMAMemoryManager::QueryInterface(
+    IN  REFIID refiid,
+    OUT PVOID* Output)
+{
+    return STATUS_UNSUCCESSFUL;
+}
+
+NTSTATUS
+CDMAMemoryManager::Initialize(
+    IN PUSBHARDWAREDEVICE Device,
+    IN PKSPIN_LOCK Lock,
+    IN ULONG DmaBufferSize,
+    IN PVOID VirtualBase,
+    IN PHYSICAL_ADDRESS PhysicalAddress,
+    IN ULONG DefaultBlockSize)
+{
+    ULONG BitmapLength;
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(DmaBufferSize >= PAGE_SIZE);
+    PC_ASSERT(DmaBufferSize % PAGE_SIZE == 0);
+    PC_ASSERT(DefaultBlockSize == 32 || DefaultBlockSize == 64 || DefaultBlockSize == 128);
+
+    //
+    // calculate bitmap length
+    //
+    BitmapLength = (DmaBufferSize / DefaultBlockSize) / sizeof(ULONG);
+
+    //
+    // allocate bitmap buffer
+    //
+    m_BitmapBuffer = (PULONG)ExAllocatePoolWithTag(NonPagedPool, BitmapLength, TAG_USBEHCI);
+    if (!m_BitmapBuffer)
+    {
+        //
+        // no memory
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // initialize bitmap
+    //
+    RtlInitializeBitMap(&m_Bitmap, m_BitmapBuffer, BitmapLength);
+
+    //
+    // clear all bits
+    //
+    RtlClearAllBits(&m_Bitmap);
+
+    //
+    // initialize rest of memory allocator
+    //
+    m_PhysicalAddress = PhysicalAddress;
+    m_VirtualBase = VirtualBase;
+    m_DmaBufferSize = DmaBufferSize;
+    m_BitmapBuffer = m_BitmapBuffer;
+    m_Lock = Lock;
+    m_BlockSize = DefaultBlockSize;
+
+    /* done */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+CDMAMemoryManager::Allocate(
+    IN ULONG Size,
+    OUT PVOID *OutVirtualAddress,
+    OUT PPHYSICAL_ADDRESS OutPhysicalAddress)
+{
+    ULONG Length, BlockCount, FreeIndex, StartPage, EndPage;
+    KIRQL OldLevel;
+
+    //
+    // sanity checks
+    //
+    ASSERT(Size < PAGE_SIZE);
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+    //
+    // align request
+    //
+    Length = (Size + m_BlockSize -1) & ~(m_BlockSize -1);
+
+    //
+    // sanity check
+    //
+    ASSERT(Length);
+
+    //
+    // convert to block count
+    //
+    BlockCount = Length / m_BlockSize;
+
+    //
+    // acquire lock
+    //
+    KeAcquireSpinLock(m_Lock, &OldLevel);
+
+    //
+    // start search
+    //
+    FreeIndex = 0;
+    do
+    {
+        //
+        // search for an free index
+        //
+        FreeIndex = RtlFindClearBits(&m_Bitmap, BlockCount, FreeIndex);
+
+        //
+        // check if there was a block found
+        //
+        if (FreeIndex == MAXULONG)
+        {
+           //
+           // no free block found
+           //
+           break;
+        }
+
+        //
+        // check that the allocation does not spawn over page boundaries
+        //
+        StartPage = (FreeIndex * m_BlockSize);
+        StartPage = (StartPage != 0 ? StartPage / PAGE_SIZE : 0);
+        EndPage = ((FreeIndex + BlockCount) * m_BlockSize) / PAGE_SIZE;
+
+        //
+        // does the request start and end on the same page
+        //
+        if (StartPage == EndPage)
+        {
+            //
+            // reserve block
+            //
+            RtlSetBits(&m_Bitmap, FreeIndex, BlockCount);
+
+            //
+            // reserve block
+            //
+            break;
+        }
+        else
+        {
+            //
+            // request spawned over page boundary
+            // restart search on next page
+            //
+            FreeIndex = (EndPage *  PAGE_SIZE) / m_BlockSize;
+        }
+    }
+    while(TRUE);
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(m_Lock, OldLevel);
+
+    //
+    // did allocation succeed
+    //
+    if (FreeIndex == MAXULONG)
+    {
+        //
+        // failed to allocate block, requestor must retry
+        //
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    //
+    // return result
+    //
+    *OutVirtualAddress = (PVOID)((ULONG_PTR)m_VirtualBase + FreeIndex * m_BlockSize);
+    OutPhysicalAddress->QuadPart = m_PhysicalAddress.QuadPart + FreeIndex * m_BlockSize;
+
+    //
+    // clear block
+    //
+    RtlZeroMemory(*OutVirtualAddress, Length);
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+CDMAMemoryManager::Release(
+    IN PVOID VirtualAddress,
+    IN ULONG Size)
+{
+    KIRQL OldLevel;
+    ULONG BlockOffset = 0, BlockLength;
+
+    //
+    // sanity checks
+    //
+    PC_ASSERT(VirtualAddress);
+    PC_ASSERT((ULONG_PTR)VirtualAddress >= (ULONG_PTR)m_VirtualBase);
+    PC_ASSERT((ULONG_PTR)m_VirtualBase + m_DmaBufferSize > (ULONG_PTR)m_VirtualBase);
+
+    //
+    // calculate block length
+    //
+    BlockLength = ((ULONG_PTR)VirtualAddress - (ULONG_PTR)m_VirtualBase);
+
+    //
+    // check if its the first block
+    //
+    if (BlockLength)
+    {
+        //
+        // divide by base block size
+        //
+        BlockOffset = BlockLength / m_BlockSize;
+    }
+
+    //
+    // align length to block size
+    //
+    Size = (Size + m_BlockSize - 1) & ~(m_BlockSize - 1);
+
+    //
+    // acquire lock
+    //
+    KeAcquireSpinLock(m_Lock, &OldLevel);
+
+    //
+    // release buffer
+    //
+    RtlClearBits(&m_Bitmap, BlockOffset, Size);
+
+    //
+    // release lock
+    //
+    KeReleaseSpinLock(m_Lock, OldLevel);
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+CreateDMAMemoryManager(
+    PDMAMEMORYMANAGER *OutMemoryManager)
+{
+    CDMAMemoryManager* This;
+
+    //
+    // allocate controller
+    //
+    This = new(NonPagedPool, TAG_USBEHCI) CDMAMemoryManager(0);
+    if (!This)
+    {
+        //
+        // failed to allocate
+        //
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    //
+    // add reference count
+    //
+    This->AddRef();
+
+    //
+    // return result
+    //
+    *OutMemoryManager = (PDMAMEMORYMANAGER)This;
+
+    //
+    // done
+    //
+    return STATUS_SUCCESS;
+}
+

Propchange: branches/usb-bringup/drivers/usb/usbehci_new/memory_manager.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h
URL: http://svn.reactos.org/svn/reactos/branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h?rev=51369&r1=51368&r2=51369&view=diff
==============================================================================
--- branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h [iso-8859-1] (original)
+++ branches/usb-bringup/drivers/usb/usbehci_new/usbehci.h [iso-8859-1] Sat Apr 16 12:26:06 2011
@@ -62,4 +62,9 @@
 //
 NTSTATUS CreateHubController(PHUBCONTROLLER * OutHubController);
 
+//
+// memory_manager.cpp
+//
+NTSTATUS CreateDMAMemoryManager(PDMAMEMORYMANAGER *OutMemoryManager);
+
 #endif




More information about the Ros-diffs mailing list