PBUILD_SCATTER_GATHER_LIST_EX callback function (wdm.h)

The BuildScatterGatherListEx routine allocates the resources that are required for a DMA transfer, builds a scatter/gather list, and calls the driver-supplied AdapterListControl routine to initiate the DMA transfer.

Caution

Do not call this routine for a system DMA device.

Syntax

PBUILD_SCATTER_GATHER_LIST_EX PbuildScatterGatherListEx;

NTSTATUS PbuildScatterGatherListEx(
  [in]            PDMA_ADAPTER DmaAdapter,
  [in]            PDEVICE_OBJECT DeviceObject,
  [in]            PVOID DmaTransferContext,
  [in]            PMDL Mdl,
  [in]            ULONGLONG Offset,
  [in]            ULONG Length,
  [in]            ULONG Flags,
  [in, optional]  PDRIVER_LIST_CONTROL ExecutionRoutine,
  [in, optional]  PVOID Context,
  [in]            BOOLEAN WriteToDevice,
  [in]            PVOID ScatterGatherBuffer,
  [in]            ULONG ScatterGatherLength,
  [in, optional]  PDMA_COMPLETION_ROUTINE DmaCompletionRoutine,
  [in, optional]  PVOID CompletionContext,
  [out, optional] PVOID ScatterGatherList
)
{...}

Parameters

[in] DmaAdapter

A pointer to a DMA_ADAPTER structure. This structure is the adapter object that represents the driver's bus-master DMA device or system DMA channel. The caller obtained this pointer from a previous call to the IoGetDmaAdapter routine.

[in] DeviceObject

A pointer to a DEVICE_OBJECT structure. This structure is the physical device object (PDO) that represents the target device for the requested DMA operation.

[in] DmaTransferContext

A pointer to an initialized DMA transfer context. This context was initialized by a previous call to the InitializeDmaTransferContext routine. This context must be unique across all adapter allocation requests. To cancel a pending allocation request, the caller must supply the DMA transfer context for the request to the CancelAdapterChannel routine.

[in] Mdl

A pointer to an MDL chain that describes the physical page layout for a collection of locked-down buffers in virtual memory. The scatter/gather list for the DMA transfer will use the region of this memory that is specified by the Offset and Length parameters. For more information about MDL chains, see Using MDLs.

[in] Offset

The starting offset for the scatter/gather DMA transfer. This parameter is a byte offset from the start of the buffer in the first MDL in the MDL chain. If the MDLs in the MDL chain specify a total of N bytes of buffer space, valid values of Offset are in the range 0 to N–1.

[in] Length

The size, in bytes, of the DMA transfer. If the MDL chain specifies a total of N bytes of buffer space, valid values of Length are in the range 1 to N–Offset.

[in] Flags

The adapter channel allocation flags. The following flag is supported:

Flag Meaning
DMA_SYNCHRONOUS_CALLBACK The BuildScatterGatherListEx routine is called synchronously. If this flag is set, and the required DMA resources are not immediately available, the call fails and returns STATUS_INSUFFICIENT_RESOURCES.

If the DMA_SYNCHRONOUS_CALLBACK flag is set, the ExecutionRoutine parameter is optional and can be NULL. If this flag is not set, ExecutionRoutine must be a valid, non-NULL pointer. For more information about this flag, see the Remarks section.

[in, optional] ExecutionRoutine

A pointer to the driver-supplied AdapterListControl routine that initiates the DMA transfer for the driver. The I/O manager calls the AdapterListControl routine after the required resources are allocated for the adapter object. After the AdapterListControl routine returns, the I/O manager automatically frees the adapter object and the resources that were allocated for this object.

If the DMA_SYNCHRONOUS_CALLBACK flag is set, ExecutionRoutine is optional and can be NULL. If ExecutionRoutine is NULL, the caller can use the resources allocated by BuildScatterGatherListEx. For more information, see the Remarks section.

[in, optional] Context

The driver-determined, adapter-control context. This context is passed to the AdapterListControl routine as the Context parameter.

[in] WriteToDevice

The direction of the DMA transfer. Set this parameter to TRUE for a write operation, which transfers data from memory to the device. Set this parameter to FALSE for a read operation, which transfers data from the device to memory.

[in] ScatterGatherBuffer

A pointer to a caller-allocated buffer into which the routine writes the scatter/gather list for the DMA transfer. This list begins with a SCATTER_GATHER_LIST structure, which is followed by a SCATTER_GATHER_ELEMENT array.

[in] ScatterGatherLength

The size, in bytes, of the buffer passed in the ScatterGatherBuffer parameter. The allocated buffer size must be large enough to contain the scatter/gather list, plus internal data that the operating system stores in this buffer. To calculate the required buffer size, call the GetDmaTransferInfo or CalculateScatterGatherList routine.

