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 |
---|---|
|
El controlador llamado anteriormente WdfDmaTransactionSetImmediateExecution y los recursos necesarios para la solicitud no están disponibles. |
|
La llamada a WdfDmaTransactionExecute no estaba precedida por una llamada a WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingRequest. |
|
El dispositivo realiza transferencias de paquetes únicos y el controlador llamado WdfDmaTransactionExecute mientras se estaba ejecutando otra transacción. |
|
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
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength