Author: janderwald
Date: Wed Apr 13 01:37:14 2011
New Revision: 51324

URL: http://svn.reactos.org/svn/reactos?rev=51324&view=rev
Log:
[USBEHCI]
- Re-implement DMA buffer routines. It is now faster and consumes less memory 
overhead per allocated memory block.
- IoGetDeviceProperty needs a PDO
- Add few comments
- No need to clear buffer twice in CreateQueueHead / CreateDescriptor




Modified:
    branches/cmake-bringup/drivers/usb/usbehci/fdo.c
    branches/cmake-bringup/drivers/usb/usbehci/hardware.h
    branches/cmake-bringup/drivers/usb/usbehci/hwiface.c
    branches/cmake-bringup/drivers/usb/usbehci/hwiface.h
    branches/cmake-bringup/drivers/usb/usbehci/physmem.c
    branches/cmake-bringup/drivers/usb/usbehci/physmem.h
    branches/cmake-bringup/drivers/usb/usbehci/transfer.c
    branches/cmake-bringup/drivers/usb/usbehci/usbehci.h

Modified: branches/cmake-bringup/drivers/usb/usbehci/fdo.c
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/fdo.c?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/fdo.c [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/fdo.c [iso-8859-1] Wed Apr 13 
01:37:14 2011
@@ -69,7 +69,7 @@
         {
             CompletedTD = NextTD;
             NextTD = NextTD->NextDescriptor;
-            FreeDescriptor(CompletedTD);
+            FreeDescriptor(hcd, CompletedTD);
         }
         
         /* If the Event is set then release waiter */
@@ -136,7 +136,7 @@
         /* Unlink QueueHead */
         UnlinkQueueHead(hcd, CompletedQH);
         /* Wait for a complete AsnycList tranversal before deleting? */
-        DeleteQueueHead(CompletedQH);
+        DeleteQueueHead(hcd, CompletedQH);
     }
 
     /* Port Change */
@@ -279,7 +279,7 @@
 
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
+    Status = IoGetDeviceProperty(FdoDeviceExtension->Pdo,
                                  DevicePropertyAddress,
                                  sizeof(ULONG),
                                  &DeviceAddress,
@@ -289,7 +289,7 @@
         DPRINT1("--->DeviceAddress: %x\n", DeviceAddress);
     }
 
-    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
+    Status = IoGetDeviceProperty(FdoDeviceExtension->Pdo,
                                  DevicePropertyBusNumber,
                                  sizeof(ULONG),
                                  &BusNumber,
@@ -364,6 +364,7 @@
         }
     }
 
+    /* initialize dpc */
     KeInitializeDpc(&FdoDeviceExtension->DpcObject,
                     EhciDefferedRoutine,
                     FdoDeviceExtension);
@@ -377,7 +378,7 @@
     DeviceDescription.InterfaceType = PCIBus;
     DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER;
 
-    FdoDeviceExtension->pDmaAdapter = 
IoGetDmaAdapter(FdoDeviceExtension->LowerDevice,
+    FdoDeviceExtension->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->Pdo,
                                                       &DeviceDescription,
                                                       
&FdoDeviceExtension->MapRegisters);
 
@@ -416,14 +417,33 @@
         return STATUS_UNSUCCESSFUL;
     }
 
+    /* Init SpinLock for host controller device lock */
+    KeInitializeSpinLock(&FdoDeviceExtension->hcd.Lock);
+
     FdoDeviceExtension->hcd.CommonBufferSize = PAGE_SIZE * 16;
 
     /* Zeroize it */
     RtlZeroMemory(FdoDeviceExtension->hcd.CommonBufferVA,
                   PAGE_SIZE * 16);
 
-    /* Init SpinLock for host controller device lock */
-    KeInitializeSpinLock(&FdoDeviceExtension->hcd.Lock);
+    /* create memory allocator */
+    Status = DmaMemAllocator_Create(&FdoDeviceExtension->hcd.DmaMemAllocator);
+    if (FdoDeviceExtension->hcd.DmaMemAllocator == 0)
+    {
+        /* FIXME cleanup */
+        DPRINT1("Ehci: Failed to create dma memory allocator!\n");
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* initialize memory allocator */
+    Status = 
DmaMemAllocator_Initialize(FdoDeviceExtension->hcd.DmaMemAllocator, 32, 
&FdoDeviceExtension->hcd.Lock, FdoDeviceExtension->hcd.CommonBufferPA, 
FdoDeviceExtension->hcd.CommonBufferVA, 
FdoDeviceExtension->hcd.CommonBufferSize);
+    if (!NT_SUCCESS(Status))
+    {
+        /* FIXME cleanup */
+        DPRINT1("Ehci: Failed to initialize dma memory allocator %x\n", 
Status);
+        return Status;
+    }
+
 
     /* Reserved a Queue Head that will always be in the AsyncList Address 
Register */
     FdoDeviceExtension->hcd.AsyncListQueue = 
CreateQueueHead(&FdoDeviceExtension->hcd);
@@ -436,7 +456,7 @@
 
     Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt,
                                 InterruptService,
-                                FdoDeviceExtension->DeviceObject,
+                                DeviceObject,
                                 NULL,
                                 FdoDeviceExtension->Vector,
                                 FdoDeviceExtension->Irql,
@@ -621,7 +641,7 @@
 }
 
 NTSTATUS NTAPI
-AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT Pdo)
+AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject)
 {
     NTSTATUS Status = STATUS_UNSUCCESSFUL;
     PDEVICE_OBJECT Fdo;
@@ -673,6 +693,7 @@
         }
     }
 
+    /* FIXME  */
     swprintf(CharSymLinkName, L"\\Device\\HCD%d", UsbDeviceNumber);
     RtlInitUnicodeString(&SymLinkName, CharSymLinkName);
     Status = IoCreateSymbolicLink(&SymLinkName, &DeviceName);
@@ -683,15 +704,19 @@
     }
 
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) Fdo->DeviceExtension;
-    RtlZeroMemory(FdoDeviceExtension, sizeof(PFDO_DEVICE_EXTENSION));
-
+    RtlZeroMemory(FdoDeviceExtension, sizeof(FDO_DEVICE_EXTENSION));
+
+    /* initialize timer */
     KeInitializeTimerEx(&FdoDeviceExtension->UpdateTimer, 
SynchronizationTimer);
 
+    /* initialize device extension */
     FdoDeviceExtension->Common.IsFdo = TRUE;
-    FdoDeviceExtension->DeviceObject = Fdo;
-
-    FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, Pdo);
-
+    FdoDeviceExtension->Common.DriverObject = DriverObject;
+    FdoDeviceExtension->Common.DeviceObject = Fdo;
+    FdoDeviceExtension->Pdo = PhysicalDeviceObject;
+
+    /* attach to device stack */
+    FdoDeviceExtension->LowerDevice = IoAttachDeviceToDeviceStack(Fdo, 
PhysicalDeviceObject);
     if (FdoDeviceExtension->LowerDevice == NULL)
     {
         DPRINT1("UsbEhci: Failed to attach to device stack!\n");
@@ -701,12 +726,13 @@
         return STATUS_NO_SUCH_DEVICE;
     }
 
-    Fdo->Flags |= DO_BUFFERED_IO;// | DO_POWER_PAGABLE;
-
-    ASSERT(FdoDeviceExtension->LowerDevice == Pdo);
-
-    Status = GetBusInterface(FdoDeviceExtension->LowerDevice, 
&FdoDeviceExtension->BusInterface);
-
+    /* setup device flags */
+    Fdo->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE;
+
+    /* get bus interface */
+    Status = GetBusInterface(PhysicalDeviceObject, 
&FdoDeviceExtension->BusInterface);
+
+    /* check for success */
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("GetBusInterface() failed with %x\n", Status);
@@ -716,6 +742,7 @@
         return Status;
     }
 
