次の方法で共有


バス ドライバー (PDO) での待機/ウェイク IRP の処理

他の電源 IRP と同様、各待機/ウェイク IRP は、最終的に IRP の完了を担当するバス ドライバー (PDO) にデバイス スタックのすべての方法を渡す必要があります。 IRP を受け取ると、バス ドライバーはすぐに失敗するか、後で完了できるように保留にすることができます。 バス ドライバーが実行する必要がある手順を以下に示します。

  1. Irp->Parameters.WaitWake.PowerState の値を調べます。 デバイスでウェイクアップがサポートされているが、指定された SystemWake 状態から、または現在のデバイス電源状態からのウェイクアップはサポートされていない場合、ドライバーは以下のように IRP を失敗させる必要があります。

    • Irp->IoStatus.Status で STATUS_INVALID_DEVICE_STATE を設定します。

    • IRP (IoCompleteRequest) を完了し、IO_NO_INCREMENT の優先度ブーストを指定します。

    • DispatchPower ルーチンから Irp->IoStatus.Status に設定された状態を返します。

  2. 待機/ウェイク IRP が PDO に対して既に保留中かどうかを確認します。 その場合、Irp->IoStatus.Status を STATUS_DEVICE_BUSY に設定して、ドライバーの待機/ウェイク IRP の内部カウントをインクリメントし、前の手順で説明したように IRP を完了します。

    PDO に対して保留中の待機/ウェイク IRP は 1 つだけです。

  3. 指定されたシステム電源状態からのウェイクアップがデバイスによりサポートされていて、待機/ウェイク IRP がまだ保留中でない場合、IoMarkIrpPending を呼び出して、IRP が後で完了または取り消されることを I/O マネージャーに示します。 IoCompletion ルーチンを設定しないでください。

  4. ウェイクアップを有効にするようデバイス ハードウェアを設定します。

    バス ドライバーがウェイクアップのハードウェアを有効にする特定のメカニズムは、デバイスに依存しています。 PCI デバイスの場合、このドライバーが PME レジスタを所有しているため、Pci.sys が PME 対応ビットの設定を担当します。 その他のデバイスについては、デバイス クラス固有のドキュメントをご覧ください。

  5. PDO が FDO の子である場合、FDO の待機/ウェイク IRP を要求し、現在の IRP (保留中になっている IRP) の Cancel ルーチンを設定することを確認します。 現在の IRP を渡したり、再利用したりしないでください。

  6. DispatchPower ルーチンから STATUS_PENDING を返します。

  7. ウェイクアップ シグナルが到着したら、IoCompleteRequest を呼び出して保留中の待機/ウェイク IRP を完了し、Irp-IoStatus.Status を STATUS_SUCCESS に設定して、IO_NO_INCREMENT の優先度ブーストを指定します。

Note

デバイスの取り出し中、電源ポリシー所有者 (PPO) は通常、待機ウェイク IRP を取り消す必要があります。 ただし、PPO がそうしない場合、回復性メカニズムとして、バス PDO がエラー ステータスで IRP を完了することをお勧めします。 バス PDO は、IRP_MN_SURPRISE_REMOVE と IRP_MN_REMOVE_DEVICE の両方を処理するときにこれを行う必要があります。

ウェイクアップをサポートしていないデバイスの場合

デバイスでウェイクアップがサポートされていない場合、バス ドライバー (PDO) は以下のように続行する必要があります。

  1. ioCompleteRequest を呼び出して待機/ウェイク IRP を完了し、IO_NO_INCREMENT を指定します。

  2. DispatchPower ルーチンから戻り、Irp->IoStatus.Status の値を戻り値として渡します。