チェーン化された MDL の送信方法

このトピックでは、USB ドライバースタックのチェーン MDLs 機能について、およびクライアントドライバーが MDL 構造体のチェーンとして転送バッファーを送信する方法について説明します。

ほとんどの USB ホストコントローラーでは、転送バッファーが実質的に連続している必要があります。 実質的に連続しているは、ページ内のどこでもバッファーを開始および終了できるが、バッファーの残りの部分はページ境界で開始して終了する必要があることを意味します。 多くの USB クライアントドライバーは、その要件を満たすことができます。 ただし、特定のクライアントドライバー (特に、バッファーとの間で追加のデータを追加または削除する必要があるドライバー) については、転送バッファーに実質的に連続するメモリを割り当てることは推奨されません。

たとえば、3つのドライバー (ネットワークプロトコルドライバー、中間ドライバー、およびミニポートドライバー) のネットワークスタックを考えてみます。 プロトコルドライバーは転送を開始し、スタック内の次のドライバー (中間ドライバー) にパケットを送信します。 中間ドライバーは、(別のメモリブロックに含まれる) カスタムヘッダーをパケットに追加しようとしています。 中間ドライバーは、そのヘッダーと受信パケットをスタック内の次のドライバー (ミニポートドライバー) に送信します。 ミニポートドライバーは、USB ドライバースタックとのインターフェイスを持つため、実質的に連続する転送バッファーを準備する必要があります。 このようなバッファーを作成するために、ミニポートドライバーは大きなバッファーを割り当て、カスタムヘッダーを追加してから、ペイロードをコピーします。 ペイロードは通常は大きいため、ペイロード全体をコピーすると、パフォーマンスに大きな影響を与える可能性があります。

クライアントドライバーは、転送バッファーを メモリ記述子リスト (mdls) のチェーンとして送信することによって、パフォーマンスへの影響を克服できます。 Windows 8 の新しい USB ドライバースタックは、クライアントドライバーのチェーンされた mdl (「 mdl」を参照) を受け入れることができます。 チェーン化された MDL を指定することにより、クライアントドライバーは、余分なコピー操作を実行する代わりに、メモリ内の連続していないページを参照できます。 この機能により、バッファーの数、サイズ、およびアラインメントに関する制限がなくなり、転送バッファーを物理メモリに分割できるようになります。

チェーン mdls を使用するには、クライアントドライバーは、Windows によって読み込まれた基になる USB ドライバースタックが機能をサポートしているかどうかを検出してから、適切な順序で mdls のチェーンを構築する必要があります。

前提条件

チェーン化された MDL 機能は、一括、アイソクロナス、および割り込み転送でのみサポートされています。 チェーン化された MDL 機能に対してクエリを実行する前に、クライアントドライバーに、ドライバーの USB ドライバースタックへの登録用の USBD ハンドルがあることを確認してください。 USBD ハンドルを作成するには、 USBD_CreateHandleを呼び出します。通常、クライアントドライバーは AddDevice ルーチンで USBD ハンドルを作成します。

チェーン化された MDL 機能は、クライアントドライバーの IRP_MN_START_DEVICE ハンドラーで、または後でいつでも照会できます。 クライアントドライバーは、 AddDevice ルーチンでこの機能のクエリを実行することはできません。

Instructions

  1. USBD_QueryUsbCapabilityルーチンを呼び出して、USB ドライバースタックがチェーン mdls 機能をサポートしているかどうかを確認します。 その機能を照会するには、GUID として UsbCapabilityChainedMdls を指定します。 Outputbufferパラメーターを NULL に設定し、 outputbufferパラメーターを0に設定します。

  2. USBD_QueryUsbCapabilityによって返された NTSTATUS 値を確認し、結果を評価します。 ルーチンが正常に完了した場合は、チェーン MDLs 機能がサポートされます。 それ以外の値は、機能がサポートされていないことを示します。

  3. MDLs のチェーンを作成します。 各mdlには、別のMdlを指すのポインターがあります。

    ドライバーは、 のポインターを手動で設定することによって、チェーン MDL を構築できます。

    前の例では、プロトコルドライバーはパケットを MDL として送信します。 中間ドライバーは、ヘッダーデータを使用してメモリブロックを参照する別の MDL を作成できます。 チェーンを作成するために、中間ドライバーは、プロトコルドライバーから受信した MDL へのヘッダー MDL の のポインターを指すことができます。 その後、中間ドライバーは2つの MDLs のチェーンをミニポートドライバーに転送します。これは、要求の URB でチェーンされている MDL への参照を提供し、USB ドライバースタックに要求を送信します。 詳細については、「MDL の使用」を参照してください。

  4. チェーン MDLs を使用する i/o 要求の URB を構築するときに、関連付けられているurb構造 ( _URB_BULK_OR_INTERRUPT_TRANSFER_URB_ISOCH_TRANSFERなど) のtransferbuffermdlメンバーをチェーン内の最初の MDL に設定し、 transferbuffermdlに転送する合計バイト数を設定します。 データが、MDL チェーン内の複数の MDL エントリにまたがる場合があります。

    Windows 8 では、クライアントドライバーがデータ転送にチェーン mdls を使用できるようにする、2つの新しい種類の URB 関数が追加されています。 この機能を使用する場合は、URB ヘッダーの 関数 メンバーが次の urb 関数のいずれかに設定されていることを確認してください。

    • URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER_USING_CHAINED_MDL
    • URB_FUNCTION_ISOCH_TRANSFER_USING_CHAINED_MDL

    これらの URB 関数の詳細については、「 _URB_HEADER」を参照してください。

注釈

基になる USB ドライバースタックに対してクエリを実行し、ドライバースタックがチェーン MDLs を受け入れることができるかどうかを判断するコード例については、「 USBD_QueryUsbCapability」を参照してください。

USB i/o 操作