当框架收到定向到某个驱动程序设备的 I/O 请求时,它会将请求置于 I/O 队列中。 驱动程序可以通过提供请求处理程序或轮询队列来从 I/O 队列中获取 I/O 请求。 有关 I/O 队列的详细信息,请参阅 框架队列对象。
在设计驱动程序时,将驱动程序收到的 I/O 请求分组为两个类别:
要求设备处于工作状态(D0)的请求,包括:
- 读取或写入请求,这些请求要求设备的功能驱动程序从设备读取数据或将数据写入设备。
- 无法在不访问设备的情况下由函数或总线驱动程序提供服务的设备控制请求。
不要求设备处于其工作状态(D0)的请求,包括:
- 设备控制请求可以由功能或总线驱动程序处理,而无需访问设备。
- 可能是筛选器驱动程序接收的所有请求。
- 所有驱动程序堆栈中的驱动程序收到的所有请求,如果该堆栈支持仅限软件的设备且不与任何硬件通信。
除非你正在编写筛选器驱动程序,或为不与硬件通信的堆栈编写驱动程序,否则您的驱动程序可能会收到一些请求,这些请求要求设备处于工作状态,而另一些则不需要。
为了支持这两种类型的请求,框架提供了两种类型的 I/O 队列:电源托管队列和非电源托管队列。 当驱动程序创建其每个 I/O 队列时,它将队列WDF_IO_QUEUE_CONFIG结构中的 PowerManaged 成员设置为 WdfTrue 或 WdfFalse 以指示以下选项之一:
如果驱动程序将 PowerManaged 设置为 WdfTrue,则队列是电源管理的。
当 I/O 请求在电源管理的队列中可用时,框架仅当设备处于工作状态(D0)时,才会将请求传送到驱动程序。 因此,每当驱动程序从电源管理的队列收到请求时,框架都保证设备可用。 如果设备未处于工作状态,则框架会将请求存储在队列中,直到设备可用为止。
如果设备处于低功率状态,因为它处于空闲状态,并且如果框架将 I/O 请求置于驱动程序的一个电源托管队列中,则框架会要求驱动程序堆栈在将请求传递到驱动程序之前将设备还原到其工作状态。
如果设备处于低功率状态,因为系统未处于工作状态(S0),并且如果框架将 I/O 请求置于驱动程序的一个电源托管队列中,则框架会等待设备返回到其工作状态(D0),然后将请求传递到驱动程序。
由于如果设备未处于工作状态,框架不会将 I/O 请求从电源管理的队列传递到驱动程序,因此位于驱动程序堆栈中的电源策略所有者上方的驱动程序不得使用电源管理的 I/O 队列。 如果位于电源策略所有者上方的驱动程序使用电源管理的队列,并且设备处于低功率状态,则驱动程序不会收到请求,并且无法将其传递给电源策略所有者。 因此,控制设备电源状态的电源策略所有者不会唤醒设备。
如果驱动程序将 PowerManaged 设置为 WdfFalse,则队列不受电源管理。
当 I/O 请求在不受电源管理的队列中可用时,框架会将请求传送到驱动程序,而不考虑设备是否处于工作状态(D0)。 如果设置了队列,以便它只接收不需要访问设备的请求,则驱动程序可以为每个请求提供服务,即使设备不可用也是如此。
有关电源管理 I/O 队列的更多信息,请参阅 使用 Power-Managed I/O 队列。
一些驱动程序需要对即插即用(PnP)和电源管理作进行直接控制。 这些驱动程序可以使用 自管理 I/O。 有关详细信息,请参阅 使用 Self-Managed I/O。