Envoi de IRP_MN_QUERY_POWER ou de IRP_MN_SET_POWER pour les états d’alimentation de l’appareil
Un propriétaire de stratégie d’alimentation de l’appareil envoie un IRP de requête d’appareil (IRP_MN_QUERY_POWER) pour déterminer si les pilotes inférieurs peuvent prendre en charge une modification de l’état d’alimentation de l’appareil, et un IRP (IRP_MN_SET_POWER) pour modifier l’état d’alimentation de l’appareil. (Ce pilote peut également envoyer un IRP d’attente/veille pour permettre à son appareil de se réveiller en réponse à un signal externe ; pour plus d’informations, consultez Appareils de prise en charge dotés de fonctionnalités Wake-Up .)
Le pilote doit envoyer une demande de IRP_MN_QUERY_POWER lorsque l’une des conditions suivantes est remplie :
Le pilote reçoit un IRP de requête système.
Le pilote se prépare à mettre un appareil inactif en veille. Il doit donc interroger les pilotes inférieurs pour savoir si cela est possible.
Le pilote doit envoyer une demande de IRP_MN_SET_POWER lorsque l’une des conditions suivantes est remplie :
Le pilote a déterminé que l’appareil est inactif et peut être mis en veille.
L’appareil est en veille et doit entrer à nouveau dans l’état de fonctionnement pour gérer les E/S en attente.
Le pilote reçoit un IRP set-power du système.
Un pilote ne doit pas allouer sa propre IRP d’alimentation; le gestionnaire d’alimentation fournit la routine PoRequestPowerIrp à cet effet. Comme l’explique les règles de gestion des IRP d’alimentation , PoRequestPowerIrp alloue et envoie l’IRP et, en combinaison avec IoCallDriver (dans Windows 7 et Windows Vista), ou PoCallDriver (dans Windows Server 2003, Windows XP et Windows 2000), garantit que toutes les demandes d’alimentation sont correctement synchronisées. Les appelants de PoRequestPowerIrp doivent s’exécuter sur IRQL <= DISPATCH_LEVEL.
Voici le prototype de cette 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
);
Pour envoyer l’IRP, le pilote appelle PoRequestPowerIrp, en spécifiant un pointeur vers l’objet d’appareil cible dans DeviceObject, le code IRP mineur IRP_MN_SET_POWER ou IRP_MN_QUERY_POWER dans MinorFunction, la valeur DevicePowerState dans powerState. Type et état d’alimentation de l’appareil dans PowerState. État. Dans Windows 98/Me, DeviceObject doit spécifier l’AOP de l’appareil sous-jacent ; dans Windows 2000 et versions ultérieures de Windows, cette valeur peut pointer vers le PDO ou un FDO d’un pilote dans la même pile d’appareils.
Si le pilote doit effectuer des tâches supplémentaires une fois que tous les autres pilotes ont terminé l’IRP, il doit passer un pointeur vers une fonction d’arrêt d’alimentation dans CompletionFunction. Le gestionnaire d’E/S appelle CompletionFunction après avoir appelé toutes les routines IoCompletion définies par les pilotes lorsqu’ils ont passé l’IRP dans la pile.
Chaque fois qu’un propriétaire de stratégie d’alimentation de l’appareil envoie une requête IRP d’alimentation de l’appareil, il doit ensuite envoyer un IRP de définition de l’appareil à partir de la routine de rappel (CompletionFunction) qu’il a spécifiée dans l’appel à PoRequestPowerIrp. Si la requête a réussi, l’IRP set-power spécifie l’état d’alimentation interrogé. Si la requête a échoué, l’IRP set-power affirme à nouveau l’état d’alimentation actuel de l’appareil. Il est important de rétablir l’état actuel, car les pilotes souhaitent mettre en file d’attente les E/S en réponse à la requête ; le propriétaire de la stratégie doit envoyer l’IRP set-power pour avertir les pilotes de sa pile d’appareils de commencer à traiter les demandes d’E/S en file d’attente.
Gardez à l’esprit que le propriétaire de la stratégie d’un appareil envoie non seulement l’IRP d’alimentation de l’appareil, mais gère également l’IRP à mesure qu’il est transmis dans la pile de l’appareil. Par conséquent, un tel pilote définit souvent une routine IoCompletion (avec IoSetCompletionRoutine) dans le cadre de son code de gestion IRP, en particulier lorsque l’appareil s’allume. La routine IoCompletion est appelée dans l’ordre avec les routines IoCompletion définies par d’autres pilotes et avant la fonction CompletionFunction. Pour plus d’informations, consultez Routines IoCompletion pour les irps d’alimentation des appareils.
Étant donné que l’IRP a été effectué par tous les pilotes lorsque la fonction CompletionFunction est appelée, la fonction CompletionFunction ne doit pas appeler IoCallDriver, PoCallDriver ou PoStartNextPowerIrp avec l’IRP qu’elle a générée. (Il peut toutefois appeler ces routines pour un IRP de puissance différent.) Au lieu de cela, cette routine effectue toutes les actions supplémentaires requises par le pilote à l’origine de l’IRP. Si le pilote a envoyé l’IRP de l’appareil en réponse à un IRP système, la fonction CompletionFunction peut terminer l’IRP système. Pour plus d’informations, consultez Gestion d’un système Set-Power IRP dans un propriétaire de stratégie d’alimentation d’appareil.
En réponse à l’appel à PoRequestPowerIrp, le gestionnaire d’alimentation alloue un IRP d’alimentation et l’envoie en haut de la pile de l’appareil pour l’appareil. Le gestionnaire d’alimentation retourne un pointeur vers l’IRP alloué.
Si aucune erreur ne se produit, PoRequestPowerIrp retourne STATUS_PENDING. Cette status signifie que l’IRP a été envoyé avec succès et qu’il est en attente d’achèvement. L’appel échoue si le gestionnaire d’alimentation ne peut pas allouer l’IRP ou si l’appelant a spécifié un code IRP d’alimentation mineure non valide.
Les demandes de mise sous tension d’un appareil doivent d’abord être gérées par le pilote de bus sous-jacent de l’appareil, puis par chaque pilote successivement supérieur dans la pile. Par conséquent, lors de l’envoi d’une requête PowerDeviceD0 , le pilote doit s’assurer que sa fonction CompletionFunction effectue les tâches requises une fois l’IRP terminée et que l’appareil est sous tension.
Lors de la mise hors tension d’un appareil (PowerDeviceD3), chaque pilote de la pile de périphériques doit enregistrer tout son contexte nécessaire et effectuer les propre-up nécessaires avant d’envoyer l’IRP au pilote inférieur suivant. L’étendue des informations de contexte et la propre-up dépendent du type de pilote. Un pilote de fonction doit enregistrer le contexte matériel ; un pilote de filtre peut avoir besoin d’enregistrer son propre contexte logiciel. Un paramètre CompletionFunction défini dans cette situation peut effectuer des actions associées à un IRP d’alimentation terminé, mais le pilote ne peut pas accéder à l’appareil.