Share via


Behandeln von Geräte-Power-Down IRPs

Ein Geräteeinschalt-IRP gibt den Nebenfunktionscode IRP_MN_SET_POWER und einen Gerätestromzustand (PowerDeviceD0, PowerDeviceD1, PowerDeviceD2 oder PowerDeviceD3) an, der weniger oder gleich dem aktuellen Gerätestromzustand ist. Treiber müssen die Herunterschalt-IRP verarbeiten, während der IRP den Gerätestapel hinunter bewegt. Treiber auf höherer Ebene müssen die IRP vor Treibern auf niedrigerer Ebene verarbeiten. Treiber, die keine gerätespezifischen Aufgaben ausführen müssen, sollten den IRP umgehend an den nächstniedrigen Treiber übergeben.

Die folgende Abbildung zeigt die Schritte, die bei der Behandlung einer solchen IRP erforderlich sind.

Diagramm, das die Behandlung einer Geräteeinschaltanforderung veranschaulicht.

Wenn der IRP PowerDeviceD3 angibt, sollte der Funktionstreiber in der Regel die folgenden Aufgaben ausführen:

  • Rufen Sie IoAcquireRemoveLock an, und übergeben Sie die aktuelle IRP, um sicherzustellen, dass der Treiber keine PnP-IRP_MN_REMOVE_DEVICE-Anforderung empfängt, während er die Energie-IRP verarbeitet.

    Wenn IoAcquireRemoveLock einen Fehler status zurückgibt, sollte der Treiber die Verarbeitung des IRP nicht fortsetzen. Stattdessen sollte der Treiber ab Windows Vista IoCompleteRequest aufrufen, um die IRP abzuschließen und dann den Fehler status zurückzugeben. In Windows Server 2003, Windows XP und Windows 2000 sollte der Treiber IoCompleteRequest aufrufen, um die IRP abzuschließen, dann PoStartNextPowerIrp aufrufen, um die nächste Energie-IRP zu starten, und dann den Fehler status zurückgeben.

  • Führen Sie alle gerätespezifischen Aufgaben aus, die vor dem Entfernen des Gerätestroms ausgeführt werden müssen, z. B. Schließen des Geräts, Abschließen oder Leeren ausstehender E/A-Vorgänge, Deaktivieren von Interrupts, Warteschlangen für nachfolgende eingehende IRPs und Speichern des Gerätekontexts, aus dem das Gerät wiederhergestellt oder neu initialisiert werden soll.

    Der Treiber sollte keine lange Verzögerung verursachen (z. B. eine Verzögerung, die ein Benutzer für diesen Gerätetyp als unangemessen empfinden könnte) während der Behandlung des IRP.

    Der Treiber sollte alle eingehenden E/A-Anforderungen in die Warteschlange stellen, bis das Gerät in den Arbeitszustand zurückgekehrt ist.

  • Überprüfen Sie den Wert möglicherweise unter Parameters.Power.ShutdownType. Wenn ein IRP für Systemsatzleistung aktiv ist, stellt shutdownType Informationen zum System-IRP bereit. Weitere Informationen zu diesem Wert finden Sie unter System Power Actions.For more information about this value, see System Power Actions.

    Treiber von Geräten im Ruhezustandspfad müssen diesen Wert überprüfen. Wenn ShutdownTypePowerActionHibernate ist, sollte der Treiber den kontext speichern, der zum Wiederherstellen des Geräts erforderlich ist, aber das Gerät nicht herunterfahren.

  • Ändern Sie den physischen Leistungszustand des Geräts, wenn der Treiber dazu in der Lage ist und ob die Änderung angemessen ist.

  • Rufen Sie PoSetPowerState auf, um den Power Manager über den neuen Gerätestromzustand zu benachrichtigen.

  • Rufen Sie IoCopyCurrentIrpStackLocationToNext auf, um den Stapelspeicherort für den nächstniedrigen Treiber einzurichten.

  • Legen Sie eine IoCompletion-Routine fest, die PoStartNextPowerIrp aufruft, die angibt, dass der Treiber bereit ist, die nächste Energie-IRP zu verarbeiten. Dieser Schritt ist in Windows 7 und Windows Vista nicht erforderlich.

  • Rufen Sie IoCallDriver (in Windows 7 und Windows Vista) oder PoCallDriver (in Windows Server 2003, Windows XP und Windows 2000) auf, um die IRP an den nächstniedrigen Treiber zu übergeben. Die IRP muss bis zum Bustreiber übergeben werden, der die IRP abschließt.

  • Rufen Sie IoReleaseRemoveLock auf, um die zuvor erworbene Sperre zu freigeben.

  • Gibt STATUS_PENDING zurück.

