디바이스 트리를 통한 대기/절전 모드 해제 IRP 경로 이해
단일 디바이스 스택 내에서 전원 정책 소유자는 대기/절전 모드 해제 IRP를 보내고 모든 드라이버는 대기/절전 모드 해제 IRP를 처리합니다. 대기/절전 모드 해제 작업 개요 및 대기/절전 모드 해제 IRP 보내기 및 대기/절전 모드 해제 IRP 수신에 각각 설명되어 있습니다.
디바이스 트리의 분기 내에서(리프 devnode 및 부모, 조부모 등의 devnodes로 구성됨) 드라이버는 대기/절전 모드 해제 IRP가 절전 모드 해제에 필요한 모든 하드웨어를 사용하도록 설정할 수 있는 드라이버에 도달할 수 있도록 협력해야 합니다.
ACPI 컴퓨터에서 ACPI는 각 리프 디바이스의 절전 모드 해제 신호와 연결된 시스템별 GPE(범용 이벤트) 레지스터를 사용하도록 설정하는 역할을 담당합니다. 따라서 드라이버는 ACPI 필터 드라이버(시작 시 디바이스 스택에 삽입됨) 또는 기본 Windows ACPI 드라이버인 Acpi.sys 도달할 때까지 대기/절전 모드 해제 IRP를 요청하고 전달해야 합니다. 이에 대한 응답으로 ACPI는 레지스터를 사용하도록 설정하고, 신호가 도착할 때까지 보류 중인 IRP를 보유한 다음, IRP를 완료합니다. ACPI는 절전 모드 해제 신호에 응답할 수 있으므로 IRP를 더 낮은 드라이버로 전달하지 않습니다.
기본 ACPI 드라이버 자체와 같은 ACPI 필터 드라이버는 다른 드라이버에 투명합니다. 하드웨어 디자인에서 최대 유연성을 제공하기 위해 모든 디바이스 스택에서 ACPI 필터 드라이버의 정확한 위치는 디바이스 및 시스템별 위치입니다. 드라이버를 디자인할 때 디바이스 스택에서 ACPI 필터의 현재 상태 또는 위치에 대해 어떤 가정도 할 수 없습니다.
자식을 열거하는 드라이버는 각 자식 디바이스에 대한 PDO와 부모 디바이스에 대한 FDO를 만듭니다. 따라서 드라이버는 자식 디바이스의 버스 드라이버 역할을 하고 부모 디바이스의 함수 드라이버/정책 소유자 역할을 합니다. 따라서 버스 드라이버가 자식 PDO에 대한 대기/절전 모드 해제 IRP를 받을 때마다 부모 PDO에 대해 다른 대기/절전 모드 해제 IRP를 요청해야 합니다.
다음 그림에서는 이러한 상황이 발생하는 샘플 구성을 보여 줍니다.
샘플 구성에서 키보드와 모뎀은 USB 허브의 자식이며, 이는 PCI 버스에 의해 열거되는 USB 호스트 컨트롤러의 자식입니다. 다음 그림에서는 샘플 구성에서 키보드의 디바이스 스택을 보여 줍니다.
이전 그림과 같이 아래에서 위로 읽습니다.
Acpi.sys Windows ACPI 드라이버는 PCI용 PDO를 만듭니다.
PCI 드라이버는 PCI FDO 및 USB 호스트 컨트롤러 PDO를 만들고 PCI 디바이스 스택에 대한 정책을 소유합니다.
USB 호스트 컨트롤러 드라이버(호스트 포트/미니포트 드라이버 쌍)는 USB 호스트 컨트롤러 FDO 및 USB 허브 PDO를 만듭니다. USB 호스트 컨트롤러 디바이스 스택에 대한 정책을 소유합니다. Acpi.sys 이 스택에도 DO 필터를 만듭니다.
USB 허브 드라이버는 USB 허브 FDO 및 키보드 PDO를 만듭니다. 이 드라이버는 USB 허브 디바이스 스택에 대한 전원 정책을 소유합니다.
키보드의 함수 드라이버는 USB HID 클래스 드라이버/미니드라이버 쌍입니다. 이 드라이버는 키보드에 대한 FDO를 만들고 해당 전원 정책을 소유합니다. 키보드에 자식 디바이스가 없으므로 이 드라이버는 PDO를 생성하지 않습니다.
각 디바이스 스택에는 표시되지 않는 추가 선택적 필터 DO가 포함될 수 있습니다.
키보드 입력이 시스템을 깨우도록 허용하기 위해 키보드의 정책 소유자는 PDO에 대한 IRP_MN_WAIT_WAKE 요청합니다. IRP는 다음 그림과 같이 다른 대기/절전 모드 해제 IRP의 체인을 설정합니다.
버스 드라이버가 만든 PDO를 대상으로 하는 IRP_MN_WAIT_WAKE 받으면 전원 정책을 소유하고 FDO를 만든 디바이스 스택에 대해 다른 IRP_MN_WAIT_WAKE 요청해야 합니다.
이전 그림과 같이 다음을 수행합니다.
키보드 드라이버는 PoRequestPowerIrp 를 호출하여 IRP1(대기/절전 모드 해제 IRP)을 해당 PDO에 보냅니다.
전원 관리자는 IRP를 할당하고 I/O 관리자를 통해 키보드의 디바이스 스택 맨 위에 보냅니다. 드라이버는 IoCompletion 루틴을 설정하고 키보드 PDO에 도달할 때까지 IRP를 스택 아래로 전달합니다. 키보드의 버스 드라이버 역할을 하는 USB 허브 드라이버는 보류 중인 IRP1을 보유합니다.
절전 모드 해제 신호가 도착하면 USB 허브 드라이버가 시스템을 절전 모드 해제할 수 없으므로 USB 허브 드라이버는 PoRequestPowerIrp 를 호출하여 USB 허브 디바이스 스택에 대한 대기/절전 모드 해제 IRP(IRP2)를 요청해야 합니다.
전원 관리자는 이 IRP를 USB 허브 디바이스 스택의 맨 위로 보냅니다. 이 스택의 드라이버는 IoCompletion 루틴을 설정하고 IRP를 USB 호스트 컨트롤러 드라이버(USB 허브의 버스 드라이버 역할을 하는)에 전달합니다. USB 호스트 컨트롤러 드라이버는 키보드가 절전 모드 해제 이벤트를 신호할 때까지 IRP2 보류를 유지합니다.
마찬가지로 USB 호스트 컨트롤러 드라이버는 시스템을 절전 모드 해제할 수 없으므로 USB 호스트 컨트롤러 드라이버는 PoRequestPowerIrp 를 호출하여 IRP3(대기/절전 모드 해제 IRP)을 USB 호스트 컨트롤러 디바이스 스택에 보냅니다.
전원 관리자는 이 IRP를 USB 호스트 컨트롤러 디바이스 스택의 맨 위로 보냅니다. 여기서 드라이버는 IoCompletion 루틴을 설정하고 IRP를 PCI 드라이버(USB 허브의 버스 드라이버 역할)로 전달합니다. PCI 드라이버는 키보드가 절전 모드 해제 이벤트에 신호를 보낼 때까지 보류 중인 IRP3을 보유합니다.
PCI 드라이버는 시스템을 절전 모드 해제할 수 없으므로 PCI 드라이버는 PoRequestPowerIrp 를 호출하여 IRP4(대기/절전 모드 해제 IRP)를 PCI 디바이스 스택으로 보냅니다. 해당 부모는 ACPI가 버스 드라이버인 루트 디바이스입니다.
전원 관리자는 IRP를 PCI 버스 디바이스 스택의 맨 위로 보냅니다. 드라이버가 완료 루틴을 설정하고 IRP를 Windows ACPI 드라이버로 전달한다고 Acpi.sys.
Acpi.sys 시스템을 절전 모드 해제할 수 있으므로 대기/절전 모드 해제 IRP를 다른 PDO로 보내지 않습니다. Acpi.sys 절전 모드 해제 신호가 도착할 때까지 보류 중인 IRP4를 보유합니다.
키보드가 절전 모드 해제 신호를 어설션하면 Acpi.sys 절전 모드를 가로챌 수 있습니다. 그러나 ACPI는 키보드가 신호를 어설션했는지 확인할 수 없으며, 신호가 루트 디바이스를 통해 왔다는 것만 확인할 수 없습니다. 그런 다음 Acpi.sys IRP4를 완료하고 I/O 관리자는 PCI 디바이스 스택을 다시 이동하는 IoCompletion 루틴을 호출합니다. IRP4가 완료되고 모든 IoCompletion 루틴이 실행되면 PCI 드라이버의 콜백 루틴이 호출됩니다. 콜백 루틴에서 PCI 드라이버는 신호가 USB 호스트 컨트롤러를 통해 수신되었음을 확인합니다. 그런 다음 PCI 드라이버가 IRP3을 완료합니다. 키보드 드라이버가 IRP1을 받을 때까지 USB 호스트 컨트롤러 스택 및 USB 허브 스택을 통해 동일한 시퀀스가 발생합니다. 이 시점에서 키보드 드라이버는 필요에 따라 절전 모드 해제 이벤트를 서비스할 수 있습니다.
드라이버가 부모 PDO에 대기/절전 모드 해제 IRP를 보낼 때마다 자체 IRP에 대해 취소 루틴을 설정해야 합니다. 취소 루틴을 설정하면 트리거된 IRP가 취소된 경우 드라이버가 새 IRP를 취소할 수 있습니다. USB 예제에서 키보드 드라이버가 대기/절전 모드 해제 IRP를 취소하는 경우(따라서 키보드 절전 모드 해제를 사용하지 않도록 설정), USB 허브, USB 호스트 컨트롤러 및 PCI 드라이버는 키보드 IRP의 결과로 보낸 IRP를 취소해야 합니다. 자세한 내용은 대기/절전 모드 해제 IRP에 대한 루틴 취소를 참조하세요.
부모 드라이버가 대기/절전 모드 해제를 사용하도록 설정할 수 있는 자식이 두 개 이상 열거될 수 있지만 PDO에 대해 대기/절전 모드 해제 IRP는 하나만 보류할 수 있습니다. 이러한 경우 부모 드라이버는 디바이스가 절전 모드 해제를 사용하도록 설정될 때마다 대기/절전 모드 해제 IRP를 보류 상태로 유지해야 합니다. 이렇게 하려면 드라이버는 대기/절전 모드 해제 IRP를 받을 때마다 내부 카운터를 증가합니다. 드라이버가 대기/절전 모드 해제 IRP를 완료할 때마다 개수가 감소하고 결과 값이 0이 아닌 경우 디바이스 스택에 다른 대기/절전 모드 해제 IRP를 보냅니다.
예를 들어 이전에 샘플 USB 구성 그림에 표시된 USB 구성에서 USB 허브는 키보드와 모뎀이라는 두 디바이스를 열거합니다. USB 허브 드라이버가 키보드 PDO에 대한 대기/절전 모드 해제 IRP를 수신하면 자체 PDO에 대한 IRP를 요청하기 전에 대기/절전 모드 해제 IRP 수가 증가합니다. 모뎀의 정책 소유자가 나중에 모뎀에 대해 절전 모드 해제를 사용하도록 설정하는 경우 USB 허브 드라이버는 모뎀 PDO에 대한 새 IRP를 보류하고 대기/절전 모드 해제 참조 수를 증분합니다. 그러나 USB 허브 PDO에는 동시에 대기/절전 모드 해제 IRP가 두 개 있을 수 없으므로 USB 허브 드라이버는 USB 허브 PDO에 대한 새 대기/절전 모드 해제 IRP를 요청하지 않습니다.
절전 모드 해제 신호가 키보드 또는 모뎀에서 도착하면 USB 허브 드라이버는 신호를 받은 디바이스를 결정하고, 해당 IRP를 완료하고, 참조 횟수를 줄입니다. 두 디바이스 모두 절전 모드 해제를 사용하도록 설정되었으므로(따라서 참조 수가 0이 아니므로) 자체 디바이스 스택을 다른 대기/절전 모드 해제 IRP를 보내 절전 모드 해제를 위해 자체 PDO를 "다시 정렬"해야 합니다. (USB 호스트 컨트롤러 및 PCI 드라이버도 마찬가지입니다.)
그러나 드라이버는 절전 모드 해제 신호가 방금 도착한 동일한 디바이스에서 다시 활성화 가능한 대기/절전 모드 해제에 IRP를 보내지 않습니다. 디바이스 전원 정책 관리자만 이 작업을 수행할 수 있습니다. 다시 설정 대기/절전 모드 해제는 자동이 아닙니다.