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
STATUS_INSUFFICIENT_RESOURCES
Eine Punkt-/Sammlungsliste konnte nicht zugeordnet werden.
STATUS_INVALID_PARAMETER
Ein ungültiger Parameter wurde erkannt.
STATUS_WDF_TOO_FRAGMENTED
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 .

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
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.

STATUS_WDF_TOO_MANY_TRANSFERS
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)

Weitere Informationen

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest