次の方法で共有


DMA トランザクションのキャンセル

[KMDF のみに適用]

ドライバーがバージョン 1.11 以降のバージョンの KMDF でビルドされており、ダイレクト メモリ アクセス (DMA) バージョン 3 を使用して Windows 8 以降で実行されている場合、ドライバーは WdfDmaTransactionCancel メソッドを呼び出すことによって保留中の DMA トランザクションの取り消しを試みることができます。

WdfDmaTransactionCancel を呼び出すとき、ドライバーは、指定した DMA トランザクションが呼び出し中に完了しないことを確認する必要があります。 ドライバーは、DMA チャネルの割り当て前またはいくつかの転送操作が既に完了した後、トランザクションを安全に取り消すために、次の手法を使用できます。

  1. ドライバーの要求ハンドラーのいずれかで、ドライバーは WdfRequestMarkCancelableEx を呼び出し、I/O 要求の EvtRequestCancel コールバック関数を提供します。 要求ハンドラーは、次に WdfDmaTransactionExecute を呼び出します。

  2. ドライバーの EvtRequestCancel コールバック関数 (WdfRequestMarkCancelableEx の呼び出しの直後に別のスレッドで実行を開始する可能性があります) は、WdfDmaTransactionCancel を呼び出します。

  3. WdfDmaTransactionCancel への呼び出しが WdfDmaTransactionExecute の呼び出しの後、WdfDmaTransactionExecute メソッドが DMA 割り当てを開始する前に発生した場合、トランザクションの取り消しは成功し、WdfDmaTransactionCancel は TRUE を返します。 この場合、ドライバーの EvtRequestCancel コールバック関数は、DMA トランザクションを完了する必要があります。 WdfDmaTransactionExecute はエラー値を返します。

  4. WdfDmaTransactionExecute メソッドが DMA 割り当てを開始した後にドライバーが WdfDmaTransactionCancel を呼び出した場合、トランザクションの取り消しは失敗し、WdfDmaTransactionCancel は FALSE を返します。 この場合、WdfDmaTransactionExecute は STATUS_SUCCESS を返し、ドライバーの要求ハンドラーは DMA トランザクションを完了する必要があります。

    この時点で、ドライバーがシステムモード DMA を使用している場合、EvtRequestCancel コールバック関数は WdfDmaTransactionStopSystemTransfer を呼び出して、進行中のシステムモード DMA 転送の停止を試みる可能性があります。 これを行う方法を示すコード例については、「WdfDmaTransactionStopSystemTransfer」を参照してください。

  5. WdfDmaTransactionExecute メソッドが DMA 割り当てを完了すると、フレームワークはドライバーの EvtProgramDma コールバック関数を呼び出します (WdfDmaTransactionExecute の呼び出しの直後に、別のスレッドで実行を開始することがあります)。 この時点で、WdfDmaTransactionCancel メソッドを呼び出すと FALSE が返されます。

    EvtProgramDma では、ドライバーは WdfRequestUnmarkCancelable を呼び出して、要求の取り消しの可能性を終了できます。 WdfRequestUnmarkCancelable が STATUS_SUCCESS を返す場合、コールバック関数は転送を開始するようにハードウェアをプログラムする必要があります。 WdfRequestUnmarkCancelable が STATUS_CANCELLED を返した場合、要求は取り消されています。 この場合、EvtProgramDma は、DMA トランザクションを完了するために WdfDmaTransactionDmaCompletedFinal を呼び出す必要があります。

    ドライバーは、いくつかの転送操作が既に完了した後、DMA トランザクションを取り消すために同じ手法を使用できます。 この場合、ドライバーは WdfDmaTransactionDmaCompleted を呼び出した後、フレームワークが EvtProgramDma を呼び出して次の転送操作をプログラムする前に、WdfDmaTransactionCancel を呼び出します。 ドライバーが WdfDmaTransactionDmaCompleted を呼び出す前に WdfDmaTransactionCancel を呼び出すと、WdfDmaTransactionDmaCompleted は DMA トランザクションが完了したことを示す TRUE を返します。