Freigeben über


Senden von IRP_MN_QUERY_POWER oder IRP_MN_SET_POWER für Gerätestromzustände

Ein Besitzer der Geräteenergierichtlinie sendet eine Geräteabfrage-Energie-IRP (IRP_MN_QUERY_POWER), um zu bestimmen, ob niedrigere Treiber eine Änderung des Geräteenergiezustands berücksichtigen können, und eine Gerätesatz-Leistungs-IRP (IRP_MN_SET_POWER), um den Energiezustand des Geräts zu ändern. (Dieser Treiber kann auch eine Warte-/Aktivierungs-IRP senden, um das Gerät als Reaktion auf ein externes Signal zu aktivieren. Weitere Informationen finden Sie unter Unterstützen von Geräten, die über Wake-Up Funktionen verfügen .)

Der Treiber sollte eine IRP_MN_QUERY_POWER-Anforderung senden, wenn eine der folgenden Punkte zutrifft:

  • Der Treiber empfängt eine Systemabfrage-Leistungs-IRP.

  • Der Treiber bereitet sich darauf vor, ein Gerät im Leerlauf in einen Ruhezustand zu versetzen. Daher müssen niedrigere Treiber abgefragt werden, um herauszufinden, ob dies möglich ist.

Der Treiber sollte eine IRP_MN_SET_POWER-Anforderung senden, wenn eine der folgenden Punkte zutrifft:

  • Der Treiber hat ermittelt, dass sich das Gerät im Leerlauf befindet und in den Standbymodus versetzt werden kann.

  • Das Gerät befindet sich im Ruhezustand und muss erneut in den Arbeitszustand wechseln, um wartende E/A-Vorgänge zu verarbeiten.

  • Der Treiber erhält eine Systemsatz-Leistungs-IRP.

Ein Treiber darf keine eigene Leistungs-IRP zuordnen. der Energie-Manager stellt die PoRequestPowerIrp-Routine für diesen Zweck bereit. Wie Regeln für die Behandlung von Power IRPs erläutert, weist PoRequestPowerIrp die IRP zu und sendet sie und stellt in Kombination mit IoCallDriver (in Windows 7 und Windows Vista) oder PoCallDriver (in Windows Server 2003, Windows XP und Windows 2000) sicher, dass alle Energieanforderungen ordnungsgemäß synchronisiert werden. Aufrufer von PoRequestPowerIrp müssen unter IRQL <= DISPATCH_LEVEL ausgeführt werden.

Im Folgenden ist der Prototyp für diese Routine dargestellt:

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
    );

Um das IRP zu senden, ruft der Treiber PoRequestPowerIrp auf und gibt einen Zeiger auf das Zielgeräteobjekt in DeviceObject an, den untergeordneten IRP-Code IRP_MN_SET_POWER oder IRP_MN_QUERY_POWER in MinorFunction, den Wert DevicePowerState in PowerState. Geben Sie ein, und geben Sie den Energiezustand des Geräts in PowerState an. Status. In Windows 98/Me muss DeviceObject die PDO des zugrunde liegenden Geräts angeben. In Windows 2000 und höheren Versionen von Windows kann dieser Wert entweder auf die PDO oder eine FDO eines Treibers im selben Gerätestapel verweisen.

Wenn der Treiber zusätzliche Aufgaben ausführen muss, nachdem alle anderen Treiber das IRP abgeschlossen haben, sollte er einen Zeiger auf eine Energieabschlussfunktion in CompletionFunction übergeben. Der E/A-Manager ruft die CompletionFunction auf, nachdem alle IoCompletion-Routinen aufgerufen wurden, die von Treibern festgelegt wurden, während sie den IRP im Stapel übergeben haben.

