使用 GUID_DEVICE_RESET_INTERFACE_STANDARD

GUID_DEVICE_RESET_INTERFACE_STANDARD接口定义了函数驱动程序尝试重置和恢复故障设备的标准方法。

可通过此接口使用两种类型的设备重置:

  • 功能级设备重置。 在这种情况下,重置操作仅限于特定设备,对其他设备不可见。 设备在整个重置过程中保持与总线的连接,并在重置后) (初始状态返回到有效状态。 这种类型的重置对系统的影响最小。

    • 此类重置可由总线驱动程序或 ACPI 固件实现。 如果总线规范定义了满足要求的带内重置机制,则总线驱动程序可以实现函数级重置。 ACPI 固件可以选择使用自己的实现替代总线驱动程序定义的函数级重置。
  • 平台级设备重置。 在这种情况下,重置操作会导致设备报告为总线丢失。 重置操作会影响特定设备,以及通过同一电源轨或重置线路连接到该设备的所有其他设备。 这种类型的重置对系统的影响最大。 OS 将拆毁并重新生成所有受影响设备的堆栈,以确保一切从空白状态重启。

从 Windows 10 开始,项下的HKLM\SYSTEM\CurrentControlSet\Control\Pnp这些注册表项将配置重置操作:

  • DeviceResetRetryInterval:重置操作开始之前的时间段。 默认值为 3 秒。 最小值为 100 毫秒;最大值为 30 秒。

  • DeviceResetMaximumRetries:尝试重置操作的次数。

注意

GUID_DEVICE_RESET_INTERFACE_STANDARD 接口从 Windows 10 开始可用。

使用设备重置接口

如果函数驱动程序检测到设备无法正常工作,则应首先尝试函数级重置。 如果函数级重置无法解决问题,驱动程序可以选择尝试平台级重置。 但是,平台级重置应仅用作最终选项。

若要查询此接口,设备驱动程序会向驱动程序堆栈发送IRP_MN_QUERY_INTERFACE IRP。 对于此 IRP,驱动程序将 InterfaceType 输入参数设置为 GUID_DEVICE_RESET_INTERFACE_STANDARD。 成功完成 IRP 后,Interface 输出参数是指向DEVICE_RESET_INTERFACE_STANDARD结构的指针。 此结构包含指向 DeviceReset 例程的指针,该例程可用于请求函数级或平台级重置。

支持功能驱动程序中的设备重置接口

若要支持设备重置接口,设备堆栈必须满足以下要求。

函数驱动程序必须正确处理IRP_MN_QUERY_REMOVE_DEVICE、IRP_MN_REMOVE_DEVICE和IRP_MN_SURPRISE_REMOVAL。

在大多数情况下,当驱动程序收到IRP_MN_QUERY_REMOVE_DEVICE时,它应返回成功,以便可以安全地删除设备。 但是,在某些情况下,设备可能无法安全停止,例如,设备停滞在写入内存缓冲区的循环中。 在这种情况下,驱动程序应将STATUS_DEVICE_HUNG返回到IRP_MN_QUERY_REMOVE_DEVICE。 PnP 管理器将继续IRP_MN_QUERY_REMOVE_DEVICE和IRP_MN_REMOVE_DEVICE进程,但该特定堆栈不会接收IRP_MN_REMOVE_DEVICE。 相反,在重置设备后,设备堆栈将收到IRP_MN_SURPRISE_REMOVAL。

有关这些 IRP 的详细信息,请参阅:

处理 IRP_MN_QUERY_REMOVE_DEVICE 请求

处理 IRP_MN_REMOVE_DEVICE 请求

处理 IRP_MN_SURPRISE_REMOVAL 请求

支持筛选器驱动程序中的设备重置接口

筛选器驱动程序可能会截获具有GUID_DEVICE_RESET_INTERFACE_STANDARD接口类型的IRP_MN_QUERY_INTERFACE IRP。 通过这样做,他们可以继续委托给GUID_DEVICE_RESET_INTERFACE_STANDARD接口,但在重置操作之前或之后执行特定于设备的操作。 或者,它们可以使用自己的接口替代总线驱动程序返回的 GUID_DEVICE_RESET_INTERFACE_STANDARD 接口,以提供其自己的重置操作。

支持总线驱动程序中的设备重置接口

参与设备重置过程的总线驱动程序 (也就是说,与请求重置的设备关联的总线驱动程序以及与响应重置请求的设备关联的总线驱动程序) 必须满足以下要求之一:

  • 支持热插拔。 总线驱动程序必须能够在没有通知的情况下检测到正在从总线中取出的设备,以及插入总线的设备。

  • 或者,它必须实现 GUID_REENUMERATE_SELF_INTERFACE_STANDARD 接口。 这会模拟从总线上拉取并重新插入的设备。 PCI 和 SDBUS) 等内置总线驱动程序 (支持此接口。 因此,如果要重置的设备使用其中一个总线,则无需修改总线驱动程序。

对于基于 WDF 的总线驱动程序,WDF 框架代表驱动程序注册 GUID_REENUMERATE_SELF_INTERFACE_STANDARD 接口。 因此,这些驱动程序不需要注册此接口。 如果总线驱动程序需要在重新枚举其子设备之前执行某些操作,则必须注册 EvtChildListDeviceReenumerated 回调例程并在该例程中执行操作。 由于可以针对所有 PDO 并行调用此回调例程,因此该例程中的代码可能需要防范争用情况。

ACPI 固件:功能级别重置

若要支持功能级设备重置,必须在设备范围内定义_RST方法。 如果存在,此方法将替代总线驱动程序实现的功能级设备重置 (如果该设备存在) 。 执行时,_RST方法必须仅重置该设备,并且不得影响其他设备。 此外,设备必须在总线上保持连接状态。

ACPI 固件:平台级重置

若要支持平台级设备重置,有两个选项:

  • ACPI 固件可以定义实现 _RST 方法的 PowerResource,受此重置方法影响的所有设备都可以通过其设备范围下定义的_PRR对象引用此 PowerResource。

  • 设备可以声明_PR3对象。 在这种情况下,ACPI 驱动程序将使用 D3cold 电源循环来执行重置,并且将从 _PR3 对象确定设备之间的重置依赖项。

如果设备范围中存在 _PRR 对象,则 ACPI 驱动程序将使用引用的 PowerResource 中的 _RST 方法执行重置。 如果未定义_PRR对象,但定义了_PR3对象,则 ACPI 驱动程序将使用 D3cold 电源循环来执行重置。 如果_PRR或_PR3对象均未定义,则设备不支持平台级重置,ACPI 驱动程序将报告平台级重置不可用。

验证测试系统上的 ACPI 固件

若要测试支持设备重置和恢复的驱动程序,请遵循此过程。 此过程假定你使用此示例 ASL 文件。

DefinitionBlock("SSDT.AML", "SSDT", 0x01, "XyzOEM", "TestTabl", 0x00001000)
{
   Scope(\_SB_)
      {
       PowerResource(PWFR, 0x5, 0x0)
       {
           Method(_RST, 0x0, NotSerialized)    { }
           
           // Placeholder methods as power resources need _ON, _OFF, _STA.
           Method(_STA, 0x0, NotSerialized)
           {
               Return(0xF)
           }

           Method(_ON_, 0x0, NotSerialized)    { }

           Method(_OFF, 0x0, NotSerialized)    { }

       } // PowerResource()
   } // Scope (\_SB_)

   // Assumes WiFi device is declared under \_SB.XYZ.
   Scope(\_SB_.XYZ.WIFI)
       {

       // Declare PWFR as WiFi reset power rail
       Name(_PRR, Package(One)
           {
               \_SB_.PWFR
           })
       } // Scope (\_SB)
}
  1. 使用 ASL 编译器(如 Asl.exe)将测试 ASL 文件编译为 AML。 包含在 Windows 驱动程序工具包中的可执行文件 (WDK) 。
Asl <test>.asl

上述命令生成 SSDT.aml。

  1. 将 SSDT.aml 重命名为 acpitabl.dat。

  2. 将 acpitabl.dat 复制到测试系统上的 %systemroot%\system32。

  3. 在测试系统上启用测试签名。

bcdedit /set testsigning on
  1. 重新启动测试系统。

  2. 验证表是否已加载。 在 Windows 调试器中,使用以下命令。

  • !acpicache
  • SSDT 表的 dt _DESCRIPTION_HEADER 地址
0: kd> !acpicache
Dumping cached ACPI tables...
  SSDT @(ffffffffffd03018) Rev: 0x1 Len: 0x000043 TableID: TestTabl
  XSDT @(ffffffffffd05018) Rev: 0x1 Len: 0x000114 TableID: HSW-FFRD
       ...
       ...
 
0: kd> dt _DESCRIPTION_HEADER ffffffffffd03018
ACPI!_DESCRIPTION_HEADER
   +0x000 Signature        : 0x54445353
   +0x004 Length           : 0x43
   +0x008 Revision         : 0x1 ''
   +0x009 Checksum         : 0x37 '7'
   +0x00a OEMID            : [6]  "XyzOEM"
   +0x010 OEMTableID       : [8]  "TestTabl"
   +0x018 OEMRevision      : 0x1000
   +0x01c CreatorID        : [4]  "MSFT"
   +0x020 CreatorRev       : 0x5000000

另请参阅

_DEVICE_RESET_INTERFACE_STANDARD