ACPI 掃描處理程式¶
- 版權所有:
© 2012, Intel Corporation
- 作者:
Rafael J. Wysocki <rafael.j.wysocki@intel.com>
在系統初始化和基於 ACPI 的裝置熱新增期間,會掃描 ACPI 名稱空間以搜尋通常代表各種硬體的裝置物件。 這會導致為 ACPI 名稱空間中的每個裝置物件建立一個 struct acpi_device 物件並將其註冊到驅動程式核心,並且這些 struct acpi_device 物件的層次結構反映了名稱空間佈局(即,名稱空間中的父裝置物件由父 struct acpi_device 物件表示,其子物件也類似)。 這些 struct acpi_device 物件在下面稱為“裝置節點”,但它們不應與裝置樹解析程式碼使用的 struct device_node 物件混淆(儘管它們的作用與這些物件的作用類似)。
在基於 ACPI 的裝置熱移除期間,表示要移除的硬體的裝置節點將被取消註冊和刪除。
drivers/acpi/scan.c 中的核心 ACPI 名稱空間掃描程式碼執行裝置節點的基本初始化,例如從它們表示的裝置物件檢索通用配置資訊並使用適當的資料填充它們,但其中一些需要在註冊後進行額外處理。 例如,如果給定的裝置節點表示 PCI 主橋,則其註冊應導致列舉該橋下的 PCI 匯流排,並將該總線上的 PCI 設備註冊到驅動程式核心。 類似地,如果裝置節點表示 PCI 中斷連結,則必須配置該連結,以便核心可以使用它。
這些額外的配置任務通常取決於給定裝置節點所代表的硬體元件的型別,該型別可以根據裝置節點的硬體 ID (HID) 確定。 它們由稱為 ACPI 掃描處理程式的物件執行,這些物件由以下結構表示
struct acpi_scan_handler {
const struct acpi_device_id *ids;
struct list_head list_node;
int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id);
void (*detach)(struct acpi_device *dev);
};
其中 ids 是給定處理程式應處理的裝置節點的 ID 列表,list_node 是連線到 ACPI 核心維護的 ACPI 掃描處理程式全域性列表的鉤子,並且 .attach() 和 .detach() 回撥分別在新裝置節點註冊之後和處理程式先前附加到的裝置節點取消註冊之前執行。
名稱空間掃描函式 acpi_bus_scan() 首先將給定名稱空間範圍內的所有裝置節點註冊到驅動程式核心。 然後,它嘗試使用可用掃描處理程式的 ids 陣列將掃描處理程式與每個裝置節點進行匹配。 如果找到匹配的掃描處理程式,則為其給定裝置節點執行其 .attach() 回撥。 如果該回調返回 1,則表示處理程式已宣告該裝置節點,現在負責執行與其相關的任何其他配置任務。 在這種情況下,它還將負責準備裝置節點以進行取消註冊。 然後,裝置節點的處理程式欄位將填充已宣告它的掃描處理程式的地址。
如果 .attach() 回撥返回 0,則表示給定掃描處理程式對該裝置節點不感興趣,並且可以與列表中的下一個掃描處理程式匹配。 如果它返回(負)錯誤程式碼,則表示由於嚴重錯誤,應終止名稱空間掃描。 返回的錯誤程式碼應反映錯誤的型別。
名稱空間修剪函式 acpi_bus_trim() 首先執行給定名稱空間範圍內的所有裝置節點的掃描處理程式中的 .detach() 回撥(如果它們有掃描處理程式)。 接下來,它會取消註冊該範圍內的所有裝置節點。
可以使用 acpi_scan_add_handler() 函式將 ACPI 掃描處理程式新增到 ACPI 核心維護的列表中,該函式將指向新掃描處理程式的指標作為引數。 掃描處理程式新增到列表中的順序是在名稱空間掃描期間它們與裝置節點匹配的順序。
所有掃描處理程式都必須在 acpi_bus_scan() 首次執行之前新增到列表中,並且不能從列表中刪除。