取得配接器物件
在裝置啟動時,使用系統或匯流排主機 DMA 的驅動程式會呼叫 IoGetDmaAdapter 來取得配接器物件的指標,並判斷每個傳輸作業可用的地圖暫存器數目上限。 當驅動程式呼叫 IoGetDmaAdapter時,I/O 管理員接著會呼叫 HAL 以取得必要的平臺特定資訊。
驅動程式必須在系統定義的 DEVICE_DESCRIPTION 結構中提供特定資訊,以呼叫 IoGetDmaAdapter。 驅動程式必須使用 RtlZeroMemory ,先以零初始化 DEVICE_DESCRIPTION 結構,然後再設定其中的值。
必要的資料包含驅動程式裝置功能的相關資訊,例如裝置是否為匯流排主機、如果裝置具有散佈/收集功能,以及裝置一次可以傳輸的資料位元組數, (MaximumLength) 。
必要的裝置描述資料也包含平臺特定資訊,例如平臺特定和系統指派的匯流排號碼,是匯流排主要裝置的驅動程式所控制。 驅動程式可以藉由呼叫 IoGetDeviceProperty來取得這項資訊。
DEVICE_DESCRIPTION結構包含一些可能與某些 DMA 裝置或驅動程式無關的欄位。 例如,WDM 驅動程式中不會使用 BusNumber 欄位。 每個驅動程式都應該提供相關結構成員的值,並將所有其他成員的值設定為零。
除非裝置能夠等候系統 DMA 控制器在要求必須分解成兩個以上的 DMA 作業時,否則從屬裝置的驅動程式不應該在ScatterGather欄位中傳遞TRUE。
IoGetDmaAdapter 會同時傳回配接器物件的指標,以及平臺特定或裝置特定值,指出每個 DMA 傳輸作業的配接器物件可以使用多少地圖暫存器。
傳回的配接器物件包含三個可供驅動程式存取的欄位:
版本號碼 (版本)
大小 (大小)
DMA_OPERATIONS結構的指標 (DmaOperations)
DMA_OPERATIONS結構包含驅動程式必須用來在其裝置上執行 DMA 作業的函式指標資料表。 函式只能透過此資料結構中的指標來存取;驅動程式無法直接依名稱呼叫它們。 (請注意,這些常式會取代舊版Windows NT中支援的HalXxx常式。為了確保舊版驅動程式的相容性,Wdm.h 和 Ntddk.h 標頭檔會提供具有過時名稱的宏,但新的驅動程式應該一律透過資料結構呼叫函式。)
地圖暫存器的數目可能會因裝置到裝置和平臺而異。 一般而言,HAL 會根據下列準則指派一些地圖暫存器:
可能的話,HAL 會傳回一個值,該值超過傳輸 MaximumLength 位元組所需的對應暫存器數目,如驅動程式對 IoGetDmaAdapter的呼叫中所指定。
否則,HAL 會傳回比特定平臺盡可能大的較小值。
換句話說,HAL 通常會為每個驅動程式提供足夠的地圖暫存器,以最大化其裝置的 DMA 輸送量,但 HAL 可以在某些 Windows 平臺上傳回較少的值。 不保證驅動程式會取得其要求的地圖暫存器數目,因此驅動程式應該一律檢查傳回的值。
任何 DMA 設備磁碟機都必須為IoGetDmaAdapter所傳回的配接器物件指標和NumberOfMapRegisters值提供儲存體。 此指標是系統提供之支援常式的必要參數,用於 DMA。 由於必須在 IRQL = DISPATCH_LEVEL呼叫其中許多支援常式,因此驅動程式配置的儲存體必須駐留。 大部分的 DMA 驅動程式會在 裝置擴充功能中提供必要的儲存體。 不過,如果驅動程式也使用 控制器物件 或驅動程式所配置的非分頁集區,則儲存體可以在控制器擴充功能中。 如需詳細資訊,請參閱 配置System-Space記憶體 和管理 硬體優先順序 。
當驅動程式完成所有 DMA 作業時,它會呼叫 PutDmaAdapter 以釋放配接器物件。
下列各節 使用系統 DMA 和使用 Bus-Master DMA) 說明 DMA 裝置的整合型驅動程式如何使用支援常式來滿足傳輸要求。 這些區段假設驅動程式具有下列專案:
標準 StartIo 常式,而不是設定和管理 IRP 的內部佇列
用來分割傳輸要求的內部常式,其中地圖暫存器數目不足
沒有裝置特定的 DMA 條件約束
換句話說,這些章節描述驅動程式 DMA 作業最簡單的可能技術,但個別驅動程式不一定使用相同的技術。 對於 DMA 裝置的任何驅動程式,驅動程式常式應該分割大型 DMA 傳輸要求,取決於驅動程式模型 (類別/埠或整合型) 、裝置的功能,以及驅動程式必須處理的任何裝置特定 DMA 條件約束。