Partager via


WdfDmaTransactionDmaCompleted, fonction (wdfdmatransaction.h)

[S’applique uniquement à KMDF]

La méthode WdfDmaTransactionDmaCompleted informe l’infrastructure que l’opération de transfert DMA d’un appareil est terminée.

Syntaxe

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

Paramètres

[in] DmaTransaction

Handle pour un objet de transaction DMA que le pilote a obtenu à partir d’un appel précédent à WdfDmaTransactionCreate.

[out] Status

Pointeur vers un emplacement qui reçoit le status du transfert DMA. Pour plus d'informations, consultez la section Notes qui suit.

Valeur retournée

WdfDmaTransactionDmaCompleted retourne FALSE et Status reçoit STATUS_MORE_PROCESSING_REQUIRED si des transferts supplémentaires sont nécessaires pour terminer la transaction DMA. La méthode retourne TRUE si aucun transfert supplémentaire n’est requis.

Un bogue case activée se produit si le pilote fournit un handle d’objet non valide.

Remarques

Les pilotes basés sur l’infrastructure doivent appeler l’une des méthodes suivantes chaque fois qu’un transfert DMA est terminé :

En règle générale, les pilotes appellent ces méthodes à partir d’une fonction de rappel d’événement EvtInterruptDpc , après qu’une interruption d’appareil indique la fin d’une opération de transfert DMA. Un pilote pour un appareil DMA en mode système peut appeler ces méthodes à partir d’une fonction de rappel d’événement EvtDmaTransactionDmaTransferComplete .

L’infrastructure peut diviser une transaction DMA en plusieurs opérations de transfert DMA. Par conséquent, le pilote doit examiner la valeur de retour de la méthode pour déterminer si des transferts supplémentaires sont nécessaires.

Si la méthode retourne FALSE, l’emplacement d’état reçoit STATUS_MORE_PROCESSING_REQUIRED et des opérations DMA supplémentaires sont nécessaires pour terminer la transaction. En règle générale, la fonction de rappel d’événement EvtInterruptDpc ne fait rien d’autre à ce stade. Au lieu de cela, l’infrastructure appelle la fonction de rappel d’événement EvtProgramDma du pilote, afin que la fonction de rappel puisse commencer le transfert suivant.

Si la méthode retourne TRUE, plus aucun transfert n’aura lieu pour la transaction spécifiée. Dans ce cas, une valeur Status de STATUS_SUCCESS signifie que l’infrastructure n’a rencontré aucune erreur et que la transaction DMA est terminée.

Si le pilote appelle WdfDmaTransactionStopSystemTransfer avant d’appeler WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted retourne TRUE et une valeur Statusde STATUS_CANCELLED.

Pour les transactions qui ont été définies pour un transfert unique, WdfDmaTransactionDmaCompleted retourne TRUE et une valeur Statusde STATUS_WDF_TOO_MANY_TRANSFERS si le matériel ne parvient pas à terminer la transaction dans un seul transfert, même si l’initialisation a réussi. Cela peut se produire pour le matériel qui signale des transferts résiduels pour chaque opération DMA. Par exemple, le pilote programme l’appareil pour écrire 64 Ko, mais l’appareil n’écrit que 60 Ko. Dans ce cas, le pilote peut répéter l’opération DMA ou réinitialiser l’appareil.

Toute autre valeur pour Status signifie que l’infrastructure a détecté une erreur et que la transaction DMA n’a peut-être pas été effectuée.

Lorsque WdfDmaTransactionDmaCompleted retourne TRUE, le pilote effectue généralement les opérations suivantes :

Pour plus d’informations sur la fin des transferts DMA, consultez Terminer un transfert DMA.

Exemples

L’exemple de code suivant provient de l’exemple de pilote AMCC5933 . Cet exemple montre une fonction de rappel EvtInterruptDpc . L’exemple indique à l’infrastructure qu’un transfert DMA est terminé. Si l’infrastructure indique que ce transfert est le dernier pour la transaction DMA, le code supprime l’objet de transaction DMA et termine la demande d’E/S associée.

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

Configuration requise

Condition requise Valeur
Plateforme cible Universal
Version KMDF minimale 1.0
En-tête wdfdmatransaction.h (inclure Wdf.h)
Bibliothèque Wdf01000.sys (consultez Gestion de version de la bibliothèque d’infrastructure.)
IRQL <=DISPATCH_LEVEL
Règles de conformité DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Voir aussi

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation