WdfDmaTransactionExecute 函数 (wdfdmatransaction.h)

[仅适用于 KMDF]

WdfDmaTransactionExecute 方法开始执行指定的 DMA 事务。

语法

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

参数

[in] DmaTransaction

驱动程序从上一次调用 WdfDmaTransactionCreate获取的 DMA 事务对象的句柄。

[in, optional] Context

驱动程序定义的上下文信息。 框架将指定的值传递给驱动程序的 EvtProgramDma 事件回调函数的 上下文(可以是指针)。 此参数是可选的,可以 NULL

返回值

如果作成功,WdfDmaTransactionExecute 返回STATUS_SUCCESS。 否则,该方法可能会返回以下值之一。

返回代码 说明
STATUS_INSUFFICIENT_RESOURCES
驱动程序以前称为 WdfDmaTransactionSetImmediateExecution,请求所需的资源不可用。
STATUS_INVALID_DEVICE_REQUEST
WdfDmaTransactionExecute 的调用前面没有调用 WdfDmaTransactionInitializeWdfDmaTransactionInitializeUsingRequest
STATUS_WDF_BUSY
设备执行单数据包传输,并在执行另一个事务时调用 WdfDmaTransactionExecute 驱动程序。
STATUS_WDF_TOO_FRAGMENTED
作系统处理指定传输大小所需的散点/收集元素数大于驱动程序调用 WdfDmaEnablerSetMaximumScatterGatherElements 的值。 有关详细信息,请参阅以下“备注”部分。
 

此方法还可以 返回其他NTSTATUS 值。

如果驱动程序提供无效的对象句柄,则会发生 bug 检查。

注解

WdfDmaTransactionExecute 方法初始化与指定 DMA 事务关联的第一个 DMA 传输 的事务散点/收集列表。 (对于单数据包传输,散点/收集列表包含单个元素。然后,该方法调用驱动程序的 EvtProgramDma 事件回调函数,回调函数可以编程设备以开始传输。

基于框架的驱动程序通常从 I/O 队列事件回调函数内调用 WdfDmaTransactionExecute

在驱动程序调用 WdfDmaTransactionInitializeWdfDmaTransactionInitializeUsingRequest 初始化 DMA 事务后,驱动程序必须仅调用 WdfDmaTransactionExecute,然后才能 完成 DMA 事务

如果 WdfDmaTransactionInitializeXxx 返回成功,但 WdfDmaTransactionExecute 返回错误值,驱动程序必须调用 WdfDmaTransactionRelease

在 1.11 之前的框架版本中,如果设备执行单数据包传输,则作系统一次只能执行一个 DMA 事务。 在这种情况下,如果另一个事务正在执行,WdfDmaTransactionExecute 将返回STATUS_WDF_BUSY。

在框架版本 1.11 及更高版本中,如果驱动程序使用 DMA 版本 3 执行单数据包传输,则作系统可以在内部队列中存储多个 DMA 事务。 在这种情况下,驱动程序可以在执行另一个事务时调用 WdfDmaTransactionExecute。 若要选择 DMA 版本 3,请将 WdmDmaVersionOverrideWDF_DMA_ENABLER_CONFIG 成员设置为 3。

如果设备执行散点/收集传输,作系统可以同时执行多个 DMA 事务。 在这种情况下,驱动程序可以在执行另一个事务时调用 WdfDmaTransactionExecute

如果驱动程序调用 WdfDmaTransactionDmaCompletedWithLength 来报告部分传输, 如果驱动程序已通过使用链接在一起的 MDL 指定了 DMA 事务的数据缓冲区(使用 MDL 结构的下一个 成员),WdfDmaTransactionExecute 可以返回STATUS_WDF_TOO_FRAGMENTED,因为框架可能会重新计算片段的数量和大小,并可能超过允许的片段数。

WdfDmaTransactionExecute 在成功启动事务时返回STATUS_SUCCESS。 若要确定框架是否成功将事务的所有传输发送到驱动程序的 EvtProgramDma 回调函数, 驱动程序必须调用 WdfDmaTransactionDmaCompletedWdfDmaTransactionDmaCompletedWithLengthWdfDmaTransactionDmaCompletedFinal

如果 Context 参数提供的值是指针或句柄,则必须在 IRQL = DISPATCH_LEVEL 的驱动程序的 EvtProgramDma 事件回调函数中访问它引用的内存。 可以使用 框架对象上下文 来满足此要求。

如果驱动程序以前 WdfDmaTransactionSetImmediateExecution,则驱动程序可以以非阻塞方式调用 WdfDmaTransactionExecute

有关 DMA 事务的详细信息,请参阅 启动 DMA 事务

例子

下面的代码示例来自 PCIDRV 示例驱动程序。 此示例创建并初始化 DMA 传输并开始其执行。

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

要求

要求 价值
目标平台 普遍
最低 KMDF 版本 1.0
标头 wdfdmatransaction.h (包括 Wdf.h)
图书馆 Wdf01000.sys(请参阅框架库版本控制。
IRQL <=DISPATCH_LEVEL
DDI 符合性规则 DriverCreate(kmdf)KmdfIrql(kmdf)KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf)

另请参阅

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution