使用通过电源管理的 I/O 队列
驱动程序创建 I/O 队列时,可以指定队列是否由 电源管理。 当 I/O 请求在电源管理的队列中可用时,框架仅当设备处于其工作 (D0) 状态时,才会将请求传送到驱动程序。 在框架从电源管理的队列传递到驱动程序的所有 I/O 请求都已完成、取消或推迟之前,框架不允许设备离开其工作状态。
有关电源管理的 I/O 队列的详细信息,请参阅 I/O 队列的电源管理。
Power-Managed队列的回调函数
如果驱动程序使用电源管理的 I/O 队列,它可以提供两个附加的回调函数:
EvtIoStop
EvtIoStop 回调函数停止处理指定的 I/O 请求。 当设备离开其工作 (D0) 状态或删除时,框架会针对驱动程序尚未完成的每个 I/O 请求(包括驱动程序拥有的请求和已转发到 I/O 目标的请求)调用 I/O 队列的 EvtIoStop 回调函数一次。
EvtIoResume
EvtIoResume 回调函数继续处理以前停止的 I/O 请求。 当框架在设备返回到其工作状态后,从队列继续向驱动程序传递 I/O 请求时,会调用 I/O 队列的 EvtIoResume 回调函数。
每次框架调用驱动程序的 EvtIoStop 回调函数时,该函数通常会 完成 或 取消 I/O 请求,或调用 WdfRequestStopAcknowledge 将请求的所有权返回到框架。
虽然这样做是可选的,但通常应该为电源管理的队列提供 EvtIoStop 回调函数。 通过提供 EvtIoStop,驱动程序可以帮助缩短设备(可能是系统)进入低功耗状态之前经过的时间。
如果不为电源管理的队列提供 EvtIoStop ,框架将等到从电源托管队列传递到驱动程序的所有请求完成之后,再将设备 (或系统) 移动到较低的电源状态或删除设备。 这种不作为可能会阻止系统进入其休眠状态或另一个低系统电源状态。 在极端情况下,它可能会导致系统崩溃,并出现 bug 检查代码 9F。
如果驱动程序未将请求转发到 I/O 目标,并且未在不确定的时间内保留请求,则可以安全地省略电源托管队列的 EvtIoStop 。
正在等待 Dispatcher 对象
通常,驱动程序应仅使用调度程序对象作为非比特线程上下文中的同步机制。
由于 请求处理程序 在任意线程上下文中运行,因此电源托管队列的请求处理程序不得等待内核调度程序对象设置。 这样做可能会导致死锁。
有关驱动程序何时可以等待调度程序对象以及当无法等待调度程序对象时要执行的操作的详细信息,请参阅 内核调度程序对象简介。