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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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/usbehc... ============================================================================== --- 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;