自己管理 I/O の使用
ほとんどのフレームワークベースのドライバーでは、サポート対象のデバイスに対して、フレームワークの PnP 機能と電源管理機能を利用します。つまり、ほとんどのフレームワークベースのドライバーでは、次の操作をすべて行うことによって、デバイスの PnP および電源状態の管理をフレームワークに委任します。
EvtDeviceD0Entry と EvtDeviceD0Exit の各コールバック関数を指定します。
EvtDevicePrepareHardware と EvtDeviceReleaseHardware の各コールバック関数を指定します。
デバイスが作業状態であることを必要とする I/O 要求には電源管理されたキューを使用し、その他すべての要求には電源管理されていないキューを使用します。
しかし、フレームワークベースのドライバーの中には、デバイスの状態に関するより詳細な情報を必要とするものがまれにあります。次に示す状況にあるドライバーがこれに該当します。
ドライバーが実行する処理が、フレームワーク I/O キューから受信する一連の I/O キューによって決定されない場合。
ドライバーが、フレームワークを使用しない旧型のドライバーと通信し、WDM インターフェイスを直接操作する場合。
ドライバーが受信する I/O 要求を、デバイスが作業状態であることを必要とする要求とそれ以外の要求の 2 つのグループに分類できない場合。
ほとんどのドライバーは上記の状況に該当しませんが、作成対象のドライバーがこれに該当する場合は、デバイスの PnP 処理および電源管理処理をより直接的に制御する必要が生じる場合があります。このようなドライバーでは、"自己管理 I/O" を使用できます**。自己管理 I/O を使用すると、いずれかのデバイスが接続または接続解除されたとき、およびデバイスが一時的に停止されたときに、ドライバーが (一連のコールバック関数によって) 通知を受けます。
ドライバーでは、自己管理 I/O を使用する場合でも、フレームワークの I/O キュー (電源管理された I/O キューと電源管理されていない I/O キューのどちらでも) を使用できます。たとえば、ドライバーで、フレームワークの I/O キュー (電源管理されていない I/O キュー) を、一連の自己管理 I/O コールバック関数と組み合わせて使用できます。
ドライバーで自己管理 I/O を使用するには、WdfDeviceInitSetPnpPowerEventCallbacks の呼び出し時に、一連の追加のイベント コールバック関数を登録します。登録対象となるイベント コールバック関数は次のとおりです。
EvtDeviceSelfManagedIoInit: デバイスの I/O 操作を初期化および開始します。
EvtDeviceSelfManagedIoSuspend: I/O 操作を中断します。
EvtDeviceSelfManagedIoRestart: デバイスの中断された I/O 操作を再開します。
EvtDeviceSelfManagedIoFlush: 未処理の I/O 要求を削除します。
EvtDeviceSelfManagedIoCleanup: EvtDeviceSelfManagedIoInit によって割り当てられたリソースの割り当てを解除します。
フレームワークは、デバイスが初めて作業状態 (D0) に移行したときに、ドライバーの EvtDeviceSelfManagedIoInit コールバック関数を呼び出します。この処理は、ユーザーがシステムにデバイスを接続したとき、およびシステムが再起動されたときに、その都度実行されます。
ドライバーがデバイスの I/O 操作を停止する必要がある状況は、3 つあります。1 つ目は、デバイスが低電力状態に移行しようとしているとき、2 つ目は、デバイスが取り外されようとしてるとき、3 つ目は、デバイスが予期せずに取り外されたときです。これらの各状況について、次の一覧で詳細に説明します。
デバイスが低電力状態に移行しようとしているが、いずれは作業状態に戻る場合。
(デバイスがアイドル状態である、システム全体が低電力状態に移行しようとしている、または PnP マネージャーがシステムのハードウェア リソースを再配布しようとしていることにより)、ドライバーが低電力状態に移行しようとすると、フレームワークはドライバーの EvtDeviceSelfManagedIoSuspend コールバック関数を呼び出します。デバイスが再び作業状態に移行すると、フレームワークはドライバーの EvtDeviceSelfManagedIoRestart コールバック関数を呼び出します。
デバイスが取り外されようとしているとき。
ユーザーから要求されたデバイスの取り外しを処理する場合、フレームワークは、デバイスを停止する前に、ドライバーの EvtDeviceSelfManagedIoSuspend コールバック関数を呼び出します。デバイスの停止後、フレームワークはドライバーの EvtDeviceSelfManagedIoFlush コールバック関数を呼び出します。デバイスが取り外されると、フレームワークは EvtDeviceSelfManagedIoCleanup コールバック関数を呼び出します。
デバイスが予期せずに取り外されたとき (突然の取り外し)。
デバイスのバス ドライバーが、デバイスがもう存在しないと判断した場合、またはスタック内の他のドライバーが、デバイスが応答しないと判断した場合、問題を発見したドライバーはそのことを PnP マネージャーに通知します。これを受けて、PnP マネージャーは、デバイスが取り外されたことを他のすべてのドライバーに通知します。フレームワークベースのドライバーでは、フレームワークが PnP マネージャーのメッセージを受信し、ドライバーの EvtDeviceSelfManagedIoSuspend、EvtDeviceSelfManagedIoFlush、および EvtDeviceSelfManagedIoCleanup の各コールバック関数を呼び出します。
(ドライバーで EvtDeviceSurpriseRemoval コールバック関数を登録することもできます。デバイスが取り外し時に作業状態 (D0) であった場合、フレームワークは、自己管理 I/O のコールバック関数を呼び出す前に、EvtDeviceSurpriseRemoval を呼び出します。デバイスが取り外し時に低電力状態であった場合、EvtDeviceSurpriseRemoval は EvtDeviceSelfManagedIoSuspend の後に呼び出されます。)
フレームワークがドライバーのイベント コールバック関数を呼び出す順序の詳細については、「PnP と電源管理のシナリオ」を参照してください。
必要になることはほとんどありませんが、フレームワークでは、ドライバーがフレームワークのステート マシンにアクセスすることによって、デバイスの PnP および電源状態をより詳細に制御できます。