Grundlegendes zum Pfad von Warte-/Aktivierungs-IRPs durch eine Gerätestruktur
Innerhalb eines einzelnen Gerätestapels sendet der Besitzer der Energierichtlinie eine Warte-/Aktivierungs-IRP, und alle Treiber behandeln die Warte-/Aktivierungs-IRP, wie in Übersicht über den Warte-/Aktivierungsvorgang beschrieben und unter Senden eines Warte-/Aktivierungs-IRP bzw . Empfangen eines Warte-/Aktivierungs-IRP beschrieben.
Innerhalb eines Branchs der Gerätestruktur (die einen Blattentwicklungsknoten und die Devnodes seiner übergeordneten Elemente, Großeltern usw.) umfasst, müssen Treiber zusammenarbeiten, um sicherzustellen, dass ein Warte-/Aktivierungs-IRP einen Treiber erreicht, der die gesamte erforderliche Hardware für das Reaktivieren ermöglicht.
Auf ACPI-Computern ist ACPI dafür verantwortlich, das systemspezifische GPE-Register (Universell Event) zu aktivieren, das dem Aktivierungssignal jedes Blattgeräts zugeordnet ist. Daher müssen Treiber Wait/Wake IRPs anfordern und weiterleiten, bis sie entweder einen ACPI-Filtertreiber (beim Start in den Gerätestapel eingefügt) oder den zugrunde liegenden Windows ACPI-Treiber erreicht Acpi.sys. Als Reaktion darauf aktiviert ACPI das Register, hält die IRP ausstehend, bis das Signal eingeht, und schließt dann den IRP ab. Da ACPI auf das Aktivierungssignal reagieren kann, wird der IRP nicht an einen niedrigeren Treiber weitergeleitet.
ACPI-Filtertreiber, wie der zugrunde liegende ACPI-Treiber selbst, sind für andere Treiber transparent. Um maximale Flexibilität beim Hardwareentwurf zu gewährleisten, ist die genaue Position eines ACPI-Filtertreibers in jedem Gerätestapel geräte- und systemspezifisch. Beim Entwerfen eines Treibers können Sie keine Annahmen über das Vorhandensein oder die Position eines ACPI-Filters im Gerätestapel treffen.
Beachten Sie, dass Treiber, die untergeordnete Elemente auflisten, eine PDO für jedes untergeordnete Gerät und eine FDO für das übergeordnete Gerät erstellen. Der Treiber fungiert somit als Bustreiber für ein untergeordnetes Gerät und als Funktionstreiber-/Richtlinienbesitzer für ein übergeordnetes Gerät. Wenn ein Bustreiber daher eine Warte-/Aktivierungs-IRP für ein untergeordnetes PDO empfängt, sollte er eine weitere Warte-/Aktivierungs-IRP für seine übergeordnete PDO anfordern.
Die folgende Abbildung zeigt eine Beispielkonfiguration, in der eine solche Situation auftritt.
In der Beispielkonfiguration sind Tastatur und Modem untergeordnete Elemente des USB-Hubs, der wiederum ein untergeordnetes Element des USB-Hostcontrollers ist, der vom PCI-Bus aufgezählt wird. Die folgende Abbildung zeigt die Gerätestapel für die Tastatur in der Beispielkonfiguration.
Wie in der vorherigen Abbildung gezeigt, lesen Sie von unten nach oben:
Der Windows ACPI-Treiber Acpi.sys erstellt die PDO für PCI.
Der PCI-Treiber erstellt die PCI-FDO und die USB-Hostcontroller-PDO und besitzt die Richtlinie für den PCI-Gerätestapel.
Der USB-Hostcontrollertreiber (ein Hostport-/Miniporttreiberpaar) erstellt die USB-Hostcontroller-FDO und die USB-Hub-PDO. Sie besitzt die Richtlinie für den USB-Hostcontroller-Gerätestapel. Beachten Sie, dass Acpi.sys auch in diesem Stapel eine Filter-DO erstellt.
Der USB-Hubtreiber erstellt die USB-Hub-FDO und die Tastatur-PDO. Dieser Treiber besitzt die Energierichtlinie für den USB-Hub-Gerätestapel.
Der Funktionstreiber für die Tastatur ist das USB HID-Klassentreiber/Minidriver-Paar. Dieser Treiber erstellt die FDO für die Tastatur und besitzt die Energierichtlinie. Da die Tastatur über keine untergeordneten Geräte verfügt, erstellt dieser Treiber keine PDOs.
Beachten Sie, dass jeder Gerätestapel zusätzliche optionale Filter-DOs enthalten kann, die nicht angezeigt werden.
Damit das System durch Tastatureingaben aktiviert werden kann, fordert der Richtlinienbesitzer für die Tastatur eine IRP_MN_WAIT_WAKE für die PDO an. Diese IRP löst eine Kette anderer Warte-/Aktivierungs-IRPs aus, wie in der folgenden Abbildung dargestellt.
Wenn ein Bustreiber eine IRP_MN_WAIT_WAKE empfängt, die für ein von ihn erstelltes PDO bestimmt ist, muss er eine weitere IRP_MN_WAIT_WAKE für den Gerätestapel anfordern, für den er die Energierichtlinie besitzt, und eine FDO erstellt haben.
Wie in der vorherigen Abbildung gezeigt:
Der Tastaturtreiber ruft PoRequestPowerIrp auf, um ein Wait/Wake IRP (IRP1) an seine PDO zu senden.
Der Energie-Manager ordnet die IRP zu und sendet sie über den E/A-Manager an den oberen Rand des Gerätestapels für die Tastatur. Treiber legen IoCompletion-Routinen fest und übergeben den IRP im Stapel, bis es die Tastatur-PDO erreicht. Der USB-Hubtreiber, der als Bustreiber für die Tastatur fungiert, hält IRP1 ausstehend.
Da der USB-Hubtreiber das System beim Eintreffen des Aktivierungssignals nicht reaktivieren kann, muss der USB-Hubtreiber PoRequestPowerIrp aufrufen, um ein Wait/Wake IRP (IRP2) für den USB-Hub-Gerätestapel anzufordern.
Der Energie-Manager sendet diese IRP an den oberen Rand des USB-Hub-Gerätestapels. Die Treiber in diesem Stapel legen IoCompletion-Routinen fest und übergeben den IRP an den USB-Hostcontrollertreiber (der als Bustreiber für den USB-Hub fungiert). Der USB-Hostcontrollertreiber hält IRP2 ausstehend, bis die Tastatur ein Aktivierungsereignis signalisiert.
Ebenso kann der USB-Hostcontrollertreiber das System nicht reaktivieren, sodass der USB-Hostcontrollertreiber PoRequestPowerIrp aufruft , um eine Wait/Wake-IRP (IRP3) an den USB-Hostcontroller-Gerätestapel zu senden.
Der Energie-Manager sendet diese IRP an den oberen Rand des USB-Hostcontroller-Gerätestapels, wo Treiber IoCompletion-Routinen festlegen und den IRP an den PCI-Treiber übergeben (der als Bustreiber für den USB-Hub fungiert). Der PCI-Treiber hält IRP3 ausstehend, bis die Tastatur ein Aktivierungsereignis signalisiert.
Der PCI-Treiber kann das System nicht reaktivieren, sodass der PCI-Treiber PoRequestPowerIrp aufruft , um eine Wait/Wake-IRP (IRP4) an den PCI-Gerätestapel zu senden. Das übergeordnete Gerät ist das Stammgerät, für das ACPI der Bustreiber ist.
Der Energie-Manager sendet den IRP an den anfang des PCI-Bus-Gerätestapels. Seine Treiber legen Vervollständigungsroutinen fest und übergeben den IRP an den Windows ACPI-Treiber, Acpi.sys.
Acpi.sys kann das System reaktivieren, sodass keine Warte-/Aktivierungs-IRP an andere PDO gesendet wird. Acpi.sys hält IRP4 aus, bis ein Aktivierungssignal eingeht.
Wenn die Tastatur das Aktivierungssignal bestätigt, fängt Acpi.sys es ab. ACPI kann jedoch nicht feststellen, dass die Tastatur das Signal bestätigt hat, nur, dass das Signal über das Stammgerät gelangt ist. Acpi.sys schließt dann IRP4 ab, und der E/A-Manager ruft IoCompletion-Routinen auf, die den PCI-Gerätestapel zurückführen. Wenn IRP4 abgeschlossen ist und alle IoCompletion-Routinen ausgeführt wurden, wird die Rückrufroutine des PCI-Treibers aufgerufen. In seiner Rückrufroutine bestimmt der PCI-Treiber, dass das Signal über den USB-Hostcontroller gelangt ist. Der PCI-Treiber schließt dann IRP3 ab. Die gleiche Sequenz erfolgt über den USB-Hostcontrollerstapel und den USB-Hubstapel, bis der Tastaturtreiber IRP1 empfängt. An diesem Punkt kann der Tastaturtreiber das Aktivierungsereignis nach Bedarf verwalten.
Jedes Mal, wenn ein Treiber einen Warte-/Aktivierungs-IRP an eine übergeordnete PDO sendet, muss er eine Cancel-Routine für sein eigenes IRP festlegen. Das Festlegen einer Cancel-Routine gibt dem Treiber die Möglichkeit, die neue IRP abzubrechen, wenn das IRP, das sie ausgelöst hat, abgebrochen wird. Wenn im USB-Beispiel der Tastaturtreiber seine Warte-/Aktivierungs-IRP abbricht (wodurch die Tastaturreaktivierung deaktiviert wird), müssen der USB-Hub, der USB-Hostcontroller und die PCI-Treiber die IRPs abbrechen, die sie als Folge der Tastatur-IRP gesendet haben. Weitere Informationen finden Sie unter Abbrechen von Routinen für Wait/Wake IRPs.
Obwohl ein übergeordneter Treiber möglicherweise mehr als ein untergeordnetes Element aufzählt, das für Wait/Wake aktiviert werden kann, kann nur ein Warte-/Aktivierungs-IRP für eine PDO ausstehen. In solchen Fällen sollte der übergeordnete Treiber sicherstellen, dass ein Warte-/Aktivierungs-IRP aussteht, wenn eines seiner Geräte für die Aktivierung aktiviert ist. Dazu erhöht der Treiber bei jedem Empfang eines Warte-/Aktivierungs-IRP einen internen Zähler. Jedes Mal, wenn der Treiber einen Warte-/Aktivierungs-IRP abschließt, verringert er die Anzahl und sendet, wenn der resultierende Wert ungleich null ist, einen weiteren Wait/Wake-IRP an den Gerätestapel.
Beispielsweise listet der USB-Hub in der USB-Konfiguration, die zuvor in der Abbildung Beispiel für die USB-Konfiguration gezeigt wurde, zwei Geräte auf, eine Tastatur und ein Modem. Wenn der USB-Hubtreiber eine Warte-/Aktivierungs-IRP für die Tastatur-PDO empfängt, erhöht er die Anzahl der Warte-/Aktivierungs-IRPs, bevor ein IRP für seine eigene PDO angefordert wird. Wenn der Richtlinienbesitzer des Modems später die Aktivierung für das Modem aktiviert, stiftet der USB-Hubtreiber die neue IRP für die Modem-PDO und erhöht die Anzahl der Warte-/Aktivierungsreferenzen. Da die USB-Hub-PDO jedoch nicht über zwei gleichzeitig ausstehende Warte-/Aktivierungs-IRPs verfügen kann, fordert der USB-Hubtreiber keine neue Wait/Wake-IRP für die USB-Hub-PDO an.
Wenn ein Aktivierungssignal entweder von der Tastatur oder dem Modem eingeht, bestimmt der USB-Hubtreiber, welches Gerät signalisiert wird, schließt die entsprechende IRP ab und verringert die Referenzanzahl. Da beide Geräte für das Reaktivieren aktiviert wurden (und daher die Referenzanzahl ungleich null ist), muss sie ihrem eigenen Gerätestapel eine weitere Warte-/Aktivierungs-IRP senden, um ihre eigene PDO für das Reaktivieren zu "reaktivieren". (Gleiches gilt für den USB-Hostcontroller und den PCI-Treiber.)
Ein Treiber sendet sich jedoch kein IRP, um das Warten/Reaktivieren auf demselben Gerät, auf dem gerade ein Aktivierungssignal eingetroffen ist, wieder zu aktivieren. Nur der Energierichtlinien-Manager des Geräts kann dies tun. Das erneute Aktivieren von Wartezeiten/Aktivierungen erfolgt nicht automatisch.