Annulation de transactions DMA

[S’applique uniquement à KMDF]

Si votre pilote a été créé avec la version 1.11 ou une version ultérieure de KMDF et s’exécute sur Windows 8 ou version ultérieure à l’aide de l’accès direct à la mémoire (DMA) version 3, le pilote peut tenter d’annuler une transaction DMA en attente en appelant la méthode WdfDmaTransactionCancel.

Lors de l’appel de WdfDmaTransactionCancel, le pilote doit s’assurer que la transaction DMA spécifiée n’est pas terminée pendant l’appel. Le pilote peut utiliser la technique suivante pour annuler une transaction en toute sécurité, soit avant l’allocation du canal DMA, soit après la fin d’un certain nombre d’opérations de transfert :

  1. Dans l’un des gestionnaires de requêtes du pilote, le pilote appelle WdfRequestMarkCancelableEx et fournit une fonction de rappel EvtRequestCancel pour la demande d’E/S. Le gestionnaire de requêtes appelle ensuite WdfDmaTransactionExecute.

  2. La fonction de rappel EvtRequestCancel du pilote (qui peut commencer à s’exécuter dans un thread distinct immédiatement après l’appel à WdfRequestMarkCancelableEx) appelle WdfDmaTransactionCancel.

  3. Si l’appel à WdfDmaTransactionCancel se produit après l’appel à WdfDmaTransactionExecute, mais avant que la méthode WdfDmaTransactionExecute n’ait démarré l’allocation DMA, l’annulation de la transaction réussit et WdfDmaTransactionCancel retourne TRUE. Dans ce cas, la fonction de rappel EvtRequestCancel du pilote doit terminer la transaction DMA. WdfDmaTransactionExecute retourne une valeur d’erreur.

  4. Si le pilote appelle WdfDmaTransactionCancel après que la méthode WdfDmaTransactionExecute a démarré l’allocation DMA, la tentative d’annulation de la transaction échoue et WdfDmaTransactionCancel retourne FALSE. Dans ce cas, WdfDmaTransactionExecute retourne STATUS_SUCCESS et le gestionnaire de requêtes du pilote doit effectuer la transaction DMA.

    À ce stade, si le pilote utilise la DMA en mode système, la fonction de rappel EvtRequestCancel peut appeler WdfDmaTransactionStopSystemTransfer pour tenter d’arrêter le transfert DMA en mode système en cours. Pour obtenir un exemple de code qui montre comment procéder, consultez WdfDmaTransactionStopSystemTransfer.

  5. Une fois l’allocation DMA terminée par la méthode WdfDmaTransactionExecute , l’infrastructure appelle la fonction de rappel EvtProgramDma du pilote (qui peut commencer à s’exécuter dans un thread distinct immédiatement après l’appel à WdfDmaTransactionExecute). À ce stade, un appel à la méthode WdfDmaTransactionCancel retournerait FALSE.

    Dans EvtProgramDma, le conducteur peut appeler WdfRequestUnmarkCancelable pour mettre fin à la possibilité d’annulation de la demande. Si WdfRequestUnmarkCancelable retourne STATUS_SUCCESS, la fonction de rappel doit programmer le matériel pour démarrer le transfert. Si WdfRequestUnmarkCancelable retourne STATUS_CANCELLED, la demande a été annulée. Dans ce cas, EvtProgramDma doit appeler WdfDmaTransactionDmaCompletedFinal pour terminer la transaction DMA.

    Le pilote peut utiliser la même technique pour annuler une transaction DMA une fois qu’un certain nombre d’opérations de transfert sont déjà terminées. Dans ce cas, le pilote appelle WdfDmaTransactionCancel après avoir appelé WdfDmaTransactionDmaCompleted, mais avant que l’infrastructure appelle EvtProgramDma pour programmer l’opération de transfert suivante. Si le pilote appelle WdfDmaTransactionCancel avant d’appeler WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted retourne TRUE, indiquant que la transaction DMA a été effectuée.