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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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/usbeh…
==============================================================================
--- 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;