+    /* read pci config space */
     BytesRead = (*FdoDeviceExtension->BusInterface.GetBusData)(
         FdoDeviceExtension->BusInterface.Context,
         PCI_WHICHSPACE_CONFIG,
@@ -723,7 +750,7 @@
         0,
         PCI_COMMON_HDR_LENGTH);
 
-
+    /* check for success */
     if (BytesRead != PCI_COMMON_HDR_LENGTH)
     {
         DPRINT1("GetBusData failed!\n");
@@ -746,12 +773,16 @@
     DPRINT1("Vendor %x\n", PciConfig.VendorID);
     DPRINT1("Device %x\n", PciConfig.DeviceID);
 
+
     FdoDeviceExtension->VendorId = PciConfig.VendorID;
     FdoDeviceExtension->DeviceId = PciConfig.DeviceID;
 
+    /* update state */
     FdoDeviceExtension->DeviceState = DEVICEINTIALIZED;
 
-    Status = IoRegisterDeviceInterface(Pdo, 
&GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, &InterfaceSymLinkName);
+
+    /* FIXME: delay this until IRP_MN_START arrives */
+    Status = IoRegisterDeviceInterface(PhysicalDeviceObject, 
&GUID_DEVINTERFACE_USB_HOST_CONTROLLER, NULL, &InterfaceSymLinkName);
     if (!NT_SUCCESS(Status))
     {
         DPRINT1("Unable to register device interface!\n");
@@ -759,11 +790,14 @@
     }
     else
     {
+        /* enable device interface */
         Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
         DPRINT1("SetInterfaceState %x\n", Status);
         if (!NT_SUCCESS(Status))
             return Status;
     }
+
+    /* device is initialized */
     Fdo->Flags &= ~DO_DEVICE_INITIALIZING;
 
     return STATUS_SUCCESS;
@@ -782,6 +816,9 @@
 
     /*FIXME: This should never be called by upper drivers as they should only 
be dealing with the pdo */
 
+    ASSERT(0);
+
+
     FdoDeviceExtension = (PFDO_DEVICE_EXTENSION) DeviceObject->DeviceExtension;
     PdoDeviceExtension = (PPDO_DEVICE_EXTENSION) 
FdoDeviceExtension->Pdo->DeviceExtension;
 

Modified: branches/cmake-bringup/drivers/usb/usbehci/hardware.h
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/hardware.h?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/hardware.h [iso-8859-1] 
(original)
+++ branches/cmake-bringup/drivers/usb/usbehci/hardware.h [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -264,6 +264,18 @@
     UCHAR PortRoute [8];
 } EHCI_CAPS, *PEHCI_CAPS;
 
+
+typedef struct
+{
+    PKSPIN_LOCK Lock;
+    RTL_BITMAP Bitmap;
+    PULONG BitmapBuffer;
+    ULONG BlockSize;
+    PVOID VirtualBase;
+    PHYSICAL_ADDRESS PhysicalBase;
+    ULONG Length;
+}DMA_MEMORY_ALLOCATOR, *LPDMA_MEMORY_ALLOCATOR;
+
 typedef struct _EHCI_HOST_CONTROLLER
 {
     ULONG OpRegisters;
@@ -273,6 +285,7 @@
     ULONG CommonBufferSize;
     PQUEUE_HEAD AsyncListQueue;
     KSPIN_LOCK Lock;
+    LPDMA_MEMORY_ALLOCATOR DmaMemAllocator;
 } EHCI_HOST_CONTROLLER, *PEHCI_HOST_CONTROLLER;
 
 ULONG

Modified: branches/cmake-bringup/drivers/usb/usbehci/hwiface.c
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/hwiface.c?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/hwiface.c [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/hwiface.c [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -18,16 +18,20 @@
 /* Queue Element Transfer Descriptors */
 
 PQUEUE_TRANSFER_DESCRIPTOR
-CreateDescriptor(PEHCI_HOST_CONTROLLER hcd, UCHAR PIDCode, ULONG 
TotalBytesToTransfer)
+CreateDescriptor(
+    PEHCI_HOST_CONTROLLER hcd, 
+    UCHAR PIDCode, 
+    ULONG TotalBytesToTransfer)
 {
     PQUEUE_TRANSFER_DESCRIPTOR Descriptor;
     ULONG PhysicalAddress;
     UCHAR i;
-    KIRQL OldIrql;
+    NTSTATUS Status;
 
-    KeAcquireSpinLock(&hcd->Lock, &OldIrql);
+    Status = DmaMemAllocator_Allocate(hcd->DmaMemAllocator, 
sizeof(QUEUE_TRANSFER_DESCRIPTOR), (PVOID*)&Descriptor, &PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+       return NULL;
 
-    Descriptor = (PQUEUE_TRANSFER_DESCRIPTOR)AllocateMemory(hcd, 
sizeof(QUEUE_TRANSFER_DESCRIPTOR), &PhysicalAddress);
     RtlZeroMemory(Descriptor, sizeof(QUEUE_TRANSFER_DESCRIPTOR));
     Descriptor->NextPointer = TERMINATE_POINTER;
     Descriptor->AlternateNextPointer = TERMINATE_POINTER;
@@ -38,18 +42,16 @@
     Descriptor->Token.Bits.PIDCode = PIDCode;
     Descriptor->Token.Bits.TotalBytesToTransfer = TotalBytesToTransfer;
     Descriptor->PhysicalAddr = PhysicalAddress;
-    for (i=0;i<5;i++)
-        Descriptor->BufferPointer[i] = 0;
-
-    KeReleaseSpinLock(&hcd->Lock, OldIrql);
 
     return Descriptor;
 }
 
 VOID
-FreeDescriptor(PQUEUE_TRANSFER_DESCRIPTOR Descriptor)
+FreeDescriptor(
+    PEHCI_HOST_CONTROLLER hcd, 
+    PQUEUE_TRANSFER_DESCRIPTOR Descriptor)
 {
-    ReleaseMemory((ULONG)Descriptor);
+    DmaMemAllocator_Free(hcd->DmaMemAllocator, Descriptor, 
sizeof(QUEUE_TRANSFER_DESCRIPTOR));
 }
 
 /* Queue Head */
@@ -84,16 +86,17 @@
 CreateQueueHead(PEHCI_HOST_CONTROLLER hcd)
 {
     PQUEUE_HEAD CurrentQH;
-    ULONG PhysicalAddress , i;
-    KIRQL OldIrql;
+    NTSTATUS Status;
+    PHYSICAL_ADDRESS PhysicalAddress;
 
-    KeAcquireSpinLock(&hcd->Lock, &OldIrql);
+    Status = DmaMemAllocator_Allocate(hcd->DmaMemAllocator, 
sizeof(QUEUE_HEAD), (PVOID*)&CurrentQH, &PhysicalAddress);
+    if (!NT_SUCCESS(Status))
+       return NULL;
 
-    CurrentQH = (PQUEUE_HEAD)AllocateMemory(hcd, sizeof(QUEUE_HEAD), 
&PhysicalAddress);
     RtlZeroMemory(CurrentQH, sizeof(QUEUE_HEAD));
 
     ASSERT(CurrentQH);
-    CurrentQH->PhysicalAddr = PhysicalAddress;
+    CurrentQH->PhysicalAddr = PhysicalAddress.LowPart;
     CurrentQH->HorizontalLinkPointer = TERMINATE_POINTER;
     CurrentQH->CurrentLinkPointer = TERMINATE_POINTER;
     CurrentQH->AlternateNextPointer = TERMINATE_POINTER;
@@ -118,12 +121,9 @@
     CurrentQH->Token.DWord = 0;
     CurrentQH->NextQueueHead = NULL;
     CurrentQH->PreviousQueueHead = NULL;
-    for (i=0; i<5; i++)
-        CurrentQH->BufferPointer[i] = 0;
-
     CurrentQH->Token.Bits.InterruptOnComplete = TRUE;
 
-    KeReleaseSpinLock(&hcd->Lock, OldIrql);
+
     return CurrentQH;
 }
 
@@ -169,8 +169,10 @@
 }
 
 VOID
-DeleteQueueHead(PQUEUE_HEAD QueueHead)
+DeleteQueueHead(
+    PEHCI_HOST_CONTROLLER hcd,
+    PQUEUE_HEAD QueueHead)
 {
-    ReleaseMemory((ULONG)QueueHead);
+    DmaMemAllocator_Free(hcd->DmaMemAllocator, QueueHead, sizeof(QUEUE_HEAD));
 }
 

Modified: branches/cmake-bringup/drivers/usb/usbehci/hwiface.h
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/hwiface.h?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/hwiface.h [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/hwiface.h [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -5,7 +5,7 @@
 CreateDescriptor(PEHCI_HOST_CONTROLLER hcd, UCHAR PIDCode, ULONG 
TotalBytesToTransfer);
 
 VOID
-FreeDescriptor(PQUEUE_TRANSFER_DESCRIPTOR Descriptor);
+FreeDescriptor(PEHCI_HOST_CONTROLLER hcd, PQUEUE_TRANSFER_DESCRIPTOR 
Descriptor);
 
 VOID
 DumpQueueHeadList(PEHCI_HOST_CONTROLLER hcd);
@@ -20,5 +20,5 @@
 UnlinkQueueHead(PEHCI_HOST_CONTROLLER hcd, PQUEUE_HEAD QueueHead);
 
 VOID
-DeleteQueueHead(PQUEUE_HEAD QueueHead);
+DeleteQueueHead(PEHCI_HOST_CONTROLLER hcd, PQUEUE_HEAD QueueHead);
 

Modified: branches/cmake-bringup/drivers/usb/usbehci/physmem.c
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/physmem.c?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/physmem.c [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/physmem.c [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -10,89 +10,207 @@
 #include "physmem.h"
 #include "debug.h"
 
-#define SMALL_ALLOCATION_SIZE 32
-
 VOID
-DumpPages()
-{
-    //PMEM_HEADER MemBlock = (PMEM_HEADER)EhciSharedMemory.VirtualAddr;
-}
-
-// Returns Virtual Address of Allocated Memory
-ULONG
-AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress)
-{
-    PMEM_HEADER MemoryPage = (PMEM_HEADER)hcd->CommonBufferVA;
-    ULONG PageCount = 0;
-    ULONG NumberOfPages = hcd->CommonBufferSize / PAGE_SIZE;
-    ULONG BlocksNeeded;
-    ULONG i,j, freeCount;
-    ULONG RetAddr = 0;
-
-    Size = ((Size + SMALL_ALLOCATION_SIZE - 1) / SMALL_ALLOCATION_SIZE) * 
SMALL_ALLOCATION_SIZE;
-    BlocksNeeded = Size / SMALL_ALLOCATION_SIZE;
+NTAPI
+DmaMemAllocator_Destroy(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator)
+{
+    /* is there a bitmap buffer */
+    if (Allocator->BitmapBuffer)
+    {
+        /* free bitmap buffer */
+        ExFreePool(Allocator->BitmapBuffer);
+    }
+
+    /* free struct */
+    ExFreePool(Allocator);
+}
+
+NTSTATUS
+NTAPI
+DmaMemAllocator_Create(
+    IN LPDMA_MEMORY_ALLOCATOR *OutMemoryAllocator)
+{
+    LPDMA_MEMORY_ALLOCATOR Allocator;
+
+    /* sanity check */
+    ASSERT(OutMemoryAllocator);
+
+    /* allocate struct - must be non paged as it contains a spin lock */
+    Allocator = ExAllocatePool(NonPagedPool, sizeof(DMA_MEMORY_ALLOCATOR));
+    if (!Allocator)
+    {
+        /* no memory */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* zero struct */
+    RtlZeroMemory(Allocator, sizeof(DMA_MEMORY_ALLOCATOR));
+
+    /* store result */
+    *OutMemoryAllocator = Allocator;
+
+    /* done */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+DmaMemAllocator_Initialize(
+    IN OUT LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN ULONG DefaultBlockSize,
+    IN PKSPIN_LOCK Lock,
+    IN PHYSICAL_ADDRESS PhysicalBase,
+    IN PVOID VirtualBase,
+    IN ULONG Length)
+{
+    PULONG BitmapBuffer;
+    ULONG BitmapLength;
+
+    /* sanity checks */
+    ASSERT(Length >= PAGE_SIZE);
+    ASSERT(Length % PAGE_SIZE == 0);
+    ASSERT(DefaultBlockSize == 32 || DefaultBlockSize == 64 || 
DefaultBlockSize == 128);
+
+    /* calculate bitmap length */
+    BitmapLength = (Length / DefaultBlockSize) / sizeof(ULONG);
+
+    /* allocate bitmap buffer from nonpaged pool */
+    BitmapBuffer = ExAllocatePool(NonPagedPool, BitmapLength);
+    if (!BitmapBuffer)
+    {
+        /* out of memory */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* initialize bitmap */
+    RtlInitializeBitMap(&Allocator->Bitmap, BitmapBuffer, BitmapLength);
+    RtlClearAllBits(&Allocator->Bitmap);
+
+    /* initialize rest of allocator */
+    Allocator->PhysicalBase = PhysicalBase;
+    Allocator->VirtualBase = VirtualBase;
+    Allocator->Length = Length;
+    Allocator->BitmapBuffer = BitmapBuffer;
+    Allocator->Lock = Lock;
+    Allocator->BlockSize = DefaultBlockSize;
+
+    /* done */
+    return STATUS_SUCCESS;
+}
+
+NTSTATUS
+NTAPI
+DmaMemAllocator_Allocate(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN ULONG Size,
+    OUT PVOID *OutVirtualAddress,
+    OUT PPHYSICAL_ADDRESS OutPhysicalAddress)
+{
+    ULONG Length, BlockCount, FreeIndex, StartPage, EndPage;
+    KIRQL OldLevel;
+
+    /* sanity check */
+    ASSERT(Size < PAGE_SIZE);
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
+
+    /* align request size to block size */
+    Length = (Size + Allocator->BlockSize -1) & ~(Allocator->BlockSize -1);
+
+    /* sanity check */
+    ASSERT(Length);
+
+    /* convert to block count */
+    BlockCount = Length / Allocator->BlockSize;
+
+    /* acquire lock */
+    KeAcquireSpinLock(Allocator->Lock, &OldLevel);
+
+
+    /* start search */
+    FreeIndex = 0;
     do
     {
-        if (MemoryPage->IsFull)
+
+        /* search for an free index */
+        FreeIndex = RtlFindClearBits(&Allocator->Bitmap, BlockCount, 
FreeIndex);
+
+        /* check if there were bits found */
+        if (FreeIndex == MAXULONG)
+           break;
+
+        /* check that the allocation does not spawn over page boundaries */
+        StartPage = (FreeIndex * Allocator->BlockSize);
+        StartPage = (StartPage != 0 ? StartPage / PAGE_SIZE : 0);
+        EndPage = ((FreeIndex + BlockCount) * Allocator->BlockSize) / 
PAGE_SIZE;
+
+
+        if (StartPage == EndPage)
         {
-            PageCount++;
-            MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE);
-            continue;
+            /* reserve bits */
+            RtlSetBits(&Allocator->Bitmap, FreeIndex, BlockCount);
+
+            /* done */
+            break;
         }
-        freeCount = 0;
-        for (i = 0; i < sizeof(MemoryPage->Entry); i++)
+        else
         {
-            if (!MemoryPage->Entry[i].InUse)
-            {
-                freeCount++;
-            }
-            else
-            {
-                freeCount = 0;
-            }
-
-            if ((i-freeCount+1 + BlocksNeeded) > sizeof(MemoryPage->Entry))
-            {
-                freeCount = 0;
-                continue;
-            }
-            if (freeCount == BlocksNeeded)
-            {
-                for (j = 0; j < freeCount; j++)
-                {
-                    MemoryPage->Entry[i-j].InUse = 1;
-                    MemoryPage->Entry[i-j].Blocks = 0;
-                }
-
-                MemoryPage->Entry[i-freeCount + 1].Blocks = BlocksNeeded;
-
-                RetAddr = (ULONG)MemoryPage + (SMALL_ALLOCATION_SIZE * (i - 
freeCount + 1)) + sizeof(MEM_HEADER);
-
-                *PhysicalAddress = (ULONG)hcd->CommonBufferPA.LowPart + 
(RetAddr - (ULONG)hcd->CommonBufferVA);
-                return RetAddr;
-            }
+            /* request spaws a page boundary */
+            FreeIndex++;
         }
-
-        PageCount++;
-        MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE);
-    } while (PageCount < NumberOfPages);
-
-    return 0;
+    }
+    while(TRUE);
+
+    /* release bitmap lock */
+    KeReleaseSpinLock(Allocator->Lock, OldLevel);
+
+    /* check if allocation failed */
+    if (FreeIndex == MAXULONG)
+    {
+        /* allocation failed */
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* return result */
+    *OutVirtualAddress = (PVOID)((ULONG_PTR)Allocator->VirtualBase + FreeIndex 
* Allocator->BlockSize);
+    OutPhysicalAddress->QuadPart = Allocator->PhysicalBase.QuadPart + 
FreeIndex * Allocator->BlockSize;
+
+    /* done */
+    return STATUS_SUCCESS;
 }
 
 VOID
-ReleaseMemory(ULONG Address)
-{
-    PMEM_HEADER MemoryPage;
-    ULONG Index, i, BlockSize;
-
-    MemoryPage = (PMEM_HEADER)(Address & ~(PAGE_SIZE - 1));
-
-    Index = (Address - ((ULONG)MemoryPage + sizeof(MEM_HEADER))) / 
SMALL_ALLOCATION_SIZE;
-    BlockSize = MemoryPage->Entry[Index].Blocks;
-    for (i = 0; i < BlockSize; i++)
-    {
-        MemoryPage->Entry[Index + i].InUse = 0;
-        MemoryPage->Entry[Index + i].Blocks = 0;
-    }
-}
+NTAPI
+DmaMemAllocator_Free(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN OPTIONAL PVOID VirtualAddress,
+    IN ULONG Size)
+{
+    KIRQL OldLevel;
+    ULONG BlockOffset = 0, BlockLength;
+
+    /* sanity check */
+    ASSERT(VirtualAddress);
+
+    /* calculate block length */
+    BlockLength = ((ULONG_PTR)VirtualAddress - 
(ULONG_PTR)Allocator->VirtualBase);
+
+    /* is block offset zero */
+    if (BlockLength)
+    {
+        /* divide by base block size */
+        BlockOffset = BlockLength / Allocator->BlockSize;
+    }
+
+    /* align size to base block */
+    Size = (Size + Allocator->BlockSize - 1) & ~(Allocator->BlockSize - 1);
+
+    /* acquire bitmap lock */
+    KeAcquireSpinLock(Allocator->Lock, &OldLevel);
+
+    /* clear bits */
+    RtlClearBits(&Allocator->Bitmap, BlockOffset, Size);
+
+    /* release bitmap lock */
+    KeReleaseSpinLock(Allocator->Lock, OldLevel);
+}

Modified: branches/cmake-bringup/drivers/usb/usbehci/physmem.h
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/physmem.h?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/physmem.h [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/physmem.h [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -2,25 +2,42 @@
 
 #include "hardware.h"
 
-typedef struct _MEM_ENTRY
-{
-    UCHAR InUse:1;
-    UCHAR Blocks:7;
-} MEM_ENTRY, *PMEM_ENTRY;
+/* destroys memory allocator */
+VOID
+NTAPI
+DmaMemAllocator_Destroy(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator);
 
-typedef struct _MEM_HEADER
-{
-    UCHAR IsFull;
-    MEM_ENTRY Entry[124];
-    UCHAR Reserved[3];
-} MEM_HEADER, *PMEM_HEADER;
+/* create memory allocator */
+NTSTATUS
+NTAPI
+DmaMemAllocator_Create(
+    IN LPDMA_MEMORY_ALLOCATOR *OutMemoryAllocator);
 
+/* initializes memory allocator */
+NTSTATUS
+NTAPI
+DmaMemAllocator_Initialize(
+    IN OUT LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN ULONG DefaultBlockSize,
+    IN PKSPIN_LOCK Lock,
+    IN PHYSICAL_ADDRESS PhysicalBase,
+    IN PVOID VirtualBase,
+    IN ULONG Length);
+
+/* allocates memory from allocator */
+NTSTATUS
+NTAPI
+DmaMemAllocator_Allocate(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN ULONG Size,
+    OUT PVOID *OutVirtualAddress,
+    OUT PPHYSICAL_ADDRESS OutPhysicalAddress);
+
+/* frees memory block from allocator */
 VOID
-DumpPages(VOID);
-
-ULONG
-AllocateMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Size, ULONG *PhysicalAddress);
-
-VOID
-ReleaseMemory(ULONG Address);
-
+NTAPI
+DmaMemAllocator_Free(
+    IN LPDMA_MEMORY_ALLOCATOR Allocator,
+    IN PVOID VirtualAddress,
+    IN ULONG Size);

Modified: branches/cmake-bringup/drivers/usb/usbehci/transfer.c
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/transfer.c?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/transfer.c [iso-8859-1] 
(original)
+++ branches/cmake-bringup/drivers/usb/usbehci/transfer.c [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -143,11 +143,13 @@
     ULONG MdlPhysicalAddr;
     PKEVENT Event = NULL;
     PMDL pMdl = NULL;
-    PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetupVA, CtrlPhysicalPA;
-
-    CtrlSetupVA = (PUSB_DEFAULT_PIPE_SETUP_PACKET)AllocateMemory(hcd,
-                                                               
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET),
-                                                               
(ULONG*)&CtrlPhysicalPA);
+    PUSB_DEFAULT_PIPE_SETUP_PACKET CtrlSetupVA;
+    NTSTATUS Status;
+    PHYSICAL_ADDRESS PhysicalAddress;
+
+    /* allocate memory */
+    Status = DmaMemAllocator_Allocate(hcd->DmaMemAllocator, 
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET), (PVOID*)&CtrlSetupVA, &PhysicalAddress);
+    ASSERT(Status == STATUS_SUCCESS);
 
     RtlCopyMemory(CtrlSetupVA, CtrlSetup, 
sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
     /* If no Irp then wait on completion */
@@ -214,7 +216,7 @@
     }
     
     /* Assign the descritors buffers */
-    Descriptor[0]->BufferPointer[0] = (ULONG)CtrlPhysicalPA;
+    Descriptor[0]->BufferPointer[0] = PhysicalAddress.LowPart;
 
     if (TransferBuffer)
     {        

Modified: branches/cmake-bringup/drivers/usb/usbehci/usbehci.h
URL: 
http://svn.reactos.org/svn/reactos/branches/cmake-bringup/drivers/usb/usbehci/usbehci.h?rev=51324&r1=51323&r2=51324&view=diff
==============================================================================
--- branches/cmake-bringup/drivers/usb/usbehci/usbehci.h [iso-8859-1] (original)
+++ branches/cmake-bringup/drivers/usb/usbehci/usbehci.h [iso-8859-1] Wed Apr 
13 01:37:14 2011
@@ -104,8 +104,7 @@
 typedef struct _FDO_DEVICE_EXTENSION
 {
     COMMON_DEVICE_EXTENSION Common;
-    PDRIVER_OBJECT DriverObject;
-    PDEVICE_OBJECT DeviceObject;
+
     PDEVICE_OBJECT LowerDevice;
     PDEVICE_OBJECT Pdo;
     ULONG DeviceState;


Reply via email to