WdfDmaTransactionDmaCompleted 函数 (wdfdmatransaction.h)

[仅适用于 KMDF]

WdfDmaTransactionDmaCompleted 方法通知框架设备的 DMA 传输操作已完成。

语法

BOOLEAN WdfDmaTransactionDmaCompleted(
  [in]  WDFDMATRANSACTION DmaTransaction,
  [out] NTSTATUS          *Status
);

参数

[in] DmaTransaction

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

[out] Status

指向接收 DMA 传输状态的位置的指针。 有关更多信息,请参见下面的“备注”部分。

返回值

WdfDmaTransactionDmaCompleted 返回 FALSE ,如果需要其他传输来完成 DMA 事务, 则 Status 接收STATUS_MORE_PROCESSING_REQUIRED。 如果不需要其他传输,该方法将返回 TRUE

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

注解

每当 完成 DMA 传输 时,基于框架的驱动程序必须调用以下方法之一:

通常,驱动程序在设备中断指示完成 DMA 传输操作后,从 EvtInterruptDpc 事件回调函数中调用这些方法。 系统模式 DMA 设备的驱动程序可以从 EvtDmaTransactionDmaTransferComplete 事件回调函数中调用这些方法。

框架可以将 DMA 事务 划分为多个 DMA 传输操作。 因此,驱动程序必须检查方法的返回值以确定是否需要其他传输。

如果方法返回 FALSE,则 Status 位置会收到STATUS_MORE_PROCESSING_REQUIRED,并且需要执行其他 DMA 操作才能完成事务。 通常, EvtInterruptDpc 事件回调函数此时不执行任何其他操作。 相反,框架会调用驱动程序的 EvtProgramDma 事件回调函数,以便回调函数可以开始下一次传输。

如果方法返回 TRUE,则指定的事务不会再发生传输。 在这种情况下, 状态 值STATUS_SUCCESS表示框架未遇到任何错误,并且 DMA 事务已完成。

如果驱动程序在调用 WdfDmaTransactionDmaCompleted 之前调用 WdfDmaTransactionStopSystemTransfer则 WdfDmaTransactionDmaCompleted 返回 TRUE ,并且 StatusSTATUS_CANCELLED

对于为单次传输设置的事务,即使初始化成功,如果硬件无法在单个传输中完成事务,WdfDmaTransactionDmaCompleted 将返回 TRUEStatus 值STATUS_WDF_TOO_MANY_TRANSFERS。 对于报告每个 DMA 操作的剩余传输的硬件,可能会发生这种情况。 例如,驱动程序将设备设置为写入 64KB,但设备只写入 60KB。 在这种情况下,驱动程序可能会重复 DMA 操作或重置设备。

Status 的任何其他值表示框架检测到错误,并且 DMA 事务可能尚未完成。

WdfDmaTransactionDmaCompleted 返回 TRUE 时,驱动程序通常执行以下操作:

有关完成 DMA 传输的详细信息,请参阅 完成 DMA 传输

示例

下面的代码示例来自 AMCC5933 示例驱动程序。 此示例演示一个 EvtInterruptDpc 回调函数。 该示例通知框架 DMA 传输已完成。 如果框架指示此传输是 DMA 事务的最后一个传输,则代码将删除 DMA 事务对象并完成关联的 I/O 请求。

VOID
AmccPciEvtInterruptDpc(
    IN WDFINTERRUPT  WdfInterrupt,
    IN WDFOBJECT  WdfDevice
    )
{
    PAMCC_DEVICE_EXTENSION  devExt;
    WDFREQUEST  request;
    REQUEST_CONTEXT  *transfer;
    NTSTATUS  status;
    size_t  transferred;
    BOOLEAN  transactionComplete;

    UNREFERENCED_PARAMETER( WdfInterrupt );

    //
    // Retrieve request and transfer.
    //
    devExt = AmccPciGetDevExt(WdfDevice);
    request  = devExt->CurrentRequest;
    transfer = GetRequestContext(request);

    //
    // Check to see if the request has been canceled. 
    //
    if (WdfRequestIsCanceled(request)) {
        TraceEvents(
                    TRACE_LEVEL_ERROR,
                    AMCC_TRACE_IO,
                    "Aborted DMA transaction 0x%p",
                    request
                    );
        WdfObjectDelete( transfer->DmaTransaction );
        devExt->CurrentRequest = NULL;
        WdfRequestComplete(
                           request,
                           STATUS_CANCELLED
                           );
        return;
    }
 
    //
    // Notify the framework that a DMA transfer has completed.
    //
    transactionComplete = WdfDmaTransactionDmaCompleted(
                                                    transfer->DmaTransaction,
                                                    &status
                                                    );
    if (transactionComplete) {
        ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);

        //
        // No more data. The request is complete.
        //
        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Request %p completed: status %X",  
                    request,
                    status
                    );

        //
        // Get the byte count.
        //
        transferred =
                WdfDmaTransactionGetBytesTransferred(transfer->DmaTransaction);

        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Bytes transferred %d",
                    (int) transferred
                    );

        //
        // Delete this DmaTransaction object.
        //
        WdfObjectDelete(transfer->DmaTransaction);

        //
        // Clean up the device context for this request.
        //
        devExt->CurrentRequest = NULL;

        //
        // Complete this I/O request.
        //
        WdfRequestCompleteWithInformation(
                                          request, 
                                          status,
                                          (NT_SUCCESS(status)) ? transferred : 0
                                          );
    }
}

要求

要求
目标平台 通用
最低 KMDF 版本 1.0
标头 wdfdmatransaction.h (包括 Wdf.h)
Library Wdf01000.sys (请参阅框架库 Versioning.)
IRQL <=DISPATCH_LEVEL
DDI 符合性规则 DriverCreate (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf)

另请参阅

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation