Completing a DMA Transaction

[Applies to KMDF only]

Each time that a driver's device completes a DMA transfer, the driver must call WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength, or WdfDmaTransactionDmaCompletedFinal and then check the return value.

When the return value is TRUE, no more transfers are needed for the DMA transaction and the driver must complete the DMA transaction. Typically, the driver has not yet returned from its EvtInterruptDpc callback function. Therefore, this callback function completes the DMA transaction by:

  1. Calling WdfObjectDelete to delete the transaction object, or calling WdfDmaTransactionRelease if the driver reuses DMA transaction objects.

  2. Calling WdfRequestComplete or WdfRequestCompleteWithInformation, if the transaction is associated with a framework request object.

If the driver calls WdfRequestCompleteWithInformation, it typically first calls WdfDmaTransactionGetBytesTransferred to obtain the total length (number of bytes) of all of the transaction's transfers.

These steps are illustrated in the following code example, taken from the PLX9x5x sample’s EvtInterruptDpc callback function in the Isrdpc.c file:

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);
    }
}