Previous Next

NdisMAllocateMapRegisters

NdisMAllocateMapRegisters reserves system resources during miniport driver initialization for subsequent bus-master DMA operations.

NDIS_STATUS 
  NdisMAllocateMapRegisters(
    IN NDIS_HANDLE  MiniportAdapterHandle,
    IN UINT  DmaChannel,
    IN NDIS_DMA_SIZE  DmaSize,
    IN ULONG  BaseMapRegistersNeeded,
    IN ULONG  MaximumBufferSize
    );

Parameters

MiniportAdapterHandle
Specifies the handle input to MiniportInitialize.
DmaChannel
Specifies the bus-relative DMA channel for an ISA bus-master NIC. If the NIC is on another type of I/O bus, this parameter must be zero.
DmaSize
Specifies the address size that the NIC uses for DMA operations as one of the following:
NDIS_DMA_24BITS
24-bit DMA address
NDIS_DMA_32BITS
32-bit DMA address
NDIS_DMA_64BITS
64-bit DMA address

When NDIS_DMA_64BITS is specified on a system that is running the Microsoft Windows® 2000 and later DataCenter Server operating system with Physical Address Extension (PAE) enabled, the physical addresses of mapped buffers can be greater than 32 bits.

BaseMapRegistersNeeded
Specifies the number of base map registers required by the driver. The driver should request one base map register for each DMA send buffer that it requires. For each requested base map register, NDIS allocates one or more map registers, each of which maps a page of physical memory. NDIS allocates a sufficient number of map registers per requested base register to create a send buffer large enough to contain the specified MaximumBufferSize. NDIS imposes a limit of 64 map registers per miniport driver. If the total number of map registers that NDIS would have to allocate would exceed 64, NdisMAllocateMapRegisters returns NDIS_STATUS_RESOURCES. For more information on specifying BaseMapRegistersNeeded, see the Comments below.
MaximumBufferSize
Specifies the size, in bytes, of the largest send buffer required by the driver for a DMA transfer.

Return Value

NdisMAllocateMapRegisters can return one of the following:

NDIS_STATUS_SUCCESS
NDIS allocated enough map registers per requested base map register to accommodate the specified MaximumBufferSize. If DmaChannel was nonzero, the specified channel has been reserved.
NDIS_STATUS_RESOURCES
One of the following occurred:

Headers

Declared in Ndis.h. Include Ndis.h.

Comments

A driver of a bus-master DMA NIC calls NdisMAllocateMapRegisters from its MiniportInitialize function. The driver’s MiniportInitialize function must call NdisMSetAttributes or NdisMSetAttributesEx before it calls NdisMAllocateMapRegisters.

If its NIC can use 32-bit or 64-bit addressing for DMA operations, a miniport driver should not set DmaSize to NDIS_DMA_24BITS. A PCI NIC, for example, should always set DmaSize to NDIS_DMA_32BITS or NDIS_DMA_64BITS. System memory below 16MB is a scarce resource. Setting DmaSize to NDIS_DMA_24BITS could therefore cause NdisMAllocateMapRegisters to return NDIS_STATUS_RESOURCES.

To determine how many BaseMapRegistersNeeded the miniport driver should request, consider the following:

If, for example, a miniport driver for an Ethernet NIC has a maximum send-packet size of 1512 bytes, it should specify a MaximumBufferSize of 1512. Given a page size of 4 Kbytes, a buffer of 1512 bytes can span two physical pages. NDIS therefore allocates two map registers per requested base register. To stay within the limit of 64 map registers, in this case, the miniport driver must request no more than 32 base map registers.

If the miniport driver’s MaximumBufferSize is large enough so that NDIS would have to allocate numerous map registers per requested base map register, the miniport driver should call NdisMInitializeScatterGatherDma instead of NdisMAllocateMapRegisters to allocate DMA resources. Otherwise, the miniport driver may not be able to allocate enough send buffers to perform well. For example, a miniport driver that specifies a MaximumBufferSize of 64 Kbytes can request no more than three base registers because NDIS, in this case, will allocate 17 map registers per base register. (With a page size of 4 Kbytes, a 64-Kbyte buffer can span 17 physical pages.) Requesting more than three base registers would cause NdisMAllocateMapRegisters to return NDIS_STATUS_RESOURCES because NDIS would enforce the limit of 64 map registers per miniport driver.

Note that, on systems enabled for Physical Address Extension (PAE), requesting too many base map registers can cause the system to stop responding because not enough map registers are available to satisfy the request. PAE-enabled systems that have more than one NIC are even more likely to stop responding in this situation.

The map registers allocated with NdisMAllocateMapRegisters are implicitly numbered from zero. When calling NdisMStartBufferPhysicalMapping, the driver of a bus-master NIC specifies which map register to use in each call by specifying that map register’s zero-based index.

The driver of a bus-master DMA NIC must call NdisMAllocateMapRegisters before it calls NdisMAllocateSharedMemory.

Drivers of NICs that use PIO or the host DMA controller as slave devices do not call NdisMAllocateMapRegisters during initialization.

Callers of NdisMAllocateMapRegisters run at IRQL = PASSIVE_LEVEL.

See Also

MiniportInitialize, NdisMAllocateSharedMemory, NdisMFreeMapRegisters, NdisMInitializeScatterGatherDmaNdisMRegisterDmaChannel, NdisMSetAttributes, NdisMSetAttributesEx, NdisMStartBufferPhysicalMapping