Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Применимо только к KMDF]
После создания и инициализации транзакции DMA драйвер может вызвать метод WdfDmaTransactionExecute для запуска транзакции. Этот метод создает список scatter/gather для первой передачи 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;
}