[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を返します。 それ以外の場合、メソッドは次のいずれかの値を返す可能性があります。
リターン コード | 説明 |
---|---|
|
散布図/収集リストを割り当てませんでした。 |
|
無効なパラメーターが検出されました。 |
|
トランザクションを処理するために必要な散布図/収集要素の数が、ドライバーが WdfDmaEnablerSetMaximumScatterGatherElements 呼び出 指定した値を超えました。
単一転送 設定されたトランザクションの場合、これを修正する 1 つの方法は、物理的に連続したバッファーにデータをコピーし、そのバッファーを使用してトランザクションを初期化することです。 たとえば、mmAllocateContiguousMemory 呼び出し、元のバッファーを新しいバッファーにコピーしてから、WdfDmaTransactionInitialize 再度呼び出します。 |
|
この戻り値は、単一転送 設定されたトランザクションにのみ適用されます。
トランザクションをマップするために必要なマップ レジスタの数が、DMA アダプターが予約した数を超えています。 この問題を解決するために、ドライバーは、MDL チェーンを 1 つの MDL に結合することで、必要なマップ レジスタの数を減らすことができます。 パケットとシステム DMA を使用するドライバーは、WdfDmaTransactionAllocateResources を呼び出して、デバイスに割り当てられた合計からマップ レジスタの数を予約できます。 ドライバーが合計マップ レジスタの 8 つのうち 4 つを予約したとしますが、DMA 転送には 6 が必要です。 この場合、WdfDmaTransactionInitialize 失敗します。 修正するには、WdfDmaTransactionFreeResources を呼び出し、WdfDmaTransactionInitialize を再度呼び出します。 散布図/収集 DMA を使用するドライバーは、マップ レジスタを予約できません。 |
|
この戻り値は、単一転送 設定されたトランザクションにのみ適用されます。
トランザクションの合計長がデバイスの最大転送サイズを超えています。 |
このメソッドは、他の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 |
ヘッダー | wdfdmatransaction.h (Wdf.h を含む) |
図書館 | Wdf01000.sys (フレームワーク ライブラリのバージョン管理を参照)。 |
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 の