[in, optional] DmaCompletionRoutine

Not used. Set to NULL.

[in, optional] CompletionContext

Not used. Set to NULL.

[out, optional] ScatterGatherList

A pointer to a variable into which the routine writes a pointer to the scatter/gather list for the DMA transfer. This list begins with a SCATTER_GATHER_LIST structure, which contains a pointer to a SCATTER_GATHER_ELEMENT array. This output pointer always matches the ScatterGatherBuffer parameter value.

If the DMA_SYNCHRONOUS_CALLBACK flag is set and the ExecutionRoutine parameter is NULL, ScatterGatherList must be a valid, non-NULL pointer. If ExecutionRoutine is non-NULL, ScatterGatherList is optional and can be NULL if the calling driver does not require the scatter/gather list. The BuildScatterGatherListEx call fails if the DMA_SYNCHRONOUS_CALLBACK flag is set and ScatterGatherList and ExecutionRoutine are both NULL, or if the DMA_SYNCHRONOUS_CALLBACK flag is not set and ExecutionRoutine is NULL.

Return value

BuildScatterGatherListEx returns STATUS_SUCCESS if the call is successful. Possible error return values include the following status codes.

Return code Description
STATUS_INVALID_PARAMETERS The routine failed due to invalid parameter values passed by the caller.
STATUS_BUFFER_TOO_SMALL The caller-supplied buffer in ScatterGatherBuffer is too small to contain the scatter/gather list.
STATUS_INSUFFICIENT_RESOURCES The routine failed to allocate resources required for the DMA transfer.

Remarks

BuildScatterGatherListEx* is not a system routine that can be called directly by name. This routine can be called only by pointer from the address returned in a*DMA_OPERATIONS structure. Drivers obtain the address of this routine by calling IoGetDmaAdapter with the Version member of the DeviceDescription parameter set to DEVICE_DESCRIPTION_VERSION3. If IoGetDmaAdapter returns NULL, the routine is not available on your platform.

Use BuildScatterGatherListEx only for bus-master adapters. Do not use this routine for a system DMA adapter.

BuildScatterGatherListEx is similar to the GetScatterGatherListEx routine, except that it requires the caller to allocate the buffer for the scatter/gather list.

For example, a driver might preallocate one or more scatter/gather buffers during device initialization. Later, a BuildScatterGatherListEx call that uses such a buffer can succeed in conditions of low memory availability that might cause a GetScatterGatherListEx call to fail.

By default, BuildScatterGatherListEx returns asynchronously, without waiting for the requested resource allocation to complete. After this return, the caller can, if necessary, cancel the pending allocation request by calling the CancelAdapterChannel routine.

If the calling driver sets the DMA_SYNCHRONOUS_CALLBACK flag, the BuildScatterGatherListEx routine behaves as follows:

  • If the requested resources are not immediately available, BuildScatterGatherListEx does not wait for resources, does not build a scatter/gather list, and does not call the AdapterListControl routine. Instead, BuildScatterGatherListEx fails and returns STATUS_INSUFFICIENT_RESOURCES.

  • The driver is not required to supply an AdapterListControl routine if the DMA_SYNCHRONOUS_CALLBACK flag is set.

  • If the driver supplies an AdapterListControl routine, the DMA_SYNCHRONOUS_CALLBACK flag indicates that this routine is to be called in the context of the calling thread, before BuildScatterGatherListEx returns.

  • If the driver does not supply an AdapterListControl routine, the driver can use the allocated resources and scatter/gather list after BuildScatterGatherListEx returns. In this case, the driver must supply a valid, non-NULL ScatterGatherList pointer. In addition, after the driver-initiated DMA transfer completes, the driver must call the FreeAdapterObject routine to free the resources that BuildScatterGatherListEx allocated for the adapter object.

BuildScatterGatherListEx is an extended version of the BuildScatterGatherList routine. The following list summarizes the features that are available only in the extended version:

Feature Description
Starting offset The calling driver can specify a starting offset for a scatter/gather DMA transfer instead of starting the transfer at the first buffer address at the start of the MDL chain.
Allocation request cancellation The driver can call CancelAdapterChannel to cancel a pending allocation request when the DMA adapter is queued to wait for DMA resources.
Synchronous callback The driver can set the DMA_SYNCHRONOUS_CALLBACK flag to request that the driver-supplied AdapterListControl routine be called in the calling thread, before BuildScatterGatherListEx returns.

Requirements

Requirement Value
Minimum supported client Available starting with Windows 8.
Target Platform Desktop
Header wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
IRQL DISPATCH_LEVEL

See also

AdapterListControl

AllocateAdapterChannelEx

CalculateScatterGatherList

DMA_OPERATIONS

DmaCompletionRoutine

FreeAdapterObject

GetScatterGatherList

GetScatterGatherListEx

MapTransferEx