次の方法で共有


WdfDmaTransactionExecute 関数 (wdfdmatransaction.h)

[KMDF にのみ適用]

WdfDmaTransactionExecute メソッドは、指定した DMA トランザクションの実行を開始します。

構文

NTSTATUS WdfDmaTransactionExecute(
  [in]           WDFDMATRANSACTION DmaTransaction,
  [in, optional] WDFCONTEXT        Context
);

パラメーター

[in] DmaTransaction

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

[in, optional] Context

ドライバー定義のコンテキスト情報。 フレームワークは 、Context に指定された値を渡します。これはポインターとして使用できます。この値は、ドライバーの EvtProgramDma イベント コールバック関数に渡されます。 このパラメーターは省略可能であり、 NULL にすることができます

戻り値

操作が成功した場合、WdfDmaTransactionExecute はSTATUS_SUCCESSを返します。 それ以外の場合、メソッドは次のいずれかの値を返す可能性があります。

リターン コード 説明
STATUS_INSUFFICIENT_RESOURCES
以前に WdfDmaTransactionSetImmediateExecution と呼ばれたドライバーと、要求に必要なリソースは使用できません。
STATUS_INVALID_DEVICE_REQUEST
WdfDmaTransactionExecute の呼び出しの前に、WdfDmaTransactionInitialize または WdfDmaTransactionInitializeUsingRequest の呼び出しが行われませんでした。
STATUS_WDF_BUSY
デバイスは単一パケット転送を実行し、別のトランザクションの実行中に WdfDmaTransactionExecute というドライバーを実行します。
STATUS_WDF_TOO_FRAGMENTED
指定した転送サイズを処理するためにオペレーティング システムが必要とする散布/収集要素の数が、ドライバーが WdfDmaEnablerSetMaximumScatterGatherElements を呼び出した値を超えました。 詳細については、「解説」を参照してください。
 

このメソッドは、他の NTSTATUS 値を返す場合もあります。

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

注釈

WdfDmaTransactionExecute メソッドは、指定された DMA トランザクションに関連付けられている最初の DMA 転送のトランザクションの散布/収集リストを初期化します。 (単一パケット転送の場合、散布/収集リストには 1 つの要素が含まれます)。次に、 メソッドはドライバーの EvtProgramDma イベント コールバック関数を呼び出し、コールバック関数はデバイスをプログラムして転送を開始できます。

フレームワーク ベースのドライバーは、通常、I/O キュー イベント コールバック関数内から WdfDmaTransactionExecute を呼び出します。

ドライバーが WdfDmaTransactionInitialize または WdfDmaTransactionInitializeUsingRequest を呼び出して DMA トランザクションを初期化した後、ドライバーは DMA トランザクションを完了する前に WdfDmaTransactionExecute を 1 回だけ呼び出す必要があります。

WdfDmaTransactionInitializeXxx が成功を返し、WdfDmaTransactionExecute がエラー値を返す場合、ドライバーは WdfDmaTransactionRelease を呼び出す必要があります。

1.11 より前のフレームワーク バージョンでは、デバイスが単一パケット転送を実行する場合、オペレーティング システムは一度に 1 つの DMA トランザクションのみを実行できます。 この場合、別のトランザクションが実行されている場合、 WdfDmaTransactionExecute はSTATUS_WDF_BUSYを返します。

フレームワーク バージョン 1.11 以降では、ドライバーが DMA バージョン 3 を使用して単一パケット転送を実行する場合、オペレーティング システムは内部キューに複数の DMA トランザクションを格納できます。 この場合、ドライバーは別のトランザクションの実行中 に WdfDmaTransactionExecute を呼び出すことができます。 DMA バージョン 3 を選択するには、WDF_DMA_ENABLER_CONFIGWdmDmaVersionOverride メンバーを 3 に設定します。

デバイスが分散/収集転送を実行する場合、オペレーティング システムは複数の DMA トランザクションを同時に実行できます。 この場合、ドライバーは別のトランザクションの実行中 に WdfDmaTransactionExecute を呼び出すことができます。

ドライバーが WdfDmaTransactionDmaCompletedWithLength を呼び出して部分的な転送を報告し、(MDL 構造体の Next メンバーを使用して) チェーンされた MDL を使用して DMA トランザクションのデータ バッファーを指定した場合、フレームワークはフラグメントの数とサイズを再計算し、許容されるフラグメントの数を超える可能性があるため、STATUS_WDF_TOO_FRAGMENTEDを返すことができます。

トランザクションが正常に開始された場合、 WdfDmaTransactionExecute はSTATUS_SUCCESSを返します。 フレームワークがトランザクションのすべての転送をドライバーの EvtProgramDma コールバック関数に正常に送信したかどうかを判断するには、ドライバーで WdfDmaTransactionDmaCompletedWdfDmaTransactionDmaCompletedWithLength、または WdfDmaTransactionDmaCompletedFinal を呼び出す必要があります。

Context パラメーターが提供する値がポインターまたはハンドルの場合は、ドライバーの EvtProgramDma イベント コールバック関数 (IRQL = DISPATCH_LEVEL) で参照するメモリにアクセスできる必要があります。 フレームワーク オブジェクト コンテキストを使用して、この要件を満たすことができます。

ドライバーは、 WdfDmaTransactionSetImmediateExecution を以前に呼び出した場合、非ブロッキングの方法で WdfDmaTransactionExecute を呼び出すことができます。

DMA トランザクションの詳細については、「 DMA トランザクションの開始」を参照してください。

PCIDRV サンプル ドライバーのコード例を次に示します。 この例では、DMA 転送を作成して初期化し、その実行を開始します。

NTSTATUS
NICInitiateDmaTransfer(
    IN PFDO_DATA  FdoData,
    IN WDFREQUEST  Request
    )
{
    WDFDMATRANSACTION  dmaTransaction;
    NTSTATUS  status;
    BOOLEAN  bCreated = FALSE;
 
    do {
        status = WdfDmaTransactionCreate(
                                         FdoData->WdfDmaEnabler,
                                         WDF_NO_OBJECT_ATTRIBUTES,
                                         &dmaTransaction
                                         );
        if(!NT_SUCCESS(status)) {
            TraceEvents(TRACE_LEVEL_ERROR, DBG_WRITE, 
                        "WdfDmaTransactionCreate failed %X\n", status);
            break;
        }

        bCreated = TRUE;

        status = WdfDmaTransactionInitializeUsingRequest( 
                                     dmaTransaction,
                                     Request,
                                     NICEvtProgramDmaFunction,
                                     WdfDmaDirectionWriteToDevice
                                     );
        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionInitalizeUsingRequest failed %X\n", 
                        status
                        );
            break;
        }

        status = WdfDmaTransactionExecute(
                                          dmaTransaction,
                                          dmaTransaction
                                          );

        if(!NT_SUCCESS(status)) {
            TraceEvents(
                        TRACE_LEVEL_ERROR,
                        DBG_WRITE, 
                        "WdfDmaTransactionExecute failed %X\n",
                        status
                        );
            break;
        }
    } while (FALSE);

    if(!NT_SUCCESS(status)){
 
        if(bCreated) {
            WdfObjectDelete(dmaTransaction);
        }
    }
    return status;
}

要件

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

こちらもご覧ください

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution