使用基于数据包的系统 DMA

使用基于数据包的 DMA 的从属设备的驱动程序在处理请求 DMA 传输的 IRP 时,会调用以下支持例程的一般顺序:

  • 在尝试分配系统 DMA 控制器之前,KeFlushIoBuffers(有关详细信息,请参阅维护缓存一致性

  • 当驱动程序准备好为 DMA 对设备进行编程并且需要系统 DMA 控制器时,AllocateAdapterChannel

    AllocateAdapterChannel 反过来会调用驱动程序的 AdapterControl 例程。

  • MmGetMdlVirtualAddress 用于获取 MDL 的索引,在初始调用 MapTransfer 参数时需要作为参数

  • MapTransfer 为传输操作对系统 DMA 控制器进行编程

    驱动程序可能需要多次调用 MapTransfer 来传输所有请求的数据,如拆分传输请求中所述。

  • FlushAdapterBuffers 就在每次向/从属设备进行 DMA 传输操作后

    如果驱动程序必须多次调用 MapTransfer 来传输所有请求的数据,则它必须调用 FlushAdapterBuffers 多次调用 MapTransfer

  • 只要传输了所有请求的数据,或者驱动程序由于设备 I/O 错误而失败,则FreeAdapterChannel

IoGetDmaAdapter 返回的适配器对象指针是除 KeFlushIoBuffers MmGetMdlVirtualAddress 以外的每个例程的必需参数,后者需要指向在 >Irp-MdlAddress 中传递的 MDL 的指针。

各个驱动程序在不同的时间点调用此支持例程序列,具体取决于每个驱动程序如何实现为其设备提供服务。 例如,一个驱动程序的 StartIo 例程可能会调用 AllocateAdapterChannel,另一个驱动程序可能会从从驱动程序创建的联锁队列中删除 IRP 的例程发出此调用,而另一个驱动程序在从属 DMA 设备指示它已准备好传输数据时发出此调用。