共用方式為


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

記憶體描述項清單 (MDL) 的指標,描述將用於 DMA 交易的緩衝區。 請參閱<中的詳細資訊。

[in] VirtualAddress

將用於 DMA 交易之緩衝區的虛擬位址。

[in] Length

要傳輸的位元組數目。

返回值

如果作業成功,WdfDmaTransactionInitialize 會傳回STATUS_SUCCESS。 否則,方法可能會傳回下列其中一個值。

回傳碼 說明
資源不足狀態
無法配置散佈/收集清單。
STATUS_INVALID_PARAMETER
偵測到無效的參數。
STATUS_WDF_TOO_FRAGMENTED
處理交易所需的散佈/收集元素數目大於驅動程式呼叫 WdfDmaEnablerSetMaximumScatterGatherElements 的值。

針對針對 單一傳輸設定的交易,其中一個修正方法是將數據複製到實體連續緩衝區,然後使用該緩衝區初始化交易。 例如,呼叫 MmAllocateContiguousMemory,將原始緩衝區複製到新的緩衝區,然後再次呼叫 WdfDmaTransactionInitialize

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
這個傳回值僅適用於針對單一傳輸 設定的交易

對應交易所需的對應緩存器數目大於 DMA 配接器已保留的數目。

若要修正,驅動程式可能會藉由將 MDL 鏈結合並成單一 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 交易,請使用 WdfDmaTransactionInitializeWdfDmaTransactionInitializeUsingOffset

驅動程式可以在此方法的 Mdl 參數中指定 MDL 鏈結。 MDL 鏈結是一連串的 MDL 結構,驅動程式會使用 MDL 結構的 Next 成員鏈結在一起。 在 1.11 之前的架構版本中,只有散佈/收集 DMA 傳輸可以使用 MDL 鏈結。 從 1.11 版開始,如果驅動程式使用 DMA 第 3 版,單一封包傳輸也可以使用鏈結的 MDL。

如果驅動程式指定的緩衝區大於驅動程式呼叫 WdfDmaEnablerCreateWdfDmaTransactionSetMaximumLength時所指定的傳輸長度上限,架構會將交易分成多個 傳輸

如需 DMA 交易的詳細資訊,請參閱 建立和初始化 DMA 交易

範例

下列程式代碼範例來自 PLX9x5x5x 範例驅動程式。 首先,此範例會初始化 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

mmGetMdlByteCount

mmGetMdlVirtualAddress

WDF_DMA_DIRECTION

WdfDmaEnablerSetMaximumScatterGatherElements

WdfDmaTransactionCreate

WdfDmaTransactionExecute

WdfDmaTransactionInitializeUsingRequest