Freigeben über


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

Die Parameter

[in] DmaTransaction

Ein Handle für ein DMA-Transaktionsobjekt, das der Treiber aus einem vorherigen Aufruf von WdfDmaTransactionCreateabgerufen hat.

[in] EvtProgramDmaFunction

Ein Zeiger auf die EvtProgramDma Ereignisrückruffunktion des Treibers.

[in] DmaDirection

Ein WDF_DMA_DIRECTION-typed-Wert.

[in] Mdl

Ein Zeiger auf eine Speicherdeskriptorliste (MDL), die den Puffer beschreibt, der für die DMA-Transaktion verwendet wird. Weitere Informationen finden Sie in Anmerkungen.

[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-/Sammelliste konnte nicht zugeordnet werden.
STATUS_INVALID_PARAMETER
Ein ungültiger Parameter wurde erkannt.
STATUS_WDF_TOO_FRAGMENTED
Die Anzahl der XY/Gather-Elemente, die zum Behandeln der Transaktion erforderlich waren, war größer als der Wert, den der Aufruf des Treibers an WdfDmaEnablerSetMaximumScatterGatherElements angegeben.

Bei Transaktionen, die für einzelne Übertragungfestgelegt wurden, besteht eine Möglichkeit zum Beheben dieses Problems darin, die Daten in einen physisch zusammenhängenden Puffer zu kopieren und dann die Transaktion mit diesem Puffer zu initialisieren. Rufen Sie beispielsweise MmAllocateContiguousMemoryauf, kopieren Sie die ursprünglichen Puffer in die neue, und rufen Sie dann WdfDmaTransactionInitialize erneut auf.

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
Dieser Rückgabewert gilt nur für Transaktionen, die für einzelne Übertragungfestgelegt wurden.

Die Anzahl der Kartenregister, die zum Zuordnen der Transaktion erforderlich sind, ist größer als die Zahl, die der DMA-Adapter reserviert hat.

Zur Behebung kann der Treiber die Anzahl der erforderlichen Kartenregister reduzieren, indem eine MDL-Kette in eine einzelne MDL kombiniert wird.

Treiber, die Paket- und System-DMA verwenden, können WdfDmaTransactionAllocateResources- aufrufen, um eine Reihe von Kartenregistern aus der Gesamtsumme zu reservieren, die dem Gerät zugeordnet ist. Angenommen, Ihr Treiber reservierte 4 von 8 Gesamtkartenregistern, aber die DMA-Übertragung erfordert 6. In diesem Fall schlägt WdfDmaTransactionInitialize fehl. Rufen Sie zum Beheben WdfDmaTransactionFreeResources auf, und rufen Sie dann WdfDmaTransactionInitialize erneut auf.

Treiber, die XY/Gather-DMA verwenden, können keine Kartenregister reservieren.

STATUS_WDF_TOO_MANY_TRANSFERS
Dieser Rückgabewert gilt nur für Transaktionen, die für einzelne Übertragungfestgelegt wurden.

Die Gesamtlänge der Transaktion überschreitet die maximale Übertragungsgröße des Geräts.

 

Diese Methode kann auch andere NTSTATUS-Wertezurückgeben.

Wenn der Treiber ein ungültiges Objekthandle bereitstellt, tritt eine Fehlerüberprüfung auf.

Bemerkungen

Die WdfDmaTransactionInitialize Methode bereitet einen DMA-Vorgang für die Ausführung vor, indem Initialisierungsvorgänge wie das Zuordnen der Punkt/Gather-Liste einer Transaktion ausgeführt werden. Nachdem Ihr Treiber WdfDmaTransactionInitializeaufgerufen hat, muss der Treiber WdfDmaTransactionExecute- aufrufen, um mit der Ausführung der Transaktion zu beginnen.

Frameworkbasierte Treiber rufen in der Regel WdfDmaTransactionInitialize aus einer E/A-Ereignisrückruffunktionauf.

Wenn Sie eine DMA-Transaktion erstellen, die auf Informationen basiert, die ein Framework-Anforderungsobjekt enthält, sollte Ihr Treiber WdfDmaTransactionInitializeUsingRequestaufrufen. 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 Next Member der MDL-Struktur verkettet hat. In Frameworkversionen vor 1.11 können nur X/Gather-DMA-Übertragungen MDL-Ketten verwenden. Ab Version 1.11 können verkettete MDLs auch 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 der Treiber beim Aufrufen WdfDmaEnablerCreate oder WdfDmaTransactionSetMaximumLength-angegeben hat, bricht das Framework die Transaktion in mehrere Übertragungenum.

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 Länge des Puffers abruft. 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
Minimale KMDF-Version 1.0
Kopfzeile wdfdmatransaction.h (include Wdf.h)
Bibliothek Wdf01000.sys (siehe Framework-Bibliotheksversionsverwaltung.)
IRQL <=DISPATCH_LEVEL
DDI-Complianceregeln DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf)MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf)

Siehe auch

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest