次の方法で共有


WdfDmaTransactionExecute 関数 (wdfdmatransaction.h)

[KMDF にのみ適用]

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

構文

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

パラメーター

[in] DmaTransaction

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

[in, optional] Context

ドライバー定義のコンテキスト情報。 フレームワークは、ドライバーの EvtProgramDma イベント コールバック関数に、ポインターを指定できる Contextに指定された値を渡します。 このパラメーターは省略可能であり、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 トランザクションのデータ バッファーを指定した場合、フレームワークがフラグメントの数とサイズを再計算し、許容されるフラグメントの数を超える可能性があるため、WdfDmaTransactionExecute はSTATUS_WDF_TOO_FRAGMENTEDを返すことができます。

WdfDmaTransactionExecute は、トランザクションが正常に開始された場合にSTATUS_SUCCESSを返します。 フレームワークがドライバーの EvtProgramDma コールバック関数にトランザクションのすべての転送を正常に送信したかどうかを判断するには、ドライバーは WdfDmaTransactionDmaCompleted WdfDmaTransactionDmaCompletedWithLength、または 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
ヘッダー wdfdmatransaction.h (Wdf.h を含む)
図書館 Wdf01000.sys (フレームワーク ライブラリのバージョン管理を参照)。
IRQL <=DISPATCH_LEVEL
DDI コンプライアンス規則 する DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

こちらもご覧ください

EvtProgramDma

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionDmaCompleted

WdfDmaTransactionDmaCompletedFinal

WdfDmaTransactionDmaCompletedWithLength

WdfDmaTransactionInitialize

WdfDmaTransactionInitializeUsingRequest

WdfDmaTransactionSetImmediateExecution