PMAP_TRANSFER_EX回调函数 (wdm.h)

MapTransferEx 例程设置映射寄存器,以将散点/收集列表中的物理地址映射到执行 DMA 传输所需的逻辑地址。

语法

PMAP_TRANSFER_EX PmapTransferEx;

NTSTATUS PmapTransferEx(
  [in]            PDMA_ADAPTER DmaAdapter,
  [in]            PMDL Mdl,
  [in]            PVOID MapRegisterBase,
  [in]            ULONGLONG Offset,
  [in]            ULONG DeviceOffset,
  [in, out]       PULONG Length,
  [in]            BOOLEAN WriteToDevice,
  [out, optional] PSCATTER_GATHER_LIST ScatterGatherBuffer,
  [in]            ULONG ScatterGatherBufferLength,
  [in, optional]  PDMA_COMPLETION_ROUTINE DmaCompletionRoutine,
  [in, optional]  PVOID CompletionContext
)
{...}

参数

[in] DmaAdapter

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

[in] Mdl

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

[in] MapRegisterBase

为适配器对象分配的映射寄存器的句柄。 调用方以前从 AllocateAdapterChannelEx 例程获取此句柄。

[in] Offset

MDL 链描述的内存起始位置的字节偏移量。 此偏移量指定用于 DMA 传输的 I/O 数据缓冲区的起始位置。 如果向调用方提供散点/收集列表,则此偏移量将确定列表中第一个缓冲区片段的起始地址。 如果 MDL 链中的 MDL 描述内存的总 N 个字节, 则 Offset 的有效值介于 0 到 N–1 之间。 有关详细信息,请参阅“备注”。

[in] DeviceOffset

目标设备的数据寄存器或 FIFO 与设备基址的字节偏移量。 此参数适用于具有多个 FIFO 的设备,这些 FIFO 可由系统 DMA 控制器访问。 此参数仅用于系统 DMA 传输。 对于总线主传输,请将此参数设置为零。

[in, out] Length

指向变量的指针,该变量包含用于 DMA 传输的 I/O 数据缓冲区的长度(以字节为单位)。 在输入时,此变量包含调用驱动程序请求的长度。 在返回之前,例程会将映射缓冲区的实际长度写入此变量。 从 MapTransferEx 返回时*Length 的值指示映射了多少个字节。 如果映射寄存器数和散点/收集缓冲区大小足以映射调用方请求的整个长度,则 *Length 的输入和输出值相同。 如果 MDL 链中的 MDL 描述内存的总 N 个字节,则 *Length 的有效值介于 0 到 N–Offset 之间

[in] WriteToDevice

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

[out, optional] ScatterGatherBuffer

指向调用方分配的缓冲区的指针,例程在其中写入 DMA 传输的散点/收集列表。 此列表以 SCATTER_GATHER_LIST 结构开头,紧跟 SCATTER_GATHER_ELEMENT 数组。 对于使用总线主 DMA 设备的驱动程序, ScatterGatherBuffer 是必需参数。 对于使用系统 DMA 控制器的驱动程序, ScatterGatherBuffer 参数是可选的,可以为 NULL。 有关详细信息,请参阅“备注”。

[in] ScatterGatherBufferLength

ScatterGatherBuffer 参数指向的缓冲区的大小(以字节为单位)。 分配的缓冲区大小必须足够大,才能包含散点/收集列表,以及操作系统在此缓冲区中存储的内部数据。 若要确定所需的缓冲区大小,请调用 GetDmaTransferInfoCalculateScatterGatherList 例程。 如果 ScatterGatherBufferNULL,请将 ScatterGatherBufferLength 设置为零。

[in, optional] DmaCompletionRoutine

指向调用方提供的 DmaCompletionRoutine 例程的指针,该例程将在 DMA 传输完成时调用。 如果目标设备使用生成 DMA 完成中断的系统 DMA 控制器,则调用此例程。 DMA 传输完成后,DISPATCH_LEVEL调用 DmaCompletionRoutine 例程。 对于系统 DMA 适配器,此参数是可选的,可以为 NULL。 对于总线主适配器,请将此参数设置为 NULL

[in, optional] CompletionContext

DmaCompletionRoutine 例程的驱动程序确定上下文。 此上下文作为 CompletionContext 参数提供给 DmaCompletionRoutine 例程。 如果 DmaCompletionRoutine 参数为 NULL,请将 CompletionContext 设置为 NULL

返回值

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

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

注解

MapTransferEx 不是可直接按名称调用的系统例程。此例程只能由DMA_OPERATIONS结构中返回的地址中的指针调用 驱动程序通过调用 IoGetDmaAdapterDeviceDescription 参数的 Version 成员设置为 DEVICE_DESCRIPTION_VERSION3)来获取此例程的地址。 如果 IoGetDmaAdapter 返回 NULL,则例程在平台上不可用。

