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。 否則,方法可能會傳回下列其中一個值。

傳回碼 Description
STATUS_INSUFFICIENT_RESOURCES
無法配置散佈/收集清單。
STATUS_INVALID_PARAMETER
偵測到無效的參數。
STATUS_WDF_TOO_FRAGMENTED
處理交易所需的散佈/收集元素數目大於驅動程式呼叫 WdfDmaEnablerSetMaximumScatterGatherElements 所指定的值。

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

STATUS_WDF_NOT_ENOUGH_MAP_REGISTERS
此傳回值僅適用於針對 單一傳輸所設定的交易。

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

若要修正,驅動程式可能會將 MDL 鏈結結合成單一 MDL,以減少所需的對應緩存器數目。

使用封包和系統 DMA 的驅動程式可以呼叫 WdfDmaTransactionAllocateResources ,以從配置給裝置的總計保留一些對應緩存器。 假設您的驅動程式保留 4 個總地圖緩存器中的 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 交易

範例

下列程式代碼範例來自 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;
}

規格需求

需求
目標平台 Universal
最低 KMDF 版本 1.0
標頭 wdfdmatransaction.h (包含 Wdf.h)
程式庫 Wdf01000.sys (請參閱 Framework Library Versioning.)
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