WdfDmaTransactionDmaCompleted 函式 (wdfdmatransaction.h)
[僅適用於 KMDF]
WdfDmaTransactionDmaCompleted 方法會通知架構裝置的 DMA 傳輸作業已完成。
語法
BOOLEAN WdfDmaTransactionDmaCompleted(
[in] WDFDMATRANSACTION DmaTransaction,
[out] NTSTATUS *Status
);
參數
[in] DmaTransaction
驅動程式從先前呼叫 WdfDmaTransactionCreate 取得的 DMA 交易物件的句柄。
[out] Status
接收 DMA 傳輸狀態之位置的指標。 如需詳細資訊,請參閱接下來的<備註>一節。
傳回值
WdfDmaTransactionDmaCompleted 會傳回 FALSE ,如果需要額外的傳輸才能完成 DMA 交易, 則會STATUS_MORE_PROCESSING_REQUIRED狀態 。 如果不需要額外的傳輸,此方法會傳回 TRUE 。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
架構型驅動程式必須在 DMA 傳輸 完成時呼叫下列其中一種方法:
- WdfDmaTransactionDmaCompleted
架構可能會將 DMA 交易 分割成數個 DMA 傳輸作業。 因此,驅動程式必須檢查 方法的傳回值,以判斷是否需要額外的傳輸。
如果方法傳回 FALSE, 則狀態 位置會收到STATUS_MORE_PROCESSING_REQUIRED,而且需要額外的 DMA 作業才能完成交易。 一般而言, EvtInterruptDpc 事件回呼函式目前不會執行任何其他動作。 相反地,架構會呼叫驅動程式的 EvtProgramDma 事件回呼函式,因此回呼函式可以開始下一次傳輸。
如果方法傳回 TRUE,則不會再針對指定的交易進行傳輸。 在此情況下, 狀態值STATUS_SUCCESS 表示架構未發生任何錯誤,且 DMA 交易已完成。
如果驅動程式在呼叫 WdfDmaTransactionDmaCompleted 之前呼叫 WdfDmaTransactionStopSystemTransfer,則 WdfDmaTransactionDmaCompleted 會傳回 TRUE,而 Status 值為 STATUS_CANCELLED。
針對針對 單一傳輸所設定的交易, WdfDmaTransactionDmaCompleted 會傳回 TRUE ,如果硬體無法在單一傳輸中完成交易,即使初始化成功, 仍 會傳回 status 值 STATUS_WDF_TOO_MANY_TRANSFERS 。 針對報告每個 DMA 作業剩餘傳輸的硬體,可能會發生這種情況。 例如,驅動程式會將裝置程式撰寫為 64KB,但裝置只會寫入 60KB。 在此情況下,驅動程式可能會重複 DMA 作業或重設裝置。
Status 的任何其他值表示架構偵測到錯誤,而且 DMA 交易可能尚未完成。
當 WdfDmaTransactionDmaCompleted 傳回 TRUE 時,驅動程式通常會執行下列動作:
- 分別呼叫 WdfObjectDelete 或 WdfDmaTransactionRelease 來刪除或重複使用交易物件。
- 如果 DMA 交易與 I/O 要求相關聯,則完成 I/O 要求。 (驅動程式藉由呼叫 WdfRequestComplete 或 WdfRequestCompleteWithInformation.) 來完成要求
範例
下列程式代碼範例來自 AMCC5933 範例驅動程式。 此範例顯示 EvtInterruptDpc 回呼函式。 此範例會通知架構 DMA 傳輸已完成。 如果架構指出此傳輸是 DMA 交易的最後一項,程式代碼會刪除 DMA 交易物件,並完成相關聯的 I/O 要求。
VOID
AmccPciEvtInterruptDpc(
IN WDFINTERRUPT WdfInterrupt,
IN WDFOBJECT WdfDevice
)
{
PAMCC_DEVICE_EXTENSION devExt;
WDFREQUEST request;
REQUEST_CONTEXT *transfer;
NTSTATUS status;
size_t transferred;
BOOLEAN transactionComplete;
UNREFERENCED_PARAMETER( WdfInterrupt );
//
// Retrieve request and transfer.
//
devExt = AmccPciGetDevExt(WdfDevice);
request = devExt->CurrentRequest;
transfer = GetRequestContext(request);
//
// Check to see if the request has been canceled.
//
if (WdfRequestIsCanceled(request)) {
TraceEvents(
TRACE_LEVEL_ERROR,
AMCC_TRACE_IO,
"Aborted DMA transaction 0x%p",
request
);
WdfObjectDelete( transfer->DmaTransaction );
devExt->CurrentRequest = NULL;
WdfRequestComplete(
request,
STATUS_CANCELLED
);
return;
}
//
// Notify the framework that a DMA transfer has completed.
//
transactionComplete = WdfDmaTransactionDmaCompleted(
transfer->DmaTransaction,
&status
);
if (transactionComplete) {
ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);
//
// No more data. The request is complete.
//
TraceEvents(
TRACE_LEVEL_INFORMATION,
AMCC_TRACE_IO,
"Request %p completed: status %X",
request,
status
);
//
// Get the byte count.
//
transferred =
WdfDmaTransactionGetBytesTransferred(transfer->DmaTransaction);
TraceEvents(
TRACE_LEVEL_INFORMATION,
AMCC_TRACE_IO,
"Bytes transferred %d",
(int) transferred
);
//
// Delete this DmaTransaction object.
//
WdfObjectDelete(transfer->DmaTransaction);
//
// Clean up the device context for this request.
//
devExt->CurrentRequest = NULL;
//
// Complete this I/O request.
//
WdfRequestCompleteWithInformation(
request,
status,
(NT_SUCCESS(status)) ? transferred : 0
);
}
}
規格需求
需求 | 值 |
---|---|
目標平台 | 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) |
另請參閱
WdfDmaTransactionDmaCompletedFinal