Gestione dei IRP_MN_QUERY_POWER per gli stati di alimentazione dei dispositivi

Un IRP per query sul dispositivo esegue query su una modifica dello stato per un singolo dispositivo e viene inviato a tutti i driver nello stack per il dispositivo. Tale IRP specifica DevicePowerState nel membro Power.Type della posizione dello stack I/O.

I driver gestiscono i runtime di integrazione di power query mentre si spostano verso il basso nello stack.

Una funzione o un driver di filtro può avere esito negativo in una richiesta di IRP_MN_QUERY_POWER se una delle condizioni seguenti è vera:

  • Il dispositivo è abilitato per la riattivazione e lo stato di alimentazione richiesto è inferiore allo stato da cui il dispositivo può riattivare il sistema. Ad esempio, un dispositivo in grado di riattivare il sistema da D2 ma non da D3 non riuscirà a eseguire una query per D3, ma avrà esito positivo su una query per D2.

  • L'immissione dello stato richiesto forza il driver ad abbandonare un'operazione che perde dati, ad esempio una connessione modem aperta. Un driver raramente non riuscirà a eseguire una query per questo motivo; nella maggior parte dei casi, l'applicazione gestisce tali casi.

Per non eseguire una richiesta di IRP_MN_QUERY_POWER , un driver esegue i passaggi seguenti:

  1. Chiamare PoStartNextPowerIrp per indicare che il driver è pronto per gestire l'IRP di alimentazione successiva. (Solo Windows Server 2003, Windows XP e Windows 2000).

  2. Impostare Irp-IoStatus.Status> su uno stato di errore e chiamare IoCompleteRequest, specificando IO_NO_INCREMENT. Il driver non passa ulteriormente l'IRP nello stack di dispositivi.

  3. Restituisce uno stato di errore dalla routine DispatchPower .

Se il driver ha esito positivo sull'IRP di potenza della query, non deve avviare alcuna operazione o eseguire qualsiasi altra azione che impedisce il completamento di una richiesta di IRP_MN_SET_POWER successiva allo stato di alimentazione sottoposto a query.

Un driver che ha esito positivo per L'IRP deve preparare un IRP di risparmio energia per lo stato sottoposto a query e passare l'IRP della query, come indicato di seguito:

  1. Completare tutte le operazioni di I/O in sospeso.

  2. Accoda le richieste di I/O in ingresso.

  3. Evitare di avviare altre nuove attività che interferiscono con una transizione allo stato di alimentazione specificato. Tuttavia, il driver non deve salvare il contesto di dispositivo o eseguire altri passaggi per l'arresto.

  4. Chiamare IoCopyCurrentIrpStackLocationToNext per impostare il percorso dello stack IRP per il driver inferiore successivo.

  5. Impostare una routine IoCompletion . Nella routine IoCompletion chiamare PoStartNextPowerIrp (Solo Windows Server 2003, Windows XP e Windows 2000) per indicare la preparazione del driver per gestire la potenza successiva IRP.

  6. Chiama IoCallDriver (in Windows 7 e Windows Vista) o PoCallDriver (in Windows Server 2003, Windows XP e Windows 2000) per passare l'IRP della query al driver inferiore successivo. Non completare l'IRP.

  7. Restituisce STATUS_PENDING. Il driver non deve modificare il valore in Irp-IoStatus.Status>.

Quando query-power IRP raggiunge il driver del bus, il driver del bus chiama PoStartNextPowerIrp (Solo Windows Server 2003, Windows XP e Windows 2000) e imposta Irp-IoStatus.Status> su STATUS_SUCCESS se il driver può passare allo stato di alimentazione specificato o imposta uno stato di errore se non riesce. Il driver dell'autobus chiama quindi IoCompleteRequest, specificando IO_NO_INCREMENT.

I driver in uno stack di dispositivi tipico gestiscono un IRP di query del dispositivo come indicato di seguito:

  • La maggior parte dei driver di filtro deve semplicemente passare l'IRP al driver inferiore successivo (vedere Passaggio di power IRP) e restituire STATUS_PENDING. Alcuni driver di filtro, tuttavia, potrebbero prima dover eseguire attività specifiche del dispositivo, ad esempio accodare i runtime di integrazione in ingresso o salvare lo stato di alimentazione del dispositivo.

  • Un driver di funzione esegue attività specifiche del dispositivo (ad esempio, il completamento di richieste di I/O in sospeso, l'accodamento delle richieste di I/O in ingresso, il salvataggio del contesto di dispositivo o la modifica dell'alimentazione del dispositivo), imposta una routine IoCompletion e passa l'IRP di alimentazione del dispositivo al driver inferiore successivo (vedere Passaggio di power IRP). Restituisce STATUS_PENDING dalla routine DispatchPower .

  • Il driver del bus chiama PoStartNextPowerIrp (Solo Windows Server 2003, Windows XP e Windows 2000) per avviare l'IRP di alimentazione successiva. Completa quindi l'IRP, specificando IO_NO_INCREMENT. Se il driver non riesce a completare immediatamente l'IRP, chiama IoMarkIrpPending, restituisce STATUS_PENDING dalla routine DispatchPower e completa l'IRP in un secondo momento.

Anche se il dispositivo di destinazione è già nello stato di alimentazione sottoposto a query, ogni funzione o driver di filtro deve accodare I/O e passare l'IRP al driver inferiore successivo. L'IRP deve viaggiare fino allo stack di dispositivi fino all'autista dell'autobus, che lo completa.

Durante la gestione di una richiesta di IRP_MN_QUERY_POWER , un driver deve tornare dalla routine DispatchPower il più rapidamente possibile. Un driver non deve attendere nella routine DispatchPower per un evento kernel segnalato dal codice che gestisce lo stesso IRP. Poiché i runtime di integrazione di alimentazione vengono sincronizzati in tutto il sistema, potrebbe verificarsi un deadlock.