Condividi tramite


Funzione WdfDmaTransactionDmaCompleted (wdfdmatransaction.h)

[Si applica solo a KMDF]

Il metodo WdfDmaTransactionDmaCompleted notifica al framework che l'operazione di trasferimento DMA di un dispositivo viene completata.

Sintassi

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

Parametri

[in] DmaTransaction

Handle a un oggetto transazione DMA ottenuto dal driver da una chiamata precedente a WdfDmaTransactionCreate.

[out] Status

Puntatore a una posizione che riceve lo stato del trasferimento DMA. Per ulteriori informazioni, vedere la sezione Osservazioni successiva.

Valore restituito

WdfDmaTransactionDmaCompleted restituisce FALSE e Status riceve STATUS_MORE_PROCESSING_REQUIRED se sono necessari trasferimenti aggiuntivi per completare la transazione DMA. Il metodo restituisce TRUE se non sono necessari trasferimenti aggiuntivi.

Un controllo di bug si verifica se il driver fornisce un handle di oggetti non valido.

Commenti

I driver basati su framework devono chiamare uno dei metodi seguenti ogni volta che viene completato un trasferimento DMA :

In genere, i driver chiamano questi metodi dall'interno di una funzione di callback degli eventi EvtInterruptDpc , dopo un interruzione del dispositivo indica il completamento di un'operazione di trasferimento DMA. Un driver per un dispositivo DMA in modalità sistema potrebbe chiamare questi metodi da una funzione di callback dell'evento EvtDmaTransactionDmaTransferComplete .

Il framework potrebbe dividere una transazione DMA in diverse operazioni di trasferimento DMA. Pertanto, il driver deve esaminare il valore restituito del metodo per determinare se sono necessari trasferimenti aggiuntivi.

Se il metodo restituisce FALSE, la posizione status riceve STATUS_MORE_PROCESSING_REQUIRED e sono necessarie operazioni DMA aggiuntive per completare la transazione. In genere, la funzione di callback dell'evento EvtInterruptDpc non fa altro a questo punto. Il framework chiama invece la funzione di callback dell'evento EvtProgramDma del driver, in modo che la funzione di callback possa iniziare il trasferimento successivo.

Se il metodo restituisce TRUE, non si verificheranno più trasferimenti per la transazione specificata. In questo caso, un valore Stato di STATUS_SUCCESS significa che il framework non ha rilevato errori e la transazione DMA è stata completata.

Se il driver chiama WdfDmaTransactionStopSystemTransfer prima di chiamare WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted restituisce TRUE e un valore Status di STATUS_CANCELLED.

Per le transazioni impostate per il trasferimento singolo, WdfDmaTransactionDmaCompleted restituisce TRUE e un valore Status di STATUS_WDF_TOO_MANY_TRANSFERS se l'hardware non riesce a completare la transazione in un singolo trasferimento, anche se l'inizializzazione ha avuto esito positivo. Ciò potrebbe verificarsi per l'hardware che segnala i trasferimenti residui per ogni operazione DMA. Ad esempio, il driver programma il dispositivo per scrivere 64 KB, ma il dispositivo scrive solo 60 KB. In questo caso, il driver potrebbe ripetere l'operazione DMA o reimpostare il dispositivo.

Qualsiasi altro valore per Stato indica che il framework ha rilevato un errore e la transazione DMA potrebbe non essere stata completata.

Quando WdfDmaTransactionDmaCompleted restituisce TRUE, il driver esegue in genere le operazioni seguenti:

Per altre informazioni sul completamento dei trasferimenti DMA, vedere Completamento di un trasferimento DMA.

Esempio

L'esempio di codice seguente proviene dal driver di esempio AMCC5933 . Questo esempio mostra una funzione di callback EvtInterruptDpc . L'esempio notifica al framework che è stato completato il trasferimento DMA. Se il framework indica che questo trasferimento è l'ultimo per la transazione DMA, il codice elimina l'oggetto transazione DMA e completa la richiesta di I/O associata.

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

Requisiti

Requisito Valore
Piattaforma di destinazione Universale
Versione KMDF minima 1,0
Intestazione wdfdmatransaction.h (include Wdf.h)
Libreria Wdf01000.sys (vedere Framework Library Versioning).
IRQL <=DISPATCH_LEVEL
Regole di conformità DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Vedi anche

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation