保留 DMA 资源
[仅适用于 KMDF]
通常,基于框架的驱动程序不会提前保留映射寄存器。 但是,在某些情况下,司机可能需要提前预留这些资源。
在 Windows 8 或更高版本上运行的基于框架的驱动程序可以为指定数据包或系统配置文件的 DMA 启用程序保留指定数量的映射寄存器。 为此,驱动程序调用 WdfDmaTransactionAllocateResources 并注册 EvtReserveDma 回调函数。
框架在已保留映射寄存器和 WDM DMA 适配器的锁时调用驱动程序的 EvtReserveDma 函数。 然后,驱动程序可以使用同一事务对象多次初始化和启动事务,然后再最终释放事务对象。 若要将 DMA 资源释放回系统,驱动程序会调用 WdfDmaTransactionFreeResources。
若要确定事务所需的映射寄存器数,驱动程序可以在调用 WdfDmaTransactionAllocateResources 之前调用 WdfDmaTransactionGetTransferInfo。 驱动程序必须在调用 WdfDmaTransactionGetTransferInfo 之前初始化事务。
以下步骤演示了驱动程序如何保留和释放 DMA 启用程序,以便与指定事务独占使用:
驱动程序接收 I/O 请求。
驱动程序 的请求处理程序 调用 WdfDmaTransactionCreate 为请求创建 DMA 事务对象。
驱动程序 的请求处理程序 调用 WdfDmaTransactionAllocateResources 来保留资源。
框架在保留请求的资源后调用 EvtReserveDma 。
在 EvtReserveDma 中,驱动程序调用 WdfDmaTransmaTransactionInitializeUsingRequest 或 WdfDmaTransactionInitialize 来初始化事务对象。
在 EvtReserveDma 中,驱动程序调用 WdfDmaTransactionExecute 方法来启动事务。 由于事务具有保留的资源,因此框架会立即调用驱动程序的 EvtProgramDma 回调函数。
从 EvtInterruptDpc 或 EvtDmaTransactionDmaTransferComplete,驱动程序调用 WdfDmaTransactionDmaCompleted、 WdfDmaTransactionDmaCompletedWithLength 或 WdfDmaTransactionDmaCompletedFinal,后跟 WdfObjectDelete 或 WdfDmaTransactionRelease。 在事务完成或取消之前,驱动程序不得删除或释放事务。 完成此步骤后,映射寄存器将保留。
驱动程序可以根据需要多次重复步骤 5-7。
当驱动程序不再需要预留时,驱动程序从 EvtInterruptDpc 或 EvtDmaTransactionDmaTransferComplete 调用 WdfDmaTransactionFreeResources。 或者,驱动程序可以从其 EvtReserveDma 事件回调函数调用 WdfDmaTransactionFreeResources。