Condividi tramite


Invio di IRP_MN_QUERY_POWER o IRP_MN_SET_POWER per stati di alimentazione del dispositivo

Un proprietario della politica di gestione dell'energia del dispositivo invia un IRP (IRP_MN_QUERY_POWER) di richiesta di potenza del dispositivo per determinare se i driver di livello inferiore possono supportare una modifica dello stato di alimentazione del dispositivo e un IRP (IRP_MN_SET_POWER) di richiesta di impostazione della potenza per modificare lo stato di alimentazione del dispositivo. Questo driver può anche inviare un IRP di attesa/riattivazione per consentire al dispositivo di riattivarsi in risposta a un segnale esterno. Per informazioni dettagliate, vedere Dispositivi di supporto con funzionalità Wake-Up .

Il driver deve inviare una richiesta di IRP_MN_QUERY_POWER quando una delle condizioni seguenti è vera:

  • Il driver riceve un IRP di richiesta di alimentazione.

  • Il driver si sta preparando a mettere un dispositivo inattivo in uno stato di sospensione, quindi è necessario consultare i driver sottostanti per verificare se è possibile farlo.

Il driver deve inviare una richiesta di IRP_MN_SET_POWER quando è true una delle condizioni seguenti:

  • Il driver ha determinato che il dispositivo è inattivo e può essere messo in modalità sospensione.

  • Il dispositivo è in modalità sospensione e deve rientrare nello stato di lavoro per gestire l'I/O in attesa.

  • Il driver riceve un IRP di alimentazione del sistema.

Un driver non deve allocare il proprio IRP di alimentazione; il gestore di alimentazione fornisce la routine PoRequestPowerIrp a questo scopo. Come le regole per la gestione degli IRP di alimentazione spiegano, PoRequestPowerIrp alloca e invia l'IRP e in combinazione con IoCallDriver (in Windows 7 e Windows Vista) o PoCallDriver (in Windows Server 2003, Windows XP e Windows 2000), garantisce che tutte le richieste di alimentazione siano sincronizzate correttamente. I chiamanti di PoRequestPowerIrp devono essere in esecuzione in IRQL <= DISPATCH_LEVEL.

Di seguito è riportato il prototipo per questa routine:

NTSTATUS
PoRequestPowerIrp (
    IN PDEVICE_OBJECT DeviceObject,
    IN UCHAR MinorFunction,
    IN POWER_STATE PowerState,
    IN PREQUEST_POWER_COMPLETE CompletionFunction,
    IN PVOID Context,
    OUT PIRP *Irp OPTIONAL
    );

Per inviare l'IRP, il driver chiama PoRequestPowerIrp, specificando un puntatore all'oggetto dispositivo di destinazione in DeviceObject, il codice IRP secondario IRP_MN_SET_POWER o IRP_MN_QUERY_POWER in MinorFunction, il valore DevicePowerState in PowerState.Tipo e uno stato energetico del dispositivo in PowerState.Stato. In Windows 98/Me, DeviceObject deve specificare il PDO del dispositivo sottostante; in Windows 2000 e versioni successive di Windows, questo valore può puntare al PDO o a un FDO relativo a un driver nello stesso stack di dispositivi.

Se il driver deve eseguire attività aggiuntive dopo che tutti gli altri driver hanno completato l'IRP, deve passare un puntatore a una funzione di completamento dell'alimentazione in CompletionFunction. Il gestore di I/O chiama CompletionFunction dopo aver chiamato tutte le routine IoCompletion impostate dai driver durante il passaggio dell'IRP nello stack.

Ogni volta che un proprietario dei criteri di potenza del dispositivo invia un IRP per la query della potenza del dispositivo, deve successivamente inviare un IRP di impostazione della potenza del dispositivo dalla routine di callback (CompletionFunction) specificata nella chiamata a PoRequestPowerIrp. Se la query ha avuto esito positivo, il set-power IRP specifica lo stato di alimentazione interrogato. Se la query non è riuscita, l'IRP set-power riafferma lo stato di alimentazione corrente del dispositivo. Riaffermare lo stato attuale è importante perché i driver mettono in coda le operazioni di I/O in risposta alla query; il proprietario dei criteri deve inviare l'IRP di impostazione alimentazione per notificare ai driver nel proprio stack di dispositivi di iniziare l'elaborazione delle richieste di I/O in coda.

Ricorda che il proprietario della politica per un dispositivo non solo invia l'IRP di alimentazione del dispositivo, ma gestisce anche l'IRP man mano che viene passato lungo lo stack di dispositivi. Di conseguenza, un driver di questo tipo imposta spesso una routine IoCompletion (con IoSetCompletionRoutine) come parte del codice di gestione di IRP, in particolare quando il dispositivo è alimentato. La routine IoCompletion viene chiamata in sequenza con routine IoCompletion impostate da altri driver e prima di CompletionFunction. Per ulteriori informazioni, vedere Routine IoCompletion per IRP di alimentazione del dispositivo.

Poiché l'IRP è stato completato da tutti i driver quando viene chiamato CompletionFunction, CompletionFunction non deve chiamare IoCallDriver, PoCallDriver o PoStartNextPowerIrp con l'IRP da cui ha avuto origine. Potrebbe tuttavia chiamare queste routine per un'IRP di alimentazione diversa. Questa routine esegue invece eventuali azioni aggiuntive richieste dal driver che ha originato l'IRP. Se il driver ha inviato l'IRP del dispositivo in risposta a un IRP di sistema, CompletionFunction potrebbe completare l'IRP di sistema. Per altre informazioni, vedere Gestione di un sistema Set-Power IRP in un proprietario della politica energetica del dispositivo.

In risposta alla chiamata a PoRequestPowerIrp, il gestore dell'alimentazione assegna un IRP di alimentazione e lo invia all'inizio dello stack di dispositivi per il dispositivo. Il gestore dell'alimentazione restituisce un puntatore all'IRP allocato.

Se non si verificano errori, PoRequestPowerIrp restituisce STATUS_PENDING. Questo stato indica che l'IRP è stato inviato correttamente e che è in attesa di completamento. La chiamata ha esito negativo se il gestore dell'alimentazione non può allocare l'IRP o se il chiamante ha specificato un codice IRP minore di alimentazione non valido.

Le richieste di accensione di un dispositivo devono essere gestite prima dal driver del bus sottostante per il dispositivo e quindi da ogni driver successivamente superiore nello stack. Pertanto, quando si invia una richiesta PowerDeviceD0 , il driver deve assicurarsi che CompletionFunction esegua le attività necessarie dopo il completamento dell'IRP e che il dispositivo sia acceso.

Quando si spegne un dispositivo (PowerDeviceD3), ogni driver nello stack di dispositivi deve salvare tutto il contesto necessario ed eseguire tutte le operazioni di pulizia necessarie prima di inviare l'IRP al driver inferiore successivo. L'estensione delle informazioni di contesto e la pulizia dipendono dal tipo di driver. Un driver di funzione deve salvare il contesto hardware; un driver di filtro potrebbe dover salvare il proprio contesto software. Un oggetto CompletionFunction impostato in questa situazione può eseguire azioni associate a un IRP di alimentazione completato, ma il driver non può accedere al dispositivo.