Partager via


Gestion des IRP_MN_QUERY_POWER pour les états d’alimentation de l’appareil

Un IRP de requête d’appareil interroge un changement d’état pour un seul appareil et est envoyé à tous les pilotes de la pile pour l’appareil. Un tel IRP spécifie DevicePowerState dans le membre Power.Type de l’emplacement de la pile d’E/S.

Les pilotes gèrent les runtimes d’intégration d’alimentation des requêtes au fur et à mesure qu’ils descendent de la pile.

Un pilote de fonction ou de filtre peut échouer à une demande de IRP_MN_QUERY_POWER si l’une des conditions suivantes est remplie :

  • L’appareil est activé pour la mise en éveil et l’état d’alimentation demandé est inférieur à l’état à partir duquel l’appareil peut sortir le système. Par exemple, un appareil qui peut sortir le système de D2, mais pas de D3, échouerait une requête pour D3, mais réussirait une requête pour D2.

  • L’entrée dans l’état demandé forcerait le pilote à abandonner une opération qui perdrait des données, telle qu’une connexion de modem ouverte. Un pilote échoue rarement une requête pour cette raison ; dans la plupart des cas, l’application gère ces cas.

Pour faire échouer une demande de IRP_MN_QUERY_POWER , un pilote effectue les étapes suivantes :

  1. Appelez PoStartNextPowerIrp pour indiquer que le pilote est prêt à gérer la prochaine IRP d’alimentation. (Windows Server 2003, Windows XP et Windows 2000 uniquement.)

  2. Définissez Irp-IoStatus.Status> sur un échec status et appelez IoCompleteRequest, en spécifiant IO_NO_INCREMENT. Le pilote ne passe pas l’IRP plus loin dans la pile de périphériques.

  3. Retourne une erreur status à partir de sa routine DispatchPower.

Si le pilote réussit l’IRP d’alimentation de requête, il ne doit pas démarrer d’opérations ou prendre d’autres mesures qui empêcheraient l’achèvement d’une demande de IRP_MN_SET_POWER suivante à l’état d’alimentation interrogé.

Un pilote qui réussit l’IRP doit se préparer à un IRP de puissance définie pour l’état interrogé et transmettre l’IRP de requête, comme suit :

  1. Terminez toutes les opérations d’E/S en suspens.

  2. Mettre en file d’attente les demandes d’E/S entrantes.

  3. Évitez de démarrer d’autres activités qui interféreraient avec une transition vers l’état d’alimentation spécifié. Toutefois, le pilote ne doit pas enregistrer le contexte de l’appareil ou effectuer d’autres étapes vers l’arrêt.

  4. Appelez IoCopyCurrentIrpStackLocationToNext pour définir l’emplacement de la pile IRP pour le pilote inférieur suivant.

  5. Définissez une routine IoCompletion . Dans la routine IoCompletion , appelez PoStartNextPowerIrp (Windows Server 2003, Windows XP et Windows 2000 uniquement) pour indiquer que le pilote est prêt à gérer la prochaine IRP d’alimentation.

  6. Appelez IoCallDriver (dans Windows 7 et Windows Vista) ou PoCallDriver (dans Windows Server 2003, Windows XP et Windows 2000) pour passer l’IRP de requête au pilote inférieur suivant. Ne terminez pas le IRP.

  7. Retourne STATUS_PENDING. Le pilote ne doit pas modifier la valeur dans Irp-IoStatus.Status>.

Lorsque l’IRP d’alimentation de requête atteint le pilote de bus, le pilote de bus appelle PoStartNextPowerIrp (Windows Server 2003, Windows XP et Windows 2000 uniquement) et définit Irp-IoStatus.Status> sur STATUS_SUCCESS si le pilote peut passer à l’état d’alimentation spécifié ou définit une défaillance status si ce n’est pas le cas. Le pilote de bus appelle ensuite IoCompleteRequest, en spécifiant IO_NO_INCREMENT.

Les pilotes d’une pile de périphériques classique gèrent un IRP de requête d’appareil comme suit :

  • La plupart des pilotes de filtre doivent simplement passer l’IRP au pilote inférieur suivant (voir Passer des irps d’alimentation) et retourner STATUS_PENDING. Toutefois, certains pilotes de filtre peuvent devoir d’abord effectuer des tâches spécifiques aux appareils, telles que la mise en file d’attente des IRP entrants ou l’enregistrement de l’état d’alimentation de l’appareil.

  • Un pilote de fonction effectue des tâches spécifiques à l’appareil (par exemple, terminer les demandes d’E/S en attente, mettre en file d’attente les demandes d’E/S entrantes, enregistrer le contexte de l’appareil ou modifier l’alimentation de l’appareil), définit une routine IoCompletion et transmet l’IRP d’alimentation du périphérique au pilote inférieur suivant (voir Passer des irps d’alimentation). Il retourne STATUS_PENDING de sa routine DispatchPower .

  • Le pilote de bus appelle PoStartNextPowerIrp (Windows Server 2003, Windows XP et Windows 2000 uniquement) pour démarrer la prochaine IRP d’alimentation. Il termine ensuite l’IRP, en spécifiant IO_NO_INCREMENT. Si le pilote ne peut pas terminer l’IRP immédiatement, il appelle IoMarkIrpPending, retourne STATUS_PENDING à partir de sa routine DispatchPower et termine l’IRP ultérieurement.

Même si l’appareil cible est déjà dans l’état d’alimentation interrogé, chaque pilote de fonction ou de filtre doit mettre en file d’attente les E/S et passer l’IRP au pilote inférieur suivant. L’IRP doit descendre de la pile d’appareils jusqu’au pilote de bus, qui le termine.

Lors de la gestion d’une demande de IRP_MN_QUERY_POWER , un pilote doit revenir de la routine DispatchPower aussi rapidement que possible. Un pilote ne doit pas attendre dans sa routine DispatchPower un événement de noyau signalé par le code qui gère le même IRP. Étant donné que les irps d’alimentation sont synchronisés dans tout le système, un interblocage peut se produire.