Share via


디바이스 Power-Down IRP 처리

디바이스 전원이 낮아지거나 현재 디바이스 전원 상태와 같은 부 함수 코드 IRP_MN_SET_POWER 디바이스 전원 상태(PowerDeviceD0, PowerDeviceD1, PowerDeviceD2 또는 PowerDeviceD3)를 지정합니다. IRP가 디바이스 스택 아래로 이동함에 따라 드라이버는 전원이 켜진 IRP를 처리해야 합니다. 상위 수준 드라이버는 하위 수준 드라이버보다 먼저 IRP를 처리해야 합니다. 수행할 디바이스별 작업이 없는 드라이버는 IRP를 다음 하위 드라이버에 즉시 전달해야 합니다.

다음 그림은 이러한 IRP 처리와 관련된 단계를 보여줍니다.

디바이스 전원 다운 요청 처리를 보여 주는 다이어그램

IRP가 PowerDeviceD3을 지정하는 경우 함수 드라이버는 일반적으로 다음 작업을 수행해야 합니다.

  • IoAcquireRemoveLock을 호출하여 현재 IRP를 전달하여 드라이버가 전원 IRP를 처리하는 동안 PnP IRP_MN_REMOVE_DEVICE 요청을 받지 않도록 합니다.

    IoAcquireRemoveLock이 오류 상태 반환하는 경우 드라이버는 IRP를 계속 처리해서는 안 됩니다. 대신 Windows Vista부터 드라이버는 IoCompleteRequest를 호출하여 IRP를 완료한 다음 실패 상태 반환해야 합니다. Windows Server 2003, Windows XP 및 Windows 2000에서 드라이버는 IoCompleteRequest를 호출하여 IRP를 완료한 다음 PoStartNextPowerIrp를 호출하여 다음 전원 IRP를 시작한 다음 실패 상태 반환해야 합니다.

  • 디바이스 전원이 제거되기 전에 수행해야 하는 모든 디바이스별 작업(예: 디바이스 닫기, 보류 중인 I/O 완료 또는 플러시, 인터럽트 비활성화, 후속 들어오는 IRP 큐 대기, 디바이스를 복원하거나 다시 초기화할 디바이스 컨텍스트 저장)을 수행합니다.

    드라이버는 IRP를 처리하는 동안 긴 지연(예: 사용자가 이 유형의 디바이스에 대해 불합리하다고 생각될 수 있는 지연)을 발생시키지 않아야 합니다.

    드라이버는 디바이스가 작업 상태로 돌아갈 때까지 들어오는 I/O 요청을 큐에 대기해야 합니다.

  • Parameters.Power.ShutdownType에서 값을 검사 수 있습니다. 시스템 집합 전원 IRP가 활성화된 경우 ShutdownType 은 시스템 IRP에 대한 정보를 제공합니다. 이 값에 대한 자세한 내용은 시스템 전원 작업을 참조하세요.

    최대 절전 모드 경로의 디바이스 드라이버는 이 값을 검사해야 합니다. ShutdownTypePowerActionHibernate인 경우 드라이버는 디바이스를 복원하는 데 필요한 컨텍스트를 저장해야 하지만 디바이스 전원을 끄면 안 됩니다.

  • 드라이버가 이 작업을 수행할 수 있고 변경이 적절한 경우 디바이스의 물리적 전원 상태를 변경합니다.

  • PoSetPowerState를 호출하여 전원 관리자에게 새 디바이스 전원 상태를 알립니다.

  • IoCopyCurrentIrpStackLocationToNext를 호출하여 다음 하위 드라이버에 대한 스택 위치를 설정합니다.

  • 드라이버가 다음 전원 IRP를 처리할 준비가 되었음을 나타내는 PoStartNextPowerIrp을 호출하는 IoCompletion 루틴을 설정합니다. Windows 7 및 Windows Vista에서는 이 단계가 필요하지 않습니다.

  • IoCallDriver(Windows 7 및 Windows Vista)에 전화하거나 PoCallDriver(Windows Server 2003, Windows XP 및 Windows 2000)를 호출하여 IRP를 다음 하위 드라이버에 전달합니다. IRP는 IRP를 완료하는 버스 드라이버로 전달되어야 합니다.

  • IoReleaseRemoveLock을 호출하여 이전에 획득한 잠금을 해제합니다.

  • STATUS_PENDING 반환합니다.