Jedes Mal, wenn ein Besitzer einer Geräteenergierichtlinie eine IRP für die Geräteenergieabfrage sendet, sollte er anschließend eine Gerätesatz-Energie-IRP aus der Rückrufroutine (CompletionFunction) senden, die er im Aufruf von PoRequestPowerIrp angegeben hat. Wenn die Abfrage erfolgreich war, gibt der IRP set-power den abgefragten Energiezustand an. Wenn bei der Abfrage ein Fehler aufgetreten ist, bestätigt der Set-Power-IRP den aktuellen Gerätestromzustand erneut. Die erneute Bestätigung des aktuellen Zustands ist wichtig, da Treiber E/A-E/A als Reaktion auf die Abfrage in die Warteschlange stellen. Der Richtlinienbesitzer muss den Set-Power-IRP senden, um Treiber in seinem Gerätestapel zu benachrichtigen, um mit der Verarbeitung von E/A-Anforderungen in der Warteschlange zu beginnen.

Beachten Sie, dass der Richtlinienbesitzer für ein Gerät nicht nur die IRP für die Geräteleistung sendet, sondern auch die IRP verarbeitet, während sie im Gerätestapel übergeben wird. Daher legt ein solcher Treiber häufig eine IoCompletion-Routine (mit IoSetCompletionRoutine) als Teil seines IRP-Behandlungscodes fest, insbesondere wenn das Gerät hochgeschalten wird. Die IoCompletion-Routine wird nacheinander mit IoCompletion-Routinen aufgerufen, die von anderen Treibern und vor der CompletionFunction festgelegt werden. Weitere Informationen finden Sie unter IoCompletion Routines for Device Power IRPs( IoCompletion Routines for Device Power IRPs).

Da die IRP von allen Treibern abgeschlossen wurde, wenn die CompletionFunction aufgerufen wird, darf die CompletionFunctionioCallDriver, PoCallDriver oder PoStartNextPowerIrp nicht mit dem IRP aufrufen, das sie stammt. (Es kann jedoch diese Routinen für eine andere Leistungs-IRP aufrufen.) Stattdessen führt diese Routine alle zusätzlichen Aktionen aus, die vom Treiber erforderlich sind, der aus dem IRP stammt. Wenn der Treiber die Geräte-IRP als Reaktion auf eine System-IRP gesendet hat, kann die CompletionFunction die System-IRP abschließen. Weitere Informationen finden Sie unter Handling a System Set-Power IRP in a Device Power Policy Owner.For further information, see Handling a System Set-Power IRP in a Device Power Policy Owner.

Als Reaktion auf den Aufruf von PoRequestPowerIrp ordnet der Energie-Manager eine Energie-IRP zu und sendet sie an den Anfang des Gerätestapels für das Gerät. Der Energie-Manager gibt einen Zeiger auf die zugeordnete IRP zurück.

Wenn keine Fehler auftreten, gibt PoRequestPowerIrp STATUS_PENDING zurück. Dies status bedeutet, dass das IRP erfolgreich gesendet wurde und aussteht. Der Aufruf schlägt fehl, wenn der Energie-Manager die IRP nicht zuordnen kann oder wenn der Aufrufer einen ungültigen Nebenleistungs-IRP-Code angegeben hat.

Anforderungen zum Einschalten eines Geräts müssen zuerst vom zugrunde liegenden Bustreiber für das Gerät und dann von jedem nacheinander höheren Treiber im Stapel verarbeitet werden. Daher muss der Treiber beim Senden einer PowerDeviceD0-Anforderung sicherstellen, dass seine CompletionFunction die erforderlichen Aufgaben ausführt, nachdem das IRP abgeschlossen und das Gerät eingeschaltet ist.

Beim Ausschalten eines Geräts (PowerDeviceD3) muss jeder Treiber im Gerätestapel den gesamten erforderlichen Kontext speichern und alle erforderlichen sauber ausführen, bevor der IRP an den nächstniedrigen Treiber gesendet wird. Der Umfang der Kontextinformationen und sauber hängt vom Typ des Treibers ab. Ein Funktionstreiber muss den Hardwarekontext speichern. Ein Filtertreiber muss möglicherweise seinen eigenen Softwarekontext speichern. Ein CompletionFunction-Satz kann in dieser Situation Aktionen ausführen, die einem abgeschlossenen Energie-IRP zugeordnet sind, aber der Treiber kann nicht auf das Gerät zugreifen.