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 |
---|---|
|
先前稱為 WdfDmaTransactionSetImmediateExecution 的驅動程式和要求所需的資源無法使用。 |
|
對 WdfDmaTransactionExecute 的呼叫之前沒有呼叫 WdfDmaTransactionInitialize 或 WdfDmaTransactionInitializeUsingRequest。 |
|
裝置會執行單一封包傳輸,並在另一筆交易執行時呼叫 WdfDmaTransactionExecute 的驅動程式。 |
|
操作系統處理指定傳輸大小所需的散佈/收集元素數目大於驅動程式呼叫 WdfDmaEnablerSetMaximumScatterGatherElements 的值。 如需詳細資訊,請參閱接下來的<備註>一節。 |
這個方法也可能傳回其他 NTSTATUS值。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
WdfDmaTransactionExecute 方法會針對與指定的 DMA 交易相關聯的第一個 DMA 傳輸,初始化交易的散佈/收集清單。 (針對單一封包傳輸,散佈/收集清單包含單一元素。) 然後,方法會呼叫驅動程式的 EvtProgramDma 事件回呼函式,而回呼函式可以程式設計裝置以開始傳輸。
架構型驅動程式通常會從 I/O 佇列事件回呼函式內呼叫 WdfDmaTransactionExecute。
在驅動程式呼叫 WdfDmaTransactionInitialize 或 WdfDmaTransactionInitializeUsingRequest 以初始化 DMA 交易之後,驅動程式必須先呼叫 WdfDmaTransactionExecute 一次,才能 完成 DMA 交易。
如果 WdfDmaTransactionInitializeXxx 傳回成功,但 WdfDmaTransactionExecute 會傳回錯誤值,您的驅動程式必須呼叫 WdfDmaTransactionRelease。
在 1.11 之前的架構版本中,如果裝置執行單一封包傳輸,操作系統一次只能執行一個 DMA 交易。 在此情況下,如果另一個交易正在執行, WdfDmaTransactionExecute 會傳回STATUS_WDF_BUSY。
在架構 1.11 版和更新版本中,如果驅動程式使用 DMA 第 3 版來執行單一封包傳輸,操作系統可以將多個 DMA 交易儲存在內部佇列中。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute 。 若要選取 DMA 第 3 版,請將 WDF_DMA_ENABLER_CONFIG 的 WdmDmaVersionOverride 成員設定為 3。
如果裝置執行散佈/收集傳輸,操作系統可以同時執行多個 DMA 交易。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute 。
如果驅動程式呼叫 WdfDmaTransactionDmaCompletedWithLength 來報告部分傳輸, 如果驅動程式已使用 MDL 結構) 的 Next 成員鏈結在一 (起的 MDL 來指定 DMA 交易的數據緩衝區,WdfDmaTransactionExecute 可以傳回STATUS_WDF_TOO_FRAGMENTED,因為架構可能會重新計算片段的數目和大小,而且可能超過允許的片段數目。
如果已成功啟動交易, WdfDmaTransactionExecute 會傳回STATUS_SUCCESS。 若要判斷架構是否已成功傳送所有交易的傳輸至驅動程式的 EvtProgramDma 回呼函式,驅動程式必須呼叫 WdfDmaTransactionDmaCompleted、 WdfDmaTransactionDmaCompletedWithLength 或 WdfDmaTransactionDmaCompletedFinal。
如果 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) |
另請參閱
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength