Función WdfDmaTransactionExecute (wdfdmatransaction.h)

[Solo se aplica a KMDF]

El método WdfDmaTransactionExecute inicia la ejecución de una transacción DMA especificada.

Sintaxis

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

Parámetros

[in] DmaTransaction

Identificador de un objeto de transacción DMA que el controlador obtuvo de una llamada anterior a WdfDmaTransactionCreate.

[in, optional] Context

Información de contexto definida por el controlador. El marco pasa el valor especificado para Context, que puede ser un puntero, a la función de devolución de llamada de evento EvtProgramDma del controlador. Este parámetro es opcional y puede ser NULL.

Valor devuelto

WdfDmaTransactionExecute devuelve STATUS_SUCCESS si la operación se realiza correctamente. De lo contrario, el método podría devolver uno de los valores siguientes.

Código devuelto Descripción
STATUS_INSUFFICIENT_RESOURCES
El controlador llamado anteriormente WdfDmaTransactionSetImmediateExecution y los recursos necesarios para la solicitud no están disponibles.
STATUS_INVALID_DEVICE_REQUEST
La llamada a WdfDmaTransactionExecute no estaba precedida por una llamada a WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest.
STATUS_WDF_BUSY
El dispositivo realiza transferencias de paquetes únicos y el controlador llamado WdfDmaTransactionExecute mientras se estaba ejecutando otra transacción.
STATUS_WDF_TOO_FRAGMENTED
El número de elementos de dispersión o recopilación que el sistema operativo necesitaba para controlar el tamaño de transferencia especificado era mayor que el valor que especificó la llamada del controlador a WdfDmaEnablerSetMaximumScatterGatherElements . Para obtener más información, vea la sección Comentarios que se muestra más adelante.
 

Este método también podría devolver otros valores NTSTATUS.

Se produce una comprobación de errores si el controlador proporciona un identificador de objeto no válido.

Comentarios

El método WdfDmaTransactionExecute inicializa la lista de dispersión y recopilación de una transacción para la primera transferencia DMA asociada a la transacción DMA especificada. (Para las transferencias de paquetes únicos, la lista de dispersión y recopilación contiene un solo elemento). A continuación, el método llama a la función de devolución de llamada de eventos EvtProgramDma del controlador y la función de devolución de llamada puede programar el dispositivo para iniciar la transferencia.

Normalmente, los controladores basados en marcos llaman a WdfDmaTransactionExecute desde dentro de una función de devolución de llamada de eventos de cola de E/S.

Una vez que un controlador ha llamado a WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest para inicializar una transacción DMA, el controlador debe llamar a WdfDmaTransactionExecute solo una vez antes de completar la transacción DMA.

Si WdfDmaTransactionInitializeXxx devuelve éxito, pero WdfDmaTransactionExecute devuelve un valor de error, el controlador debe llamar a WdfDmaTransactionRelease.

En versiones de marco anteriores a la versión 1.11, si el dispositivo realiza transferencias de paquetes únicos, el sistema operativo solo puede ejecutar una transacción DMA a la vez. En este caso, WdfDmaTransactionExecute devuelve STATUS_WDF_BUSY si se está ejecutando otra transacción.

En las versiones 1.11 y posteriores del marco, si el controlador usa DMA versión 3 para realizar transferencias de paquetes únicos, el sistema operativo puede almacenar varias transacciones DMA en una cola interna. En este caso, el controlador puede llamar a WdfDmaTransactionExecute mientras se ejecuta otra transacción. Para seleccionar DMA versión 3, establezca el miembro WdmDmaVersionOverride de WDF_DMA_ENABLER_CONFIG en 3.

Si el dispositivo realiza transferencias de dispersión y recopilación, el sistema operativo puede ejecutar varias transacciones DMA simultáneamente. En este caso, el controlador puede llamar a WdfDmaTransactionExecute mientras se ejecuta otra transacción.

Si el controlador llama a WdfDmaTransactionDmaCompletedWithLength para notificar una transferencia parcial y si el controlador había especificado el búfer de datos de la transacción DMA mediante MDL que encadenó juntos (mediante el miembro Next de la estructura MDL ), WdfDmaTransactionExecute puede devolver STATUS_WDF_TOO_FRAGMENTED porque el marco podría volver a calcular el número y el tamaño de los fragmentos y podría superar el número de fragmentos permitidos.

WdfDmaTransactionExecute devuelve STATUS_SUCCESS si la transacción se inició correctamente. Para determinar si el marco envió correctamente todas las transferencias de la transacción a la función de devolución de llamada EvtProgramDma del controlador, el controlador debe llamar a WdfDmaTransactionDmaCompleted, WdfDmaTransactionDmaCompletedWithLength o WdfDmaTransactionDmaCompletedFinal.

Si el valor que proporciona el parámetro Context es un puntero o identificador, la memoria a la que hace referencia debe ser accesible en la función de devolución de llamada de eventos EvtProgramDma del controlador en IRQL = DISPATCH_LEVEL. Puede usar el contexto de objeto de marco para cumplir este requisito.

El controlador puede llamar a WdfDmaTransactionExecute de forma no bloqueada si anteriormente se llamó a WdfDmaTransactionSetImmediateExecution.

Para obtener más información sobre las transacciones de DMA, consulte Inicio de una transacción DMA.

Ejemplos

El ejemplo de código siguiente procede del controlador de ejemplo PCIDRV . En este ejemplo se crea e inicializa una transferencia DMA y se inicia su ejecución.

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 Value
Plataforma de destino Universal
Versión mínima de KMDF 1.0
Encabezado wdfdmatransaction.h (incluya Wdf.h)
Library Wdf01000.sys (consulte Control de versiones de la biblioteca de marcos).
IRQL <=DISPATCH_LEVEL
Reglas de cumplimiento de DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

Consulte también

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution