StartIo 例程的注意事项

实现 StartIo 例程时,请记住以下几点:

  • StartIo 例程必须将其对物理设备的访问权限与驱动程序访问同一设备、内存位置或资源的其他例程同步到驱动程序在设备扩展中维护的任何共享状态信息或资源。

    如果 StartIo 例程与 ISR 共享设备或状态,则必须使用 KeSynchronizeExecution 调用驱动程序提供的 SynchCritSection 例程来编程设备或访问共享状态。 有关详细信息,请参阅 使用关键节

    如果 StartIo 例程与 ISR 以外的例程共享状态或资源,则必须使用驱动程序为其提供存储的驱动程序初始化执行旋转锁保护共享状态或资源。 有关详细信息,请参阅 旋转锁

  • 如果整体式非 WDM 设备驱动程序设置了控制器对象,其 StartIo 例程可以使用控制器对象通过共享的物理设备与附加的(类似)设备来同步操作。

    有关详细信息,请参阅 控制器对象

  • 除非紧密耦合的更高级别的驱动程序预先将大型 DMA 传输请求拆分给其基础设备驱动程序,否则基础设备驱动程序的 StartIo 例程必须将大型传输请求拆分为部分传输范围,并且驱动程序必须执行一系列部分传输设备操作。 必须依据硬件的能力来确定每个部分传输的大小:要么基于驱动设备的能力,要么对于从属 DMA 设备,基于系统 DMA 控制器的能力,以其中约束更严格者为准。

    有关使用系统或总线主 DMA 的详细信息,请参阅 适配器对象和 DMA。

  • 使用 DMA 的驱动程序的 StartIo 例程必须使用 适配器对象同步传输。

  • StartIo 例程在 IRQL = DISPATCH_LEVEL运行,这会限制它可以调用的支持例程集。

    例如, StartIo 例程既无法访问也不能分配可分页内存,也不能等待调度程序对象设置为信号状态。 另一方面, StartIo 例程可以使用 KeAcquireSpinLockAtDpcLevelKeReleaseSpinLockFromDpcLevel 获取和释放驱动程序分配的执行旋转锁,这比 KeAcquireSpinLockKeReleaseSpinLock 运行速度更快。

    有关详细信息,请参阅 管理硬件优先级旋转锁

  • 如果驱动程序持有处于可取消状态的 IRP,则其 StartIo 例程必须检查输入 IRP 是否已取消,然后才能开始对其设备上的该请求进行任何处理。 有关详细信息,请参阅 “取消 IRP”。