突如其来的唤醒是意外地过渡到 D0。 设备进入 D3cold 后,当同一电源轨上的另一台设备的驱动程序请求从 D3cold 转换为 D0 时,它可能会遇到意外唤醒的副作用。 第一个设备的驱动程序必须收到意外唤醒通知,以防止设备保持未初始化的 D0 状态。
当设备从 D3hot 移动到 D3cold 时,它可能会这样做,因为它与一些其他设备共享的电源已关闭。 这些设备进入 D3cold 后一段时间,其中一台设备的驱动程序可能会请求转换为 D0。 为了响应此请求,父总线驱动程序或 ACPI 筛选器驱动程序接通电源,共享电源的所有设备都进入其默认的上电硬件状态。
唯一需要此电源状态更改的设备驱动程序是请求更改的驱动程序。 其他设备的驱动程序必须收到有关此更改的通知,以便他们可以正确初始化其设备以在 D0 中运行。 只有能够接收此通知的驱动程序才能使其设备进入 D3cold。 否则,驱动程序将不知道设备何时进入 D0。
设备打开后,它将进入默认的未初始化硬件状态。 例如, PCI Express Base 3.0 规范 定义了设备首次接收电源时输入的 D0 未初始化 状态。 此状态的定义特定于 PCI 和 PCI Express 设备,但连接到其他总线的设备在打开时会进入类似的硬件状态。
对于实现多个功能的 PCI 或 PCI Express 设备,这些设备功能可能共享相同的电源轨。 但是,每个函数可能具有单独的驱动程序,并且这些函数的驱动程序不太可能彼此直接通信。 当其中一个函数的驱动程序请求从 D3cold 更改为 D0 电源状态时,其他函数的驱动程序不希望发生此更改。 当这些其他函数接收电源时,必须通知其驱动程序,以便它们可以将函数配置为在 D0 中正常运行。
总线驱动程序检测到何时打开了子设备的电源。 如果此设备的函数驱动程序未请求转换到 D0,则总线驱动程序会提示设备驱动程序自行发送 D0 电源 IRP(目标状态为 PowerDeviceD0 的IRP_MN_SET_POWER请求),以初始化设备以在 D0 中运行。 在此初始化的 D0 状态中,设备驱动程序随后可以启动设备的转换到 D3hot。 设备驱动程序可以通过以下方式从总线驱动程序接收到关于突发转换至 D0 状态的通知:
- 直接或间接注册为 运行时电源管理框架 (PoFx)客户端的设备驱动程序接收通知回调。
- 为使设备具备唤醒功能的驱动程序,其挂起的 IRP_MN_WAIT_WAKE 请求由总线驱动程序完成。
从 Windows 8 开始,设备的功能驱动程序(充当电源策略所有者)可以自行注册为 PoFx 的客户端。 当总线驱动程序通知 PoFx 设备意外切换到 D0 时,PoFx 可帮助设备进入已初始化的 D0 状态,然后转移到 D3hot。 首先,PoFx 调用驱动程序的 DevicePowerRequiredCallback 例程,以提示设备驱动程序将 D0 电源 IRP 向下发送设备堆栈。 接下来,PoFx 调用驱动程序的 DevicePowerNotRequiredCallback 例程,以通知设备驱动程序设备不需要保持 D0 状态。
从 Kernel-Mode Driver Framework (KMDF) 版本 1.11 开始,单组件设备的 KMDF 驱动程序可以通过调用 WdfDeviceWdmAssignPowerFrameworkSettings 方法间接地向 PoFx 注册自身。 在此调用中,驱动程序提供指向回调例程的指针,这些回调例程通知驱动程序关于意外转换到 D0 的事件。 有关详细信息,请参阅 “支持功能电源状态”。
如果设备已设为可唤醒,即便驱动程序没有将其设备注册到 PoFx,它仍会收到设备意外转换到 D0 状态的通知。 当总线驱动程序打开设备的电源时,它们完成驱动程序的 IRP_MN_WAIT_WAKE 请求。 作为响应,驱动程序初始化其设备以在 D0 中运行。 设备可能处于空闲状态,在这种情况下,驱动程序会在一段时间后将此设备移动到 D3hot。
未在 PoFx 注册且未设置设备唤醒功能的功能驱动程序不会收到从 D3cold 到 D0 的意外转换通知。 设备可能花费大量时间处于未初始化的 D0 状态。 在此状态下,设备中的所有组件通常都处于打开状态。 为了减少空闲设备的能耗,驱动程序只有在能够接收到意外转换到 D0 的信息时才应允许设备进入 D3cold。