Compartilhar via


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