WdfDmaTransactionDmaCompleted function (wdfdmatransaction.h)

[Applies to KMDF only]

The WdfDmaTransactionDmaCompleted method notifies the framework that a device's DMA transfer operation is completed.

Syntax

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

Parameters

[in] DmaTransaction

A handle to a DMA transaction object that the driver obtained from a previous call to WdfDmaTransactionCreate.

[out] Status

A pointer to a location that receives the status of the DMA transfer. For more information, see the following Remarks section.

Return value

WdfDmaTransactionDmaCompleted returns FALSE and Status receives STATUS_MORE_PROCESSING_REQUIRED if additional transfers are needed to complete the DMA transaction. The method returns TRUE if no additional transfers are required.

A bug check occurs if the driver supplies an invalid object handle.

Remarks

Framework-based drivers must call one of the following methods whenever a DMA transfer is complete:

Typically, drivers call these methods from within an EvtInterruptDpc event callback function, after a device interrupt indicates the completion of a DMA transfer operation. A driver for a system-mode DMA device might call these methods from within an EvtDmaTransactionDmaTransferComplete event callback function.

The framework might divide a DMA transaction into several DMA transfer operations. Therefore, the driver must examine the method's return value to determine if additional transfers are required.

If the method returns FALSE, the Status location receives STATUS_MORE_PROCESSING_REQUIRED and additional DMA operations are required to complete the transaction. Typically, the EvtInterruptDpc event callback function does nothing else at this point. Instead, the framework calls the driver's EvtProgramDma event callback function, so the callback function can begin the next transfer.

If the method returns TRUE, no more transfers will occur for the specified transaction. In this case, a Status value of STATUS_SUCCESS means that the framework did not encounter any errors and the DMA transaction is complete.

If the driver calls WdfDmaTransactionStopSystemTransfer before calling WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted returns TRUE and a Status value of STATUS_CANCELLED.

For transactions that were set for single transfer, WdfDmaTransactionDmaCompleted returns TRUE and a Status value of STATUS_WDF_TOO_MANY_TRANSFERS if the hardware fails to complete the transaction in a single transfer, even though initialization succeeded. This could happen for hardware that reports residual transfers for each DMA operation. For example, the driver programs the device to write 64KB, but the device writes only 60KB. In this case, the driver might repeat the DMA operation or reset the device.

Any other value for Status means that the framework detected an error and the DMA transaction might not have been completed.

When WdfDmaTransactionDmaCompleted returns TRUE, the driver typically does the following:

For more information about completing DMA transfers, see Completing a DMA Transfer.

Examples

The following code example is from the AMCC5933 sample driver. This example shows an EvtInterruptDpc callback function. The example notifies the framework that a DMA transfer has completed. If the framework indicates that this transfer is the last one for the DMA transaction, the code deletes the DMA transaction object and completes the associated I/O request.

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

Requirements

Requirement Value
Target Platform Universal
Minimum KMDF version 1.0
Header wdfdmatransaction.h (include Wdf.h)
Library Wdf01000.sys (see Framework Library Versioning.)
IRQL <=DISPATCH_LEVEL
DDI compliance rules DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

See also

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation