I/O 要求のキューへの再配置

ドライバーは、I/O キューから受信した I/O 要求をキューに再配置できます。ドライバーは、ドライバーが同じデバイスに対して作成した別の I/O キューに、I/O 要求を再配置できます。また、バス ドライバーは、子デバイスの I/O キューから親デバイスの I/O キューに、I/O 要求を移動させることができます。

デバイスの別の I/O キューへの I/O 要求の再配置

ドライバーは、ドライバーの要求ハンドラーがドライバーの I/O キューから I/O 要求を受信した後、WdfRequestForwardToIoQueue を呼び出すことにより、その要求を他のキューに再配置できます。

たとえば、ドライバーで要求を処理する前に、その要求にリソースを割り当てる場合は、ドライバーの EvtIoDefault コールバック関数ですべての要求を受け取り、各要求のコンテキスト メモリにリソース情報を保存した上で、WdfRequestForwardToIoQueue を呼び出して、各要求を別のキューに再配置できます。

ディスパッチ方法として順次ディスパッチを使用する I/O キューから I/O 要求を受け取ったときに、ドライバーが WdfRequestForwardToIoQueue を呼び出してその I/O 要求をキューに再配置した場合、フレームワークは、キューに再配置された要求が完了するまで待たずに、順次ディスパッチを行うキューから次の I/O 要求をドライバーに送信します。

一方、手動ディスパッチを使用しているドライバーは、WdfRequestRequeue メソッドを呼び出して、I/O 要求の取得元の I/O キューの先頭に I/O 要求を戻すことができます。WdfRequestRequeue の呼び出し後、ドライバーが次に WdfIoQueueRetrieveNextRequest を呼び出すと、キューに再配置された要求が取得されます。

親デバイスの I/O キューへの I/O 要求の再配置

親デバイスの関数ドライバーは、バス ドライバーとして機能できます。バス ドライバーは、親デバイスの子デバイスを列挙し、子デバイスの物理デバイス オブジェクト (PDO) を作成します。このようなドライバーは、親デバイスによる処理を要する子デバイスへの I/O 要求を受信することがあります。

たとえば、プロトコル バス (USB など) は、通常、接続された各デバイスに割り当てられたハードウェア リソースを制御します。このため、親バスの関数ドライバーは、多くの場合、各子デバイスに代わって I/O 操作を処理します。I/O マネージャーが I/O 要求をいずれかの子デバイスのデバイス スタックに送信すると、バスの関数ドライバーは、子デバイスのいずれかの I/O キューで I/O 要求を受け取ります。これは、バスの関数ドライバーが子デバイスの PDO を作成したためです。ドライバーが親バス デバイスのコンテキストで I/O 要求を処理できるようにするには、子デバイスの I/O キューから親デバイスに属する I/O キューに、I/O 要求を移動する必要があります。

しかし、ドライバーは、WdfRequestForwardToIoQueue を呼び出して、子のキューから親のキューに要求を移動することができません。I/O マネージャーは、親デバイスと子デバイスに別々のデバイス スタックを作成するため、まず基になる WDM デバイス オブジェクトを、子デバイスを表すオブジェクトから親を表すオブジェクトに変更する必要があります。

Version 1.9 より前の KMDF では、ドライバーが I/O 要求を子デバイスから親デバイスに送信するには、リモート I/O ターゲットを作成して、子デバイスのデバイス スタックのサイズを増やし、適切な WDM デバイス オブジェクトを指定するしか方法がありませんでした。

Version 1.9 以降の KMDF では、ドライバーが子デバイスを作成する前に WdfPdoInitAllowForwardingRequestToParent を呼び出し、その後に WdfRequestForwardToParentDeviceIoQueue を呼び出して、子の I/O キューから親のキューに要求を移動できるようになりました。ドライバーが WdfPdoInitAllowForwardingRequestToParentWdfRequestForwardToParentDeviceIoQueue を使用すると、フレームワークが子のデバイス スタックのサイズを増やし、I/O 要求に適切な WDM デバイス オブジェクトを割り当てます。