使用 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:重试重置操作的次数。

注释

从 Windows 10 开始,GUID_DEVICE_RESET_INTERFACE_STANDARD接口可用。

使用设备重置接口

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

为了查询该接口,设备驱动程序会在驱动程序堆栈中下传一个IRP_MN_QUERY_INTERFACE IRP。 对于该 IRP,驱动程序将 InterfaceType 输入参数设定为 GUID_DEVICE_RESET_INTERFACE_STANDARD。 成功完成 IRP 后,接口输出参数是一个指向 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 文件编译为 AML,例如 Asl.exe。 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

另请参阅

_设备重置接口标准