|
|
/*++
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; }
|