DMA ハードウェアのプログラミング

ドライバーがフレームワークの DMA サポートを使用する場合、ドライバーで EvtProgramDma イベント コールバック関数を指定する必要があります。このコールバック関数は、IRQL = DISPATCH_LEVEL で呼び出され、デバイスが DMA 転送を開始するようプログラミングします。このコールバック関数の入力パラメーターでは、転送の方向 (入力または出力) と、scatter/gather リストを指定します。転送に含まれるパケットが 1 つだけである場合、scatter/gather リストに含まれる要素は 1 つだけです。

EvtProgramDma コールバック関数は、ドライバーの EvtDevicePrepareHardware コールバック関数が受け取ったハードウェア リソースを使用してデバイスをプログラミングします。EvtProgramDma コールバック関数は、ハードウェアのプログラミングが正常に完了すると、TRUE を返します。

ハードウェアによる DMA 転送が完了すると、多くの場合、ハードウェアが割り込みを発行し、ドライバーの EvtInterruptIsr コールバック関数が呼び出されます。EvtInterruptIsr コールバック関数では、次の処理を行う必要があります。

  • 割り込みを無効にします。

  • 割り込みのコンテキスト情報を保存します。

  • WdfInterruptQueueDpcForIsr を呼び出して EvtInterruptDpc コールバック関数をスケジュールします。

EvtInterruptDpc コールバック関数は、EvtInterruptIsr コールバック関数が保存したコンテキスト情報を使用して、DMA 転送を完了させます。

EvtProgramDma コールバック関数では、エラーを検出した場合に、トランザクションを中止するか、トランザクションの現在の転送を再開することができます。

ドライバーがエラーを検出したときにトランザクションを中止する場合、EvtProgramDma コールバック関数で次の処理を行う必要があります。

  1. WdfDmaTransactionDmaCompletedFinal を呼び出します。

  2. WdfObjectDelete を呼び出して DMA トランザクション オブジェクトを削除するか、WdfDmaTransactionRelease を呼び出して DMA トランザクション オブジェクトを解放および再利用します。

  3. トランザクションがフレームワーク要求オブジェクトに関連付けられている場合は、I/O 要求をキューに再配置するか、I/O 要求を完了させます。

  4. FALSE を返します。

ドライバーがエラーを検出したときにトランザクションの現在の転送を再開するには、ドライバーの EvtInterruptDpc コールバック関数で TransferredLength パラメーターを 0 に設定して WdfDmaTransactionDmaCompletedWithLength を呼び出す必要があります。WdfDmaTransactionDmaCompletedWithLength の呼び出しの詳細については、「DMA 転送の完了」を参照してください。