reactos/drivers/usb/usbehci/physmem.c

99 lines
2.7 KiB
C
Raw Normal View History

/*
* PROJECT: ReactOS Universal Serial Bus Bulk Enhanced Host Controller Interface
* LICENSE: GPL - See COPYING in the top level directory
* FILE: drivers/usb/usbehci/physmem.c
* PURPOSE: Common Buffer routines.
* PROGRAMMERS:
* Michael Martin (michael.martin@reactos.org)
*/
#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;
do
{
if (MemoryPage->IsFull)
{
PageCount++;
MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE);
continue;
}
freeCount = 0;
for (i = 0; i < sizeof(MemoryPage->Entry); i++)
{
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;
}
}
PageCount++;
MemoryPage = (PMEM_HEADER)((ULONG)MemoryPage + PAGE_SIZE);
} while (PageCount < NumberOfPages);
return 0;
}
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;
}
}