UMDF ドライバーでのバッファー アクセス方法の管理

UMDF ドライバーを記述する場合は、フレームワークが読み取りおよび書き込みリクエスト、およびデバイス I/O 制御リクエストに使用するバッファー アクセス メソッド優先を指定できます。 UMDF ドライバーが提供する値は単なる優先であり、フレームワークで使用されることは保証されていません。

優先 バッファー アクセス メソッドの指定

UMDF バージョン 2.0 以降、UMDF ドライバーは WdfDeviceInitSetIoTypeExを呼び出して、読み取り/書き込みリクエストとデバイス I/O 制御リクエストの優先 アクセス メソッドを登録します。

ドライバーがWdfDeviceInitSetIoTypeExを呼び出さまい場合、UMDF は、このデバイスへの I/O リクエストにバッファーされたメソッドを使用します。

フレームワークでは、次の規則を使用して、使用するアクセス方法を決定します:

  • ドライバー スタック内のすべての UMDF ドライバーは、デバイスのバッファーにアクセスするために同じメソッドを使用する必要があります。フレームワークは、バッファーされた I/O を優先します。

    一部のドライバーがデバイスに対してバッファー I/O またはダイレクト I/O のいずれかを優先し、他のドライバーがデバイスのバッファー I/O のみを優先するとUMDFが判断した場合、UMDF はすべてのドライバーにバッファー I/O を使用します。 1 つ以上のスタックのドライバーがバッファー I/O のみを優先し、他のドライバーがダイレクト I/O のみを優先する場合、UMDF はシステム イベント ログにイベントを記録し、ドライバー スタックを開始しません。

    ドライバーは、WdfDeviceGetDeviceStackIoTypeを呼び出して、UMDF がデバイスの読み取り/書き込みリクエストと I/O 制御リクエストに割り当てたバッファー アクセス メソッドを決定できます。

  • 場合によっては、UMDF はダイレクト I/O をデバイスに割り当てますが、最適なパフォーマンスを得るために、1 つ以上のデバイスのリクエストにバッファー I/O を使用します。 たとえば、UMDF は、直接アクセスのためにバッファーをマップするよりも、データをドライバーのバッファーに高速にコピーできる場合、バッファー I/O を小さなバッファーに使用します。

    必要に応じて、ドライバーは WdfDeviceInitSetIoTypeExを呼び出すときに DirectTransferThreshold値を提供できます。 フレームワークはこの値を使用して、フレームワークがダイレクト I/O を使用する最小のバッファー サイズを決定します。 通常、フレームワークは最適なパフォーマンスを提供する設定を使用するため、この値を提供する必要はありません。

  • UMDF は、メモリ ページの境界で開始および終了するバッファー領域にのみ、ダイレクト I/O を使用します。 バッファーの先頭または末尾がページ境界上にない場合、UMDF はバッファーのその部分にバッファー I/O を使用します。 つまり、UMDF は、複数の I/O リクエストで構成される大規模なデータ転送に、バッファー I/O とダイレクト I/O の両方を使用ことがあります。

  • デバイス I/O 制御リクエストの場合、UMDF は、I/O 制御コード (IOCTL) がダイレクト I/O を指定した場合と、すべてのデバイスの UMDF ドライバーが WdfDeviceInitSetIoTypeExを呼び出してダイレクト アクセス メソッドを指定した場合にのみ、ダイレクト I/O を使用します。

I/O リクエストの アクセス メソッドの取得

ドライバーは、バッファー アクセス メソッドに関係なく、データ バッファーにアクセスするために同じリクエストオブジェクト メソッドのセットを使用します。 そのため、ほとんどのドライバーは通常、UMDF が I/O リクエストにバッファー I/O またはダイレクト I/O のどちらを使用しているかを認識する必要はありません。

場合によっては、I/O リクエストのアクセス方法がわかっている場合は、ドライバーのパフォーマンスを向上させることができます。 たとえば、通常、ダイレクト I/O を使用する高スループット デバイスを考えてみましょう。 ドライバーは、I/O リクエストを受信すると、検証のために共有バッファー領域からローカル ドライバー メモリにデータをコピーします。

ただし、ドライバーは、バッファー I/O を使用するバッファーを受信する場合があります。 I/O マネージャーは既にこのデータを中間バッファーにコピーしているため、ドライバーはパラメーターをローカルにコピーする必要はありません。 コピー操作を回避することで、ドライバーのパフォーマンスが向上します。

UMDF ドライバーは、WdfRequestGetEffectiveIoTypeを呼び出して、I/O リクエストのバッファー アクセス メソッドを取得します。 前述のように、特定のリクエストの I/O タイプは、デバイスのフレームワークによって割り当てられた I/O タイプの設定とは異なる場合があります。

バッファー I/O とダイレクト I/O の両方からの変換

UMDF ドライバーは、「どちらの」 メソッドも使用できません。

ただし、一部のデバイス I/O 制御コード (IOCTL) の定義では、リクエストで「どちらの」メソッドも使用しないことを指定します。 必要に応じて、UMDFトライバー は、このようなデバイス I/O 制御リクエストのバッファー アクセスメソッドをバッファー I/O またはダイレクト I/O に変換できます。 次の手順に従います。

  1. ドライバーの INF ファイルの INF DDInstall sectionUmdfMethodNeitherActionディレクティブを含めます。 このディレクティブの値を設定して、UMDF が「どちらの」アクセス メソッドも使用しないデバイス I/O 制御リクエストをドライバーに渡す必要があることを示すことができます。 (それ以外の場合、UMDF はエラー状態値でこれらの I/O リクエストを完了します)。

  2. UMDF がバッファー I/O またはダイレクト I/O に対して 提供するオブジェクト メソッドを使用して、I/O リクエストのバッファーにアクセスします。

UMDF がアクセス メソッドをバッファー I/O またはダイレクト I/O に変換できることが確実である場合にのみ、「どちらの」メソッドも使用しない IOCTL リクエストのサポートを有効にする必要があります。 たとえば、 I/O 制御コードのバッファーの説明で説明されているバッファー指定ルールに従っていない、カスタマイズされたリクエストを IOCTL で指定した場合、UMDF はバッファーを変換できません。