完成 DMA 事务

[仅适用于 KMDF]

每次驱动程序的设备完成 DMA 传输时,驱动程序都必须调用 WdfDmaTransactionDmaCompletedWdfDmaTransactionDmaCompletedWithLengthWdfDmaTransmaTransactionDmaCompletedFinal,然后检查返回值。

如果返回值为 TRUE,则 DMA 事务不需要更多传输,驱动程序必须完成 DMA 事务。 通常,驱动程序尚未从其 EvtInterruptDpc 回调函数返回。 因此,此回调函数通过以下方式完成 DMA 事务:

  1. 调用 WdfObjectDelete 以删除事务对象;如果驱动程序重用 DMA 事务对象,则调用 WdfDmaTransactionRelease

  2. 如果事务与框架请求对象关联,则调用 WdfRequestCompleteWdfRequestCompleteWithInformation

如果驱动程序调用 WdfRequestCompleteWithInformation,则通常首先调用 WdfDmaTransactionGetBytesTransferred 以获取所有事务传输) 的总长度 (字节数。

下面的代码示例演示了这些步骤,该示例取自 Isrdpc.c 文件中 PLX9x5x 示例的 EvtInterruptDpc 回调函数:

if (readComplete) {
    BOOLEAN              transactionComplete;
    WDFDMATRANSACTION    dmaTransaction;
    size_t               bytesTransferred;

    // Get the current Read DmaTransaction.
    dmaTransaction = devExt->CurrentReadDmaTransaction;

    // Indicate that this DMA operation has completed:
    // This may start the transfer on the next packet if 
    // there is still data to be transferred.
    transactionComplete = 
          WdfDmaTransactionDmaCompleted( dmaTransaction, &status ); 
    if (transactionComplete) {
        // Complete the DmaTransaction and the request.
        devExt->CurrentReadDmaTransaction = NULL;
        bytesTransferred =  
               ((NT_SUCCESS(status)) ? 
               WdfDmaTransactionGetBytesTransferred(dmaTransaction): 0 );
        WdfDmaTransactionRelease(dmaTransaction);
        WdfRequestCompleteWithInformation(request, status, bytesTransferred);
    }
}