2010-12-30 15:12:46 +00:00
|
|
|
/*
|
|
|
|
* 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)
|
|
|
|
{
|
2011-04-13 04:43:25 +00:00
|
|
|
PMEM_HEADER MemoryPage = NULL;
|
2010-12-30 15:12:46 +00:00
|
|
|
ULONG PageCount = 0;
|
|
|
|
ULONG NumberOfPages = hcd->CommonBufferSize / PAGE_SIZE;
|
2011-04-13 04:43:25 +00:00
|
|
|
ULONG BlocksNeeded = 0;
|
2010-12-30 15:12:46 +00:00
|
|
|
ULONG i,j, freeCount;
|
|
|
|
ULONG RetAddr = 0;
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
MemoryPage = (PMEM_HEADER)hcd->CommonBufferVA[0];
|
2010-12-30 15:12:46 +00:00
|
|
|
Size = ((Size + SMALL_ALLOCATION_SIZE - 1) / SMALL_ALLOCATION_SIZE) * SMALL_ALLOCATION_SIZE;
|
|
|
|
BlocksNeeded = Size / SMALL_ALLOCATION_SIZE;
|
2011-04-13 04:43:25 +00:00
|
|
|
|
2010-12-30 15:12:46 +00:00
|
|
|
do
|
|
|
|
{
|
|
|
|
if (MemoryPage->IsFull)
|
|
|
|
{
|
|
|
|
PageCount++;
|
2011-04-13 04:43:25 +00:00
|
|
|
|
|
|
|
if (!(PMEM_HEADER)hcd->CommonBufferVA[PageCount])
|
|
|
|
{
|
|
|
|
hcd->CommonBufferVA[PageCount] =
|
|
|
|
hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter,
|
|
|
|
PAGE_SIZE,
|
|
|
|
&hcd->CommonBufferPA[PageCount],
|
|
|
|
FALSE);
|
|
|
|
}
|
|
|
|
MemoryPage = (PMEM_HEADER)hcd->CommonBufferVA[PageCount];
|
2010-12-30 15:12:46 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
freeCount = 0;
|
|
|
|
for (i = 0; i < sizeof(MemoryPage->Entry); i++)
|
|
|
|
{
|
|
|
|
if (!MemoryPage->Entry[i].InUse)
|
|
|
|
{
|
|
|
|
freeCount++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
freeCount = 0;
|
|
|
|
}
|
|
|
|
|
2011-01-06 17:46:59 +00:00
|
|
|
if ((i-freeCount+1 + BlocksNeeded) > sizeof(MemoryPage->Entry))
|
|
|
|
{
|
|
|
|
freeCount = 0;
|
2011-04-13 04:43:25 +00:00
|
|
|
break;
|
2011-01-06 17:46:59 +00:00
|
|
|
}
|
2011-04-13 04:43:25 +00:00
|
|
|
|
2010-12-30 15:12:46 +00:00
|
|
|
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);
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
*(ULONG*)PhysicalAddress = (ULONG)hcd->CommonBufferPA[PageCount].LowPart + (RetAddr - (ULONG)hcd->CommonBufferVA[PageCount]);
|
|
|
|
|
2010-12-30 15:12:46 +00:00
|
|
|
return RetAddr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PageCount++;
|
2011-04-13 04:43:25 +00:00
|
|
|
if (!(PMEM_HEADER)hcd->CommonBufferVA[PageCount])
|
|
|
|
{
|
|
|
|
|
|
|
|
hcd->CommonBufferVA[PageCount] =
|
|
|
|
hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter,
|
|
|
|
PAGE_SIZE,
|
|
|
|
&hcd->CommonBufferPA[PageCount],
|
|
|
|
FALSE);
|
|
|
|
DPRINT1("Allocated CommonBuffer VA %x, PA %x\n", hcd->CommonBufferVA[PageCount], hcd->CommonBufferPA[PageCount]);
|
|
|
|
}
|
|
|
|
MemoryPage = (PMEM_HEADER)hcd->CommonBufferVA[PageCount];
|
|
|
|
|
2010-12-30 15:12:46 +00:00
|
|
|
} while (PageCount < NumberOfPages);
|
|
|
|
|
2011-04-13 04:43:25 +00:00
|
|
|
if (PageCount == NumberOfPages)
|
|
|
|
ASSERT(FALSE);
|
|
|
|
|
2010-12-30 15:12:46 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
2011-04-13 04:43:25 +00:00
|
|
|
ReleaseMemory(PEHCI_HOST_CONTROLLER hcd, ULONG Address)
|
2010-12-30 15:12:46 +00:00
|
|
|
{
|
|
|
|
PMEM_HEADER MemoryPage;
|
2011-01-06 17:46:59 +00:00
|
|
|
ULONG Index, i, BlockSize;
|
2010-12-30 15:12:46 +00:00
|
|
|
|
|
|
|
MemoryPage = (PMEM_HEADER)(Address & ~(PAGE_SIZE - 1));
|
|
|
|
|
|
|
|
Index = (Address - ((ULONG)MemoryPage + sizeof(MEM_HEADER))) / SMALL_ALLOCATION_SIZE;
|
2011-01-06 17:46:59 +00:00
|
|
|
BlockSize = MemoryPage->Entry[Index].Blocks;
|
2011-04-13 04:43:25 +00:00
|
|
|
|
2011-01-06 17:46:59 +00:00
|
|
|
for (i = 0; i < BlockSize; i++)
|
2010-12-30 15:12:46 +00:00
|
|
|
{
|
|
|
|
MemoryPage->Entry[Index + i].InUse = 0;
|
|
|
|
MemoryPage->Entry[Index + i].Blocks = 0;
|
|
|
|
}
|
2011-04-13 04:43:25 +00:00
|
|
|
|
|
|
|
if (MemoryPage != (PMEM_HEADER)hcd->CommonBufferVA[0])
|
|
|
|
{
|
|
|
|
for (i=0; i < sizeof(MemoryPage->Entry) / 2; i++)
|
|
|
|
{
|
|
|
|
if ((MemoryPage->Entry[i].InUse) || (MemoryPage->Entry[sizeof(MemoryPage->Entry) - i].InUse))
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DPRINT1("Freeing CommonBuffer VA %x, PA %x\n", MemoryPage, MmGetPhysicalAddress(MemoryPage));
|
|
|
|
hcd->pDmaAdapter->DmaOperations->FreeCommonBuffer(hcd->pDmaAdapter,
|
|
|
|
PAGE_SIZE,
|
|
|
|
MmGetPhysicalAddress(MemoryPage),
|
|
|
|
MemoryPage,
|
|
|
|
FALSE);
|
|
|
|
}
|
2010-12-30 15:12:46 +00:00
|
|
|
}
|