Enviando IRP_MN_QUERY_POWER ou IRP_MN_SET_POWER para estados de energia do dispositivo

Um proprietário da política de energia do dispositivo envia um IRP (IRP_MN_QUERY_POWER) de energia de consulta do dispositivo para determinar se drivers inferiores podem acomodar uma alteração no estado de energia do dispositivo e um IRP (IRP_MN_SET_POWER) de configuração de dispositivo para alterar o estado de energia do dispositivo. (Esse driver também pode enviar um IRP de espera/ativação para permitir que seu dispositivo desperte em resposta a um sinal externo; consulte Dispositivos de suporte que têm recursos de Wake-Up para obter detalhes.)

O driver deve enviar uma solicitação de IRP_MN_QUERY_POWER quando qualquer uma das seguintes opções for verdadeira:

  • O driver recebe um IRP de consulta do sistema.

  • O driver está se preparando para colocar um dispositivo ocioso em um estado de suspensão, portanto, deve consultar drivers inferiores para descobrir se isso é viável.

O driver deve enviar uma solicitação IRP_MN_SET_POWER quando qualquer uma das seguintes opções for verdadeira:

  • O driver determinou que o dispositivo está ocioso e pode ser colocado em suspensão.

  • O dispositivo está em suspensão e deve inserir novamente o estado de trabalho para lidar com a E/S em espera.

  • O driver recebe um IRP de set-power do sistema.

Um driver não deve alocar seu próprio IRP de energia; o power manager fornece a rotina PoRequestPowerIrp para essa finalidade. Como explica as Regras para Lidar com Power IRPs , PoRequestPowerIrp aloca e envia o IRP e, em combinação com IoCallDriver (no Windows 7 e no Windows Vista), ou PoCallDriver (no Windows Server 2003, Windows XP e Windows 2000), garante que todas as solicitações de energia sejam sincronizadas corretamente. Os chamadores de PoRequestPowerIrp devem estar em execução em IRQL <= DISPATCH_LEVEL.

Veja a seguir o protótipo dessa rotina:

NTSTATUS
PoRequestPowerIrp (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PREQUEST_POWER_COMPLETE CompletionFunction,
    IN PVOID Context,
    OUT PIRP *Irp OPTIONAL
    );

Para enviar o IRP, o driver chama PoRequestPowerIrp, especificando um ponteiro para o objeto de dispositivo de destino em DeviceObject, o código IRP secundário IRP_MN_SET_POWER ou IRP_MN_QUERY_POWER em MinorFunction, o valor DevicePowerState no PowerState. Digite e um estado de energia do dispositivo no PowerState. Estado. No Windows 98/Me, DeviceObject deve especificar o PDO do dispositivo subjacente; no Windows 2000 e versões posteriores do Windows, esse valor pode apontar para o PDO ou um FDO de um driver na mesma pilha de dispositivos.

Se o driver precisar executar tarefas adicionais depois que todos os outros drivers tiverem concluído o IRP, ele deverá passar um ponteiro para uma função de conclusão de energia em CompletionFunction. O gerente de E/S chama CompletionFunction depois de chamar todas as rotinas de IoCompletion definidas por drivers conforme eles passavam o IRP para baixo na pilha.

Sempre que um proprietário de política de energia do dispositivo envia um IRP de consulta de energia do dispositivo, ele deve enviar posteriormente um IRP de set-power do dispositivo da rotina de retorno de chamada (CompletionFunction) especificada na chamada para PoRequestPowerIrp. Se a consulta tiver sido bem-sucedida, o IRP set-power especificará o estado de energia consultado. Se a consulta falhou, o IRP de set-power reafirmou o estado de energia do dispositivo atual. Reafirmar o estado atual é importante porque os drivers enfileiram E/S em resposta à consulta; o proprietário da política deve enviar o IRP set-power para notificar os drivers em sua pilha de dispositivos para começar a processar solicitações de E/S enfileiradas.

Tenha em mente que o proprietário da política de um dispositivo não só envia o IRP de energia do dispositivo, mas também manipula o IRP conforme ele é passado para baixo na pilha do dispositivo. Portanto, esse driver geralmente define uma rotina IoCompletion (com IoSetCompletionRoutine) como parte de seu código de manipulação de IRP, especialmente quando o dispositivo está sendo ligado. A rotina IoCompletion é chamada em sequência com rotinas IoCompletion definidas por outros drivers e antes de CompletionFunction. Para obter mais informações, consulte IoCompletion Routines for Device Power IRPs.

Como o IRP foi concluído por todos os drivers quando CompletionFunction é chamado, o CompletionFunction não deve chamar IoCallDriver, PoCallDriver ou PoStartNextPowerIrp com o IRP originado. (No entanto, pode chamar essas rotinas para um IRP de energia diferente.) Em vez disso, essa rotina executa todas as ações adicionais exigidas pelo driver que originou o IRP. Se o driver enviou o IRP do dispositivo em resposta a um IRP do sistema, o CompletionFunction poderá concluir o IRP do sistema. Para obter mais informações, consulte Manipulando um sistema Set-Power IRP em um proprietário de política de energia do dispositivo.

Em resposta à chamada para PoRequestPowerIrp, o power manager aloca um IRP de energia e o envia para a parte superior da pilha de dispositivos para o dispositivo. O power manager retorna um ponteiro para o IRP alocado.

Se nenhum erro ocorrer, PoRequestPowerIrp retornará STATUS_PENDING. Esse status significa que o IRP foi enviado com êxito e está pendente de conclusão. A chamada falhará se o power manager não puder alocar o IRP ou se o chamador tiver especificado um código IRP de energia secundária inválido.

As solicitações para ligar um dispositivo devem ser tratadas primeiro pelo driver de ônibus subjacente para o dispositivo e, em seguida, por cada driver sucessivamente maior na pilha. Portanto, ao enviar uma solicitação PowerDeviceD0 , o driver deve garantir que sua CompletionFunction execute as tarefas necessárias após a conclusão do IRP e que o dispositivo esteja ligado.

Ao desligar um dispositivo (PowerDeviceD3), cada driver na pilha do dispositivo deve salvar todo o contexto necessário e fazer qualquer limpo necessário antes de enviar o IRP para o driver mais baixo. A extensão das informações de contexto e limpo depende do tipo de driver. Um driver de função deve salvar o contexto de hardware; um driver de filtro pode precisar salvar seu próprio contexto de software. Um CompletionFunction definido nessa situação pode executar ações associadas a um IRP de energia completa, mas o driver não pode acessar o dispositivo.