NdisMStartBufferPhysicalMapping function

Note   NDIS 5. x has been deprecated and is superseded by NDIS 6. x. For new NDIS driver development, see Network Drivers Starting with Windows Vista. For information about porting NDIS 5. x drivers to NDIS 6. x, see Porting NDIS 5.x Drivers to NDIS 6.0.

NdisMStartBufferPhysicalMapping sets up a mapping for a bus-master DMA transfer operation.


VOID NdisMStartBufferPhysicalMapping(
  _In_  NDIS_HANDLE                 MiniportAdapterHandle,
  _In_  PNDIS_BUFFER                Buffer,
  _In_  ULONG                       PhysicalMapRegister,
  _In_  BOOLEAN                     WriteToDevice,
  _Out_ PNDIS_PHYSICAL_ADDRESS_UNIT PhysicalAddressArray,
  _Out_ PUINT                       ArraySize


  • MiniportAdapterHandle [in]
    Specifies the handle originally input to MiniportInitialize.

  • Buffer [in]
    Pointer to a buffer descriptor mapping the virtual range for the transfer. This buffer contains the data to be transferred.

  • PhysicalMapRegister [in]
    Specifies the zero-based index of the map register to be used for the transfer. This value must be no greater than one less than the number of map registers that the driver allocated during initialization with NdisMAllocateMapRegisters.

  • WriteToDevice [in]
    Specifies TRUE when the mapping is used for an outbound transfer from the system through the NIC.

  • PhysicalAddressArray [out]
    Pointer to a caller-supplied array of NDIS_PHYSICAL_UNIT structures, in which each element is defined as follows:

    typedef struct _NDIS_PHYSICAL_ADDRESS_UNIT {
        NDIS_PHYSICAL_ADDRESS PhysicalAddress;
        UINT Length;

    On return from a successful call to NdisMStartBufferPhysicalMapping, elements in this array specify the mapped logical ranges suitable for downloading to the NIC, with the following members in each element:

    • PhysicalAddress
      Specifies the base physical address for the start of a discrete contiguous range of data to be transferred.

    • Length
      Specifies the number of bytes in the mapped range.

  • ArraySize [out]
    Pointer to a caller-supplied variable in which NdisMStartBufferPhysicalMapping returns the number of ranges it mapped in the buffer at PhysicalAddressArray. This value is a count of the elements that contain mappings, so the caller can use this count as a bound on the number of physical address ranges it downloads to the NIC subsequently.

Return value



Bus-master NIC drivers call NdisMStartBufferPhysicalMapping in response to send requests originating in protocols bound to the NIC. That is, the buffer descriptor at Buffer usually was chained to a packet input to the NIC driver's MiniportSend or MiniportSendPackets function.

Every protocol driver is responsible for setting up send packets to suit the limits of the underlying NIC. The NIC driver's MiniportQueryInformation function already returned these limits in response to certain OID_GEN_XXX requests. Consequently, a miniport driver need not test incoming send packets for oversized frames or transmit blocks, nor for transmit buffer overflows. For more information about OIDs, see NDIS Object Identifiers.

A caller of NdisMStartBufferPhysicalMapping must ensure that the array at PhysicalAddressArray is large enough to map the given buffer. A miniport driver can call NdisGetBufferPhysicalArraySize to determine how many elements are required to map the virtual range specified in the descriptor at Buffer.

For small transfer requests, such as those up to 256 bytes in length, a miniport driver can achieve higher performance by copying the data to be transmitted into a staging buffer in the shared memory space already allocated with NdisMAllocateSharedMemory or NdisMAllocateSharedMemoryAsync. Because the NIC driver already has mapped virtual and physical addresses for such a shared memory range, it need not call NdisM..BufferPhysicalMapping functions for such small DMA transfers.

Data received by a bus-master NIC is transferred directly into device-accessible buffers within a shared memory block allocated by the miniport driver. Miniports perform explicit bus-master DMA operations only for transmits.

To transfer packet data for a send request, any miniport driver basically does the following:

  1. Maps the virtual range containing the data with NdisMStartBufferPhysicalMapping to get mapped device-accessible range addresses for use by its NIC

  2. Downloads the returned physical addresses to the NIC

  3. Calls NdisFlushBuffer and (prior to Windows Vista) NdisMUpdateSharedMemory if the driver allocated cached memory

  4. Programs the NIC for the transfer operation

  5. Calls NdisMCompleteBufferPhysicalMapping, usually from the MiniportHandleInterrupt function, when the NIC has completed the transfer, which the NIC indicates by a transmit interrupt or, possibly, by a state change discovered by the NIC driver's polling MiniportTimer function

Any mapping returned by NdisMStartBufferPhysicalMapping is valid only until the miniport driver calls NdisMCompleteBufferPhysicalMapping. When NdisMCompleteBufferPhysicalMapping returns control, the PhysicalMapRegister specified in the preceding call to NdisMStartBufferPhysicalMapping can be reused in a subsequent DMA operation.


Target platform



Not supported for NDIS 6.0 drivers in Windows Vista. Use NdisMAllocateNetBufferSGList instead. Supported for NDIS 5.1 drivers in Windows Vista and Windows XP.


Ndis.h (include Ndis.h)





See also
















Send comments about this topic to Microsoft