Share via


共通バッファー バス マスター DMA の使用

バスマスター DMA の使用」で 説明されているように、バスマスター DMA デバイスの一部のドライバーでは共通バッファー DMA のみを使用し、一部ではパケット ベースの DMA と組み合わせて共通バッファー DMA を使用します。

共通バッファー DMA を経済的に使用します。 共通バッファーを設定すると、バスマスター アダプターを表すアダプター オブジェクトに関連付けられているマップ レジスタの一部 (または要求されたバッファーのサイズによってはすべて) を関連付けることができます。

PAGE_SIZE チャンクや 1 つの割り当てを使用するなど、共通バッファー領域を経済的に設定することで、パケットベースの DMA 操作に使用できるマップ レジスタが増えます。 また、他の目的のためにより多くのシステムメモリを解放し、全体的なドライバーとシステムのパフォーマンスを向上させます。

バスマスター DMA の共通バッファーを設定するには、バスマスター DMA デバイス ドライバーは、IoGetDmaAdapter によって返されるアダプター オブジェクト ポインターを使用して AllocateCommonBuffer を呼び出す必要があります。 通常、ドライバーは、IRP_MN_START_DEVICE 要求の DispatchPnP ルーチンからこの呼び出しを行います。 ドライバーは、ドライバーが読み込まれた状態の間、バッファーを DMA 操作に繰り返し使用する場合にのみ、共通のバッファーを割り当てる必要があります。 次の図は、そのような AllocateCommonBuffer の呼び出しを示しています。

diagram illustrating the allocation of a common buffer for bus-master dma.

前の図に LengthForBuffer として示されているバッファーの要求されたサイズによって、共通バッファーの仮想から論理へのマッピングを提供するために使用する必要があるマップ レジスタの数が決まります。 BYTES_TO_PAGES マクロを使用して、必要なページの最大数 (BYTES_TO_PAGES (LengthForBuffer)) を決定します。 この値は、IoGetDmaAdapter によって返される NumberOfMapRegisters より大きくすることはできません。

さらに、呼び出し元は次を指定する必要があります。

  • キャッシュを有効にするかどうかを示すブール値

    注: この値は無視されます。 オペレーティング システムは、割り当てられる共通バッファーでキャッシュされたメモリを有効にするかどうかを決定します。 この決定は、プロセッサ アーキテクチャとデバイス バスに基づいています。

    x86 ベース、x64 ベース、および Itanium ベースのプロセッサを搭載したコンピューターでは、キャッシュされたメモリが有効になります。

    Arm または Arm 64 ベースのプロセッサを搭載したコンピューターでは、オペレーティング システムはすべてのデバイスに対してキャッシュされたメモリを自動的に有効にしません。 システムは、各デバイスの ACPI_CCA メソッドに依存して、デバイスがキャッシュコヒーレントであるかどうかを判断します。

  • AllocateCommonBuffer からの戻り時にバッファーのデバイスからアクセス可能な基本論理アドレス (前の図の BufferLogicalAddress) を格納するドライバー定義変数へのポインター

呼び出しが成功した場合、AllocateCommonBuffer は、ドライバーがアクセス可能なバッファーのベース仮想アドレス (前の図の BufferVirtualAddress) を返し、ドライバーは、デバイス拡張機能、コントローラー拡張機能、またはその他のドライバーがアクセス可能な常駐記憶域 (ドライバーによって割り当てられた非ページ プール) に保存する必要があります。

バッファーにメモリを割り当てることができない場合、AllocateCommonBufferNULL を返します。 返されたベース仮想アドレスが NULL の場合、ドライバーは、システムのパケット ベースの DMA サポートのみを使用する必要があります。または、ドライバーは IRP_MN_START_DEVICE 要求を失敗し、STATUS_INSUFFICIENT_RESOURCES を返す必要があります。

それ以外の場合、ドライバーは、割り当てられた共通バッファーを DMA 転送用のドライバーとアダプターからアクセス可能な記憶域として使用できます。

PnP マネージャーがデバイスを停止または削除する IRP を送信する場合、ドライバーは FreeCommonBuffer を呼び出して、割り当てられている各共通バッファーを解放する必要があります。