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
[in] Mdl
記憶體描述項清單的指標, (MDL) ,描述將用於 DMA 交易的緩衝區。 如需詳細資訊,請參閱。
[in] VirtualAddress
將用於 DMA 交易之緩衝區的虛擬位址。
[in] Length
要傳送的位元組數目。
傳回值
如果作業成功,WdfDmaTransactionInitialize 會傳回STATUS_SUCCESS。 否則,方法可能會傳回下列其中一個值。
傳回碼 | Description |
---|---|
|
無法配置散佈/收集清單。 |
|
偵測到無效的參數。 |
|
處理交易所需的散佈/收集元素數目大於驅動程式呼叫 WdfDmaEnablerSetMaximumScatterGatherElements 所指定的值。
針對針對 單一傳輸所設定的交易,其中一個修正方法是將數據複製到實體連續緩衝區,然後使用該緩衝區初始化交易。 例如,呼叫 MmAllocateContiguousMemory,將原始緩衝區複製到新的緩衝區,然後再次呼叫 WdfDmaTransactionInitialize 。 |
|
此傳回值僅適用於針對 單一傳輸所設定的交易。
對應交易所需的對應緩存器數目大於 DMA 配接器保留的數目。 若要修正,驅動程式可能會將 MDL 鏈結結合成單一 MDL,以減少所需的對應緩存器數目。 使用封包和系統 DMA 的驅動程式可以呼叫 WdfDmaTransactionAllocateResources ,以從配置給裝置的總計保留一些對應緩存器。 假設您的驅動程式保留 4 個總地圖緩存器中的 4 個,但 DMA 傳輸需要 6 個。 在此情況下, WdfDmaTransactionInitialize 會失敗。 若要修正,請呼叫 WdfDmaTransactionFreeResources ,然後再次呼叫 WdfDmaTransactionInitialize 。 使用散佈圖/收集 DMA 的驅動程式無法保留地圖緩存器。 |
|
此傳回值僅適用於針對 單一傳輸所設定的交易。
交易的總長度超過裝置的最大傳輸大小。 |
這個方法也可能傳回其他 NTSTATUS值。
如果驅動程式提供無效的物件句柄,就會發生錯誤檢查。
備註
WdfDmaTransactionInitialize 方法會執行 DMA 作業,方法是執行初始化作業,例如配置交易的散佈/收集清單。 驅動程式呼叫 WdfDmaTransactionInitialize 之後,驅動程式必須呼叫 WdfDmaTransactionExecute 才能開始執行交易。
架構型驅動程式通常會從 I/O 佇列事件回呼函式內呼叫 WdfDmaTransactionInitialize。
如果您要建立以架構要求物件所包含的資訊為基礎的 DMA 交易,驅動程式應該呼叫 WdfDmaTransactionInitializeUsingRequest。 如果您要建立不是以要求對象為基礎的 DMA 交易,請使用 WdfDmaTransactionInitialize 或 WdfDmaTransactionInitializeUsingOffset。
驅動程式可以在此方法的 Mdl 參數中指定 MDL 鏈結。 MDL 鏈結是一系列 MDL 結構,驅動程式會使用 MDL 結構的 Next 成員鏈結在一起。 在 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;
}
規格需求
需求 | 值 |
---|---|
目標平台 | 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) |