Gestione di una richiesta di risparmio energia impostata
Un driver intermedio deve gestire le richieste per impostare l'alimentazione sullo stato di lavoro (uno stato di alimentazione del dispositivo di rete di D0) e per gli stati di sospensione (uno stato di alimentazione del dispositivo di rete D1, D2 o D3). Il driver intermedio deve anche mantenere le variabili di stato di alimentazione e un flag StandBy. Questi problemi vengono illustrati più avanti in questo argomento.
Per esempi di risparmio energia del driver intermedio, vedere l'esempio di driver intermedio MUX NDIS e Notify Object driver nel repository degli esempi di driver di Windows su GitHub.
Gestione di una richiesta di alimentazione impostata su uno stato di sospensione
Esistono due casi in cui un driver intermedio deve gestire una richiesta di alimentazione impostata su uno stato di sospensione:
NDIS richiede che il bordo superiore del miniport virtuale del driver intermedio vada a uno stato di sospensione.
Il bordo inferiore del protocollo del driver intermedio gestisce la transizione del driver miniport sottostante a uno stato di sospensione quando riceve una notifica degli eventi Plug and Play (PnP).
Questi eventi possono verificarsi in qualsiasi ordine e un evento non accompagna necessariamente l'altro.
Quando il bordo superiore del miniport virtuale del driver intermedio riceve una richiesta di impostare l'alimentazione su uno stato di sospensione, la sequenza di eventi per la gestione della richiesta è la seguente:
NDIS chiama la funzione ProtocolNetPnPEvent di ogni driver di protocollo associato al miniport virtuale. La chiamata a ProtocolNetPnPEvent specifica un evento NetEventSetPower per uno stato di sospensione. I driver di protocollo associati al driver intermedio interrompono l'invio di dati di rete e effettuano richieste OID al miniport virtuale del driver intermedio. Il bordo inferiore del protocollo del driver intermedio può continuare a inviare i dati di rete e le richieste fino a quando NDIS indica che il driver miniport sottostante sta effettuando la transizione a uno stato di sospensione.
NDIS sospende i driver overlying e quindi il miniport virtuale dopo l'emissione dell'evento NetEventSetPower . Il motivo specificato per la sospensione è una transizione a uno stato a basso consumo. Per altre informazioni sulla sospensione di un miniport virtuale, vedere Sospensione di un adapter.
Nota Non è possibile inviare richieste OID al miniport virtuale mentre si trova in uno stato a basso consumo, ad eccezione di OID_PNP_edizione Standard T_POWER.
NDIS invia una richiesta di OID_PNP_edizione Standard T_POWER al miniport virtuale del driver intermedio. Il driver intermedio accetta la richiesta restituendo NDIS_STATUS_SUCCESS. Il driver intermedio non deve propagare la richiesta di OID_PNP_edizione Standard T_POWER al driver miniport sottostante. Dopo che il driver intermedio ha completato questa richiesta, non deve indicare altri dati di rete ricevuti o indicare lo stato, anche se continua a ricevere dati di rete e indicazioni sullo stato dal driver miniport sottostante.
Quando il bordo inferiore del protocollo del driver intermedio passa il driver miniport sottostante a uno stato di sospensione, la sequenza di eventi per la gestione della transizione è la seguente:
NDIS chiama la funzione ProtocolNetPnPEvent del bordo inferiore del protocollo del driver intermedio. La chiamata a ProtocolNetPnPEvent specifica un evento NetEventSetPower per uno stato di sospensione. Il driver intermedio deve interrompere l'invio di dati di rete ed effettuare richieste OID al driver miniport sottostante. Se sono presenti richieste o invii in sospeso, il driver intermedio deve restituire NDIS_STATUS_PENDING dalla chiamata a ProtocolNetPnPEvent. Il driver intermedio chiama NdisCompleteNetPnPEvent per completare la chiamata a ProtocolNetPnPEvent. Il bordo del protocollo di un driver intermedio può comunque ottenere le indicazioni di stato e pacchetti ricevuti dal driver miniport sottostante. I dati di rete ricevuti possono essere ignorati. Se l'implementazione di un driver intermedio dipende dal monitoraggio dello stato del driver miniport sottostante, le indicazioni sullo stato devono comunque essere monitorate.
NDIS sospende il bordo del protocollo del driver intermedio e quindi sospende l'adattatore miniport sottostante dopo l'emissione dell'evento NetEventSetPower . Il motivo specificato per la sospensione è una transizione a uno stato a basso consumo. Per altre informazioni sulla sospensione di un'associazione di protocollo, vedere Sospensione di un'associazione.
Nota Nessuna richiesta OID può essere inviata all'adattatore miniport sottostante mentre è in uno stato a basso consumo, ad eccezione di OID_PNP_edizione Standard T_POWER.
NDIS invia una richiesta di OID_PNP_edizione Standard T_POWER al driver miniport sottostante. Tuttavia, se il driver miniport sottostante non supporta il risparmio energia, verrà interrotto. In questo caso, anche se NDIS interrompe il driver miniport sottostante, non richiede il protocollo intermedio del driver per scollegare dal driver miniport sottostante e dalla scheda di interfaccia di rete. Dopo che il driver miniport sottostante ha completato correttamente l'elaborazione dell'OID (o il driver miniport è stato interrotto), non indicherà altri dati o stato di rete.
Gestione di una richiesta di risparmio energia impostata sullo stato di lavoro
Esistono due casi in cui un driver intermedio gestisce una richiesta di alimentazione impostata sullo stato di lavoro:
NDIS richiede che il bordo superiore del miniport virtuale del driver intermedio vada allo stato di lavoro.
Il bordo inferiore del protocollo del driver intermedio gestisce la transizione del driver miniport sottostante allo stato di lavoro, quando riceve una notifica degli eventi Plug and Play (PnP).
Questi eventi possono verificarsi in qualsiasi ordine e un evento non accompagna necessariamente l'altro.
Quando il bordo superiore del miniport virtuale del driver intermedio riceve una richiesta di impostare l'alimentazione su uno stato di lavoro, la sequenza di eventi per la gestione della richiesta è la seguente:
NDIS rilascia un OID_PNP_edizione Standard T_POWER al miniport virtuale del driver intermedio. Il driver intermedio restituisce NDIS_STATUS_SUCCESS alla richiesta di alimentazione impostata. Il driver intermedio non deve propagare la richiesta di OID_PNP_edizione Standard T_POWER al driver miniport sottostante.
NDIS riavvia il miniport virtuale e quindi riavvia i driver overlying dopo l'emissione dell'OID di alimentazione impostata. Per altre informazioni sul riavvio di un miniport virtuale, vedere Avvio di un adapter.
NDIS chiama la funzione ProtocolNetPnPEvent dei driver di protocollo overlying. La chiamata a ProtocolNetPnPEvent specifica un evento NetEventSetPower per impostare lo stato di lavoro (D0). I driver di protocollo associati possono iniziare a inviare dati di rete al miniport virtuale del driver intermedio.
Quando il bordo inferiore del protocollo del driver intermedio passa il driver miniport sottostante a uno stato di lavoro, la sequenza di eventi per la gestione della transizione è la seguente:
NDIS rilascia un OID_PNP_edizione Standard T_POWER al driver miniport sottostante o chiama il relativo gestore MiniportInitializeEx se il driver miniport sottostante è stato interrotto.
NDIS riavvia il driver miniport sottostante e quindi il bordo del protocollo dell'NDIS intermedio e dell'adattatore miniport sottostante dopo l'emissione dell'OID. Per altre informazioni sulla sospensione di un'associazione di protocollo, vedere Riavvio di un'associazione.
NDIS chiama la funzione ProtocolNetPnPEvent del driver intermedio. La chiamata a ProtocolNetPnPEvent specifica un evento NetEventSetPower per impostare lo stato di lavoro (D0). Il driver intermedio può iniziare a inviare dati di rete al driver miniport sottostante.
Stati di alimentazione e flag di standby
Il driver intermedio deve mantenere una variabile di stato di alimentazione separata per ogni istanza di miniport virtuale e per ogni driver miniport sottostante a cui è associato il driver. Il driver intermedio deve anche mantenere un flag StandingBy per ogni miniport virtuale che è:
Impostare su TRUE quando lo stato di alimentazione del miniport virtuale o del driver miniport sottostante lascia D0.
Impostare su FAL edizione Standard quando lo stato di alimentazione del miniport virtuale o del driver miniport sottostante torna a D0.
Nota Per i driver intermedi MUX, possono essere presenti più miniport virtuali associati a un driver miniport sottostante o a più miniport sottostanti associati a ogni miniport virtuale. Quando lo stato di alimentazione di qualsiasi adattatore miniport cambia, anche il comportamento di tutti i miniport associati è interessato. La modalità di influenza del comportamento è specifica dell'implementazione. Ad esempio, un driver che implementa una soluzione LBFO (Load Balancing Failover) potrebbe non disattivare i miniport virtuali quando viene disattivato un singolo driver miniport sottostante. Tuttavia, un'implementazione del driver che dipende da tutti i driver miniport sottostanti richiederebbe la disattivazione di miniport virtuali quando qualsiasi driver miniport sottostante viene disattivato.
Il driver intermedio deve usare il flag StandingBy e le variabili di stato di alimentazione durante l'elaborazione delle richieste come indicato di seguito:
La funzione MiniportSendNetBufferLists del driver non riesce a meno che il miniport virtuale e la relativa scheda miniport sottostante non siano entrambi in D0.
La funzione MiniportOidRequest del driver deve avere sempre esito positivo OID_PNP_QUERY_POWER per assicurarsi che il driver riceva le richieste di OID_PNP_edizione Standard T_POWER successive.
La funzione MiniportOidRequest del driver non riesce se il miniport virtuale non è in D0 o se StandingBy è TRUE. In caso contrario, deve accodarsi una singola richiesta se il driver miniport sottostante non è in D0. Una richiesta in coda deve essere elaborata quando lo stato del driver miniport sottostante diventa D0.
Il miniport virtuale del driver intermedio deve segnalare lo stato solo se il driver miniport sottostante e il miniport virtuale sono in D0.