Compartir a través de


Iniciar una transacción DMA

[Solo se aplica a KMDF]

Una vez que el controlador haya creado e inicializado una transacción DMA, el controlador puede llamar al método WdfDmaTransactionExecute para iniciar la transacción. Este método crea una lista de dispersión y recopilación para la primera transferencia DMA asociada a la transacción. A continuación, el método llama a la función de devolución de llamada EvtProgramDma que el controlador registró para la transacción. La función de devolución de llamada programa el hardware DMA para iniciar la transferencia.

Antes de que el controlador llame a WdfDmaTransactionExecute, el controlador debe almacenar el identificador de transacción DMA para que se pueda recuperar más adelante cuando el controlador complete cada transferencia DMA asociada a la transacción. Un buen lugar para almacenar el identificador de transacción se encuentra en la memoria contextual de un objeto de marco, normalmente el objeto de dispositivo de marco del dispositivo. Para obtener más información sobre el uso de la memoria de contexto de objetos, vea Espacio de contexto de objeto de marco.

En el ejemplo de código siguiente del ejemplo PLX9x5x se muestra cómo inicializar y, a continuación, ejecutar una transacción DMA. Este código aparece en el archivo 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;
}