I/O 要求のディスパッチ方法

ドライバーが I/O キューを作成するために WdfIoQueueCreate を呼び出すときは、キューのディスパッチ方法を指定します。フレームワークには、順次、並列、および手動の 3 つのディスパッチ方法が用意されています。ドライバーは、デバイスの既定の I/O キューを含むすべての I/O キューにこれらのディスパッチ方法を指定できます。

ドライバーはキューの WDF_IO_QUEUE_CONFIG 構造体で WDF_IO_QUEUE_DISPATCH_TYPE 型の値を指定することで、キューのディスパッチ方法を設定します。

各ディスパッチ方法の使用例については、「I/O キューの使用例」を参照してください。

順次ディスパッチ

ドライバーまたはデバイスが 1 つのキューから一度に処理できる I/O 要求の数が 1 つのみである場合、"順次ディスパッチ" を使用するようにデバイスの I/O キューを設定する必要があります。これは "同期ディスパッチ" とも呼ばれます。**この種類のディスパッチを使用する場合、フレームワークは要求を一度に 1 つずつドライバーに送信します。ドライバーが前の要求を完了取り消し、または再度キューに追加するまで、フレームワークは次の要求を送信しません。

フレームワークが要求をドライバーの要求ハンドラーの 1 つに送信した後、ドライバーが要求を処理します。ドライバーが要求を一般 I/O ターゲットに転送する場合、通常は I/O ターゲット オブジェクトの同期メソッドの 1 つを呼び出します。これらのメソッドの詳細については、「I/O 要求の同期送信」を参照してください。ドライバーは、I/O キューから受信するすべての要求を最終的に完了または取り消す必要があります。

順次ディスパッチの I/O キューを設定したドライバーは WdfIoQueueRetrieveNextRequest または WdfIoQueueRetrieveRequestByFileObject を呼び出して、最後に受信した要求が完了または取り消される前にキューから別の要求を取得できます。この操作を関数ドライバーで実行することにより、ドライバーの EvtInterruptDpc コールバック関数が前のハードウェア操作からのデータをまだ処理している間に、ドライバーが次のハードウェア操作を開始することもできます。

複数の I/O キューを作成し、すべてを順次ディスパッチ用に設定した場合、フレームワークは各キューから要求を順次ディスパッチしますが、キューは並列で実行されます。ドライバーまたはデバイスで一度に処理できる要求が種類を問わず 1 つのみである場合、1 つの I/O キューを 1 つの EvtIoDefault コールバック関数と共に使用する必要があります。

並列ディスパッチ

ドライバーおよびデバイスが複数の I/O 要求を同時に処理できる場合、"並列ディスパッチ" を使用するようにデバイスの I/O キューを設定することにより、ドライバーは要求を非同期に処理できます。このディスパッチ方法は、"非同期ディスパッチ" とも呼ばれます。

ドライバーが並列ディスパッチを使用するように I/O キューを設定した場合、フレームワークは I/O 要求がキューで使用可能になると直ちにドライバーに送信します。その結果、ドライバーは複数の要求を同時に処理しなければならない場合があります。

ドライバーの要求ハンドラーの 1 つが要求を受信するたびに、ドライバーは要求を処理し、次にその要求を完了する必要があります。ドライバーが要求を一般 I/O ターゲットに転送する場合、通常は I/O ターゲット オブジェクトの非同期メソッドの 1 つを呼び出します。これらのメソッドの詳細については、「I/O 要求の非同期送信」を参照してください。ドライバーは、I/O キューから受信するすべての要求を最終的に完了または取り消す必要があります。

並列ディスパッチを使用するドライバーは WdfIoQueueStop または WdfIoQueueStopSynchronously を呼び出してキューを一時的に停止した後、WdfIoQueueStart を呼び出してキューを再開できます。

手動ディスパッチ

ドライバーが I/O 要求の配信を完全に制御できるようにするには、"手動ディスパッチ" を使用するようにデバイスの I/O キューを設定します。これは、ドライバーが明示的に要求しない限り、フレームワークは要求をドライバーに送信しないことを意味します。**

手動キューから要求を取得するには、ドライバーはキューをポーリングするループ内で WdfIoQueueRetrieveNextRequest または WdfIoQueueRetrieveRequestByFileObject を呼び出します。ドライバーは WdfIoQueueReadyNotify を呼び出して、キュー内の要求を 1 つ以上入手できるときにフレームワークが呼び出すコールバック関数を登録することもできます。フレームワークがコールバック関数を呼び出した後、ドライバーはループ内で WdfIoQueueRetrieveNextRequest または WdfIoQueueRetrieveRequestByFileObject を呼び出して要求を取得できます。

ドライバーはキューから要求を取得した後、要求を処理する必要があります。ドライバーは、各要求を最終的に完了または取り消す必要があります。