WdfDmaTransactionExecute 函数 (wdfdmatransaction.h)

[仅适用于 KMDF]

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

语法

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

参数

[in] DmaTransaction

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

[in, optional] Context

驱动程序定义的上下文信息。 框架会将为 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 事务后,驱动程序必须在完成 DMA 事务之前仅调用一次 WdfDmaTransactionExecute

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

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

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

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

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

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

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

如果驱动程序以前已调用 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)
Library Wdf01000.sys (请参阅框架库版本控制.)
IRQL <=DISPATCH_LEVEL
DDI 符合性规则 DriverCreate (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf)

另请参阅

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution