次の方法で共有


アダプター オブジェクトの取得

デバイスの起動に、システムまたはバス マスター DMA を使用するドライバーは、IoGetDmaAdapter を呼び出してアダプター オブジェクトへのポインターを取得し、各転送操作で使用可能なマップ レジスタの最大数を決定します。 ドライバーが IoGetDmaAdapter を呼び出すと、I/O マネージャーは HAL を呼び出し、必要なプラットフォーム固有の情報を取得します。

ドライバーは、IoGetDmaAdapter の呼び出しでシステム定義の DEVICE_DESCRIPTION 構造に特定の情報を提供する必要があります。 ドライバーは、値を設定する前に、RtlZeroMemory を使用して、DEVICE_DESCRIPTION 構造をゼロで初期化する必要があります。

必須のデータには、デバイスがバス マスターかどうか、スキャッター/ギャザー機能があるかどうか、デバイスが一度に転送できるデータのバイト数 (MaximumLength) など、ドライバーのデバイスの機能に関する情報が含まれます。

必須のデバイス記述データには、プラットフォーム固有の情報や、バス マスター デバイスのドライバーが制御するバスのシステム割り当て番号なども含まれます。 ドライバーは、IoGetDeviceProperty を呼び出すことによって、この情報を取得できます。

DEVICE_DESCRIPTION 構造には、一部の DMA デバイスまたはドライバーとは無関係な可能性があるいくつかのフィールドが含まれています。 たとえば、BusNumber フィールドは WDM ドライバーでは使用されません。 各ドライバーは、関連する構造メンバーの値を指定し、他のすべてのメンバーの値を 0 に設定する必要があります。

下位デバイスのドライバーは、ScatterGather フィールドで TRUE を渡すべきではありません。ただし、要求を複数の DMA 操作に分割する必要がある場合に、システム DMA コントローラーの再プログラミングを待機できる場合を除きます。

IoGetDmaAdapter は、アダプター オブジェクトへのポインターと、DMA 転送操作ごとにアダプター オブジェクトで使用できるマップ レジスタの数を示すプラットフォーム固有またはデバイス固有の値の両方を返します。

返されるアダプター オブジェクトには、ドライバーからアクセスできる 3 つのフィールドが含まれています。

  • バージョン番号 (バージョン)

  • サイズ (Size)

  • DMA_OPERATIONS 構造へのポインター (DmaOperations)

DMA_OPERATIONS 構造は、ドライバーがデバイスで DMA 操作を実行するために使用する必要がある関数へのポインターのテーブルで構成されています。 関数には、このデータ構造内のポインターを介してのみアクセスできます。ドライバーが名前で直接呼び出すことはできません。 (これらのルーチンにより、以前のバージョンの Windows NT でサポートされていた HalXxx ルーチンが置き換えられる点に注意してください。レガシ ドライバーの互換性を確保するため、Wdm.h ヘッダー ファイルと Ntddk.h ヘッダー ファイルは古い名前のマクロを提供しますが、新しいドライバーは常にデータ構造を介して関数を呼び出す必要があります)。

マップ レジスタの数は、デバイスやプラットフォームによって異なる場合があります。 一般に、HAL は次の条件に従ってマップ レジスタの数を割り当てます。

  • 可能な場合、HAL は、ドライバーの IoGetDmaAdapter への呼び出しで指定されている、MaximumLength バイトを転送するのに必要なマップ レジスタの数より 1 つ大きい値を返します。

  • それ以外の場合、HAL は特定のプラットフォームに対して、より小さく、かつ可能な限り大きい値を返します。

言い換えると、HAL は通常、デバイスの DMA スループットを最大化するのに十分なマップ レジスタを各ドライバーに付与しますが、HAL は一部の Windows プラットフォームではより小さい値を返すことができます。 ドライバーが要求したマップ レジスタの数を取得する保証はないため、ドライバーは、常に戻り値をチェックする必要があります。

DMA デバイス ドライバーは、アダプター オブジェクト ポインターと、IoGetDmaAdapter によって返される NumberOfMapRegisters 値のストレージを提供する必要があります。 このポインターは、DMA に使用されるシステム提供のサポート ルーチンに必要なパラメーターです。 これらのサポート ルーチンの多くは IRQL = DISPATCH_LEVEL で呼び出す必要があるため、ドライバーによって割り当てられたストレージは常駐している必要があります。 ほとんどの DMA ドライバーは、デバイス拡張機能に必要なストレージを提供します。 ただし、ドライバーがコントローラー オブジェクトも使用している場合、またはドライバーによって割り当てられている非ページ プール内にある場合、ストレージをコントローラー拡張機能に配置できます。 詳しくは、「システム領域メモリの割り当て」と「ハードウェア優先順位の管理」をご覧ください。

ドライバーがすべての DMA 操作を完了すると、PutDmaAdapter を呼び出してアダプター オブジェクトを解放します。

次のセクションでは、「システム DMA の使用」と「バス マスター DMA の使用」では、DMA デバイスのモノリシック ドライバーがサポート ルーチンを使って転送要求を満たす方法について説明します。 これらのセクションでは、ドライバーに以下があることを前提としています。

  • 標準 StartIo ルーチン (IRP の内部キューの設定と管理は行わない)

  • マップ レジスタの数が不足している転送要求を分割する内部ルーチン

  • デバイス固有の DMA 制約なし

言い換えると、これらのセクションでは、ドライバーの DMA 操作の最も簡単な手法について説明しますが、個々のドライバーでは必ずしもまったく同じ手法が使用されるとは限りません。 DMA デバイスのドライバーでは、大きな DMA 転送要求を分割する必要があるドライバー ルーチンは、ドライバー モデル (クラス/ポートまたはモノリシック)、デバイスの機能、ドライバーが処理する必要があるデバイス固有の DMA 制約によって決まります。