드라이버는 IRP를 전달하기 전에 디바이스 컨텍스트 정보를 저장하고 새 전원 상태를 설정해야 합니다. 컨텍스트 정보에는 최소한 요청된 새 전원 상태가 포함되어야 합니다. 또한 전원이 켜질 때 드라이버에 필요한 추가 정보도 포함되어야 합니다. IRP가 완료되고 디바이스 전원이 꺼진 후 드라이버는 더 이상 디바이스에 액세스할 수 없으며 디바이스 컨텍스트를 사용할 수 없습니다.

각 드라이버는 IRP를 다음 하위 드라이버에 전달해야 합니다. IRP가 버스 드라이버에 도달하면 버스 드라이버가 디바이스에서 전원을 끄고(이 기능을 사용할 수 있는 경우) PoSetPowerState 를 호출하여 전원 관리자에게 알리고 IRP를 완료합니다.

그러나 버스 드라이버가 최대 절전 모드 디바이스를 서비스하는 경우 IRP의 ShutdownType 값이 PowerSystemHibernate인지 여부를 검사 합니다. 그렇다면 버스 드라이버는 PoSetPowerState 를 호출하여 PowerDeviceD3을 보고해야 하지만 디바이스의 전원을 끕니다. 디바이스는 시스템의 나머지 부분과 함께 최대 절전 모드 파일을 저장한 후 전원이 켜집니다.

모든 자식 디바이스의 전원이 켜지면 버스 드라이버가 버스의 전원을 낮추도록 선택할 수도 있습니다. 이러한 동작은 디바이스에 종속됩니다.

IRP가 다른 상태(D0, D1 또는 D2)를 지정하는 경우 필수 드라이버 작업은 디바이스에 종속됩니다. 일반적으로 이러한 상태를 지원하는 디바이스는 I/O 요청이 도착하면 작업 상태로 빠르게 돌아갈 수 있습니다. 이러한 디바이스에 대한 드라이버는 보류 중인 I/O 요청을 완료하고, 새 요청을 큐에 대기하고, IRP를 다음 하위 드라이버로 전달하기 전에 필요한 모든 컨텍스트를 저장해야 합니다. IRP가 버스 드라이버에 도달하면 요청된 상태로 하드웨어를 설정합니다. 드라이버가 절전 모드인 동안 디바이스에 액세스할 수 없습니다.

경우에 따라 함수 또는 필터 드라이버는 디바이스가 이미 D0 상태일 때 PowerDeviceD0을 지정하는 디바이스 전원 IRP를 받을 수 있습니다. 드라이버는 보류 중인 I/O 요청을 완료하고, 들어오는 I/O 요청을 큐에 대기하고, IoCompletion 루틴을 설정하고, IRP를 다음 하위 드라이버로 전달하는 다른 설정 전원 IRP와 마찬가지로 이 IRP를 처리해야 합니다. 그러나 드라이버는 디바이스의 하드웨어 설정을 변경하지 않아야 합니다. 버스 드라이버가 IRP를 받으면 IRP를 완료하기만 하면 됩니다. IRP가 완료되면 함수 및 필터 드라이버는 대기 중인 모든 요청을 처리할 수 있습니다. IRP가 완료될 때까지 I/O를 큐에 대기하면 더 높은 드라이버가 I/O를 시도하는 동안 낮은 드라이버가 디바이스 레지스터를 변경하려고 할 가능성이 없습니다.