使用散佈圖/收集 DMA
執行系統或匯流排主機、封包型 DMA 的驅動程式可以使用專為散佈/收集 DMA 而設計的支援常式。 驅動程式可以使用GetScatterGatherList和PutScatterGatherList,而不是呼叫使用 Packet-Based system DMA和Packet-Based Bus-Master DMA中所述的常式序列。
裝置不需要有內建散佈/收集支援,其驅動程式才能使用這些常式。
使用封包型 DMA 的驅動程式會針對散佈/收集作業呼叫下列一般支援常式:
MmGetMdlVirtualAddress以取得 MDL 中的索引,在呼叫 GetScatterGatherList時需要做為參數
當驅動程式準備好為其裝置進行 DMA 的程式設計,且需要系統 DMA 控制器或匯流排主機介面卡時,GetScatterGatherList
GetScatterGatherList 會配置系統 DMA 控制器或匯流排主機介面卡、決定需要多少地圖暫存器並配置它們、填入散佈/收集清單,並在 DMA 控制器或配接器及地圖暫存器可用時呼叫驅動程式的 AdapterListControl 常式。
一旦傳輸所有要求的資料,或驅動程式因為裝置 I/O 錯誤而失敗,PutScatterGatherList
PutScatterGatherList 會排清配接器緩衝區、釋放地圖暫存器,並釋放散佈/收集清單。 驅動程式必須先呼叫 PutScatterGatherList ,才能存取緩衝區中的資料。
IoGetDmaAdapter所傳回的配接器物件指標是每個常式的必要參數,但 MmGetMdlVirtualAddress除外,這需要 Irp-MdlAddress > 上的MDL指標。
GetScatterGatherList常式包含AllocateAdapterChannel和MapTransfer的呼叫,因此驅動程式不需要進行這些呼叫。 常式會採用下列作為參數:
IoGetDmaAdapter所傳回之DMA_ADAPTER結構的指標
DMA 作業之目標裝置物件的指標
描述Irp-MdlAddress> 緩衝區之 MDL 的指標
Mdl 所描述之緩衝區中目前虛擬位址的指標
要對應的位元組數目
執行傳輸之 AdapterListControl 常式的指標
要傳遞至 AdapterListControl 常式之驅動程式定義內容區域的指標
布林值:傳送至裝置的TRUE;否則為 FALSE
判斷所需的地圖暫存器數目、配置配接器通道和地圖暫存器、填入散佈/收集清單並準備傳輸之後, GetScatterGatherList 會呼叫驅動程式提供的 AdapterListControl 常式。 AdapterListControl常式是在 IRQL = DISPATCH_LEVEL的任意執行緒內容中執行。
驅動程式在呼叫GetScatterGatherList時提供的 AdapterListControl常式與下列重要方面傳遞給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 System DMA 和 Using Packet-Based Bus-Master DMA) 中所述。 不同于 AllocateAdapterChannel的呼叫,一次可以針對裝置物件排入一個以上的 GetScatterGatherList 呼叫。 驅動程式可以在其AdapterListControl常式完成執行之前,針對相同驅動程式物件上的另一個 DMA 作業再次呼叫GetScatterGatherList。
從驅動程式提供的 AdapterListControl 常式傳回時, GetScatterGatherList 會保留地圖暫存器,但釋放 DMA 配接器結構。
當驅動程式滿足目前的 IRP 傳輸要求,或因為裝置或匯流排 I/O 錯誤而失敗 IRP 時,它必須先呼叫 PutScatterGatherList ,才能存取緩衝區中傳輸的資料。 PutScatterGatherList 會排清配接器緩衝區,並釋放地圖暫存器和散佈/收集清單。