Запуск транзакции DMA
[Применяется только к KMDF]
После создания и инициализации транзакции DMA драйвер может вызвать метод WdfDmaTransactionExecute , чтобы запустить транзакцию. Этот метод создает точечный или собираемый список для первой передачи DMA , связанной с транзакцией. Затем метод вызывает функцию обратного вызова EvtProgramDma , зарегистрированную драйвером для транзакции. Функция обратного вызова программировать оборудование DMA , чтобы начать передачу.
Прежде чем драйвер вызовет WdfDmaTransactionExecute, драйвер должен сохранить дескриптор транзакции DMA, чтобы его можно было получить позже после завершения каждой передачи DMA, связанной с транзакцией. Лучше всего хранить дескриптор транзакций в контекстной памяти объекта платформы, обычно это объект устройства платформы. Дополнительные сведения об использовании памяти контекста объекта см. в разделе Пространство контекста объектов платформы.
В следующем примере кода из примера PLX9x5x показано, как инициализировать и затем выполнить транзакцию DMA. Этот код отображается в файле 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;
}