デバイス ツリーを通じた待機/ウェイク IRP のパスの概要

1 つのデバイス スタック内で、電源ポリシーの所有者は待機/ウェイク IRP を送信し、すべてのドライバーが待機/ウェイク IRP を処理します。これは「待機/ウェイク操作の概要」と「待機/ウェイク IRP の送信」と「待機/ウェイク IRP の受信」でそれぞれ説明しているとおりです。

デバイス ツリーのブランチ (リーフ devnode とその親、祖父母などの devnode で構成される) 内で、ドライバーは協力して、待機/ウェイク IRP がウェイクアップに必要なすべてのハードウェアを有効にできるドライバーに到達するようにします。

ACPI コンピューターでは、ACPI は、各リーフ デバイスからのウェイクアップ信号に関連付けられているシステム固有の汎用イベント (GPE) レジスタを有効にする役割を担います。 したがって、ドライバーは、ACPI フィルター ドライバー (起動時にデバイス スタックに挿入) または基になる Windows ACPI ドライバーである Acpi.sys に到達するまで、待機/ウェイク IRP を要求して転送する必要があります。 これに対して、ACPI はレジスタを有効にし、信号が到着するまで保留中の IRP を保持し、IRP を完了します。 ACPI はウェイクアップ信号に応答できるため、下位ドライバーに IRP を転送しません。

基になる ACPI ドライバー自体と同様に、ACPI フィルター ドライバーは、他のドライバーに対して透過的です。 ハードウェア設計の柔軟性を最大限に高めるために、すべてのデバイス スタックにおける ACPI フィルター ドライバーの正確な位置は、デバイスおよびシステム固有です。 ドライバーの設計では、デバイス スタック内の ACPI フィルターの存在または位置について仮定することはできません。

子デバイスを列挙するドライバーは、子デバイスごとに PDO を作成し、親デバイスの FDO を作成します。 したがって、ドライバーは、子デバイスのバス ドライバーとして機能し、親デバイスの関数 ドライバー/ポリシー所有者として機能します。 そのため、バス ドライバーは、子 PDO の待機/ウェイク IRP を受信するたびに、その親 PDO の別の待機/ウェイク IRP を要求する必要があります。

次の図は、このような状況が発生するサンプル構成を示しています。

diagram illustrating a sample usb configuration.

サンプル構成では、キーボードとモデムは USB ハブの子であり、USB ハブは PCI バスによって列挙される USB ホスト コントローラーの子です。 次の図は、サンプル構成のキーボードのデバイス スタックを示しています。

diagram illustrating device stacks for the sample usb keyboard configuration.

前の図に示すように、下から上に読みます。

  1. Windows ACPI ドライバー、 Acpi.sys は、PCI 用の PDO を作成します。

  2. PCI ドライバーは、PCI FDO と USB ホスト コントローラー PDO を作成し、PCI デバイス スタックのポリシーを所有します。

  3. USB ホスト コントローラー ドライバー (ホスト ポート/ミニポート ドライバー ペア) は、USB ホスト コントローラー FDO と USB ハブ PDO を作成します。 USB ホスト コントローラー デバイス スタックのポリシーを所有しています。 Acpi.sys は、このスタックにもフィルター DO を作成します。

  4. USB ハブ ドライバーは、USB ハブ FDO とキーボード PDO を作成します。 このドライバーは、USB ハブ デバイス スタックの電源ポリシーを所有しています。

  5. キーボードのファンクション ドライバーは、USB HID クラス ドライバーとミニドライバーのペアです。 このドライバーは、キーボードの FDO を作成し、その電源ポリシーを所有します。 キーボードには子デバイスがないため、このドライバーは PDO を作成しません。

各デバイス スタックには、表示されない追加のオプションのフィルター DO が含まれる場合があることに注意してください。

キーボード入力でシステムをスリープ解除させるために、キーボードのポリシー所有者は その PDO の IRP_MN_WAIT_WAKE を要求します。 その IRP は、次の図に示すように、他の待機/ウェイク IRP のチェーンをオフに設定します。

wait/wake irp requests for sample usb configuration.

バス ドライバーは、作成した PDO を対象とする IRP_MN_WAIT_WAKE を受け取ると、電源ポリシーを所有し、FDO を作成したデバイス スタックに対して、別の IRP_MN_WAIT_WAKE を要求する必要があります。

前の図に示すように、

  1. キーボード ドライバーは PoRequestPowerIrp を呼び出して、待機/ウェイク IRP (IRP1) を その PDO に送信します。

    電源マネージャーは IRP を割り当て、I/O マネージャーを介してキーボードのデバイス スタックの上部に送信します。 ドライバーは IoCompletion ルーチンを設定し、IRP をキーボード PDO に到達するまでスタックを渡します。 USB ハブ ドライバーは、キーボードのバス ドライバーとして機能し、保留中の IRP1 を保持します。

  2. USB ハブ ドライバーは、ウェイクアップ信号が到着したときにシステムをスリープ解除できないため、USB ハブ ドライバーは PoRequestPowerIrp を呼び出して、USB ハブ デバイス スタックの待機/ウェイク IRP (IRP2) を要求する必要があります。

    電源マネージャーは、USB ハブ デバイス スタックの上部にこの IRP を送信します。 このスタックのドライバーは、IoCompletion ルーチンを設定し、USB ホスト コント ローラー ドライバー (USB ハブのバス ドライバーとして機能する) に IRP を渡します。 USB ホスト コントローラー ドライバーは、キーボードがウェイク イベントを通知するまで保留中の IRP2 を保持します。

  3. 同様に、USB ホスト コントローラー ドライバーはシステムをスリープ解除できないため、PoRequestPowerIrp を呼び出して、待機/ウェイク IRP (IRP3) を USB ホスト コントローラー デバイス スタックに送信します。

    電源マネージャーは、USB ホスト コントローラーデバイス スタックの上部にこの IRP を送信します。そこでドライバーが IoCompletion ルーチンを設定し、PCI ドライバー (USB ハブのバス ドライバーとして機能する) に IRP を渡します。 PCI ドライバーは、キーボードがウェイク イベントを通知するまで保留中の IRP3 を保持します。

  4. PCI ドライバーはシステムをスリープ解除できないため、PoRequestPowerIrp を呼び出して、待機/ウェイク IRP (IRP4) を PCI デバイス スタックに送信します。 その親は、ACPI がバス ドライバーであるルート デバイスです。

    電源マネージャーは、PCI バス デバイス スタックの上位に IRP を送信します。そのドライバーは、完了ルーチンを設定し、Windows ACPI ドライバーの Acpi.sys に IRP を渡します。

  5. Acpi.sys はシステムをスリープ解除できるため、待機/ウェイク IRP は他の PDO に送信されません。 Acpi.sys は、スリープ解除信号が到着するまで IRP4 を保留にします。

キーボードがウェイクアップ信号をアサートすると、Acpi.sys がウェイクアップ信号をインターセプトします。 ただし、ACPI は、キーボードが信号をアサートしたことを判断できません。ルートデバイスを経由して信号が来たとしか判断できません。 Acpi.sys は IRP4 を完了させ、I/O マネージャーは PCI デバイス スタックをバックアップする IoCompletion ルーチンを呼び出します。 IRP4 が完了し、すべての IoCompletion ルーチンが実行されると、PCI ドライバーのコールバック ルーチンが呼び出されます。 そのコールバック ルーチンでは、PCI ドライバーは、信号が USB ホスト コント ローラーを介して来たと判断します。 その後、PCI ドライバーによって IRP3 が完了します。 キーボード ドライバーが IRP1 を受け取るまで、USB ホスト コントローラー スタックと USB ハブ スタックを介して同じシーケンスが発生します。 この時点で、キーボード ドライバーは、必要に応じてウェイクアップ イベントを提供できます。

ドライバーが待機/ウェイク IRP を親 PDO に送信するたびに、独自の IRP のキャンセル ルーチンを設定する必要があります。 キャンセル ルーチンを設定することで、それをトリガーした IRP が取り消された場合、ドライバーは新しい IRP をキャンセルすることができます。 USB の例では、キーボード ドライバーが待機/ウェイク IRP を取り消す場合 (キーボードのウェイクアップを無効にする)、USB ハブ、USB ホスト コントローラー、および PCI ドライバーは、キーボード IRP の結果として送信された IRP を取り消す必要があります。 詳細については、「待機/ウェイク IRP のキャンセル ルーチン」を参照してください。

親ドライバーは、待機/ウェイクを有効にできる複数の子を列挙する場合がありますが、PDO に対して保留中の待機/ウェイク IRP は 1 つだけです。 このような場合、親ドライバーは、そのデバイスのいずれかがウェイクアップを有効にするたびに、待機/ウェイク IRP が保留されるようにする必要があります。 これを行うには、ドライバーは待機/ウェイク IRP を受け取るたびに内部カウンターをインクリメントします。 ドライバーが待機/ウェイク IRP を完了するたびに、カウントをデクリメントし、結果の値が 0 以外の場合は、別の待機/ウェイク IRP をデバイス スタックに送信します。

たとえば、USB 構成例の図に示した USB 構成では、USB ハブはキーボードとモデムの 2 つのデバイスを列挙します。 USB ハブ ドライバーは、キーボード PDO の待機/ウェイク IRP を受け取ると、自身の PDO の IRP を要求する前に、待機/ウェイク IRP の数をインクリメントします。 モデムのポリシー所有者が後でモデムのウェイクアップを有効にした場合、USB ハブ ドライバーは、モデム PDO の新しい IRP を保留し、その待機/ウェイクの参照カウントをインクリメントします。 ただし、USB ハブ PDO に 2 つの待機/ウェイク IRP を同時に設定できないため、USB ハブ ドライバーは、USB ハブ PDO の新しい待機/ウェイク IRP を要求しません。

ウェイクアップ信号がキーボードまたはモデムから到着すると、USB ハブ ドライバーは、どちらのデバイスから信号が来たかを判断し、、対応する IRP を完了し、その参照カウントをデクリメントします。 両方のデバイスがウェイクアップに対して有効になっているため (したがって、参照カウントは 0 以外)、独自のデバイス スタックに別の待機/ウェイク IRP を送信して、ウェイクアップ用に独自の PDO を "リアーム" する必要があります。 (USB ホスト コントローラーと PCI ドライバーの場合も同じです)。

ただし、ドライバーは、ウェイクアップ信号が到着したのと同じデバイスで、待機/ウェイクを再び有効にする IRP を自分自身に送信しません。 これを行うことができるのは、デバイス電源ポリシー マネージャーだけです。 待機/ウェイクの再有効化は自動的には行われません。