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 接收STATUS_MORE_PROCESSING_REQUIRED。 如果不需要其他传输,该方法将返回 TRUE 。
如果驱动程序提供无效的对象句柄,则会发生 bug 检查。
注解
每当 完成 DMA 传输 时,基于框架的驱动程序必须调用以下方法之一:
- WdfDmaTransactionDmaCompleted
框架可以将 DMA 事务 划分为多个 DMA 传输操作。 因此,驱动程序必须检查方法的返回值以确定是否需要其他传输。
如果方法返回 FALSE,则 Status 位置会收到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
);
}
}
要求
要求 | 值 |
---|---|
目标平台 | 通用 |
最低 KMDF 版本 | 1.0 |
标头 | wdfdmatransaction.h (包括 Wdf.h) |
Library | Wdf01000.sys (请参阅框架库 Versioning.) |
IRQL | <=DISPATCH_LEVEL |
DDI 符合性规则 | DriverCreate (kmdf) 、 KmdfIrql (kmdf) 、 KmdfIrql2 (kmdf) 、 KmdfIrqlExplicit (kmdf) |
另请参阅
WdfDmaTransactionDmaCompletedFinal