WdfDmaTransactionInitialize, fonction (wdfdmatransaction.h)
[S’applique uniquement à KMDF]
La méthode WdfDmaTransactionInitialize initialise une transaction DMA spécifiée.
Syntaxe
NTSTATUS WdfDmaTransactionInitialize(
[in] WDFDMATRANSACTION DmaTransaction,
[in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
[in] WDF_DMA_DIRECTION DmaDirection,
[in] PMDL Mdl,
[in] PVOID VirtualAddress,
[in] size_t Length
);
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] EvtProgramDmaFunction
Pointeur vers la fonction de rappel d’événement EvtProgramDma du pilote.
[in] DmaDirection
Valeur de type WDF_DMA_DIRECTION.
[in] Mdl
Pointeur vers une liste de descripteurs de mémoire (MDL) qui décrit la mémoire tampon qui sera utilisée pour la transaction DMA. Pour plus d’informations, consultez Remarques.
[in] VirtualAddress
Adresse virtuelle de la mémoire tampon qui sera utilisée pour la transaction DMA.
[in] Length
Nombre d’octets à transférer.
Valeur retournée
WdfDmaTransactionInitialize retourne STATUS_SUCCESS si l’opération réussit. Sinon, la méthode peut retourner l’une des valeurs suivantes.
Code de retour | Description |
---|---|
|
Une liste de points/regroupement n’a pas pu être allouée. |
|
Un paramètre non valide a été détecté. |
|
Le nombre d’éléments de diffusion/collecte nécessaires pour gérer la transaction était supérieur à la valeur spécifiée par l’appel du pilote à WdfDmaEnablerSetMaximumScatterGatherElements .
Pour les transactions qui ont été définies pour un transfert unique, une façon de résoudre ce problème consiste à copier les données dans une mémoire tampon contiguë physiquement, puis à initialiser la transaction avec cette mémoire tampon. Par exemple, appelez MmAllocateContiguousMemory, copiez les mémoires tampons d’origine dans le nouveau, puis appelez À nouveau WdfDmaTransactionInitialize . |
|
Cette valeur de retour s’applique uniquement aux transactions qui ont été définies pour un transfert unique.
Le nombre de registres de carte nécessaires pour mapper la transaction est supérieur au nombre réservé par l’adaptateur DMA. Pour résoudre ce problème, le pilote peut réduire le nombre de registres de carte requis en combinant une chaîne MDL en une seule MDL. Les pilotes utilisant le DMA de paquet et le système peuvent appeler WdfDmaTransactionAllocateResources pour réserver un certain nombre de registres de carte à partir du total alloué à l’appareil. Supposons que votre pilote a réservé 4 registres de carte sur 8 au total, mais que le transfert DMA en nécessite 6. Dans ce cas, WdfDmaTransactionInitialize échoue. Pour résoudre le problème, appelez WdfDmaTransactionFreeResources , puis appelez à nouveau WdfDmaTransactionInitialize . Les pilotes qui utilisent la DMA de nuages de points/regroupements ne peuvent pas réserver les registres de carte. |
|
Cette valeur de retour s’applique uniquement aux transactions qui ont été définies pour un transfert unique.
La longueur totale de la transaction dépasse la taille de transfert maximale de l’appareil. |
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 WdfDmaTransactionInitialize prépare une opération DMA pour l’exécution, en effectuant des opérations d’initialisation telles que l’allocation de la liste de points/regroupements d’une transaction. Une fois que votre pilote a appelé WdfDmaTransactionInitialize, le pilote doit appeler WdfDmaTransactionExecute pour commencer à exécuter la transaction.
Les pilotes basés sur l’infrastructure appellent généralement WdfDmaTransactionInitialize à partir d’une fonction de rappel d’événement de file d’E/S.
Si vous créez une transaction DMA basée sur les informations contenues dans un objet de demande d’infrastructure, votre pilote doit appeler WdfDmaTransactionInitializeUsingRequest. Si vous créez une transaction DMA qui n’est pas basée sur un objet de requête, utilisez WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingOffset.
Le pilote peut spécifier une chaîne MDL dans le paramètre Mdl de cette méthode. Une chaîne MDL est une séquence de structures MDL que le pilote a chaînées ensemble à l’aide du membre Suivant de la structure MDL. Dans les versions de framework antérieures à la version 1.11, seuls les transferts DMA de diffusion/collecte peuvent utiliser des chaînes MDL. À compter de la version 1.11, si le pilote utilise DMA version 3, les transferts à paquet unique peuvent également utiliser des dll MDL chaînées.
Si la mémoire tampon spécifiée par le pilote est supérieure à la longueur de transfert maximale spécifiée par votre pilote lorsqu’il a appelé WdfDmaEnablerCreate ou WdfDmaTransactionSetMaximumLength, l’infrastructure décompose la transaction en plusieurs transferts.
Pour plus d’informations sur les transactions DMA, consultez Création et initialisation d’une transaction DMA.
Exemples
L’exemple de code suivant provient de l’exemple de pilote PLX9x5x . Tout d’abord, l’exemple initialise une structure WDF_OBJECT_ATTRIBUTES et crée un objet de transaction DMA. Ensuite, il obtient un MDL qui représente la mémoire tampon d’entrée d’une demande d’E/S reçue, et il obtient l’adresse virtuelle et la longueur de la mémoire tampon. Enfin, l’exemple appelle WdfDmaTransactionInitialize pour initialiser la transaction.
WDF_OBJECT_ATTRIBUTES attributes;
PMDL mdl;
PVOID virtualAddress;
ULONG length;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
&attributes,
TRANSACTION_CONTEXT
);
status = WdfDmaTransactionCreate(
devExt->DmaEnabler,
&attributes,
&dmaTransaction
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
status = WdfRequestRetrieveInputWdmMdl(
Request,
&mdl
);
if (!NT_SUCCESS(status)) {
goto CleanUp;
}
virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);
status = WdfDmaTransactionInitialize(
dmaTransaction,
PLxEvtProgramWriteDma,
WdfDmaDirectionWriteToDevice,
mdl,
virtualAddress,
length
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
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 | DeferredRequestCompleted(kmdf),DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf),MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |