windows-nt/Source/XPSP1/NT/net/atm/arp/atmarps/util.c
2020-09-26 16:20:57 +08:00

252 lines
4.8 KiB
C

/*++
Copyright (c) 1992-1996 Microsoft Corporation
Module Name:
util.c
Abstract:
This file contains the code for misc. functions.
Author:
Jameel Hyder (jameelh@microsoft.com) July 1996
Environment:
Kernel mode
Revision History:
--*/
#include <precomp.h>
#define _FILENUM_ FILENUM_UTIL
#if DBG
PVOID
ArpSAllocMem(
IN UINT Size,
IN ULONG FileLine,
IN ULONG Tag,
IN BOOLEAN Paged
)
{
PVOID pMem;
pMem = ExAllocatePoolWithTag(Paged ? PagedPool : NonPagedPool, Size, Tag);
#if _DBG
DBGPRINT(DBG_LEVEL_INFO,
("ArpSAllocMem: %d bytes (%sPaged) from %lx -> %lx\n",
Size, Paged ? "" : "Non", FileLine, pMem));
#endif
return pMem;
}
VOID
ArpSFreeMem(
IN PVOID pMem,
IN ULONG FileLine
)
{
#if _DBG
DBGPRINT(DBG_LEVEL_INFO,
("ArpSFreeMem: %lx from %lx\n", FileLine, pMem));
#endif
ExFreePool(pMem);
}
#endif
PVOID
ArpSAllocBlock(
IN PINTF pIntF,
IN ENTRY_TYPE EntryType
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PARP_BLOCK ArpBlock;
PENTRY_HDR pBlock;
PHW_ADDR HwAddr;
USHORT Size;
BOOLEAN Paged;
#if 0
// arvindm - used by MARS
ARPS_PAGED_CODE( );
#endif
ASSERT (EntryType < ARP_BLOCK_TYPES);
pBlock = NULL;
//
// If the block head has no free entries then there are none !!
// Pick the right block based on whether it is file or dir
//
Size = ArpSEntrySize[EntryType];
Paged = ArpSBlockIsPaged[EntryType];
ArpBlock = pIntF->PartialArpBlocks[EntryType];
if (ArpBlock == NULL)
{
DBGPRINT(DBG_LEVEL_INFO,
("ArpSAllocBlock: ... and allocating a new block for EntryType %ld\n", EntryType));
ArpBlock = Paged ? (PARP_BLOCK)ALLOC_PG_MEM(BLOCK_ALLOC_SIZE) :
(PARP_BLOCK)ALLOC_NP_MEM(BLOCK_ALLOC_SIZE, POOL_TAG_BLK);
if (ArpBlock != NULL)
{
USHORT i;
USHORT Cnt;
DBGPRINT(DBG_LEVEL_WARN,
("ArpSAllocBlock: Allocated a new block for EntryType %d\n", EntryType));
//
// Link it in the list
//
ArpBlock->IntF = pIntF;
ArpBlock->EntryType = EntryType;
ArpBlock->NumFree = Cnt = ArpSNumEntriesInBlock[EntryType];
LinkDoubleAtHead(pIntF->PartialArpBlocks[EntryType], ArpBlock);
//
// Initialize the list of free entries
//
for (i = 0, pBlock = ArpBlock->FreeHead = (PENTRY_HDR)((PUCHAR)ArpBlock + sizeof(ARP_BLOCK));
i < Cnt;
i++, pBlock = pBlock->Next)
{
HwAddr = (PHW_ADDR)(pBlock + 1);
pBlock->Next = (i == (Cnt - 1)) ? NULL : ((PUCHAR)pBlock + Size);
HwAddr->SubAddress = NULL;
if ((EntryType == ARP_BLOCK_SUBADDR) || (EntryType == MARS_CLUSTER_SUBADDR))
HwAddr->SubAddress = (PATM_ADDRESS)((PUCHAR)pBlock+Size);
}
}
}
else
{
ASSERT(ArpBlock->NumFree <= ArpSNumEntriesInBlock[EntryType]);
ASSERT(ArpBlock->NumFree > 0);
DBGPRINT(DBG_LEVEL_INFO,
("ArpSAllocBlock: Found space in Block %lx\n", ArpBlock));
}
if (ArpBlock != NULL)
{
PARP_BLOCK pTmp;
pBlock = ArpBlock->FreeHead;
ArpBlock->FreeHead = pBlock->Next;
ArpBlock->NumFree --;
ZERO_MEM(pBlock, Size);
if ((EntryType == ARP_BLOCK_SUBADDR) || (EntryType == MARS_CLUSTER_SUBADDR))
{
HwAddr = (PHW_ADDR)(pBlock + 1);
HwAddr->SubAddress = (PATM_ADDRESS)((PUCHAR)pBlock + Size);
}
//
// If the block is now empty (completely used), unlink it from here and move it
// to the Used list.
//
if (ArpBlock->NumFree == 0)
{
UnlinkDouble(ArpBlock);
LinkDoubleAtHead(pIntF->UsedArpBlocks[EntryType], ArpBlock)
}
}
return pBlock;
}
VOID
ArpSFreeBlock(
IN PVOID pBlock
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PARP_BLOCK ArpBlock;
#if 0
// arvindm - MARS
ARPS_PAGED_CODE( );
#endif
//
// NOTE: The following code *depends* on the fact that we allocate ARP_BLOCKs as
// single page blocks and also that these are allocated *at* page boundaries
// This lets us *cheaply* get to the owning ARP_BLOCK from ARP_ENTRY.
//
ArpBlock = (PARP_BLOCK)((ULONG_PTR)pBlock & ~(PAGE_SIZE-1));
ASSERT (ArpBlock->EntryType < ARP_BLOCK_TYPES);
ASSERT(ArpBlock->NumFree < ArpSNumEntriesInBlock[ArpBlock->EntryType]);
DBGPRINT(DBG_LEVEL_INFO,
("ArpSFreepBlock: Returning pBlock %lx to Block %lx\n", pBlock, ArpBlock));
ArpBlock->NumFree ++;
((PENTRY_HDR)pBlock)->Next = ArpBlock->FreeHead;
ArpBlock->FreeHead = pBlock;
if (ArpBlock->NumFree == 1)
{
//
// The block is now partially free (was completely used). Move it to the partial list
//
UnlinkDouble(ArpBlock);
LinkDoubleAtHead(ArpBlock->IntF->PartialArpBlocks[ArpBlock->EntryType], ArpBlock)
}
else if (ArpBlock->NumFree == ArpSNumEntriesInBlock[ArpBlock->EntryType])
{
//
// The block is now completely free (was partially used). Free it.
//
UnlinkDouble(ArpBlock);
FREE_MEM(ArpBlock);
}
}
BOOLEAN
ArpSValidAtmAddress(
IN PATM_ADDRESS AtmAddr,
IN UINT MaxSize
)
{
//
// TODO -- validate
//
return TRUE;
}