執行系統或總線主機、封包型 DMA 的驅動程式可以使用專為散佈/收集 DMA 而設計的支援例程。 驅動程式可以使用 GetScatterGatherList 和 PutScatterGatherList,而不是呼叫 Packet-Based System DMA 和 Packet-Based Bus-Master DMA中所述的例程。
裝置不需要有內建散佈/收集支援,其驅動程式才能使用這些例程。
使用封包型 DMA 的驅動程式會針對散佈/收集作業呼叫下列一般支援例程:
MmGetMdlVirtualAddress 以取得 MDL 的索引,這是呼叫 getScatterGatherList 時所需的參數
GetScatterGatherList,當驅動程式準備好要為其 DMA 裝置進行設置,而且需要系統 DMA 控制器或總線主控介面卡時
GetScatterGatherList 分配系統的 DMA 控制器或總線主控適配器,確定所需的映射寄存器數量並進行分配,填寫分散/聚集清單,並在 DMA 控制器或適配器以及映射寄存器可用時,呼叫驅動程式的 AdapterListControl 例程。
一旦所有要求的數據已傳輸完畢,或因裝置 I/O 錯誤導致驅動程式失敗 IRP,即可執行 PutScatterGatherList。
PutScatterGatherList 排清配接器緩衝區、釋放地圖緩存器,並釋放散佈/收集清單。 驅動程式必須先呼叫 putScatterGatherList ,才能存取緩衝區中的數據。
IoGetDmaAdapter 所傳回的配接器對象指標是每個這些例程所需的參數,除了 MmGetMdlVirtualAddress之外,該例程需要一個指向 Irp->MdlAddress的MDL指標。
GetScatterGatherList 例程包括呼叫 AllocateAdapterChannel 和 MapTransfer,因此驅動程式不需要進行這些呼叫。 例程會採用下列作為參數:
IoGetDmaAdapter 所傳回之 DMA_ADAPTER 結構的指標
指向 DMA 作業目標裝置物件的指標
指向描述位於 Irp處之緩衝區的 MDL 的指標 ->MdlAddress
Mdl 所描述之緩衝區中目前虛擬位址的指標
要對應的位元組數目
指向執行傳輸的AdapterListControl 例程的指標
供驅動程式使用者傳遞至 AdapterListControl 例程的上下文區域指標
布爾值:TRUE 傳送至裝置;否則 FALSE
在判斷所需的地圖緩存器數目、配置配接器通道和地圖緩存器、填入散佈/收集清單並準備傳輸之後,GetScatterGatherList 呼叫驅動程式提供的 AdapterListControl 例程。 AdapterListControl 例程是在 IRQL = DISPATCH_LEVEL 的任意線程內容中執行。
AdapterListControl 驅動程式在呼叫 GetScatterGatherList 時提供的例程與傳遞至 AllocateAdapterChannel 的 AdapterControl 例程在以下重要方面有所不同:
AdapterListControl 例程沒有傳回值,而 AdapterControl 例程會傳回 IO_ALLOCATION_ACTION。
MapRegisterBase 系統配置的對應緩存器,AdapterListControl 例程的第三個參數會指向驅動程式可執行 DMA 的 SCATTER_GATHER_LIST 結構。
AdapterListControl 例程會執行 AdapterControl 例程中所需的工作子集。
AdapterListControl 例程不會呼叫 AllocateAdapterChannel 或 MapTransfer。 其唯一的責任是儲存輸入散佈圖/收集清單指標、設定其裝置,並使用散佈圖/收集清單來執行 DMA。
散佈/收集清單結構包含 SCATTER_GATHER_ELEMENT 陣列和陣列中的元素數目。 陣列的每個元素都會提供實體連續散佈/收集區域的長度和起始實體位址。 驅動程式會在數據傳輸中使用長度和位址。
不論其裝置是否支援散佈/收集 DMA,驅動程式都可以使用 GetScatterGatherList。 對於不支援散佈/收集 DMA 的裝置,散佈/收集清單只會包含一個項目。
使用散佈/收集程式可以比呼叫 AllocateAdapterChannel 更加提升效能(如先前在 使用 Packet-Based 系統 DMA 和 使用 Packet-Based Bus-Master DMA中所述)。 與呼叫 AllocateAdapterChannel不同,同一時間可以對一個裝置物件排入多個 GetScatterGatherList 的呼叫。 驅動程式可以在 AdapterListControl 例程完成執行之前,針對相同驅動程式物件的另一個 DMA 作業,再次呼叫 GetScatterGatherList。
從驅動程式提供的 AdapterListControl 例程傳回時,GetScatterGatherList 保留地圖緩存器,但釋放 DMA 配接器結構。
當驅動程式滿足目前的 IRP 傳輸要求,或由於裝置或總線 I/O 錯誤而失敗 IRP 時,它必須呼叫 PutScatterGatherList,才能存取緩衝區中傳輸的數據。 PutScatterGatherList 清空配接器緩衝區,並釋放映射暫存器和散佈/收集清單。