Función WdfDmaTransactionInitialize (wdfdmatransaction.h)
[Solo se aplica a KMDF]
El método WdfDmaTransactionInitialize inicializa una transacción DMA especificada.
Sintaxis
NTSTATUS WdfDmaTransactionInitialize(
[in] WDFDMATRANSACTION DmaTransaction,
[in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
[in] WDF_DMA_DIRECTION DmaDirection,
[in] PMDL Mdl,
[in] PVOID VirtualAddress,
[in] size_t Length
);
Parámetros
[in] DmaTransaction
Identificador de un objeto de transacción DMA que el controlador obtuvo de una llamada anterior a WdfDmaTransactionCreate.
[in] EvtProgramDmaFunction
Puntero a la función de devolución de llamada de eventos EvtProgramDma del controlador.
[in] DmaDirection
Valor con tipo WDF_DMA_DIRECTION.
[in] Mdl
Puntero a una lista de descriptores de memoria (MDL) que describe el búfer que se usará para la transacción DMA. Vea más información en Comentarios.
[in] VirtualAddress
Dirección virtual del búfer que se usará para la transacción DMA.
[in] Length
Número de bytes que se van a transferir.
Valor devuelto
WdfDmaTransactionInitialize 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 |
---|---|
|
No se pudo asignar una lista de dispersión o recopilación. |
|
Se ha detectado un parámetro no válido. |
|
El número de elementos de dispersión y recopilación necesarios para controlar la transacción era mayor que el valor que especificó la llamada del controlador a WdfDmaEnablerSetMaximumScatterGatherElements .
Para las transacciones que se establecieron para una sola transferencia, una manera de corregir esto es copiar los datos en un búfer físico contiguo y, a continuación, inicializar la transacción con ese búfer. Por ejemplo, llame a MmAllocateContiguousMemory, copie los búferes originales en el nuevo y, a continuación, vuelva a llamar a WdfDmaTransactionInitialize . |
|
Este valor devuelto solo se aplica a las transacciones que se establecieron para una única transferencia.
El número de registros de mapa necesarios para asignar la transacción es mayor que el número que el adaptador DMA ha reservado. Para corregirlo, el controlador puede reducir el número de registros de mapa necesarios mediante la combinación de una cadena MDL en una sola MDL. Los controladores que usan paquetes y DMA del sistema pueden llamar a WdfDmaTransactionAllocateResources para reservar un número de registros de mapa del total asignado al dispositivo. Supongamos que el controlador reservó 4 de 8 registros totales de mapa, pero la transferencia DMA requiere 6. En este caso, WdfDmaTransactionInitialize produce un error. Para corregirlo, llame a WdfDmaTransactionFreeResources y, a continuación, vuelva a llamar a WdfDmaTransactionInitialize . Los controladores que usan DMA de dispersión y recopilación no pueden reservar registros de mapa. |
|
Este valor devuelto solo se aplica a las transacciones que se establecieron para una única transferencia.
La longitud total de la transacción supera el tamaño máximo de transferencia del dispositivo. |
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 WdfDmaTransactionInitialize prepara una operación DMA para su ejecución mediante la realización de operaciones de inicialización, como asignar la lista de dispersión y recopilación de una transacción. Después de que el controlador llame a WdfDmaTransactionInitialize, el controlador debe llamar a WdfDmaTransactionExecute para empezar a ejecutar la transacción.
Normalmente, los controladores basados en marcos llaman a WdfDmaTransactionInitialize desde dentro de una función de devolución de llamada de eventos de cola de E/S.
Si va a crear una transacción DMA basada en información que contiene un objeto de solicitud de marco, el controlador debe llamar a WdfDmaTransactionInitializeUsingRequest. Si va a crear una transacción DMA que no se basa en un objeto de solicitud, use WdfDmaTransactionInitialize o WdfDmaTransactionInitializeUsingOffset.
El controlador puede especificar una cadena MDL en el parámetro Mdl de este método. Una cadena MDL es una secuencia de estructuras MDL que el controlador encadenó mediante el miembro Next de la estructura MDL. En las versiones de marco anteriores a la versión 1.11, solo las transferencias DMA de dispersión y recopilación pueden usar cadenas MDL. A partir de la versión 1.11, si el controlador usa la versión 3 de DMA, las transferencias de paquetes únicos también pueden usar MDL encadenadas.
Si el búfer que especifica el controlador es mayor que la longitud máxima de transferencia que el controlador especificó cuando llamó a WdfDmaEnablerCreate o WdfDmaTransactionSetMaximumLength, el marco divide la transacción en varias transferencias.
Para obtener más información sobre las transacciones de DMA, consulte Creación e inicialización de una transacción DMA.
Ejemplos
El ejemplo de código siguiente procede del controlador de ejemplo PLX9x5x . En primer lugar, el ejemplo inicializa una estructura de WDF_OBJECT_ATTRIBUTES y crea un objeto de transacción DMA. A continuación, obtiene una MDL que representa el búfer de entrada de una solicitud de E/S recibida y obtiene la dirección virtual y la longitud del búfer. Por último, el ejemplo llama a WdfDmaTransactionInitialize para inicializar la transacción.
WDF_OBJECT_ATTRIBUTES attributes;
PMDL mdl;
PVOID virtualAddress;
ULONG length;
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
&attributes,
TRANSACTION_CONTEXT
);
status = WdfDmaTransactionCreate(
devExt->DmaEnabler,
&attributes,
&dmaTransaction
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
status = WdfRequestRetrieveInputWdmMdl(
Request,
&mdl
);
if (!NT_SUCCESS(status)) {
goto CleanUp;
}
virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);
status = WdfDmaTransactionInitialize(
dmaTransaction,
PLxEvtProgramWriteDma,
WdfDmaDirectionWriteToDevice,
mdl,
virtualAddress,
length
);
if(!NT_SUCCESS(status)) {
goto CleanUp;
}
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 | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf), MdlAfterReqCompletedIntIoctlA(kmdf), MdlAfterReqCompletedIoctlA(kmdf), MdlAfterReqCompletedReadA(kmdf), MdlAfterReqCompletedWriteA(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |