620 lines
17 KiB
C
620 lines
17 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
ixphwsup.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains the HalpXxx routines for the NT I/O system that
|
|||
|
are hardware dependent. Were these routines not hardware dependent,
|
|||
|
they would normally reside in the internal.c module.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Darryl E. Havens (darrylh) 11-Apr-1990
|
|||
|
|
|||
|
Environment:
|
|||
|
|
|||
|
Kernel mode, local to I/O system
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "halp.h"
|
|||
|
#include "mca.h"
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE,HalpAllocateAdapter)
|
|||
|
#pragma alloc_text(PAGELK,HalpGrowMapBuffers)
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Some devices require a physically contiguous data buffer for DMA transfers.
|
|||
|
// Map registers are used to give the appearance that all data buffers are
|
|||
|
// contiguous. In order to pool all of the map registers a master
|
|||
|
// adapter object is used. This object is allocated and saved internal to this
|
|||
|
// file. It contains a bit map for allocation of the registers and a queue
|
|||
|
// for requests which are waiting for more map registers. This object is
|
|||
|
// allocated during the first request to allocate an adapter which requires
|
|||
|
// map registers.
|
|||
|
//
|
|||
|
|
|||
|
PADAPTER_OBJECT MasterAdapterObject;
|
|||
|
|
|||
|
#define ADAPTER_BASE_MASTER ((PVOID)-1)
|
|||
|
|
|||
|
//
|
|||
|
// Map buffer prameters. These are initialized in HalInitSystem.
|
|||
|
//
|
|||
|
|
|||
|
PHYSICAL_ADDRESS HalpMapBufferPhysicalAddress;
|
|||
|
ULONG HalpMapBufferSize;
|
|||
|
|
|||
|
//
|
|||
|
// Define DMA operations structure.
|
|||
|
//
|
|||
|
|
|||
|
DMA_OPERATIONS HalpDmaOperations = {
|
|||
|
sizeof(DMA_OPERATIONS),
|
|||
|
(PPUT_DMA_ADAPTER) HalPutDmaAdapter,
|
|||
|
(PALLOCATE_COMMON_BUFFER) HalAllocateCommonBuffer,
|
|||
|
(PFREE_COMMON_BUFFER) HalFreeCommonBuffer,
|
|||
|
(PALLOCATE_ADAPTER_CHANNEL) HalRealAllocateAdapterChannel,
|
|||
|
(PFLUSH_ADAPTER_BUFFERS) IoFlushAdapterBuffers,
|
|||
|
(PFREE_ADAPTER_CHANNEL) IoFreeAdapterChannel,
|
|||
|
(PFREE_MAP_REGISTERS) IoFreeMapRegisters,
|
|||
|
(PMAP_TRANSFER) IoMapTransfer,
|
|||
|
(PGET_DMA_ALIGNMENT) HalGetDmaAlignment,
|
|||
|
(PREAD_DMA_COUNTER) HalReadDmaCounter,
|
|||
|
(PGET_SCATTER_GATHER_LIST) HalGetScatterGatherList,
|
|||
|
(PPUT_SCATTER_GATHER_LIST) HalPutScatterGatherList,
|
|||
|
(PCALCULATE_SCATTER_GATHER_LIST_SIZE)HalCalculateScatterGatherListSize,
|
|||
|
(PBUILD_SCATTER_GATHER_LIST) HalBuildScatterGatherList,
|
|||
|
(PBUILD_MDL_FROM_SCATTER_GATHER_LIST) HalBuildMdlFromScatterGatherList
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
HalpGrowMapBuffers(
|
|||
|
PADAPTER_OBJECT AdapterObject,
|
|||
|
ULONG Amount
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function attempts to allocate additional map buffers for use by I/O
|
|||
|
devices. The map register table is updated to indicate the additional
|
|||
|
buffers.
|
|||
|
|
|||
|
Caller owns the HalpNewAdapter event
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
AdapterObject - Supplies the adapter object for which the buffers are to be
|
|||
|
allocated.
|
|||
|
|
|||
|
Amount - Indicates the size of the map buffers which should be allocated.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
TRUE is returned if the memory could be allocated.
|
|||
|
|
|||
|
FALSE is returned if the memory could not be allocated.
|
|||
|
|
|||
|
--*/
|
|||
|
{
|
|||
|
ULONG MapBufferPhysicalAddress;
|
|||
|
PVOID MapBufferVirtualAddress;
|
|||
|
PTRANSLATION_ENTRY TranslationEntry;
|
|||
|
LONG NumberOfPages;
|
|||
|
LONG i;
|
|||
|
PHYSICAL_ADDRESS physicalAddressMinimum;
|
|||
|
PHYSICAL_ADDRESS physicalAddressMaximum;
|
|||
|
PHYSICAL_ADDRESS boundaryAddress;
|
|||
|
KIRQL Irql;
|
|||
|
PVOID CodeLockHandle;
|
|||
|
ULONG maximumBufferPages;
|
|||
|
ULONG bytesToAllocate;
|
|||
|
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
boundaryAddress.QuadPart = 0;
|
|||
|
|
|||
|
NumberOfPages = BYTES_TO_PAGES(Amount);
|
|||
|
|
|||
|
//
|
|||
|
// Make sure there is room for the additional pages. The maximum number of
|
|||
|
// slots needed is equal to NumberOfPages + Amount / 64K + 1.
|
|||
|
//
|
|||
|
|
|||
|
maximumBufferPages = BYTES_TO_PAGES(MAXIMUM_PCI_MAP_BUFFER_SIZE);
|
|||
|
|
|||
|
i = maximumBufferPages - (NumberOfPages +
|
|||
|
(NumberOfPages * PAGE_SIZE) / 0x10000 + 1 +
|
|||
|
AdapterObject->NumberOfMapRegisters);
|
|||
|
|
|||
|
if (i < 0) {
|
|||
|
|
|||
|
//
|
|||
|
// Reduce the allocation amount so it will fit.
|
|||
|
//
|
|||
|
|
|||
|
NumberOfPages += i;
|
|||
|
}
|
|||
|
|
|||
|
if (NumberOfPages <= 0) {
|
|||
|
|
|||
|
//
|
|||
|
// No more memory can be allocated.
|
|||
|
//
|
|||
|
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: NumberOfPages = %d\n",
|
|||
|
NumberOfPages));
|
|||
|
|
|||
|
if (AdapterObject->NumberOfMapRegisters == 0 && HalpMapBufferSize) {
|
|||
|
|
|||
|
NumberOfPages = BYTES_TO_PAGES( HalpMapBufferSize );
|
|||
|
|
|||
|
//
|
|||
|
// Since this is the initial allocation, use the buffer allocated by
|
|||
|
// HalInitSystem rather than allocating a new one.
|
|||
|
//
|
|||
|
|
|||
|
MapBufferPhysicalAddress = HalpMapBufferPhysicalAddress.LowPart;
|
|||
|
|
|||
|
//
|
|||
|
// Map the buffer for access.
|
|||
|
//
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: MapBufferPhys = %p\n",
|
|||
|
HalpMapBufferPhysicalAddress));
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: MapBufferSize = 0x%x\n",
|
|||
|
HalpMapBufferSize));
|
|||
|
|
|||
|
|
|||
|
MapBufferVirtualAddress = MmMapIoSpace(
|
|||
|
HalpMapBufferPhysicalAddress,
|
|||
|
HalpMapBufferSize,
|
|||
|
TRUE // Cache enable.
|
|||
|
);
|
|||
|
|
|||
|
if (MapBufferVirtualAddress == NULL) {
|
|||
|
|
|||
|
//
|
|||
|
// The buffer could not be mapped.
|
|||
|
//
|
|||
|
|
|||
|
HalpMapBufferSize = 0;
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// Allocate the map buffers. Restrict to 32-bit range
|
|||
|
// (TRANSLATION_ENTRY is 32-bit)
|
|||
|
//
|
|||
|
|
|||
|
physicalAddressMinimum.QuadPart = 0;
|
|||
|
|
|||
|
physicalAddressMaximum.LowPart = 0xFFFFFFFF;
|
|||
|
physicalAddressMaximum.HighPart = 0;
|
|||
|
|
|||
|
bytesToAllocate = NumberOfPages * PAGE_SIZE;
|
|||
|
|
|||
|
MapBufferVirtualAddress =
|
|||
|
MmAllocateContiguousMemorySpecifyCache( bytesToAllocate,
|
|||
|
physicalAddressMinimum,
|
|||
|
physicalAddressMaximum,
|
|||
|
boundaryAddress,
|
|||
|
MmCached );
|
|||
|
|
|||
|
if (MapBufferVirtualAddress == NULL) {
|
|||
|
//
|
|||
|
// The allocation attempt failed.
|
|||
|
//
|
|||
|
|
|||
|
return FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Get the physical address of the map base.
|
|||
|
//
|
|||
|
|
|||
|
MapBufferPhysicalAddress =
|
|||
|
MmGetPhysicalAddress(MapBufferVirtualAddress).LowPart;
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: MapBufferVa = %p\n",
|
|||
|
MapBufferVirtualAddress));
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: MapBufferPhysAddr = %p\n",
|
|||
|
MapBufferPhysicalAddress));
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the map registers where memory has been allocated.
|
|||
|
// Serialize with master adapter object.
|
|||
|
//
|
|||
|
|
|||
|
CodeLockHandle = MmLockPagableCodeSection (&HalpGrowMapBuffers);
|
|||
|
KeAcquireSpinLock( &AdapterObject->SpinLock, &Irql );
|
|||
|
|
|||
|
TranslationEntry = ((PTRANSLATION_ENTRY) AdapterObject->MapRegisterBase) +
|
|||
|
AdapterObject->NumberOfMapRegisters;
|
|||
|
|
|||
|
for (i = 0; (LONG) i < NumberOfPages; i++) {
|
|||
|
|
|||
|
//
|
|||
|
// Make sure the perivous entry is physically contiguous with the next
|
|||
|
// entry
|
|||
|
//
|
|||
|
|
|||
|
if (TranslationEntry != AdapterObject->MapRegisterBase &&
|
|||
|
(((TranslationEntry - 1)->PhysicalAddress + PAGE_SIZE) !=
|
|||
|
MapBufferPhysicalAddress)) {
|
|||
|
|
|||
|
//
|
|||
|
// An entry needs to be skipped in the table. This entry will
|
|||
|
// remain marked as allocated so that no allocation of map
|
|||
|
// registers will cross this bountry.
|
|||
|
//
|
|||
|
|
|||
|
TranslationEntry++;
|
|||
|
AdapterObject->NumberOfMapRegisters++;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Clear the bits where the memory has been allocated.
|
|||
|
//
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HGMB: ClearBits (%p, 0x%x, 0x%x\n",
|
|||
|
AdapterObject->MapRegisters,
|
|||
|
(ULONG)(TranslationEntry - (PTRANSLATION_ENTRY)AdapterObject->MapRegisterBase),
|
|||
|
1));
|
|||
|
|
|||
|
RtlClearBits(
|
|||
|
AdapterObject->MapRegisters,
|
|||
|
(ULONG)(TranslationEntry - (PTRANSLATION_ENTRY)
|
|||
|
AdapterObject->MapRegisterBase),
|
|||
|
1
|
|||
|
);
|
|||
|
|
|||
|
TranslationEntry->VirtualAddress = MapBufferVirtualAddress;
|
|||
|
TranslationEntry->PhysicalAddress = MapBufferPhysicalAddress;
|
|||
|
TranslationEntry++;
|
|||
|
(PCCHAR) MapBufferVirtualAddress += PAGE_SIZE;
|
|||
|
MapBufferPhysicalAddress += PAGE_SIZE;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Remember the number of pages that were allocated.
|
|||
|
//
|
|||
|
|
|||
|
AdapterObject->NumberOfMapRegisters += NumberOfPages;
|
|||
|
|
|||
|
//
|
|||
|
// Release master adapter object.
|
|||
|
//
|
|||
|
|
|||
|
KeReleaseSpinLock( &AdapterObject->SpinLock, Irql );
|
|||
|
MmUnlockPagableImageSection (CodeLockHandle);
|
|||
|
return(TRUE);
|
|||
|
}
|
|||
|
|
|||
|
PADAPTER_OBJECT
|
|||
|
HalpAllocateAdapter(
|
|||
|
IN ULONG MapRegistersPerChannel,
|
|||
|
IN PVOID AdapterBaseVa,
|
|||
|
IN PVOID ChannelNumber
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine allocates and initializes an adapter object to represent an
|
|||
|
adapter or a DMA controller on the system. If no map registers are required
|
|||
|
then a standalone adapter object is allocated with no master adapter.
|
|||
|
|
|||
|
If map registers are required, then a master adapter object is used to
|
|||
|
allocate the map registers. For Isa systems these registers are really
|
|||
|
phyically contiguous memory pages.
|
|||
|
|
|||
|
Caller owns the HalpNewAdapter event
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
MapRegistersPerChannel - Specifies the number of map registers that each
|
|||
|
channel provides for I/O memory mapping.
|
|||
|
|
|||
|
AdapterBaseVa - Address of the the DMA controller.
|
|||
|
|
|||
|
ChannelNumber - Unused.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
The function value is a pointer to the allocate adapter object.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
PADAPTER_OBJECT AdapterObject;
|
|||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|||
|
ULONG Size;
|
|||
|
ULONG BitmapSize;
|
|||
|
HANDLE Handle;
|
|||
|
NTSTATUS Status;
|
|||
|
|
|||
|
UNREFERENCED_PARAMETER(ChannelNumber);
|
|||
|
|
|||
|
PAGED_CODE();
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HAA: MapRegistersPerChannel = %d\n",
|
|||
|
MapRegistersPerChannel));
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HAA: BaseVa = %p\n",
|
|||
|
AdapterBaseVa));
|
|||
|
|
|||
|
//
|
|||
|
// Initalize the master adapter if necessary.
|
|||
|
//
|
|||
|
|
|||
|
if (MasterAdapterObject == NULL && AdapterBaseVa != (PVOID) -1 &&
|
|||
|
MapRegistersPerChannel) {
|
|||
|
|
|||
|
MasterAdapterObject = HalpAllocateAdapter(
|
|||
|
MapRegistersPerChannel,
|
|||
|
(PVOID) -1,
|
|||
|
NULL
|
|||
|
);
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HAA: MasterAdapterObject = %p\n",
|
|||
|
MasterAdapterObject));
|
|||
|
|
|||
|
//
|
|||
|
// If we could not allocate the master adapter then give up.
|
|||
|
//
|
|||
|
|
|||
|
if (MasterAdapterObject == NULL) {
|
|||
|
return(NULL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Begin by initializing the object attributes structure to be used when
|
|||
|
// creating the adapter object.
|
|||
|
//
|
|||
|
|
|||
|
InitializeObjectAttributes( &ObjectAttributes,
|
|||
|
NULL,
|
|||
|
OBJ_PERMANENT,
|
|||
|
(HANDLE) NULL,
|
|||
|
(PSECURITY_DESCRIPTOR) NULL
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Determine the size of the adapter object. If this is the master object
|
|||
|
// then allocate space for the register bit map; otherwise, just allocate
|
|||
|
// an adapter object.
|
|||
|
//
|
|||
|
|
|||
|
if (AdapterBaseVa == (PVOID) -1) {
|
|||
|
|
|||
|
//
|
|||
|
// Allocate a bit map large enough MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE
|
|||
|
// of map register buffers.
|
|||
|
//
|
|||
|
|
|||
|
BitmapSize = (((sizeof( RTL_BITMAP ) +
|
|||
|
((( MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE ) + 7) >> 3)) + 3) & ~3);
|
|||
|
|
|||
|
Size = sizeof( ADAPTER_OBJECT ) + BitmapSize;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
Size = sizeof( ADAPTER_OBJECT );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Now create the adapter object.
|
|||
|
//
|
|||
|
|
|||
|
Status = ObCreateObject( KernelMode,
|
|||
|
*IoAdapterObjectType,
|
|||
|
&ObjectAttributes,
|
|||
|
KernelMode,
|
|||
|
(PVOID) NULL,
|
|||
|
Size,
|
|||
|
0,
|
|||
|
0,
|
|||
|
(PVOID *)&AdapterObject );
|
|||
|
|
|||
|
//
|
|||
|
// Reference the object.
|
|||
|
//
|
|||
|
|
|||
|
if (NT_SUCCESS(Status)) {
|
|||
|
|
|||
|
Status = ObReferenceObjectByPointer(
|
|||
|
AdapterObject,
|
|||
|
FILE_READ_DATA | FILE_WRITE_DATA,
|
|||
|
*IoAdapterObjectType,
|
|||
|
KernelMode
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the adapter object was successfully created, then attempt to insert
|
|||
|
// it into the the object table.
|
|||
|
//
|
|||
|
|
|||
|
if (NT_SUCCESS( Status )) {
|
|||
|
|
|||
|
RtlZeroMemory (AdapterObject, sizeof (ADAPTER_OBJECT));
|
|||
|
|
|||
|
Status = ObInsertObject( AdapterObject,
|
|||
|
NULL,
|
|||
|
FILE_READ_DATA | FILE_WRITE_DATA,
|
|||
|
0,
|
|||
|
(PVOID *) NULL,
|
|||
|
&Handle );
|
|||
|
|
|||
|
if (NT_SUCCESS( Status )) {
|
|||
|
|
|||
|
ZwClose( Handle );
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the adapter object itself.
|
|||
|
//
|
|||
|
|
|||
|
AdapterObject->DmaHeader.Version = IO_TYPE_ADAPTER;
|
|||
|
AdapterObject->DmaHeader.Size = (USHORT) Size;
|
|||
|
AdapterObject->MapRegistersPerChannel = 1;
|
|||
|
AdapterObject->AdapterBaseVa = AdapterBaseVa;
|
|||
|
AdapterObject->ChannelNumber = 0xff;
|
|||
|
AdapterObject->DmaHeader.DmaOperations = &HalpDmaOperations;
|
|||
|
|
|||
|
|
|||
|
if (MapRegistersPerChannel) {
|
|||
|
|
|||
|
AdapterObject->MasterAdapter = MasterAdapterObject;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
AdapterObject->MasterAdapter = NULL;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the channel wait queue for this
|
|||
|
// adapter.
|
|||
|
//
|
|||
|
|
|||
|
KeInitializeDeviceQueue( &AdapterObject->ChannelWaitQueue );
|
|||
|
|
|||
|
//
|
|||
|
// If this is the MasterAdatper then initialize register bit map,
|
|||
|
// AdapterQueue and the spin lock.
|
|||
|
//
|
|||
|
|
|||
|
if ( AdapterBaseVa == (PVOID) -1 ) {
|
|||
|
|
|||
|
KeInitializeSpinLock( &AdapterObject->SpinLock );
|
|||
|
|
|||
|
InitializeListHead( &AdapterObject->AdapterQueue );
|
|||
|
|
|||
|
AdapterObject->MapRegisters = (PVOID) ( AdapterObject + 1);
|
|||
|
|
|||
|
HalDebugPrint((HAL_VERBOSE, "HAA: InitBitMap(%p, %p, 0x%x\n",
|
|||
|
AdapterObject->MapRegisters,
|
|||
|
(PULONG)(((PCHAR)(AdapterObject->MapRegisters)) +
|
|||
|
sizeof( RTL_BITMAP )),
|
|||
|
( MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE )));
|
|||
|
|
|||
|
RtlInitializeBitMap (
|
|||
|
AdapterObject->MapRegisters,
|
|||
|
(PULONG)(((PCHAR)(AdapterObject->MapRegisters)) +
|
|||
|
sizeof( RTL_BITMAP )),
|
|||
|
( MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE )
|
|||
|
);
|
|||
|
//
|
|||
|
// Set all the bits in the memory to indicate that memory
|
|||
|
// has not been allocated for the map buffers
|
|||
|
//
|
|||
|
|
|||
|
RtlSetAllBits( AdapterObject->MapRegisters );
|
|||
|
AdapterObject->NumberOfMapRegisters = 0;
|
|||
|
AdapterObject->CommittedMapRegisters = 0;
|
|||
|
|
|||
|
//
|
|||
|
// ALlocate the memory map registers.
|
|||
|
//
|
|||
|
|
|||
|
AdapterObject->MapRegisterBase = ExAllocatePoolWithTag(
|
|||
|
NonPagedPool,
|
|||
|
(MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE) *
|
|||
|
sizeof(TRANSLATION_ENTRY),
|
|||
|
HAL_POOL_TAG
|
|||
|
);
|
|||
|
|
|||
|
if (AdapterObject->MapRegisterBase == NULL) {
|
|||
|
|
|||
|
ObDereferenceObject( AdapterObject );
|
|||
|
AdapterObject = NULL;
|
|||
|
return(NULL);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Zero the map registers.
|
|||
|
//
|
|||
|
|
|||
|
RtlZeroMemory(
|
|||
|
AdapterObject->MapRegisterBase,
|
|||
|
(MAXIMUM_PCI_MAP_BUFFER_SIZE / PAGE_SIZE) *
|
|||
|
sizeof(TRANSLATION_ENTRY)
|
|||
|
);
|
|||
|
|
|||
|
if (!HalpGrowMapBuffers(
|
|||
|
AdapterObject,
|
|||
|
INITIAL_MAP_BUFFER_LARGE_SIZE
|
|||
|
)
|
|||
|
)
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// If no map registers could be allocated then free the
|
|||
|
// object.
|
|||
|
//
|
|||
|
|
|||
|
ObDereferenceObject( AdapterObject );
|
|||
|
AdapterObject = NULL;
|
|||
|
return(NULL);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
//
|
|||
|
// An error was incurred for some reason. Set the return value
|
|||
|
// to NULL.
|
|||
|
//
|
|||
|
|
|||
|
AdapterObject = (PADAPTER_OBJECT) NULL;
|
|||
|
}
|
|||
|
} else {
|
|||
|
|
|||
|
AdapterObject = (PADAPTER_OBJECT) NULL;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return AdapterObject;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ULONG
|
|||
|
HalGetDmaAlignment (
|
|||
|
PVOID Conext
|
|||
|
)
|
|||
|
{
|
|||
|
return HalGetDmaAlignmentRequirement();
|
|||
|
}
|