共用方式為


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 參數指向之緩衝區的大小,以位元組為單位。 配置的緩衝區大小必須夠大,才能包含散佈/收集清單,以及操作系統在此緩衝區中儲存的內部數據。 若要判斷所需的緩衝區大小,請呼叫 GetDmaTransferInfoCalculateScatterGatherList 例程。 如果 ScatterGatherBufferNULL,請將 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
STATUS_INVALID_PARAMETERS
例程失敗,因為呼叫端所傳遞的參數值無效。
STATUS_BUFFER_TOO_SMALL
ScatterGatherBuffer 中的呼叫端提供的緩衝區太小,無法包含散佈/收集清單。
STATUS_INSUFFICIENT_RESOURCES
例程無法配置 DMA 傳輸所需的資源。
STATUS_CANCELLED
此傳輸已取消。

備註

MapTransferEx 不是可直接依名稱呼叫的系統例程。此例程只能由DMA_OPERATIONS結構中傳回之位址的指標呼叫 驅動程式會呼叫IoGetDmaAdapter,並將DeviceDescription參數的Version成員設定為 DEVICE_DESCRIPTION_VERSION3,以取得此例程的位址。 如果 IoGetDmaAdapter 傳回 NULL,您的平台上無法使用例程。

對於使用系統 DMA 控制器的傳輸,呼叫端可以選擇提供 DmaCompletionRoutine 回呼例程,該例程會在傳輸完成時呼叫。 操作系統會排程此回呼,以響應系統 DMA 控制器中的 DMA 完成中斷。

MapTransferEx 可以設定的地圖緩存器數目不能超過從 IoGetDmaAdapter 取得的驅動程式上限。

MdlOffsetLength 參數描述所要求 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。

MapTransferExMapTransfer 例程的擴充版本。 擴充版本具有下列優點:

  • MapTransferEx 可以在一個呼叫中處理 MDL 鏈結中的所有緩衝區片段,但 MapTransfer 每個呼叫只能處理一個實際連續的緩衝區片段。
  • MapTransferEx 可以在一個呼叫中產生整個散佈/收集清單,但 MapTransfer 每個呼叫只能產生一個散佈/收集清單元素。
  • MapTransferEx 可以在一個呼叫中對應散佈/收集清單中的所有緩衝區片段,但 MapTransfer 每個呼叫只能對應一個實際連續的緩衝區片段。
  • MapTransferEx 只需要整個散佈/收集清單的起始位移,但 MapTransfer 需要每個實際連續緩衝區片段的起始虛擬位址。
  • MapTransferEx 呼叫可以對應透過一或多個 MDL 延伸的緩衝區,但 MapTransfer 呼叫只能對應 MDL 所描述記憶體中一個實際連續的緩衝區片段。
  • 對於系統 DMA 傳輸, MapTransferEx 可讓呼叫端提供 DmaCompletionRoutine 回呼例程,以在傳輸完成之後接收通知,但 MapTransfer 不提供在 DMA 傳輸完成時通知呼叫端的方法。
每次成功呼叫 MapTransferEx 時,都必須接著 對 FlushAdapterBuffersEx 例程的對應呼叫。 FlushAdapterBuffersEx 呼叫之後的 MapTransferEx 呼叫必須在下一個 MapTransferEx 呼叫發生之前發生。 即使對 CancelMappedTransfer 例程的呼叫成功,還是需要 FlushAdapterBuffersEx 呼叫,才能取消上述 MapTransferEx 呼叫所要求的對應傳輸。

如需詳細資訊,請參閱 使用 MapTransferEx 例程

規格需求

需求
最低支援的用戶端 從 Windows 8 開始提供。
目標平台 桌面
標頭 wdm.h (包括 Wdm.h、Ntddk.h、Ntifs.h)
IRQL <= DISPATCH_LEVEL

另請參閱

AllocateAdapterChannelEx

CalculateScatterGatherList

CancelMappedTransfer

DMA_ADAPTER

DMA_OPERATIONS

DmaCompletionRoutine

FlushAdapterBuffersEx

GetDmaTransferInfo

IoGetDmaAdapter

SCATTER_GATHER_LIST