WdfDmaTransactionExecute 函式 (wdfdmatransaction.h)

[僅適用於 KMDF]

WdfDmaTransactionExecute 方法會開始執行指定的 DMA 交易。

語法

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

參數

[in] DmaTransaction

驅動程式從先前呼叫 WdfDmaTransactionCreate 取得的 DMA 交易物件的句柄。

[in, optional] Context

驅動程式定義的內容資訊。 架構會將針對 Context 指定的值傳遞至驅動程式的 EvtProgramDma 事件回呼函式,可以是指針。 此參數是選擇性的,可以是 NULL

傳回值

如果作業成功,WdfDmaTransactionExecute 會傳回STATUS_SUCCESS。 否則,方法可能會傳回下列其中一個值。

傳回碼 Description
STATUS_INSUFFICIENT_RESOURCES
先前稱為 WdfDmaTransactionSetImmediateExecution 的驅動程式和要求所需的資源無法使用。
STATUS_INVALID_DEVICE_REQUEST
對 WdfDmaTransactionExecute 的呼叫之前沒有呼叫 WdfDmaTransactionInitializeWdfDmaTransactionInitializeUsingRequest
STATUS_WDF_BUSY
裝置會執行單一封包傳輸,並在另一筆交易執行時呼叫 WdfDmaTransactionExecute 的驅動程式。
STATUS_WDF_TOO_FRAGMENTED
操作系統處理指定傳輸大小所需的散佈/收集元素數目大於驅動程式呼叫 WdfDmaEnablerSetMaximumScatterGatherElements 的值。 如需詳細資訊,請參閱接下來的<備註>一節。
 

這個方法也可能傳回其他 NTSTATUS值

如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。

備註

WdfDmaTransactionExecute 方法會針對與指定的 DMA 交易相關聯的第一個 DMA 傳輸,初始化交易的散佈/收集清單。 (針對單一封包傳輸,散佈/收集清單包含單一元素。) 然後,方法會呼叫驅動程式的 EvtProgramDma 事件回呼函式,而回呼函式可以程式設計裝置以開始傳輸。

架構型驅動程式通常會從 I/O 佇列事件回呼函式內呼叫 WdfDmaTransactionExecute

在驅動程式呼叫 WdfDmaTransactionInitializeWdfDmaTransactionInitializeUsingRequest 以初始化 DMA 交易之後,驅動程式必須先呼叫 WdfDmaTransactionExecute 一次,才能 完成 DMA 交易

如果 WdfDmaTransactionInitializeXxx 傳回成功,但 WdfDmaTransactionExecute 會傳回錯誤值,您的驅動程式必須呼叫 WdfDmaTransactionRelease

在 1.11 之前的架構版本中,如果裝置執行單一封包傳輸,操作系統一次只能執行一個 DMA 交易。 在此情況下,如果另一個交易正在執行, WdfDmaTransactionExecute 會傳回STATUS_WDF_BUSY。

在架構 1.11 版和更新版本中,如果驅動程式使用 DMA 第 3 版來執行單一封包傳輸,操作系統可以將多個 DMA 交易儲存在內部佇列中。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute 。 若要選取 DMA 第 3 版,請將 WDF_DMA_ENABLER_CONFIGWdmDmaVersionOverride 成員設定為 3。

如果裝置執行散佈/收集傳輸,操作系統可以同時執行多個 DMA 交易。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute

如果驅動程式呼叫 WdfDmaTransactionDmaCompletedWithLength 來報告部分傳輸, 如果驅動程式已使用 MDL 結構) 的 Next 成員鏈結在一 (起的 MDL 來指定 DMA 交易的數據緩衝區,WdfDmaTransactionExecute 可以傳回STATUS_WDF_TOO_FRAGMENTED,因為架構可能會重新計算片段的數目和大小,而且可能超過允許的片段數目。

如果已成功啟動交易, WdfDmaTransactionExecute 會傳回STATUS_SUCCESS。 若要判斷架構是否已成功傳送所有交易的傳輸至驅動程式的 EvtProgramDma 回呼函式,驅動程式必須呼叫 WdfDmaTransactionDmaCompletedWdfDmaTransactionDmaCompletedWithLengthWdfDmaTransactionDmaCompletedFinal

如果 Context 參數提供的值是指針或句柄,則必須在 IRQL = DISPATCH_LEVEL 的驅動程式 EvtProgramDma 事件回呼函式中存取它所參考的記憶體。 您可以使用 架構物件內容 來符合此需求。

如果驅動程式先前已呼叫 WdfDmaTransactionSetImmediateExecution,則可以以非封鎖方式呼叫 WdfDmaTransactionExecute

如需 DMA 交易的詳細資訊,請參閱 啟動 DMA 交易

範例

下列程式代碼範例來自 PCIDRV 範例驅動程式。 此範例會建立並初始化 DMA 傳輸,並開始執行。

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

規格需求

需求
目標平台 Universal
最小 KMDF 版本 1.0
標頭 wdfdmatransaction.h (包含 Wdf.h)
程式庫 Wdf01000.sys (請參閱 Framework Library Versioning.)
IRQL <=DISPATCH_LEVEL
DDI 合規性規則 DriverCreate (kmdf) KmdfIrql (kmdf) KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf)

另請參閱

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution