Finalización de una transacción de DMA

[Solo se aplica a KMDF]

Cada vez que el dispositivo de un controlador completa una transferencia DMA, el controlador debe llamar a WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength o WdfDmaTransactionDmaCompletedFinal y, a continuación, comprobar el valor devuelto.

Cuando el valor devuelto es TRUE, no se necesitan más transferencias para la transacción DMA y el controlador debe completar la transacción DMA. Normalmente, el controlador aún no ha devuelto de su función de devolución de llamada EvtInterruptDpc . Por lo tanto, esta función de devolución de llamada completa la transacción DMA por:

  1. Llamar a WdfObjectDelete para eliminar el objeto de transacción o llamar a WdfDmaTransactionRelease si el controlador reutiliza objetos de transacción DMA.

  2. Llamar a WdfRequestComplete o WdfRequestCompleteWithInformation, si la transacción está asociada a un objeto de solicitud de marco.

Si el controlador llama a WdfRequestCompleteWithInformation, normalmente llama primero a WdfDmaTransactionGetBytesTransferred para obtener la longitud total (número de bytes) de todas las transferencias de la transacción.

Estos pasos se muestran en el ejemplo de código siguiente, tomados de la función de devolución de llamada EvtInterruptDpc del ejemplo PLX9x5x en el archivo Isrdpc.c:

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