如 使用 Bus-Master DMA 中所述,總線主要 DMA 裝置的一些驅動程式會獨佔使用 common-buffer DMA,有些則使用 common-buffer DMA 搭配封包型 DMA。
在經濟上使用 common-buffer DMA。 設定一個通用緩衝區可能會占用一些(或全部,取決於所請求緩衝區的大小)與表示總線主控適配器的配接器物件相關聯的對應緩存器。
經濟地配置通用緩衝區,例如使用 PAGE_SIZE 區塊或單一配置,能使更多映對暫存器可用於封包型 DMA 作業。 它也會讓更多的系統記憶體可供其他用途使用,這會產生更佳的整體驅動程式和系統效能。
若要設定總線主要 DMA 的通用緩衝區,總線主要 DMA 裝置驅動程式必須使用 IoGetDmaAdapter 所傳回的配接器對象指標呼叫 AllocateCommonBuffer。 一般而言,驅動程式會從 其 DispatchPnP 例程進行此呼叫,以進行 IRP_MN_START_DEVICE 要求。 只有在驅動程式載入期間會重複使用緩衝區進行 DMA 作業時,才應配置共用緩衝區。 下圖說明對 AllocateCommonBuffer 的呼叫。
上圖中顯示為 LengthForBuffer 的緩衝區所需的大小會決定必須使用多少個對應緩存器來提供通用緩衝區的虛擬到邏輯的映射。 使用 BYTES_TO_PAGES 巨集來判斷所需的頁數上限 (BYTES_TO_PAGES (LengthForBuffer) )。 此值不能大於由IoGetDmaAdapter傳回的NumberOfMapRegisters。
此外,呼叫者必須提供下列資訊:
布爾值,指出是否應該啟用快取
注意 這個值會被忽略。 作業系統會決定是否在要配置的公共緩衝區中啟用快取記憶體。 該決策是以處理器架構和裝置總線為基礎。
在 x86 型、x64 型和 Itanium 型處理器的電腦上,會啟用快取的記憶體。
在具有 Arm 或 Arm 64 處理器的電腦上,作系統不會自動啟用所有裝置的快取記憶體。 系統依賴每個裝置的 ACPI_CCA 方法,判斷裝置是否快取一致。
從 AllocateCommonBuffer 返回時,指向由驅動程式定義的變數的指針,它將包含設備可存取的基礎邏輯地址(如上圖所示的 BufferLogicalAddress)。
如果呼叫成功, AllocateCommonBuffer 會傳回緩衝區的驅動程式可存取基底虛擬位址(上圖中的 BufferVirtualAddress),驅動程式必須將其儲存在其裝置擴充功能、控制器擴充功能或其他驅動程式可存取的常駐儲存區域(驅動程式所配置的非分頁集區)。
如果 AllocateCommonBuffer 無法為緩衝區配置記憶體,則會傳回 NULL。 如果傳回的基底虛擬位址為 NULL,則驅動程式必須以獨佔方式使用系統的封包型 DMA 支援,否則驅動程式必須失敗IRP_MN_START_DEVICE要求,並傳回 STATUS_INSUFFICIENT_RESOURCES 。
否則,驅動程式可以使用配置的通用緩衝區作為 DMA 傳輸的驅動程式和適配卡可存取儲存區域。
當 PnP 管理員傳送停止或移除裝置的 IRP 時,驅動程式必須呼叫 FreeCommonBuffer 以釋放它已配置的每個通用緩衝區。