PBUILD_SCATTER_GATHER_LIST_EX回调函数 (wdm.h)

BuildScatterGatherListEx 例程分配 DMA 传输所需的资源、生成散点/收集列表,并调用驱动程序提供的 AdapterListControl 例程来启动 DMA 传输。

谨慎

不要为系统 DMA 设备调用此例程。

语法

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
)
{...}

参数

[in] DmaAdapter

指向 DMA_ADAPTER 结构的指针。 此结构是表示驱动程序总线主 DMA 设备或系统 DMA 通道的适配器对象。 调用方从对 IoGetDmaAdapter 例程的上一次调用中获取此指针。

[in] DeviceObject

指向 DEVICE_OBJECT 结构的指针。 此结构是表示所请求 DMA 操作的目标设备的物理设备对象 (PDO)。

[in] DmaTransferContext

指向初始化的 DMA 传输上下文的指针。 此上下文是由对 InitializeDmaTransferContext 例程的上一次调用初始化的。 此上下文在所有适配器分配请求中必须是唯一的。 若要取消挂起的分配请求,调用方必须向 CancelAdapterChannel 例程提供请求的 DMA 传输上下文。

[in] Mdl

指向 MDL 链的指针,该链描述虚拟内存中锁定缓冲区集合的物理页面布局。 DMA 传输的散点/收集列表将使用由 偏移量长度 参数指定的此内存区域。 有关 MDL 链的详细信息,请参阅 使用 MDL

[in] Offset

散点/收集 DMA 传输的起始偏移量。 此参数是 MDL 链中第一个 MDL 中缓冲区开头的字节偏移量。 如果 MDL 链中的 MDL 指定缓冲区空间的总 N 字节数,则 Offset 的有效值在 0 到 N–1 的范围内。

[in] Length

DMA 传输的大小(以字节为单位)。 如果 MDL 链指定缓冲区空间的 N 个字节总数,则 Length 的有效值在 1 到 N 到 N-偏移量范围内。

[in] Flags

适配器通道分配标志。 支持以下标志:

意义
DMA_SYNCHRONOUS_CALLBACK BuildScatterGatherListEx 例程是同步调用的。 如果设置了此标志,并且所需的 DMA 资源无法立即可用,则调用将失败并返回STATUS_INSUFFICIENT_RESOURCES。

如果设置了 DMA_SYNCHRONOUS_CALLBACK 标志,ExecutionRoutine 参数是可选的,并且可以 NULL。 如果未设置此标志,ExecutionRoutine 必须是有效的非NULL 指针。 有关此标志的详细信息,请参阅“备注”部分。

[in, optional] ExecutionRoutine

指向驱动程序提供的 AdapterListControl 例程的指针,该例程为驱动程序启动 DMA 传输。 I/O 管理器在为适配器对象分配所需的资源后调用 AdapterListControl 例程。 AdapterListControl 例程返回后,I/O 管理器会自动释放适配器对象以及为此对象分配的资源。

如果设置了 DMA_SYNCHRONOUS_CALLBACK 标志,ExecutionRoutine 是可选的,并且可以 NULL。 如果 ExecutionRoutineNULL,则调用方可以使用 BuildScatterGatherListEx分配的资源。 有关详细信息,请参阅“备注”部分。

[in, optional] Context

驱动程序确定的适配器控制上下文。 此上下文作为 Context 参数传递给 AdapterListControl 例程。

[in] WriteToDevice

DMA 传输的方向。 将此参数设置为 TRUE 写入操作,该操作将数据从内存传输到设备。 将此参数设置为 FALSE 读取操作,该操作将数据从设备传输到内存。

[in] ScatterGatherBuffer

指向调用方分配的缓冲区的指针,该缓冲区将例程写入 DMA 传输的散点/收集列表。 此列表以 SCATTER_GATHER_LIST 结构开头,后跟 SCATTER_GATHER_ELEMENT 数组。

[in] ScatterGatherLength

ScatterGatherBuffer 参数中传递的缓冲区的大小(以字节为单位)。 分配的缓冲区大小必须足够大,才能包含散点/收集列表,以及操作系统在此缓冲区中存储的内部数据。 若要计算所需的缓冲区大小,请调用 GetDmaTransferInfoCalculateScatterGatherList 例程。

[in, optional] DmaCompletionRoutine

未使用。 设置为 NULL

[in, optional] CompletionContext

未使用。 设置为 NULL

[out, optional] ScatterGatherList

指向变量的指针,例程将指针写入到 DMA 传输的散点/收集列表。 此列表以 SCATTER_GATHER_LIST 结构开头,该结构包含指向 SCATTER_GATHER_ELEMENT 数组的指针。 此输出指针始终与 ScatterGatherBuffer 参数值匹配。

