Manipulando uma solicitação de energia definida
Um driver intermediário deve lidar com solicitações para definir a energia para o estado de trabalho (um estado de energia do dispositivo de rede de D0) e para os estados de suspensão (um estado de energia do dispositivo de rede de D1, D2 ou D3). O driver intermediário também deve manter as variáveis de estado de energia e um sinalizador de espera. Essas questões são discutidas mais adiante neste tópico.
Para obter exemplos de gerenciamento de energia de driver intermediário, consulte o exemplo de driver NDIS MUX Intermediate Driver e Notify Object no repositório de exemplos de driver do Windows no GitHub.
Manipulando uma solicitação de energia definida para um estado de suspensão
Há dois casos em que um driver intermediário deve lidar com uma solicitação de energia definida para um estado de suspensão:
O NDIS solicita que a borda superior da miniporta virtual do driver intermediário vá para um estado de suspensão.
A borda inferior do protocolo de driver intermediário manipula a transição do driver de miniporta subjacente para um estado de suspensão quando recebe uma notificação de evento Plug and Play (PnP).
Esses eventos podem acontecer em qualquer ordem e um evento não necessariamente acompanha o outro.
Quando a borda superior da miniporta virtual do driver intermediário recebe uma solicitação para definir a energia para um estado de suspensão, a sequência de eventos para manipular a solicitação é a seguinte:
O NDIS chama a função ProtocolNetPnPEvent de cada driver de protocolo vinculado à miniporta virtual. A chamada para ProtocolNetPnPEvent especifica um evento NetEventSetPower para um estado de suspensão. Os drivers de protocolo vinculados ao driver intermediário param de enviar dados de rede e fazer solicitações OID para a miniporta virtual do driver intermediário. A borda inferior do protocolo do driver intermediário pode continuar a enviar dados de rede e solicitações para baixo até que o NDIS indique que o driver de miniporta subjacente está fazendo a transição para um estado de suspensão.
O NDIS pausa os drivers sobrepostos e, em seguida, a miniporta virtual depois de emitir o evento NetEventSetPower . O motivo especificado para a pausa é uma transição para um estado de baixa potência. Para obter mais informações sobre como pausar uma miniporta virtual, consulte Pausando um adaptador.
Observação Nenhuma solicitação OID pode ser enviada para a miniporta virtual enquanto ela estiver em um estado de baixo consumo de energia, com exceção de OID_PNP_SET_POWER.
O NDIS emite uma solicitação de OID_PNP_SET_POWER para a miniporta virtual do driver intermediário. O motorista intermediário aceita a solicitação retornando NDIS_STATUS_SUCCESS. O driver intermediário não deve propagar a solicitação de OID_PNP_SET_POWER para o driver de miniporta subjacente. Depois que o driver intermediário concluir essa solicitação, ele não deve indicar mais dados de rede recebidos ou indicar o status, mesmo que continue recebendo dados de rede e indicações de status do driver de miniporta subjacente.
Quando a borda inferior do protocolo do driver intermediário faz a transição do driver de miniporta subjacente para um estado de suspensão, a sequência de eventos para manipular a transição é a seguinte:
O NDIS chama a função ProtocolNetPnPEvent da borda inferior do protocolo de driver intermediário. A chamada para ProtocolNetPnPEvent especifica um evento NetEventSetPower para um estado de suspensão. O driver intermediário deve parar de enviar dados de rede e fazer solicitações OID para o driver de miniporta subjacente. Se houver solicitações ou envios pendentes, o driver intermediário deve retornar NDIS_STATUS_PENDING da chamada para ProtocolNetPnPEvent. O driver intermediário chama NdisCompleteNetPnPEvent para concluir a chamada para ProtocolNetPnPEvent. A borda de protocolo de um driver intermediário ainda pode obter indicações de pacote e status recebidos do driver de miniporta subjacente. Os dados de rede recebidos podem ser ignorados. Se a implementação de um driver intermediário depender do monitoramento do status do driver de miniporta subjacente, as indicações de status ainda deverão ser monitoradas.
O NDIS pausa a borda de protocolo do driver intermediário e, em seguida, pausa o adaptador de miniporta subjacente depois de emitir o evento NetEventSetPower . O motivo especificado para a pausa é uma transição para um estado de baixa potência. Para obter mais informações sobre como pausar uma associação de protocolo, consulte Pausando uma associação.
Observação Nenhuma solicitação OID pode ser enviada para o adaptador de miniporta subjacente enquanto ele estiver em um estado de baixo consumo de energia, com exceção do OID_PNP_SET_POWER.
O NDIS emite uma solicitação de OID_PNP_SET_POWER para o driver de miniporta subjacente. No entanto, se o driver de miniporta subjacente não oferecer suporte ao gerenciamento de energia, ele será interrompido. Nesse caso, mesmo que o NDIS interrompa o driver de miniporta subjacente, ele não solicita que o protocolo de driver intermediário seja desvinculado do driver de miniporta subjacente e da NIC. Depois que o driver de miniporta subjacente tiver concluído com êxito o processamento do OID (ou o driver de miniporta for interrompido), ele não indicará mais dados ou status de rede.
Manipulando uma solicitação de energia definida para o estado de trabalho
Há dois casos em que um driver intermediário manipula uma solicitação de energia definida para o estado de trabalho:
O NDIS solicita que a borda superior da miniporta virtual do driver intermediário vá para o estado de funcionamento.
A borda inferior do protocolo de driver intermediário manipula a transição do driver de miniporta subjacente para o estado de trabalho, quando recebe uma notificação de evento Plug and Play (PnP).
Esses eventos podem ocorrer em qualquer ordem e um evento não necessariamente acompanha o outro.
Quando a borda superior da miniporta virtual do driver intermediário recebe uma solicitação para definir a energia para um estado de trabalho, a sequência de eventos para manipular a solicitação é a seguinte:
O NDIS emite uma OID_PNP_SET_POWER para a miniporta virtual do driver intermediário. O driver intermediário retorna NDIS_STATUS_SUCCESS para a solicitação de energia definida. O driver intermediário não deve propagar a solicitação de OID_PNP_SET_POWER para o driver de miniporta subjacente.
O NDIS reinicia a miniporta virtual e, em seguida, reinicia os drivers sobrepostos depois de emitir o OID de energia definido. Para obter mais informações sobre como reiniciar uma miniporta virtual, consulte Iniciando um adaptador.
O NDIS chama a função ProtocolNetPnPEvent dos drivers de protocolo sobrepostos. A chamada para ProtocolNetPnPEvent especifica um evento NetEventSetPower para definir o estado de trabalho (D0). Os drivers de protocolo acoplados podem começar a enviar dados de rede para a miniporta virtual do driver intermediário.
Quando a borda inferior do protocolo do driver intermediário faz a transição do driver de miniporta subjacente para um estado de trabalho, a sequência de eventos para manipular a transição é a seguinte:
O NDIS emite um OID_PNP_SET_POWER para o driver de miniporta subjacente ou chama seu manipulador MiniportInitializeEx se o driver de miniporta subjacente foi interrompido.
O NDIS reinicia o driver de miniporta subjacente e, em seguida, a borda de protocolo do NDIS intermediário e o adaptador de miniporta subjacente após emitir o OID. Para obter mais informações sobre como pausar uma associação de protocolo, consulte Reiniciando uma associação.
O NDIS chama a função ProtocolNetPnPEvent do driver intermediário. A chamada para ProtocolNetPnPEvent especifica um evento NetEventSetPower para definir o estado de trabalho (D0). O driver intermediário pode começar a enviar dados de rede para o driver de miniporta subjacente.
Estados de energia e a bandeira de espera
O driver intermediário deve manter uma variável de estado de energia separada para cada instância de miniporta virtual e para cada driver de miniporta subjacente ao qual o driver está vinculado. O driver intermediário também deve manter um sinalizador StandingBy para cada miniporta virtual que seja:
Defina como TRUE quando o estado de energia da miniporta virtual ou do driver de miniporta subjacente sair de D0.
Defina como FALSE quando o estado de energia da miniporta virtual ou do driver de miniporta subjacente retornar a D0.
Observação Para drivers intermediários MUX, pode haver várias miniportas virtuais associadas a um driver de miniporta subjacente ou várias miniportas subjacentes associadas a cada miniporta virtual. Quando o estado de energia de qualquer adaptador de miniporta muda, o comportamento de todas as miniportas associadas também é afetado. A forma como o comportamento é afetado é específica da implementação. Por exemplo, um driver que implementa uma solução LBFO (Load Balancing Failover) pode não desativar as miniportas virtuais quando um único driver de miniporta subjacente é desativado. No entanto, uma implementação de driver que depende de todos os drivers de miniporta subjacentes exigiria a desativação de miniportas virtuais quando qualquer driver de miniporta subjacente fosse desativado.
O driver intermediário deve usar o sinalizador StandingBy e as variáveis de estado de energia ao processar solicitações da seguinte maneira:
A função MiniportSendNetBufferLists do driver deve falhar, a menos que a miniporta virtual e seu adaptador de miniporta subjacente estejam ambos em D0.
A função MiniportOidRequest do driver sempre deve ser bem-sucedida OID_PNP_QUERY_POWER para garantir que o driver receba as solicitações de OID_PNP_SET_POWER subsequentes.
A função MiniportOidRequest do driver deve falhar se a miniporta virtual não estiver em D0 ou se StandingBy for TRUE. Caso contrário, ele deve enfileirar uma única solicitação se o driver de miniporta subjacente não estiver em D0. Uma solicitação enfileirada deve ser processada quando o estado do driver de miniporta subjacente se torna D0.
A miniporta virtual do driver intermediário deve relatar o status somente se o driver de miniporta subjacente e a miniporta virtual estiverem em D0.