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.
Syntax
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
);
Parameters
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; } NDIS_PHYSICAL_ADDRESS_UNIT, *PNDIS_PHYSICAL_ADDRESS_UNIT;
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
None
Remarks
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:
Maps the virtual range containing the data with NdisMStartBufferPhysicalMapping to get mapped device-accessible range addresses for use by its NIC
Downloads the returned physical addresses to the NIC
Calls NdisFlushBuffer and (prior to Windows Vista) NdisMUpdateSharedMemory if the driver allocated cached memory
Programs the NIC for the transfer operation
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.
Requirements
Target platform |
Universal |
Version |
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. |
Header |
Ndis.h (include Ndis.h) |
Library |
Ndis.lib |
IRQL |
<= DISPATCH_LEVEL |
See also
NdisGetBufferPhysicalArraySize
NdisMAllocateSharedMemoryAsync
NdisMCompleteBufferPhysicalMapping