Partager via


Fin d’une transaction DMA

[S’applique uniquement à KMDF]

Chaque fois que l’appareil d’un pilote termine un transfert DMA, le pilote doit appeler WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength ou WdfDmaTransactionDmaCompletedFinal, puis case activée la valeur de retour.

Lorsque la valeur de retour est TRUE, plus aucun transfert n’est nécessaire pour la transaction DMA et le pilote doit effectuer la transaction DMA. En règle générale, le pilote n’est pas encore retourné à partir de sa fonction de rappel EvtInterruptDpc . Par conséquent, cette fonction de rappel termine la transaction DMA en :

  1. Appel de WdfObjectDelete pour supprimer l’objet de transaction ou appel de WdfDmaTransactionRelease si le pilote réutilise les objets de transaction DMA.

  2. Appel de WdfRequestComplete ou WdfRequestCompleteWithInformation, si la transaction est associée à un objet de demande d’infrastructure.

Si le pilote appelle WdfRequestCompleteWithInformation, il appelle généralement WdfDmaTransactionGetBytesTransferred pour obtenir la longueur totale (nombre d’octets) de tous les transferts de la transaction.

Ces étapes sont illustrées dans l’exemple de code suivant, tiré de la fonction de rappel EvtInterruptDpc de l’exemple PLX9x5x dans le fichier 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);
    }
}