次の方法で共有


WdfDmaTransactionInitialize 関数 (wdfdmatransaction.h)

[KMDF にのみ適用]

WdfDmaTransactionInitialize メソッドは、指定された DMA トランザクションを初期化します。

構文

NTSTATUS WdfDmaTransactionInitialize(
  [in] WDFDMATRANSACTION   DmaTransaction,
  [in] PFN_WDF_PROGRAM_DMA EvtProgramDmaFunction,
  [in] WDF_DMA_DIRECTION   DmaDirection,
  [in] PMDL                Mdl,
  [in] PVOID               VirtualAddress,
  [in] size_t              Length
);

パラメーター

[in] DmaTransaction

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

[in] EvtProgramDmaFunction

ドライバーの EvtProgramDma イベント コールバック関数へのポインター。

[in] DmaDirection

WDF_DMA_DIRECTION型指定された値。

[in] Mdl

DMA トランザクションに使用されるバッファーを記述するメモリ記述子リスト (MDL) へのポインター。 詳細については、「解説」を参照 してください

[in] VirtualAddress

DMA トランザクションに使用されるバッファーの仮想アドレス。

[in] Length

転送するバイト数。

戻り値

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

リターン コード 説明
STATUS_INSUFFICIENT_RESOURCES
散布図/収集リストを割り当てませんでした。
STATUS_INVALID_PARAMETER
無効なパラメーターが検出されました。
STATUS_WDF_TOO_FRAGMENTED
トランザクションの処理に必要な散布/収集要素の数が、ドライバーが WdfDmaEnablerSetMaximumScatterGatherElements を呼び出した値より大きかった。

単一転送に設定されたトランザクションの場合、これを修正する 1 つの方法は、物理的に連続したバッファーにデータをコピーし、そのバッファーを使用してトランザクションを初期化することです。 たとえば、 MmAllocateContiguousMemory を呼び出し、元のバッファーを新しいバッファーにコピーしてから、 WdfDmaTransactionInitialize を再度呼び出します。

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
この戻り値は、 単一転送に設定されたトランザクションにのみ適用されます。

トランザクションをマップするために必要なマップ レジスタの数が、DMA アダプターが予約した数を超えています。

修正するために、ドライバーは、MDL チェーンを 1 つの MDL に組み合わせることによって、必要なマップ レジスタの数を減らす可能性があります。

パケットとシステム DMA を使用するドライバーは 、WdfDmaTransactionAllocateResources を呼び出して、デバイスに割り当てられた合計からマップ レジスタの数を予約できます。 ドライバーが合計マップ レジスタの 8 つのうち 4 つを予約したとしますが、DMA 転送には 6 が必要です。 この場合、 WdfDmaTransactionInitialize は失敗します。 修正するには、 WdfDmaTransactionFreeResources を呼び出し、 WdfDmaTransactionInitialize をもう一度呼び出します。

散布図/収集 DMA を使用するドライバーは、マップ レジスタを予約できません。

STATUS_WDF_TOO_MANY_TRANSFERS
この戻り値は、 単一転送に設定されたトランザクションにのみ適用されます。

トランザクションの合計の長さが、デバイスの最大転送サイズを超えています。

 

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

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

注釈

WdfDmaTransactionInitialize メソッドは、トランザクションの散布/収集リストの割り当てなどの初期化操作を実行することで、DMA 操作を実行できるように準備します。 ドライバーが WdfDmaTransactionInitialize を呼び出した後、ドライバーは WdfDmaTransactionExecute を呼び出してトランザクションの実行を開始する必要があります。

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

フレームワーク要求オブジェクトに含まれる情報に基づく DMA トランザクションを作成する場合、ドライバーは WdfDmaTransactionInitializeUsingRequest を呼び出す必要があります。 要求オブジェクトに基づかない DMA トランザクションを作成する場合は、 WdfDmaTransactionInitialize または WdfDmaTransactionInitializeUsingOffset を使用します。

ドライバーは、このメソッドの Mdl パラメーターで MDL チェーンを指定できます。 MDL チェーンは、ドライバーが MDL 構造体の Next メンバーを使用して連結された MDL 構造体のシーケンスです。 1.11 より前のフレームワーク バージョンでは、分散/収集 DMA 転送のみが MDL チェーンを使用できます。 バージョン 1.11 以降では、ドライバーが DMA バージョン 3 を使用している場合、単一パケット転送でチェーンされた MDL を使用することもできます。

ドライバーが指定するバッファーが、 WdfDmaEnablerCreate または WdfDmaTransactionSetMaximumLength を呼び出したときにドライバーが指定した転送の最大長よりも大きい場合、フレームワークはトランザクションを複数の 転送に分割します。

DMA トランザクションの詳細については、「DMA トランザクション の作成と初期化」を参照してください。

次のコード例は、 PLX9x5x サンプル ドライバーのものです。 最初に、この例では 、WDF_OBJECT_ATTRIBUTES 構造体を初期化し、DMA トランザクション オブジェクトを作成します。 次に、受信した I/O 要求の入力バッファーを表す MDL を取得し、バッファーの仮想アドレスと長さを取得します。 最後に、この例では WdfDmaTransactionInitialize を呼び出してトランザクションを初期化します。

WDF_OBJECT_ATTRIBUTES  attributes;
PMDL  mdl;
PVOID  virtualAddress;
ULONG  length;
NTSTATUS  status;

WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
                                        &attributes,
                                        TRANSACTION_CONTEXT
                                        );

status = WdfDmaTransactionCreate(
                                 devExt->DmaEnabler,
                                 &attributes,
                                 &dmaTransaction
                                 );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

status = WdfRequestRetrieveInputWdmMdl(
                                       Request,
                                       &mdl
                                       );
if (!NT_SUCCESS(status)) {
    goto CleanUp;
}

virtualAddress = MmGetMdlVirtualAddress(mdl);
length = MmGetMdlByteCount(mdl);

status = WdfDmaTransactionInitialize(
                                     dmaTransaction,
                                     PLxEvtProgramWriteDma,
                                     WdfDmaDirectionWriteToDevice,
                                     mdl,
                                     virtualAddress,
                                     length
                                     );
if(!NT_SUCCESS(status)) {
    goto CleanUp;
}

要件

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

こちらもご覧ください

EvtProgramDma

MmGetMdlByteCount

MmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest