PMAP_TRANSFER_EX回呼函式 (wdm.h)
MapTransferEx 例程會設定地圖緩存器,將散佈/收集清單中的實體位址對應至執行 DMA 傳輸所需的邏輯位址。
語法
PMAP_TRANSFER_EX PmapTransferEx;
NTSTATUS PmapTransferEx(
[in] PDMA_ADAPTER DmaAdapter,
[in] PMDL Mdl,
[in] PVOID MapRegisterBase,
[in] ULONGLONG Offset,
[in] ULONG DeviceOffset,
[in, out] PULONG Length,
[in] BOOLEAN WriteToDevice,
[out, optional] PSCATTER_GATHER_LIST ScatterGatherBuffer,
[in] ULONG ScatterGatherBufferLength,
[in, optional] PDMA_COMPLETION_ROUTINE DmaCompletionRoutine,
[in, optional] PVOID CompletionContext
)
{...}
參數
[in] DmaAdapter
DMA_ADAPTER 結構的指標。 這個結構是代表驅動程式總線主機 DMA 裝置或系統 DMA 通道的配接器物件。 呼叫端從先前呼叫 IoGetDmaAdapter 例程取得此指標。
[in] Mdl
MDL 鏈結的指標,描述虛擬記憶體中鎖定緩衝區集合的實體頁面配置。 DMA 傳輸的散佈/收集清單會使用 位移 和 長度 參數所指定的此記憶體區域。 如需 MDL 鏈結的詳細資訊,請參閱 使用 MDL。
[in] MapRegisterBase
配置給配接器對象的對應緩存器的句柄。 呼叫端先前已從 AllocateAdapterChannelEx 例程取得此句柄。
[in] Offset
MDL 鏈結所描述記憶體開頭的位元組位移。 這個位移會指定用於 DMA 傳輸的 I/O 數據緩衝區開始。 如果散佈/收集清單提供給呼叫端,此位移會決定清單中第一個緩衝區片段的起始位址。 如果 MDL 鏈結中的 MDL 描述記憶體總計 N 個字節, 則 Offset 的有效值會位於 0 到 N–1 的範圍內。 如需詳細資訊,請參閱<備註>。
[in] DeviceOffset
目標裝置數據快取器或 FIFO 的位元組位移,來自裝置的基位址。 此參數適用於具有多個 FIFO 且可由系統 DMA 控制器存取的裝置。 此參數僅用於系統 DMA 傳輸。 針對總線主機傳輸,請將此參數設定為零。
[in, out] Length
變數的指標,其中包含用於 DMA 傳輸之 I/O 數據緩衝區的長度,以位元組為單位。 在專案上,此變數包含呼叫驅動程式所要求的長度。 傳回之前,例程會將對應緩衝區的實際長度寫入此變數。 從 MapTransferEx 傳回的 *Length 值會指出對應的位元組數目。 如果對應緩存器和散佈/收集緩衝區大小的數目足以對應呼叫端所要求的整個長度,則 *Length 的輸入和輸出值相同。 如果 MDL 鏈結中的 MDL 描述記憶體總數,則有效值為 *Length 的範圍是 0 到 N–Offset。
[in] WriteToDevice
DMA 傳輸的方向。 針對寫入作業,將此參數設定為 TRUE ,以將數據從記憶體傳輸至裝置。 針對讀取作業將此參數設定為 FALSE ,以將資料從裝置傳輸到記憶體。
[out, optional] ScatterGatherBuffer
呼叫端配置的緩衝區指標,例程會寫入 DMA 傳輸的散佈/收集清單。 此清單開頭為 SCATTER_GATHER_LIST 結構,緊接著 SCATTER_GATHER_ELEMENT 陣列。 對於使用總線主機 DMA 裝置的驅動程式, ScatterGatherBuffer 是必要參數。 對於使用系統 DMA 控制器的驅動程式, ScatterGatherBuffer 參數是選擇性的,而且可以是 NULL。 如需詳細資訊,請參閱<備註>。
[in] ScatterGatherBufferLength
ScatterGatherBuffer 參數指向之緩衝區的大小,以位元組為單位。 配置的緩衝區大小必須夠大,才能包含散佈/收集清單,以及操作系統在此緩衝區中儲存的內部數據。 若要判斷所需的緩衝區大小,請呼叫 GetDmaTransferInfo 或 CalculateScatterGatherList 例程。 如果 ScatterGatherBuffer 為 NULL,請將 ScatterGatherBufferLength 設定為零。
[in, optional] DmaCompletionRoutine
呼叫端提供的 DmaCompletionRoutine 例程指標,當 DMA 傳輸完成時要呼叫。 如果目標裝置使用產生 DMA 完成中斷的系統 DMA 控制器,就會呼叫此例程。 DmaCompletionRoutine 例程會在 DMA 傳輸完成之後在DISPATCH_LEVEL呼叫。 對於系統 DMA 配接器,此參數是選擇性的,而且可以是 NULL。 如果是總線主機適配卡,請將此參數設定為 NULL。
[in, optional] CompletionContext
DmaCompletionRoutine 例程的驅動程序決定內容。 此內容會以 CompletionContext 參數的形式提供給 DmaCompletionRoutine 例程。 如果 DmaCompletionRoutine 參數為 NULL,請將 CompletionContext 設定為 NULL。
傳回值
如果呼叫成功,MapTransferEx 會傳回STATUS_SUCCESS。 可能的錯誤傳回值包括下列狀態代碼。
傳回碼 | Description |
---|---|
|
例程失敗,因為呼叫端所傳遞的參數值無效。 |
|
ScatterGatherBuffer 中的呼叫端提供的緩衝區太小,無法包含散佈/收集清單。 |
|
例程無法配置 DMA 傳輸所需的資源。 |
|
此傳輸已取消。 |
備註
MapTransferEx 不是可直接依名稱呼叫的系統例程。此例程只能由DMA_OPERATIONS結構中傳回之位址的指標呼叫 驅動程式會呼叫IoGetDmaAdapter,並將DeviceDescription參數的Version成員設定為 DEVICE_DESCRIPTION_VERSION3,以取得此例程的位址。 如果 IoGetDmaAdapter 傳回 NULL,您的平台上無法使用例程。
對於使用系統 DMA 控制器的傳輸,呼叫端可以選擇提供 DmaCompletionRoutine 回呼例程,該例程會在傳輸完成時呼叫。 操作系統會排程此回呼,以響應系統 DMA 控制器中的 DMA 完成中斷。
MapTransferEx 可以設定的地圖緩存器數目不能超過從 IoGetDmaAdapter 取得的驅動程式上限。
Mdl、Offset 和 Length 參數描述所要求 DMA 傳輸的 I/O 數據緩衝區。 配置的對應緩存器數目可能不足以對應此緩衝區中的所有記憶體,或 ScatterGatherBuffer 所指向的散佈/收集緩衝區可能不夠大,無法描述整個緩衝區。 MapTransferEx 會將輸出值寫入至 *Length ,以告知驅動程式所要求 DMA 傳輸的緩衝區內存數目是由例程所對應。 例程會將散佈/收集清單寫入 ScatterGatherBuffer 所指向的緩衝區。 此清單描述例程成功對應的緩衝區片段。
如果 MapTransferEx 的呼叫成功, MapTransferEx 會在傳回之前寫入 *Length 輸出值。 如果呼叫端指定 DmaCompletionRoutine,則更新的 *Length 輸出值一律會在 DmaCompletionRoutine 執行之前寫入。 如需詳細資訊,請參閱 MapTransferEx 的多個呼叫。
Offset 參數會指定 MDL 鏈結中描述 I/O 數據緩衝區內存的起始位移。 例如,假設 MDL 鏈結包含兩個 MDLs、MDL₁ 和 MDLー,而 MDL₁ 描述 N₁ 個字節的記憶體,而 MDLL 會描述 Nー 位元組。 如果 Offset = N,其中 N₁ N<₁ < + Nー,則緩衝區不會包含 MDL₁ 所描述的記憶體,並從 N - N₁ 位元組的位移開始於 MDL{所描述的記憶體中。
如果傳輸使用系統 DMA 控制器,則呼叫端可以設定 ScatterGatherBuffer = NULL,在此情況下 ,MapTransferEx 會使用內部配置的默認緩衝區來保存散佈/收集清單。 默認緩衝區保證夠大,足以包含至少一個元素的散佈/收集清單。 如果默認緩衝區用於散佈/收集傳送許多元素,可能需要對 MapTransferEx 進行許多呼叫,才能完成傳輸。 如果 DMA 控制器硬體支援散佈/收集傳輸,則使用預設緩衝區可能會降低效能。
如果 ScatterGatherBuffer 不是 NULL, 而 ScatterGatherBufferSize 會指定大小太小而無法包含至少一個專案的散佈/收集清單, MapTransferEx 會失敗並傳回STATUS_INVALID_PARAMETER。
MapTransferEx 是 MapTransfer 例程的擴充版本。 擴充版本具有下列優點:
- MapTransferEx 可以在一個呼叫中處理 MDL 鏈結中的所有緩衝區片段,但 MapTransfer 每個呼叫只能處理一個實際連續的緩衝區片段。
- MapTransferEx 可以在一個呼叫中產生整個散佈/收集清單,但 MapTransfer 每個呼叫只能產生一個散佈/收集清單元素。
- MapTransferEx 可以在一個呼叫中對應散佈/收集清單中的所有緩衝區片段,但 MapTransfer 每個呼叫只能對應一個實際連續的緩衝區片段。
- MapTransferEx 只需要整個散佈/收集清單的起始位移,但 MapTransfer 需要每個實際連續緩衝區片段的起始虛擬位址。
- MapTransferEx 呼叫可以對應透過一或多個 MDL 延伸的緩衝區,但 MapTransfer 呼叫只能對應 MDL 所描述記憶體中一個實際連續的緩衝區片段。
- 對於系統 DMA 傳輸, MapTransferEx 可讓呼叫端提供 DmaCompletionRoutine 回呼例程,以在傳輸完成之後接收通知,但 MapTransfer 不提供在 DMA 傳輸完成時通知呼叫端的方法。
如需詳細資訊,請參閱 使用 MapTransferEx 例程。
規格需求
需求 | 值 |
---|---|
最低支援的用戶端 | 從 Windows 8 開始提供。 |
目標平台 | 桌面 |
標頭 | wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h) |
IRQL | <= DISPATCH_LEVEL |