对于使用系统 DMA 控制器的传输,调用方可以选择提供传输完成后调用的 DmaCompletionRoutine 回调例程。 操作系统计划此回调以响应来自系统 DMA 控制器的 DMA 完成中断。

MapTransferEx 可以设置的映射寄存器数不能超过驱动程序从 IoGetDmaAdapter 获取的最大值。

MdlOffsetLength 参数描述所请求的 DMA 传输的 I/O 数据缓冲区。 分配的映射寄存器数可能不足以映射此缓冲区中的所有内存,或者 ScatterGatherBuffer 指向的散点/收集缓冲区可能不够大,无法描述整个缓冲区。 MapTransferEx 将输出值写入 *Length ,告诉驱动程序例程映射了请求的 DMA 传输的缓冲区内存量。 例程将散点/收集列表写入 ScatterGatherBuffer 指向的缓冲区。 此列表描述例程成功映射的缓冲区片段。

如果对 MapTransferEx 的 调用成功, 则 MapTransferEx 将在返回之前写入 *Length 输出值。 如果调用方指定 DmaCompletionRoutine,则更新后的 *Length 输出值始终在 DmaCompletionRoutine 运行之前写入。 有关详细信息,请参阅 多次调用 MapTransferEx

Offset 参数指定 MDL 链中的起始偏移量,该链描述 I/O 数据缓冲区中的内存。 例如,假设 MDL 链包含两个 MDL,MDL₁ 和 MDLЛ,MDL₁ 描述内存的 N₁ 字节,MDLー 描述 N 个字节。 如果 Offset = N,其中 N₁ < N < ₁ + Nл,则缓冲区不包含 MDL₁ 描述的内存,并且从 MDLЛ 描述的内存中的 N - N₁ 字节的偏移量开始。

如果传输使用系统 DMA 控制器,则调用方可以设置 ScatterGatherBuffer = NULL,在这种情况下 ,MapTransferEx 使用内部分配的默认缓冲区来保存散点/收集列表。 默认缓冲区保证足够大,以包含至少一个元素的散点/收集列表。 如果默认缓冲区用于许多元素的散点/收集传输,则可能需要多次调用 MapTransferEx 来完成传输。 如果 DMA 控制器硬件支持散点/收集传输,则使用默认缓冲区可能会降低性能。

如果 ScatterGatherBuffer 为非 NULL 且 ScatterGatherBufferSize 指定的大小太小,无法包含至少一个元素的散点/收集列表, 则 MapTransferEx 将失败并返回STATUS_INVALID_PARAMETER。

MapTransferExMapTransfer 例程的扩展版本。 扩展版本具有以下优点:

  • MapTransferEx 可以在一次调用中处理 MDL 链中的所有缓冲区片段,但 MapTransfer 每次调用只能处理一个物理连续缓冲区片段。
  • MapTransferEx 可以在一次调用中生成整个散点/收集列表,但 MapTransfer 每次调用只能生成一个散点/收集列表元素。
  • MapTransferEx 可以在一次调用中映射散点/收集列表中的所有缓冲区片段,但 MapTransfer 每次调用只能映射一个物理连续缓冲区片段。
  • MapTransferEx 只需要整个散点/收集列表的起始偏移量,但 MapTransfer 需要每个物理连续缓冲区片段的起始虚拟地址。
  • MapTransferEx 调用可以映射通过一个或多个 MDL 扩展的缓冲区,但 MapTransfer 调用只能映射 MDL 描述的内存中的一个物理连续缓冲区片段。
  • 对于系统 DMA 传输, MapTransferEx 允许调用方提供 DmaCompletionRoutine 回调例程,以便在传输完成后接收通知,但 MapTransfer 不提供在 DMA 传输完成时通知调用方的方法。
每次成功调用 MapTransferEx 后,都必须对 FlushAdapterBuffersEx 例程进行相应的调用。 在 MapTransferEx 调用之后的 FlushAdapterBuffersEx 调用必须在下一次 MapTransferEx 调用发生之前发生。 即使对 CancelMappedTransfer 例程的调用成功取消了前面的 MapTransfer 调用请求的映射传输,也需要 FlushAdapterBuffersEx 调用。

有关详细信息,请参阅 使用 MapTransferEx 例程

要求

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

另请参阅

AllocateAdapterChannelEx

CalculateScatterGatherList

CancelMappedTransfer

DMA_ADAPTER

DMA_OPERATIONS

DmaCompletionRoutine

FlushAdapterBuffersEx

GetDmaTransferInfo

IoGetDmaAdapter

SCATTER_GATHER_LIST