WdfDmaTransactionExecute, fonction (wdfdmatransaction.h)

[S’applique à KMDF uniquement]

La méthode WdfDmaTransactionExecute commence l’exécution d’une transaction DMA spécifiée.

Syntaxe

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

Paramètres

[in] DmaTransaction

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

[in, optional] Context

Informations de contexte définies par le pilote. L’infrastructure transmet la valeur spécifiée pour Context, qui peut être un pointeur, à la fonction de rappel d’événement EvtProgramDma du pilote. Ce paramètre est facultatif et peut être NULL.

Valeur retournée

WdfDmaTransactionExecute retourne STATUS_SUCCESS si l’opération réussit. Sinon, la méthode peut retourner l’une des valeurs suivantes.

Code de retour Description
STATUS_INSUFFICIENT_RESOURCES
Le pilote précédemment appelé WdfDmaTransactionSetImmediateExecution et les ressources nécessaires à la requête ne sont pas disponibles.
STATUS_INVALID_DEVICE_REQUEST
L’appel à WdfDmaTransactionExecute n’a pas été précédé d’un appel à WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingRequest.
STATUS_WDF_BUSY
L’appareil effectue des transferts de paquets uniques, et le pilote a appelé WdfDmaTransactionExecute pendant qu’une autre transaction s’exécutait.
STATUS_WDF_TOO_FRAGMENTED
Le nombre d’éléments de nuage de points/regroupements dont le système d’exploitation avait besoin pour gérer la taille de transfert spécifiée était supérieur à la valeur que le pilote appelait à WdfDmaEnablerSetMaximumScatterGatherElements spécifiée. Pour plus d'informations, consultez la section Notes qui suit.
 

Cette méthode peut également retourner d’autres valeurs NTSTATUS.

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

Remarques

La méthode WdfDmaTransactionExecute initialise la liste de points/regroupements d’une transaction pour le premier transfert DMA associé à la transaction DMA spécifiée. (Pour les transferts de paquets uniques, la liste de points/regroupements contient un seul élément.) Ensuite, la méthode appelle la fonction de rappel d’événement EvtProgramDma du pilote, et la fonction de rappel peut programmer l’appareil pour commencer le transfert.

Les pilotes basés sur l’infrastructure appellent généralement WdfDmaTransactionExecute à partir d’une fonction de rappel d’événement de file d’attente d’E/S.

Une fois qu’un pilote a appelé WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingRequest pour initialiser une transaction DMA, le pilote doit appeler WdfDmaTransactionExecute une seule fois avant de terminer la transaction DMA.

Si WdfDmaTransactionInitializeXxx renvoie la réussite, mais que WdfDmaTransactionExecute retourne une valeur d’erreur, votre pilote doit appeler WdfDmaTransactionRelease.

Dans les versions de framework antérieures à la version 1.11, si l’appareil effectue des transferts de paquets uniques, le système d’exploitation ne peut exécuter qu’une seule transaction DMA à la fois. Dans ce cas, WdfDmaTransactionExecute retourne STATUS_WDF_BUSY si une autre transaction est en cours d’exécution.

Dans le framework versions 1.11 et ultérieures, si le pilote utilise DMA version 3 pour effectuer des transferts à paquet unique, le système d’exploitation peut stocker plusieurs transactions DMA dans une file d’attente interne. Dans ce cas, le pilote peut appeler WdfDmaTransactionExecute pendant qu’une autre transaction est en cours d’exécution. Pour sélectionner DMA version 3, définissez le membre WdmDmaVersionOverride de WDF_DMA_ENABLER_CONFIG sur 3.

Si l’appareil effectue des transferts de nuages de points/de collecte, le système d’exploitation peut exécuter plusieurs transactions DMA simultanément. Dans ce cas, le pilote peut appeler WdfDmaTransactionExecute pendant qu’une autre transaction est en cours d’exécution.

Si le pilote appelle WdfDmaTransactionDmaCompletedWithLength pour signaler un transfert partiel et si le pilote a spécifié la mémoire tampon de données de la transaction DMA à l’aide de MDL qu’il a chaînées (à l’aide du membre Next de la structure MDL ), WdfDmaTransactionExecute peut retourner STATUS_WDF_TOO_FRAGMENTED, car le framework peut recalculer le nombre et la taille des fragments et peut dépasser le nombre de fragments autorisés.

WdfDmaTransactionExecute retourne STATUS_SUCCESS si la transaction a été correctement démarrée. Pour déterminer si l’infrastructure a correctement envoyé tous les transferts de la transaction à la fonction de rappel EvtProgramDma du pilote, le pilote doit appeler WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength ou WdfDmaTransactionDmaCompletedFinal.

Si la valeur que le paramètre Context fournit est un pointeur ou un handle, la mémoire qu’il référence doit être accessible dans la fonction de rappel d’événement EvtProgramDma du pilote à l’emplacement IRQL = DISPATCH_LEVEL. Vous pouvez utiliser le contexte de l’objet framework pour répondre à cette exigence.

Le pilote peut appeler WdfDmaTransactionExecute de manière non bloquante s’il a précédemment appelé WdfDmaTransactionSetImmediateExecution.

Pour plus d’informations sur les transactions DMA, consultez Démarrage d’une transaction DMA.

Exemples

L’exemple de code suivant provient de l’exemple de pilote PCIDRV . Cet exemple crée et initialise un transfert DMA et commence son exécution.

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

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 des versions de la bibliothèque d’infrastructure).)
IRQL <=DISPATCH_LEVEL
Règles de conformité DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Voir aussi

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution