[仅适用于 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 true。
如果驱动程序提供无效的对象句柄,则会发生 bug 检查。
注解
只要 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_WDF_TOO_MANY_TRANSFERS 状态 值,即使初始化成功也是如此。 对于报告每个 DMA作的残差传输的硬件,可能会发生这种情况。 例如,驱动程序将设备程序为写入 64KB,但设备只写入 60KB。 在这种情况下,驱动程序可能会重复 DMA作或重置设备。
状态 的任何其他值都意味着框架检测到错误,并且 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) |
图书馆 | Wdf01000.sys(请参阅框架库版本控制。 |
IRQL | <=DISPATCH_LEVEL |
DDI 符合性规则 | DriverCreate(kmdf),KmdfIrql(kmdf),KmdfIrql2(kmdf),KmdfIrqlExplicit(kmdf) |
另请参阅
WdfDmaTransactionDmaCompletedFinal