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 |
---|---|
|
O driver anteriormente chamado WdfDmaTransactionSetImmediateExecution e os recursos necessários para a solicitação não estão disponíveis. |
|
A chamada para WdfDmaTransactionExecute não foi precedida por uma chamada para WdfDmaTransactionInitialize ou WdfDmaTransactionInitializeUsingRequest. |
|
O dispositivo executa transferências de pacote único e o driver chamado WdfDmaTransactionExecute enquanto outra transação estava em execução. |
|
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
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength