Partilhar via


Função WdfDmaTransactionDmaCompleted (wdfdmatransaction.h)

[Aplica-se somente ao KMDF]

O método WdfDmaTransactionDmaCompleted notifica a estrutura de que a operação de transferência de DMA de um dispositivo foi concluída.

Sintaxe

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

Parâmetros

[in] DmaTransaction

Um identificador para um objeto de transação DMA que o driver obteve de uma chamada anterior para WdfDmaTransactionCreate.

[out] Status

Um ponteiro para um local que recebe o status da transferência de DMA. Para obter mais informações, consulte a seção Comentários a seguir.

Valor de retorno

WdfDmaTransactionDmaCompleted retorna FALSE e Status recebe STATUS_MORE_PROCESSING_REQUIRED se forem necessárias transferências adicionais para concluir a transação de DMA. O método retorna VERDADEIRO se nenhuma transferência adicional for necessária.

Uma verificação de bug ocorre se o driver fornece um identificador de objeto inválido.

Observações

Os drivers baseados em estrutura devem chamar um dos seguintes métodos sempre que um de transferência de DMA for concluído:

  • WdfDmaTransactionDmaCompleted
  • WdfDmaTransactionDmaCompletedWithLength

  • WdfDmaTransactionDmaCompletedFinal

Normalmente, os drivers chamam esses métodos de dentro de um função de retorno de chamada de evento EvtInterruptDpc, após uma interrupção do dispositivo indicar a conclusão de uma operação de transferência de DMA. Um driver para um dispositivo DMA no modo sistema pode chamar esses métodos de dentro de um EvtDmaTransactionDmaTransferComplete função de retorno de chamada de evento.

A estrutura pode dividir uma transação de DMA em várias operações de transferência de DMA. Portanto, o driver deve examinar o valor retornado do método para determinar se transferências adicionais são necessárias.

Se o método retornar FALSE, o status local receberá STATUS_MORE_PROCESSING_REQUIRED e operações de DMA adicionais serão necessárias para concluir a transação. Normalmente, a função de retorno de chamada de evento EvtInterruptDpc não faz mais nada neste momento. Em vez disso, a estrutura chama a função de retorno de chamada EvtProgramDma do driver, para que a função de retorno de chamada possa iniciar a próxima transferência.

Se o método retornar TRUE, não ocorrerão mais transferências para a transação especificada. Nesse caso, um Status valor de STATUS_SUCCESS significa que a estrutura não encontrou erros e a transação DMA está concluída.

Se o driver chamar WdfDmaTransactionStopSystemTransfer antes de chamar WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompleted retornará TRUE e um status valor de STATUS_CANCELLED.

Para transações que foram definidas para de transferência única, WdfDmaTransactionDmaCompleted retorna TRUE e um Status valor de STATUS_WDF_TOO_MANY_TRANSFERS se o hardware não concluir a transação em uma única transferência, mesmo que a inicialização tenha sido bem-sucedida. Isso pode acontecer para hardware que relata transferências residuais para cada operação de DMA. Por exemplo, o driver programa o dispositivo para gravar 64 KB, mas o dispositivo grava apenas 60 KB. Nesse caso, o driver pode repetir a operação de DMA ou redefinir o dispositivo.

Qualquer outro valor para Status significa que a estrutura detectou um erro e a transação DMA pode não ter sido concluída.

Quando WdfDmaTransactionDmaCompleted retorna TRUE, o driver normalmente faz o seguinte:

  • Chama WdfObjectDelete ou WdfDmaTransactionRelease para excluir ou reutilizar o objeto de transação, respectivamente.
  • Conclui a solicitação de E/S, se a transação de DMA estiver associada a uma solicitação de E/S. (Os drivers completam solicitações chamando WdfRequestComplete ou WdfRequestCompleteWithInformation.)
Para obter mais informações sobre como concluir transferências de DMA, consulte Concluir umde Transferência de DMA.

Exemplos

O exemplo de código a seguir é do driver de exemplo AMCC5933. Este exemplo mostra uma função de retorno de chamada EvtInterruptDpc. O exemplo notifica a estrutura que uma transferência de DMA concluiu. Se a estrutura indicar que essa transferência é a última para a transação de DMA, o código exclui o objeto de transação DMA e conclui a solicitação de E/S associada.

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

Requisitos

Requisito Valor
da Plataforma de Destino Universal
versão mínima do KMDF 1.0
cabeçalho wdfdmatransaction.h (inclua Wdf.h)
Biblioteca Wdf01000.sys (consulte o Controle de Versão da Biblioteca da Estrutura.)
IRQL <=DISPATCH_LEVEL
regras de conformidade de DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Consulte também

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation