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 받으면 디바이스를 안전하게 제거할 수 있도록 성공을 반환해야 합니다. 그러나 디바이스가 메모리 버퍼에 쓰는 루프에 갇혀 있는 경우와 같이 디바이스를 안전하게 중지할 수 없는 경우가 있을 수 있습니다. 이러한 경우 드라이버는 IRP_MN_QUERY_REMOVE_DEVICE STATUS_DEVICE_HUNG 반환해야 합니다. 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 펌웨어: 함수 수준 재설정

함수 수준 디바이스 재설정을 지원하려면 디바이스 scope 내에 정의된 _RST 메서드가 있어야 합니다. 있는 경우 이 메서드는 해당 디바이스에 대한 버스 드라이버의 함수 수준 디바이스 재설정 구현(있는 경우)을 재정의합니다. 실행되면 _RST 메서드는 해당 디바이스만 다시 설정해야 하며 다른 디바이스에는 영향을 미치지 않아야 합니다. 또한 디바이스는 버스에 연결되어 있어야 합니다.

ACPI 펌웨어: 플랫폼 수준 재설정

플랫폼 수준 디바이스 재설정을 지원하기 위해 다음 두 가지 옵션이 있습니다.

  • ACPI 펌웨어는 _RST 메서드를 구현하는 PowerResource를 정의할 수 있으며, 이 재설정 방법의 영향을 받는 모든 디바이스는 Device scope 정의된 _PRR 개체를 통해 이 PowerResource를 참조할 수 있습니다.

  • 디바이스는 _PR3 개체를 선언할 수 있습니다. 이 경우 ACPI 드라이버는 D3cold 파워 사이클링을 사용하여 재설정을 수행하고 디바이스 간의 다시 설정 종속성은 _PR3 개체에서 결정됩니다.

device scope _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.exe 같은 ASL 컴파일러를 사용하여 테스트 ASL 파일을 AML로 컴파일합니다. WDK(Windows 드라이버 키트)에 포함된 실행 파일입니다.
Asl <test>.asl

위의 명령은 SSDT.aml을 생성합니다.

  1. SSDT.aml의 이름을 acpitabl.dat로 바꿉니다.

  2. 테스트 시스템의 %systemroot%\system32에 acpitabl.dat를 복사합니다.

  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