WdfDmaTransactionInitialize-Funktion (wdfdmatransaction.h)
[Gilt nur für KMDF]
Die WdfDmaTransactionInitialize-Methode initialisiert eine angegebene DMA-Transaktion.
Syntax
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
);
Parameter
[in] DmaTransaction
Ein Handle für ein DMA-Transaktionsobjekt, das der Treiber aus einem vorherigen Aufruf von WdfDmaTransactionCreate abgerufen hat.
[in] EvtProgramDmaFunction
Ein Zeiger auf die EvtProgramDma-Ereignisrückruffunktion des Treibers.
[in] DmaDirection
Ein WDF_DMA_DIRECTION typisierter Wert.
[in] Mdl
Ein Zeiger auf eine Speicherdeskriptorliste (Memory Descriptor List, MDL), der den Puffer beschreibt, der für die DMA-Transaktion verwendet wird. Weitere Informationen finden Sie unter Hinweise.
[in] VirtualAddress
Die virtuelle Adresse des Puffers, der für die DMA-Transaktion verwendet wird.
[in] Length
Die Anzahl der zu übertragenden Bytes.
Rückgabewert
WdfDmaTransactionInitialize gibt STATUS_SUCCESS zurück, wenn der Vorgang erfolgreich ist. Andernfalls gibt die Methode möglicherweise einen der folgenden Werte zurück.
Rückgabecode | Beschreibung |
---|---|
|
Eine Punkt-/Sammlungsliste konnte nicht zugeordnet werden. |
|
Ein ungültiger Parameter wurde erkannt. |
|
Die Anzahl der scatter/gather-Elemente, die zum Behandeln der Transaktion erforderlich waren, war größer als der Wert, den der Aufruf des Treibers für WdfDmaEnablerSetMaximumScatterGatherElements angegeben hat.
Für Transaktionen, die für eine einzelne Übertragung festgelegt wurden, besteht eine Möglichkeit, dies zu beheben, darin, die Daten in einen physisch zusammenhängenden Puffer zu kopieren und dann die Transaktion mit diesem Puffer zu initialisieren. Rufen Sie beispielsweise MmAllocateContiguousMemory auf, kopieren Sie die ursprünglichen Puffer in den neuen, und rufen Sie dann WdfDmaTransactionInitialize erneut auf . |
|
Dieser Rückgabewert gilt nur für Transaktionen, die für eine einzelne Übertragung festgelegt wurden.
Die Anzahl der Kartenregister, die zum Zuordnen der Transaktion erforderlich sind, ist größer als die Vom DMA-Adapter reservierte Zahl. Um dies zu beheben, kann der Treiber die Anzahl der erforderlichen Kartenregister reduzieren, indem er eine MDL-Kette in einer einzelnen MDL kombiniert. Treiber, die Paket- und System-DMA verwenden, können WdfDmaTransactionAllocateResources aufrufen, um eine Anzahl von Kartenregistern aus der Gesamtsumme zu reservieren, die dem Gerät zugeordnet ist. Angenommen, Ihr Treiber hat 4 von insgesamt 8 Kartenregistern reserviert, aber die DMA-Übertragung erfordert 6. In diesem Fall schlägt WdfDmaTransactionInitialize fehl. Rufen Sie zum Beheben von WdfDmaTransactionFreeResources auf, und rufen Sie dann WdfDmaTransactionInitialize erneut auf . Treiber, die scatter/gather DMA verwenden, können keine Kartenregister reservieren. |
|
Dieser Rückgabewert gilt nur für Transaktionen, die für eine einzelne Übertragung festgelegt wurden.
Die Gesamtlänge der Transaktion überschreitet die maximale Übertragungsgröße des Geräts. |
Diese Methode kann auch andere NTSTATUS-Werte zurückgeben.
Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.
Hinweise
Die WdfDmaTransactionInitialize-Methode bereitet einen DMA-Vorgang für die Ausführung vor, indem Initialisierungsvorgänge ausgeführt werden, z. B. die Zuweisung der Scatter/Gather-Liste einer Transaktion. Nachdem Ihr Treiber WdfDmaTransactionInitialize aufgerufen hat, muss der Treiber WdfDmaTransactionExecute aufrufen, um mit der Ausführung der Transaktion zu beginnen.
Frameworkbasierte Treiber rufen in der Regel WdfDmaTransactionInitialize innerhalb einer Rückruffunktion für E/A-Warteschlangenereignisse auf.
Wenn Sie eine DMA-Transaktion erstellen, die auf Informationen basiert, die ein Frameworkanforderungsobjekt enthält, sollte Ihr Treiber WdfDmaTransactionInitializeUsingRequest aufrufen. Wenn Sie eine DMA-Transaktion erstellen, die nicht auf einem Anforderungsobjekt basiert, verwenden Sie entweder WdfDmaTransactionInitialize oder WdfDmaTransactionInitializeUsingOffset.
Der Treiber kann eine MDL-Kette im Mdl-Parameter dieser Methode angeben. Eine MDL-Kette ist eine Sequenz von MDL-Strukturen, die der Treiber mithilfe des Nächsten Elements der MDL-Struktur verkettet hat. In Frameworkversionen vor 1.11 können nur scatter/gather DMA-Übertragungen MDL-Ketten verwenden. Ab Version 1.11 können bei Einzelpaketübertragungen auch verkettete MDLs verwendet werden, wenn der Treiber DMA Version 3 verwendet.
Wenn der Puffer, den der Treiber angibt, größer als die maximale Übertragungslänge ist, die Ihr Treiber beim Aufrufen von WdfDmaEnablerCreate oder WdfDmaTransactionSetMaximumLength angegeben hat, unterbricht das Framework die Transaktion in mehrere Übertragungen.
Weitere Informationen zu DMA-Transaktionen finden Sie unter Erstellen und Initialisieren einer DMA-Transaktion.
Beispiele
Das folgende Codebeispiel stammt aus dem PLX9x5x-Beispieltreiber . Zunächst initialisiert das Beispiel eine WDF_OBJECT_ATTRIBUTES-Struktur und erstellt ein DMA-Transaktionsobjekt. Als Nächstes wird eine MDL abgerufen, die den Eingabepuffer einer empfangenen E/A-Anforderung darstellt, und die virtuelle Adresse und die Länge des Puffers abgerufen. Schließlich ruft das Beispiel WdfDmaTransactionInitialize auf, um die Transaktion zu initialisieren.
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;
}
Anforderungen
Anforderung | Wert |
---|---|
Zielplattform | Universell |
KMDF-Mindestversion | 1.0 |
Kopfzeile | wdfdmatransaction.h (einschließen von Wdf.h) |
Bibliothek | Wdf01000.sys (siehe Versionierung der Frameworkbibliothek.) |
IRQL | <=DISPATCH_LEVEL |
DDI-Complianceregeln | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompletedLocal(kmdf), RequestCompletedLocal(kmdf) |