WdfDmaTransactionDmaCompleted-Funktion (wdfdmatransaction.h)

[Gilt nur für KMDF]

Die WdfDmaTransactionDmaCompleted-Methode benachrichtigt das Framework, dass der DMA-Übertragungsvorgang eines Geräts abgeschlossen ist.

Syntax

BOOLEAN WdfDmaTransactionDmaCompleted(
  [in]  WDFDMATRANSACTION DmaTransaction,
  [out] NTSTATUS          *Status
);

Parameter

[in] DmaTransaction

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

[out] Status

Ein Zeiger auf eine Position, die die status der DMA-Übertragung empfängt. Weitere Informationen finden Sie im folgenden Abschnitt "Hinweise".

Rückgabewert

WdfDmaTransactionDmaCompleted gibt FALSE zurück, und Status empfängt STATUS_MORE_PROCESSING_REQUIRED, wenn zusätzliche Übertragungen erforderlich sind, um die DMA-Transaktion abzuschließen. Die Methode gibt TRUE zurück, wenn keine zusätzlichen Übertragungen erforderlich sind.

Eine Fehlerüberprüfung tritt auf, wenn der Treiber ein ungültiges Objekthandle bereitstellt.

Hinweise

Frameworkbasierte Treiber müssen eine der folgenden Methoden aufrufen, wenn eine DMA-Übertragung abgeschlossen ist:

In der Regel rufen Treiber diese Methoden innerhalb einer EvtInterruptDpc-Ereignisrückruffunktion auf, nachdem ein Geräteunterbrechung den Abschluss eines DMA-Übertragungsvorgangs anzeigt. Ein Treiber für ein DMA-Gerät im Systemmodus kann diese Methoden aus einer EvtDmaTransactionDmaTransferComplete-Ereignisrückruffunktion aufrufen.

Das Framework kann eine DMA-Transaktion in mehrere DMA-Übertragungsvorgänge unterteilen. Daher muss der Treiber den Rückgabewert der Methode untersuchen, um zu ermitteln, ob zusätzliche Übertragungen erforderlich sind.

Wenn die Methode FALSE zurückgibt, empfängt der Statusspeicherort STATUS_MORE_PROCESSING_REQUIRED und zusätzliche DMA-Vorgänge sind erforderlich, um die Transaktion abzuschließen. In der Regel macht die EvtInterruptDpc-Ereignisrückruffunktion an diesem Punkt nichts anderes. Stattdessen ruft das Framework die EvtProgramDma-Ereignisrückruffunktion des Treibers auf, damit die Rückruffunktion die nächste Übertragung starten kann.

Wenn die Methode TRUE zurückgibt, werden für die angegebene Transaktion keine weiteren Übertragungen mehr durchgeführt. In diesem Fall bedeutet der Statuswert STATUS_SUCCESS, dass für das Framework keine Fehler aufgetreten sind und die DMA-Transaktion abgeschlossen ist.

Wenn der Treiber WdfDmaTransactionStopSystemTransferaufruft, bevor WdfDmaTransactionDmaCompleted aufgerufen wird, gibt WdfDmaTransactionDmaCompletedTRUE und den StatuswertSTATUS_CANCELLED zurück.

Für Transaktionen, die für eine einzelne Übertragung festgelegt wurden, gibt WdfDmaTransactionDmaCompletedTRUE und den StatuswertSTATUS_WDF_TOO_MANY_TRANSFERS zurück, wenn die Hardware die Transaktion nicht in einer einzigen Übertragung abschließen kann, obwohl die Initialisierung erfolgreich war. Dies kann bei Hardware passieren, die Restübertragungen für jeden DMA-Vorgang meldet. Beispielsweise programmiert der Treiber das Gerät so, dass es 64 KB schreibt, aber das Gerät schreibt nur 60 KB. In diesem Fall kann der Treiber den DMA-Vorgang wiederholen oder das Gerät zurücksetzen.

Jeder andere Wert für Status bedeutet, dass das Framework einen Fehler erkannt hat und die DMA-Transaktion möglicherweise nicht abgeschlossen wurde.

Wenn WdfDmaTransactionDmaCompletedTRUE zurückgibt, führt der Treiber in der Regel folgendes aus:

Weitere Informationen zum Abschließen von DMA-Übertragungen finden Sie unter Abschließen einer DMA-Übertragung.

Beispiele

Das folgende Codebeispiel stammt aus dem AMCC5933 Beispieltreiber. Dieses Beispiel zeigt eine EvtInterruptDpc-Rückruffunktion . Im Beispiel wird das Framework benachrichtigt, dass eine DMA-Übertragung abgeschlossen wurde. Wenn das Framework angibt, dass diese Übertragung die letzte für die DMA-Transaktion ist, löscht der Code das DMA-Transaktionsobjekt und schließt die zugeordnete E/A-Anforderung ab.

VOID
AmccPciEvtInterruptDpc(
    IN WDFINTERRUPT  WdfInterrupt,
    IN WDFOBJECT  WdfDevice
    )
{
    PAMCC_DEVICE_EXTENSION  devExt;
    WDFREQUEST  request;
    REQUEST_CONTEXT  *transfer;
    NTSTATUS  status;
    size_t  transferred;
    BOOLEAN  transactionComplete;

    UNREFERENCED_PARAMETER( WdfInterrupt );

    //
    // Retrieve request and transfer.
    //
    devExt = AmccPciGetDevExt(WdfDevice);
    request  = devExt->CurrentRequest;
    transfer = GetRequestContext(request);

    //
    // Check to see if the request has been canceled. 
    //
    if (WdfRequestIsCanceled(request)) {
        TraceEvents(
                    TRACE_LEVEL_ERROR,
                    AMCC_TRACE_IO,
                    "Aborted DMA transaction 0x%p",
                    request
                    );
        WdfObjectDelete( transfer->DmaTransaction );
        devExt->CurrentRequest = NULL;
        WdfRequestComplete(
                           request,
                           STATUS_CANCELLED
                           );
        return;
    }
 
    //
    // Notify the framework that a DMA transfer has completed.
    //
    transactionComplete = WdfDmaTransactionDmaCompleted(
                                                    transfer->DmaTransaction,
                                                    &status
                                                    );
    if (transactionComplete) {
        ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);

        //
        // No more data. The request is complete.
        //
        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Request %p completed: status %X",  
                    request,
                    status
                    );

        //
        // Get the byte count.
        //
        transferred =
                WdfDmaTransactionGetBytesTransferred(transfer->DmaTransaction);

        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Bytes transferred %d",
                    (int) transferred
                    );

        //
        // Delete this DmaTransaction object.
        //
        WdfObjectDelete(transfer->DmaTransaction);

        //
        // Clean up the device context for this request.
        //
        devExt->CurrentRequest = NULL;

        //
        // Complete this I/O request.
        //
        WdfRequestCompleteWithInformation(
                                          request, 
                                          status,
                                          (NT_SUCCESS(status)) ? transferred : 0
                                          );
    }
}

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 DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Weitere Informationen

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation