Compartilhar via


Função WdfDmaTransactionExecute (wdfdmatransaction.h)

[Aplica-se somente ao KMDF]

O método WdfDmaTransactionExecute inicia a execução de uma transação de DMA especificada.

Sintaxe

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

Parâmetros

[in] DmaTransaction

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

[in, optional] Context

Informações de contexto definidas pelo driver. A estrutura passa o valor especificado para Context, que pode ser um ponteiro, para a função de retorno de chamada de evento EvtProgramDma do driver. Esse parâmetro é opcional e pode ser NULL.

Retornar valor

WdfDmaTransactionExecute retornará STATUS_SUCCESS se a operação for bem-sucedida. Caso contrário, o método pode retornar um dos valores a seguir.

Código de retorno Descrição
STATUS_INSUFFICIENT_RESOURCES
O driver anteriormente chamado WdfDmaTransactionSetImmediateExecution e os recursos necessários para a solicitação não estão disponíveis.
STATUS_INVALID_DEVICE_REQUEST
A chamada para WdfDmaTransactionExecute não foi precedida por uma chamada para WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingRequest.
STATUS_WDF_BUSY
O dispositivo executa transferências de pacote único e o driver chamado WdfDmaTransactionExecute enquanto outra transação estava em execução.
STATUS_WDF_TOO_FRAGMENTED
O número de elementos de dispersão/coleta que o sistema operacional precisava para lidar com o tamanho de transferência especificado foi maior do que o valor que a chamada do driver para WdfDmaEnablerSetMaximumScatterGatherElements especificou. Para obter mais informações, consulte a seção Comentários a seguir.
 

Esse método também pode retornar outros valores NTSTATUS.

Um bug marcar ocorrerá se o driver fornecer um identificador de objeto inválido.

Comentários

O método WdfDmaTransactionExecute inicializa a lista de dispersão/coleta de uma transação para a primeira transferência de DMA associada à transação de DMA especificada. (Para transferências de pacote único, a lista de dispersão/coleta contém um único elemento.) Em seguida, o método chama a função de retorno de chamada de evento EvtProgramDma do driver e a função de retorno de chamada pode programar o dispositivo para iniciar a transferência.

Drivers baseados em estrutura normalmente chamam WdfDmaTransactionExecute de dentro de uma função de retorno de chamada de evento de fila de E/S.

Depois que um driver tiver chamado WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingRequest para inicializar uma transação de DMA, o driver deverá chamar WdfDmaTransactionExecute apenas uma vez antes de concluir a transação de DMA.

Se WdfDmaTransactionInitializeXxx retornar êxito, mas WdfDmaTransactionExecute retornar um valor de erro, o driver deverá chamar WdfDmaTransactionRelease.

Em versões de estrutura anteriores à 1.11, se o dispositivo executar transferências de pacote único, o sistema operacional poderá executar apenas uma transação de AMD por vez. Nesse caso, WdfDmaTransactionExecute retornará STATUS_WDF_BUSY se outra transação estiver em execução.

Nas versões de estrutura 1.11 e posteriores, se o driver usar o DMA versão 3 para executar transferências de pacote único, o sistema operacional poderá armazenar várias transações de DMA em uma fila interna. Nesse caso, o driver pode chamar WdfDmaTransactionExecute enquanto outra transação está em execução. Para selecionar o DMA versão 3, defina o membro WdmDmaVersionOverride de WDF_DMA_ENABLER_CONFIG como 3.

Se o dispositivo executar transferências de dispersão/coleta, o sistema operacional poderá executar várias transações de DMA simultaneamente. Nesse caso, o driver pode chamar WdfDmaTransactionExecute enquanto outra transação está em execução.

Se o driver chamar WdfDmaTransactionDmaCompletedWithLength para relatar uma transferência parcial, e se o driver tiver especificado o buffer de dados da transação DMA usando MDLs encadeados (usando o membro Next da estrutura MDL ), WdfDmaTransactionExecute poderá retornar STATUS_WDF_TOO_FRAGMENTED porque a estrutura pode recalcular o número e o tamanho dos fragmentos e pode exceder o número de fragmentos permitidos.

O WdfDmaTransactionExecute retornará STATUS_SUCCESS se a transação tiver sido iniciada com êxito. Para determinar se a estrutura enviou com êxito todas as transferências da transação para a função de retorno de chamada EvtProgramDma do driver, o driver deve chamar WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength ou WdfDmaTransactionDmaCompletedFinal.

Se o valor fornecido pelo parâmetro Context for um ponteiro ou identificador, a memória referenciada por ele deverá estar acessível na função de retorno de chamada de evento EvtProgramDma do driver em IRQL = DISPATCH_LEVEL. Você pode usar o contexto de objeto de estrutura para atender a esse requisito.

O driver poderá chamar WdfDmaTransactionExecute de maneira não bloqueada se tiver chamado WdfDmaTransactionSetImmediateExecution anteriormente.

Para obter mais informações sobre transações de DMA, consulte Iniciando uma transação de DMA.

Exemplos

O exemplo de código a seguir é do driver de exemplo PCIDRV . Este exemplo cria e inicializa uma transferência de AMD e inicia sua execução.

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

Requisitos

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

Confira também

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution