啟動 DMA 交易
[僅適用於 KMDF]
在驅動程式 建立並初始化 DMA 交易之後,驅動程式可以呼叫 WdfDmaTransactionExecute 方法來啟動交易。 此方法會為與交易相關聯的第一個 DMA 傳輸 建立散佈/收集清單。 接下來,方法會呼叫驅動程式為交易註冊的 EvtProgramDma 回呼函式。 回呼函式 設定 DMA 硬體 開始傳輸。
在驅動程式呼叫 WdfDmaTransactionExecute之前,驅動程式必須儲存 DMA 交易句柄,以便稍後驅動程式完成與交易相關聯的每個 DMA 傳輸時擷取。 儲存交易句柄的好位置是在架構物件的內容記憶體中,通常是裝置的架構裝置物件。 如需使用物件內容記憶體的詳細資訊,請參閱 Framework 物件內容空間。
下列來自 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;
}