Iniciando uma transação de DMA
[Aplica-se somente ao KMDF]
Depois que o driver tiver criado e inicializado uma transação de DMA, o driver poderá chamar o método WdfDmaTransactionExecute para iniciar a transação. Esse método cria uma lista de dispersão/coleta para a primeira transferência de DMA associada à transação. Em seguida, o método chama a função de retorno de chamada EvtProgramDma que o driver registrou para a transação. A função de retorno de chamada programa o hardware de DMA para iniciar a transferência.
Antes que o driver chame WdfDmaTransactionExecute, o driver deve armazenar o identificador de transação DMA para que ele possa ser recuperado posteriormente quando o driver concluir cada transferência de DMA associada à transação. Um bom lugar para armazenar o identificador de transação está na memória de contexto de um objeto de estrutura, normalmente o objeto de dispositivo de estrutura do dispositivo. Para obter mais informações sobre como usar a memória de contexto do objeto, consulte Espaço de Contexto do Objeto framework.
O exemplo de código a seguir do exemplo PLX9x5x mostra como inicializar e, em seguida, executar uma transação DMA. Esse código aparece no arquivo Read.c .
VOID PLxEvtIoRead(
IN WDFQUEUE Queue,
IN WDFREQUEST Request,
IN size_t Length
)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
PDEVICE_EXTENSION devExt;
// Get the DevExt from the queue handle
devExt = PLxGetDeviceContext(WdfIoQueueGetDevice(Queue));
do {
// Validate the Length parameter.
if (Length > PCI9656_SRAM_SIZE) {
status = STATUS_INVALID_BUFFER_SIZE;
break;
}
// Initialize the DmaTransaction.
status =
WdfDmaTransactionInitializeUsingRequest(
devExt->ReadDmaTransaction,
Request,
PLxEvtProgramReadDma,
WdfDmaDirectionReadFromDevice
);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Execute this DmaTransaction.
status = WdfDmaTransactionExecute( devExt->ReadDmaTransaction,
WDF_NO_CONTEXT);
if(!NT_SUCCESS(status)) {
. . . //Error-handling code omitted
break;
}
// Indicate that the DMA transaction started successfully.
// The DPC routine will complete the request when the DMA
// transaction is complete.
status = STATUS_SUCCESS;
} while (0);
// If there are errors, clean up and complete the request.
if (!NT_SUCCESS(status )) {
WdfDmaTransactionRelease(devExt->ReadDmaTransaction);
WdfRequestComplete(Request, status);
}
return;
}