Manipulando IRP_MN_QUERY_POWER para estados de energia do dispositivo

Um dispositivo query-power IRP consulta sobre uma alteração de estado para um único dispositivo e é enviado para todos os drivers na pilha do dispositivo. Esse IRP especifica DevicePowerState no membro Power.Type do local da pilha de E/S.

Os motoristas lidam com IRPs query-power enquanto viajam pela pilha.

Um driver de função ou filtro poderá falhar em uma solicitação de IRP_MN_QUERY_POWER se qualquer uma das seguintes opções for verdadeira:

  • O dispositivo está habilitado para ativação e o estado de energia solicitado está abaixo do estado do qual o dispositivo pode ativar o sistema. Por exemplo, um dispositivo que pode ativar o sistema de D2, mas não de D3, falharia em uma consulta para D3, mas teria êxito em uma consulta para D2.

  • Entrar no estado solicitado forçaria o driver a abandonar uma operação que perderia dados, como uma conexão de modem aberto. Um driver raramente falhará em uma consulta por esse motivo; na maioria das circunstâncias, o aplicativo lida com esses casos.

Para falhar em uma solicitação de IRP_MN_QUERY_POWER , um driver executa as seguintes etapas:

  1. Chame PoStartNextPowerIrp para indicar que o driver está preparado para lidar com o próximo IRP de energia. (Somente Windows Server 2003, Windows XP e Windows 2000.)

  2. Defina Irp-IoStatus.Status> como uma falha status e chame IoCompleteRequest, especificando IO_NO_INCREMENT. O driver não passa o IRP mais abaixo na pilha do dispositivo.

  3. Retornar um erro status de sua rotina DispatchPower.

Se o driver tiver êxito no IRP de energia de consulta, ele não deverá iniciar nenhuma operação ou tomar qualquer outra ação que impeça a conclusão bem-sucedida de uma solicitação de IRP_MN_SET_POWER subsequente para o estado de energia consultado.

Um driver que tenha êxito no IRP deve se preparar para um IRP de set-power para o estado consultado e passar o IRP de consulta da seguinte maneira:

  1. Conclua todas as operações de E/S pendentes.

  2. Solicitações de E/S de entrada na fila.

  3. Evite iniciar outras novas atividades que interfiram em uma transição para o estado de energia especificado. No entanto, o driver não deve salvar o contexto do dispositivo nem seguir outras etapas para o desligamento.

  4. Chame IoCopyCurrentIrpStackLocationToNext para definir o local da pilha IRP para o driver mais baixo.

  5. Definir uma rotina IoCompletion . Na rotina IoCompletion , chame PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) para indicar a preparação do driver para lidar com o irP de energia seguinte.

  6. Chame IoCallDriver (no Windows 7 e Windows Vista) ou PoCallDriver (no Windows Server 2003, Windows XP e Windows 2000) para passar o IRP de consulta para o driver mais baixo. Não conclua o IRP.

  7. Retornar STATUS_PENDING. O driver não deve alterar o valor em Irp-IoStatus.Status>.

Quando o IRP de energia de consulta atinge o driver de barramento, o motorista do barramento chama PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) e define Irp-IoStatus.Status> como STATUS_SUCCESS se o driver puder alterar para o estado de energia especificado ou definir uma falha status se não puder. Em seguida, o motorista do ônibus chama IoCompleteRequest, especificando IO_NO_INCREMENT.

Os drivers em uma pilha de dispositivo típica lidam com um IRP de consulta de dispositivo da seguinte maneira:

  • A maioria dos drivers de filtro deve simplesmente passar o IRP para o driver mais baixo (consulte Passando IRPs de Energia) e retornar STATUS_PENDING. Alguns drivers de filtro, no entanto, podem primeiro precisar executar tarefas específicas do dispositivo, como enfileirar IRPs de entrada ou salvar o estado de energia do dispositivo.

  • Um driver de função executa tarefas específicas do dispositivo (como, concluir solicitações de E/S pendentes, enfileirar solicitações de E/S de entrada, salvar o contexto do dispositivo ou alterar a energia do dispositivo), define uma rotina de IoCompletion e passa o IRP de energia do dispositivo para o driver mais baixo (consulte Passando Power IRPs). Ele retorna STATUS_PENDING de sua rotina DispatchPower .

  • O driver de barramento chama PoStartNextPowerIrp (somente Windows Server 2003, Windows XP e Windows 2000) para iniciar o IRP de energia seguinte. Em seguida, ele conclui o IRP, especificando IO_NO_INCREMENT. Se o driver não puder concluir o IRP imediatamente, ele chamará IoMarkIrpPending, retornará STATUS_PENDING de sua rotina DispatchPower e concluirá o IRP posteriormente.

Mesmo que o dispositivo de destino já esteja no estado de energia consultado, cada driver de função ou filtro deverá enfileirar E/S e passar o IRP para o driver mais baixo. O IRP deve percorrer toda a pilha do dispositivo até o motorista do ônibus, o que o conclui.

Ao lidar com uma solicitação de IRP_MN_QUERY_POWER , um driver deve retornar da rotina DispatchPower o mais rápido possível. Um driver não deve esperar em sua rotina DispatchPower para um evento de kernel sinalizado por código que manipula o mesmo IRP. Como os IRPs de energia são sincronizados em todo o sistema, pode ocorrer um deadlock.