啟動 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;
}