Manipulando IRPs de Power-Down dispositivo
Um IRP de desligar o dispositivo especifica o código de função secundária IRP_MN_SET_POWER e um estado de energia do dispositivo (PowerDeviceD0, PowerDeviceD1, PowerDeviceD2 ou PowerDeviceD3) que é menos alimentado ou igual ao estado de energia do dispositivo atual. Os drivers devem lidar com o IRP desligado à medida que o IRP percorre a pilha do dispositivo. Os drivers de nível superior devem lidar com o IRP antes de drivers de nível inferior. Os drivers que não têm tarefas específicas do dispositivo a serem executadas devem passar prontamente o IRP para o driver mais baixo.
A figura a seguir mostra as etapas envolvidas no tratamento desse IRP.
Se o IRP especificar PowerDeviceD3, o driver de função normalmente deverá executar as seguintes tarefas:
Chame IoAcquireRemoveLock, passando o IRP atual, para garantir que o driver não receba uma solicitação de IRP_MN_REMOVE_DEVICE PnP ao manipular o IRP de energia.
Se IoAcquireRemoveLock retornar uma falha status, o driver não deverá continuar processando o IRP. Em vez disso, a partir do Windows Vista, o driver deve chamar IoCompleteRequest para concluir o IRP e, em seguida, retornar a falha status. No Windows Server 2003, Windows XP e Windows 2000, o driver deve chamar IoCompleteRequest para concluir o IRP e, em seguida, chamar PoStartNextPowerIrp para iniciar o próximo IRP de energia e, em seguida, retornar a falha status.
Execute todas as tarefas específicas do dispositivo que devem ser feitas antes que a energia do dispositivo seja removida, como fechar o dispositivo, concluir ou liberar qualquer E/S pendente, desabilitar interrupções, enfileirar IRPs de entrada subsequentes e salvar o contexto do dispositivo do qual restaurar ou reinicializar o dispositivo.
O driver não deve causar um longo atraso (por exemplo, um atraso que um usuário pode achar irracional para esse tipo de dispositivo) durante o tratamento do IRP.
O driver deve enfileirar todas as solicitações de E/S de entrada até que o dispositivo retorne ao estado de trabalho.
Possivelmente marcar o valor em Parameters.Power.ShutdownType. Se um IRP de set-power do sistema estiver ativo, o ShutdownType fornecerá informações sobre o IRP do sistema. Para obter mais informações sobre esse valor, consulte System Power Actions.
Os drivers de dispositivos no caminho de hibernação devem inspecionar esse valor. Se ShutdownType for PowerActionHibernate, o driver deverá salvar qualquer contexto necessário para restaurar o dispositivo, mas não deve desligar o dispositivo.
Altere o estado de energia física do dispositivo se o driver for capaz de fazer isso e se a alteração for apropriada.
Chame PoSetPowerState para notificar o power manager sobre o novo estado de energia do dispositivo.
Chame IoCopyCurrentIrpStackLocationToNext para configurar o local da pilha para o driver mais baixo.
Defina uma rotina IoCompletion que chama PoStartNextPowerIrp que indica que o driver está pronto para lidar com o próximo IRP de energia. Esta etapa não é necessária no Windows 7 e no Windows Vista.
Chame IoCallDriver (no Windows 7 e No Windows Vista) ou chame PoCallDriver (no Windows Server 2003, Windows XP e Windows 2000) para passar o IRP para o driver mais baixo. O IRP deve ser passado até o motorista do ônibus, que conclui o IRP.
Chame IoReleaseRemoveLock para liberar o bloqueio adquirido anteriormente.
Retornar STATUS_PENDING.
Os drivers devem salvar todas as informações de contexto do dispositivo e definir o novo estado de energia antes de encaminhar o IRP. As informações de contexto devem conter, no mínimo, o novo estado de energia solicitado. Ele também deve incluir informações adicionais de que o driver precisará após a ativação. Depois que o IRP for concluído e o dispositivo tiver sido desligado, o driver não poderá mais acessar o dispositivo e o contexto do dispositivo não estará disponível.
Cada driver deve passar o IRP para o driver inferior seguinte. Quando o IRP atinge o motorista do ônibus, o motorista do ônibus desligará o dispositivo (se for capaz disso), chamará PoSetPowerState para informar o gerenciador de energia e concluirá o IRP.
No entanto, se o driver de barramento atende ao dispositivo de hibernação, ele deve marcar se o valor de ShutdownType no IRP é PowerSystemHibernate. Nesse caso, o driver de barramento deve chamar PoSetPowerState para relatar PowerDeviceD3, mas não deve desligar o dispositivo. O dispositivo desligará depois que o arquivo de hibernação for salvo, juntamente com o restante do sistema.
Depois que todos os seus dispositivos filho desligarem, um motorista de ônibus pode optar por desligar seu ônibus também. Esse comportamento depende do dispositivo.
Se o IRP especificar qualquer outro estado (D0, D1 ou D2), as ações de driver necessárias serão dependentes do dispositivo. Normalmente, os dispositivos que dão suporte a esses estados podem retornar rapidamente ao estado de trabalho quando uma solicitação de E/S chega. Um driver para esse dispositivo deve concluir todas as solicitações de E/S pendentes, enfileirar novas solicitações e salvar todo o contexto necessário antes de encaminhar o IRP para o driver inferior seguinte. Quando o IRP atinge o driver de ônibus, ele define o hardware no estado solicitado. Um driver não pode acessar o dispositivo enquanto ele está em suspensão.
Em algumas circunstâncias, um driver de função ou filtro pode receber um IRP de energia do dispositivo especificando PowerDeviceD0 quando o dispositivo já estiver no estado D0. O driver deve lidar com esse IRP como faria com qualquer outro IRP de energia de conjunto: concluir solicitações de E/S pendentes, enfileirar solicitações de E/S de entrada, definir uma rotina de IoCompletion e passar o IRP para o driver mais baixo. No entanto, um driver não deve alterar as configurações de hardware do dispositivo. Quando o motorista do ônibus recebe o IRP, ele deve simplesmente concluir o IRP. Quando o IRP for concluído, os drivers de função e filtro poderão lidar com quaisquer solicitações enfileiradas. O enfileiramento de E/S até que o IRP seja concluído elimina qualquer possibilidade de drivers inferiores tentarem alterar os registros de dispositivo enquanto um driver mais alto tenta E/S.