如果设置了 DMA_SYNCHRONOUS_CALLBACK 标志,并且 ExecutionRoutine 参数 NULLScatterGatherList 必须是有效的非NULL 指针。 如果 ExecutionRoutine 为非NULL,则 ScatterGatherList 是可选的,如果调用驱动程序不需要散点/收集列表,则可以 NULL。 如果设置了 DMA_SYNCHRONOUS_CALLBACK 标志,并且 ScatterGatherListExecutionRoutineNULL,或者未设置 DMA_SYNCHRONOUS_CALLBACK 标志,并且 ExecutionRoutineNULL,则 BuildScatterGatherListEx 调用失败。

返回值

BuildScatterGatherListEx 如果调用成功,则返回STATUS_SUCCESS。 可能的错误返回值包括以下状态代码。

返回代码 描述
STATUS_INVALID_PARAMETERS 由于调用方传递的参数值无效,例程失败。
STATUS_BUFFER_TOO_SMALL ScatterGatherBuffer 中的调用方提供的缓冲区 太小,无法包含散点/收集列表。
STATUS_INSUFFICIENT_RESOURCES 例程未能分配 DMA 传输所需的资源。

言论

BuildScatterGatherListEx* 不是可以直接按名称调用的系统例程。 此例程只能由*DMA_OPERATIONS 结构中返回的地址的指针调用。 驱动程序通过调用 IoGetDmaAdapter,并将 DeviceDescription 参数的 版本 成员调用为 DEVICE_DESCRIPTION_VERSION3,从而获取此例程的地址。 如果 IoGetDmaAdapter 返回 NULL,则例程在平台上不可用。

仅对总线主适配器使用 BuildScatterGatherListEx。 不要将此例程用于系统 DMA 适配器。

BuildScatterGatherListEx 类似于 GetScatterGatherListEx 例程,只不过它要求调用方为散点/收集列表分配缓冲区。

例如,驱动程序可能会在设备初始化期间预先分配一个或多个散点/收集缓冲区。 稍后,使用此类缓冲区的 buildScatterGatherListEx 调用 可以在内存可用性低的情况下成功,这可能导致 GetScatterGatherListEx 调用失败。

默认情况下,BuildScatterGatherListEx 异步返回,而无需等待请求的资源分配完成。 此返回后,调用方可以通过调用 CancelAdapterChannel 例程来取消挂起的分配请求。

如果调用驱动程序设置 DMA_SYNCHRONOUS_CALLBACK 标志,则 BuildScatterGatherListEx 例程的行为如下所示:

  • 如果请求的资源没有立即可用,BuildScatterGatherListEx 不会等待资源,不生成散点/收集列表,并且不调用 AdapterListControl 例程。 相反,BuildScatterGatherListEx 失败并返回STATUS_INSUFFICIENT_RESOURCES。

  • 如果设置了 DMA_SYNCHRONOUS_CALLBACK 标志,则不需要驱动程序提供 AdapterListControl 例程。

  • 如果驱动程序提供 AdapterListControl 例程,DMA_SYNCHRONOUS_CALLBACK 标志指示在调用线程的上下文中调用此例程,然后 BuildScatterGatherListEx 返回。

  • 如果驱动程序不提供 AdapterListControl 例程,驱动程序可以在 BuildScatterGatherListEx 返回后使用分配的资源和散点/收集列表。 在这种情况下,驱动程序必须提供有效的非NULLScatterGatherList 指针。 此外,驱动程序启动的 DMA 传输完成后,驱动程序必须调用 FreeAdapterObject 例程来释放为适配器对象分配的 buildScatterGatherListEx 资源。

BuildScatterGatherListExBuildScatterGatherList 例程的扩展版本。 以下列表汇总了仅在扩展版本中可用的功能:

特征 描述
起始偏移量 调用驱动程序可以为散点/收集 DMA 传输指定起始偏移量,而不是在 MDL 链开头的第一个缓冲区地址启动传输。
分配请求取消 驱动程序可以调用 CancelAdapterChannel,以便在 DMA 适配器排队等待 DMA 资源时取消挂起的分配请求。
同步回调 驱动程序可以设置 DMA_SYNCHRONOUS_CALLBACK 标志以请求调用线程中调用驱动程序提供的 AdapterListControl 例程,然后 BuildScatterGatherListEx 返回。

要求

要求 价值
最低支持的客户端 从 Windows 8 开始可用。
目标平台 桌面
标头 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
IRQL DISPATCH_LEVEL

另请参阅

AdapterListControl

AllocateAdapterChannelEx

CalculateScatterGatherList

DMA_OPERATIONS

DmaCompletionRoutine

FreeAdapterObject

GetScatterGatherList

GetScatterGatherListEx

MapTransferEx