[僅適用於 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。 否則,方法可能會傳回下列其中一個值。
回傳碼 | 說明 |
---|---|
|
驅動程式先前稱為 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。
在 Framework 1.11 版和更新版本中,如果驅動程式使用 DMA 第 3 版來執行單一封包傳輸,作系統可以在內部佇列中儲存多個 DMA 交易。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute。 若要選取 DMA 第 3 版,請將 WdmDmaVersionOverrideWDF_DMA_ENABLER_CONFIG 成員設為 3。
如果裝置執行散佈/收集傳輸,作系統可以同時執行多個 DMA 交易。 在此情況下,驅動程式可以在另一筆交易執行時呼叫 WdfDmaTransactionExecute。
如果驅動程式呼叫 WdfDmaTransactionDmaCompletedWithLength 來報告部分傳輸, 如果驅動程式已使用鏈結在一起的 MDL 來指定 DMA 交易的數據緩衝區(使用 MDL 結構的成員),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;
}
需求
要求 | 價值 |
---|---|
目標平臺 | 普遍 |
最低 KMDF 版本 | 1.0 |
標題 | wdfdmatransaction.h (包括 Wdf.h) |
程式庫 | Wdf01000.sys (請參閱架構連結庫版本控制。) |
IRQL | <=DISPATCH_LEVEL |
DDI 合規性規則 | DriverCreate(kmdf),KmdfIrql(kmdf),KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf) |
另請參閱
WdfDmaEnablerSetMaximumScatterGatherElements
WdfDmaTransactionDmaCompletedFinal
WdfDmaTransactionDmaCompletedWithLength