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