完成 DMA 傳輸
[僅適用于 KMDF]
通常,驅動程式的 EvtInterruptDpc 回呼函式會完成每個 DMA 傳輸的處理。
首先,因為多個 DMA 交易可以同時進行, 所以 EvtInterruptDpc 回呼函式必須判斷已完成傳輸相關聯的 DMA 交易。 回呼函式可以藉由擷取驅動程式 啟動 DMA 交易時所儲存的交易控制碼來執行此動作。 若要擷取裝置擴充功能, PLX9x5x 範例會在其 Private.h 標頭檔中定義名為 PLxGetDeviceCoNtext 的函式:
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, PLxGetDeviceContext)
然後,在驅動程式的 EvtInterruptDpc 回呼中,它會執行下列動作:
WDFDMATRANSACTION dmaTransaction;
PDEVICE_EXTENSION devExt;
...
devExt = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));
...
dmaTransaction = devExt->WriteDmaTransaction;
接下來, EvtInterruptDpc 回呼函式必須呼叫下列其中一種傳輸完成方法,通知架構傳輸已完成:
WdfDmaTransactionDmaCompleted,如果傳輸順利完成,而且硬體不會報告已傳送的位元組計數。
WdfDmaTransactionDmaCompletedWithLength;如果傳輸順利完成,而且硬體會報告已傳送的位元組計數 (或未傳輸的位元組計數) ,或驅動程式偵測到錯誤,並指定零的傳輸計數來重試傳輸。 如果驅動程式指定零的傳輸計數,架構會從剩餘的位元組數目減去零,因此會將相同的傳輸傳送傳送至 EvtProgramDma 回 呼函式。
WdfDmaTransactionDmaCompletedFinal,如果硬體回報執行不足或失敗狀況。
您的驅動程式可以呼叫 WdfDmaTransactionGetCurrentDmaTransferLength 來取得已完成傳輸的原始長度。 如果您的裝置回報未傳輸的位元組計數,因為驅動程式可以從原始傳輸長度減去未傳輸的位元組數目,然後呼叫 WdfDmaTransactionGetCurrentDmaTransferLength 來報告實際的傳輸大小,所以此呼叫很有用。
上述每個傳輸完成方法都會通知架構,單一 DMA 傳輸 (不是整個 DMA 交易) 完成。 在驅動程式呼叫下列其中一種方法之後,驅動程式會檢查方法的傳回值,以查看交易是否需要更多傳輸:
如果完成方法的傳回值為 FALSE,架構已判斷完成處理 DMA 交易需要額外的 DMA 傳輸。
一般而言,驅動程式的 EvtInterruptDpc 回呼函式只會傳回。 架構會再次呼叫驅動程式的 EvtProgramDma 回 呼函式,而回呼函式可以針對下一次傳輸設計硬體。
傳輸完成方法會提供狀態值,在此情況下一律STATUS_MORE_PROCESSING_REQUIRED。
如果傳回值為 TRUE,則 DMA 交易不會再進行傳輸。
傳輸完成方法會提供狀態值。 如果狀態值STATUS_SUCCESS,則 DMA 交易的所有傳輸都會完成,而且驅動程式必須 完成 DMA 交易。 如果狀態值是任何其他專案,則發生錯誤,而且 DMA 交易可能尚未完成。
如果 EvtInterruptDpc 回呼函式偵測到錯誤,通常是因為計時器過期或硬體中斷發出傳輸錯誤訊號,驅動程式可以重新開機交易目前的傳輸。
若要重新開機交易目前的傳輸,驅動程式的 EvtInterruptDpc 回呼函式可以呼叫 WdfDmaTransactionDmaCompletedWithLength ,並將 TransferedLength 參數設定為零。