Treiber müssen alle Gerätekontextinformationen speichern und den neuen Energiezustand festlegen, bevor sie die IRP weiterleiten. Die Kontextinformationen sollten mindestens den angeforderten neuen Energiezustand enthalten. Es sollte auch alle zusätzlichen Informationen enthalten, die der Treiber beim Einschalten benötigt. Nachdem die IRP abgeschlossen und das Gerät ausgeschaltet wurde, kann der Treiber nicht mehr auf das Gerät zugreifen, und der Gerätekontext ist nicht verfügbar.

Jeder Treiber muss den IRP an den nächstniedrigen Treiber übergeben. Wenn der IRP den Bustreiber erreicht, schaltet der Bustreiber das Gerät aus (sofern es dazu in der Lage ist), ruft PoSetPowerState auf, um den Energiemanager zu informieren, und schließt die IRP ab.

Wenn der Bustreiber jedoch das Ruhezustandsgerät verwendet, sollte überprüft werden, ob der Wert von ShutdownType im IRP PowerSystemHibernate ist. Wenn ja, sollte der Bustreiber PoSetPowerState aufrufen, um PowerDeviceD3 zu melden, aber das Gerät nicht herunterfahren. Das Gerät wird heruntergefahren, nachdem die Ruhezustandsdatei zusammen mit dem Rest des Systems gespeichert wurde.

Nachdem alle untergeordneten Geräte heruntergefahren sind, kann ein Bustreiber auch den Bus herunterfahren. Ein solches Verhalten ist geräteabhängig.

Wenn der IRP einen anderen Zustand (D0, D1 oder D2) angibt, sind erforderliche Treiberaktionen geräteabhängig. In der Regel können Geräte, die diese Zustände unterstützen, schnell in den Arbeitszustand zurückkehren, wenn eine E/A-Anforderung eingeht. Ein Treiber für ein solches Gerät muss alle ausstehenden E/A-Anforderungen ausführen, alle neuen Anforderungen in die Warteschlange stellen und den gesamten erforderlichen Kontext speichern, bevor er den IRP an den nächstniedrigen Treiber weiterleitet. Wenn der IRP den Bustreiber erreicht, wird die Hardware in den angeforderten Zustand versetzt. Ein Treiber kann nicht auf das Gerät zugreifen, während es sich im Ruhezustand befindet.

Unter bestimmten Umständen erhält ein Funktions- oder Filtertreiber möglicherweise eine Geräteleistungs-IRP, die PowerDeviceD0 angibt, wenn sich das Gerät bereits im D0-Zustand befindet. Der Treiber sollte diese IRP wie jedes andere IRP mit Set-Power behandeln: Ausstehende E/A-Anforderungen abschließen, eingehende E/A-Anforderungen in die Warteschlange stellen, eine IoCompletion-Routine festlegen und die IRP an den nächstniedrigen Treiber übergeben. Ein Treiber darf die Hardwareeinstellungen des Geräts jedoch nicht ändern. Wenn der Bustreiber die IRP empfängt, sollte er einfach die IRP abschließen. Wenn die IRP abgeschlossen ist, können Funktions- und Filtertreiber alle Anforderungen in der Warteschlange verarbeiten. Durch E/A-Warteschlangen bis zum Abschluss des IRP wird jegliche Möglichkeit vermieden, dass niedrigere Treiber versuchen, Geräteregister zu ändern, während ein höherer Treiber E/A versucht.