WdfDmaTransactionDmaCompleted 関数 (wdfdmatransaction.h)

[KMDF にのみ適用]

WdfDmaTransactionDmaCompleted メソッドは、デバイスの DMA 転送操作が完了したことをフレームワークに通知します。

構文

BOOLEAN WdfDmaTransactionDmaCompleted(
  [in]  WDFDMATRANSACTION DmaTransaction,
  [out] NTSTATUS          *Status
);

パラメーター

[in] DmaTransaction

ドライバーが WdfDmaTransactionCreate の以前の呼び出しから取得した DMA トランザクション オブジェクトへのハンドル。

[out] Status

DMA 転送の状態を受け取る場所へのポインター。 詳細については、「解説」を参照してください。

戻り値

WdfDmaTransactionDmaCompletedFALSE を 返し、DMA トランザクションを完了するために追加の転送が必要な場合、 Status はSTATUS_MORE_PROCESSING_REQUIREDを受け取ります。 メソッドは、追加の転送が必要ない場合に TRUE を 返します。

ドライバーが無効なオブジェクト ハンドルを提供すると、バグ チェックが発生します。

注釈

フレームワーク ベースのドライバーは、 DMA 転送 が完了するたびに、次のいずれかのメソッドを呼び出す必要があります。

通常、ドライバーは、デバイスの割り込みが DMA 転送操作の完了を示した後、 EvtInterruptDpc イベント コールバック関数内からこれらのメソッドを呼び出します。 システム モード DMA デバイスのドライバーは、 EvtDmaTransactionDmaTransferComplete イベント コールバック関数内からこれらのメソッドを呼び出す場合があります。

フレームワークでは、 DMA トランザクション を複数の DMA 転送操作に分割する場合があります。 そのため、ドライバーはメソッドの戻り値を調べて、追加の転送が必要かどうかを判断する必要があります。

メソッドが FALSE を返す場合、 状態 の場所はSTATUS_MORE_PROCESSING_REQUIREDを受け取り、トランザクションを完了するには追加の DMA 操作が必要です。 通常、 EvtInterruptDpc イベント コールバック関数は、この時点で他に何も行いません。 代わりに、フレームワークはドライバーの EvtProgramDma イベント コールバック関数を呼び出して、コールバック関数が次の転送を開始できるようにします。

メソッドが TRUE を返した場合、指定したトランザクションに対してこれ以上の転送は行われません。 この場合、 Status 値STATUS_SUCCESSは、フレームワークでエラーが発生せず、DMA トランザクションが完了したことを意味します。

WdfDmaTransactionDmaCompleted を呼び出す前にドライバーが WdfDmaTransactionStopSystemTransfer を呼び出した場合、WdfDmaTransactionDmaCompletedTRUE を返し、Statusは STATUS_CANCELLED

単一転送に設定されたトランザクションの場合、WdfDmaTransactionDmaCompletedTRUE を返し、ハードウェアが 1 回の転送でトランザクションを完了できなかった場合は、STATUS_WDF_TOO_MANY_TRANSFERSの Status 値を返します。ただし、初期化は成功しました。 これは、DMA 操作ごとに残存転送を報告するハードウェアで発生する可能性があります。 たとえば、ドライバーは 64 KB を書き込むデバイスをプログラムしますが、デバイスは 60 KB のみを書き込みます。 この場合、ドライバーは DMA 操作を繰り返すか、デバイスをリセットする可能性があります。

Status のその他の値は、フレームワークがエラーを検出し、DMA トランザクションが完了していない可能性があることを意味します。

WdfDmaTransactionDmaCompleted がTRUE を返すと、ドライバーは通常、次の処理を行います。

DMA 転送の完了の詳細については、「DMA 転送 の完了」を参照してください。

次のコード例は、 AMCC5933 サンプル ドライバーのコード例です。 この例では、 EvtInterruptDpc コールバック関数を示します。 この例では、DMA 転送が完了したことをフレームワークに通知します。 この転送が DMA トランザクションの最後の転送であることをフレームワークが示す場合、コードは DMA トランザクション オブジェクトを削除し、関連付けられている I/O 要求を完了します。

VOID
AmccPciEvtInterruptDpc(
    IN WDFINTERRUPT  WdfInterrupt,
    IN WDFOBJECT  WdfDevice
    )
{
    PAMCC_DEVICE_EXTENSION  devExt;
    WDFREQUEST  request;
    REQUEST_CONTEXT  *transfer;
    NTSTATUS  status;
    size_t  transferred;
    BOOLEAN  transactionComplete;

    UNREFERENCED_PARAMETER( WdfInterrupt );

    //
    // Retrieve request and transfer.
    //
    devExt = AmccPciGetDevExt(WdfDevice);
    request  = devExt->CurrentRequest;
    transfer = GetRequestContext(request);

    //
    // Check to see if the request has been canceled. 
    //
    if (WdfRequestIsCanceled(request)) {
        TraceEvents(
                    TRACE_LEVEL_ERROR,
                    AMCC_TRACE_IO,
                    "Aborted DMA transaction 0x%p",
                    request
                    );
        WdfObjectDelete( transfer->DmaTransaction );
        devExt->CurrentRequest = NULL;
        WdfRequestComplete(
                           request,
                           STATUS_CANCELLED
                           );
        return;
    }
 
    //
    // Notify the framework that a DMA transfer has completed.
    //
    transactionComplete = WdfDmaTransactionDmaCompleted(
                                                    transfer->DmaTransaction,
                                                    &status
                                                    );
    if (transactionComplete) {
        ASSERT(status != STATUS_MORE_PROCESSING_REQUIRED);

        //
        // No more data. The request is complete.
        //
        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Request %p completed: status %X",  
                    request,
                    status
                    );

        //
        // Get the byte count.
        //
        transferred =
                WdfDmaTransactionGetBytesTransferred(transfer->DmaTransaction);

        TraceEvents(
                    TRACE_LEVEL_INFORMATION,
                    AMCC_TRACE_IO,
                    "Bytes transferred %d",
                    (int) transferred
                    );

        //
        // Delete this DmaTransaction object.
        //
        WdfObjectDelete(transfer->DmaTransaction);

        //
        // Clean up the device context for this request.
        //
        devExt->CurrentRequest = NULL;

        //
        // Complete this I/O request.
        //
        WdfRequestCompleteWithInformation(
                                          request, 
                                          status,
                                          (NT_SUCCESS(status)) ? transferred : 0
                                          );
    }
}

要件

要件
対象プラットフォーム ユニバーサル
最小 KMDF バージョン 1.0
Header wdfdmatransaction.h (Wdf.h を含む)
Library Wdf01000.sys (「Framework ライブラリのバージョン管理」を参照)。
IRQL <=DISPATCH_LEVEL
DDI コンプライアンス規則 DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

こちらもご覧ください

EvtInterruptDpc

EvtProgramDma

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionRelease

WdfObjectDelete

WdfRequestComplete

WdfRequestCompleteWithInformation