ACPI scan的时候会调用到acpi_bus_check_add->acpi_add_single_object
static int acpi_add_single_object(struct acpi_device **child,
acpi_handle handle, int type,
unsigned long long sta)
{
int result;
struct acpi_device *device;
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
device = kzalloc(sizeof(struct acpi_device), GFP_KERNEL);
if (!device) {
printk(KERN_ERR PREFIX "Memory allocation error\n");
return -ENOMEM;
}
//重点函数
acpi_init_device_object(device, handle, type, sta);
acpi_bus_get_power_flags(device);
acpi_bus_get_wakeup_device_flags(device);
//重点函数
result = acpi_device_add(device, acpi_device_release);
if (result) {
acpi_device_release(&device->dev);
return result;
}
}
我们先看第一个函数acpi_init_device_object->acpi_set_pnp_ids
static void acpi_set_pnp_ids(acpi_handle handle, struct acpi_device_pnp *pnp,
int device_type)
{
acpi_status status;
struct acpi_device_info *info;
struct acpi_pnp_device_id_list *cid_list;
int i;
switch (device_type) {
case ACPI_BUS_TYPE_DEVICE:
if (handle == ACPI_ROOT_OBJECT) {
acpi_add_id(pnp, ACPI_SYSTEM_HID);
break;
}
//调用acpi_get_object_info得到设备的HID/CID等信息
status = acpi_get_object_info(handle, &info);
if (ACPI_FAILURE(status)) {
pr_err(PREFIX "%s: Error reading device info\n",
__func__);
return;
}
//如果acpi_get_object_info 中会置为ACPI_VALID_HID,则通过acpi_add_id将设备的hardware_id保持到device->pnp中
if (info->valid & ACPI_VALID_HID) {
acpi_add_id(pnp, info->hardware_id.string);
pnp->type.platform_id = 1;
}
}
acpi_status
acpi_get_object_info(acpi_handle handle,
struct acpi_device_info **return_buffer)
{
struct acpi_namespace_node *node;
struct acpi_device_info *info;
struct acpi_pnp_device_id_list *cid_list = NULL;
struct acpi_pnp_device_id *hid = NULL;
struct acpi_pnp_device_id *uid = NULL;
struct acpi_pnp_device_id *cls = NULL;
char *next_id_string;
acpi_object_type type;
acpi_name name;
u8 param_count = 0;
u16 valid = 0;
u32 info_size;
u32 i;
acpi_status status;
/* Parameter validation */
if ((type == ACPI_TYPE_DEVICE) || (type == ACPI_TYPE_PROCESSOR)) {
//得到HID/CID 等信息
status = acpi_ut_execute_HID(node, &hid);
if (ACPI_SUCCESS(status)) {
info_size += hid->length;
valid |= ACPI_VALID_HID;
}
/* Execute the Device._UID method */
status = acpi_ut_execute_UID(node, &uid);
if (ACPI_SUCCESS(status)) {
info_size += uid->length;
valid |= ACPI_VALID_UID;
}
/*
* Now that we have the variable-length data, we can allocate the
* return buffer
*/
info = ACPI_ALLOCATE_ZEROED(info_size);
if (!info) {
status = AE_NO_MEMORY;
goto cleanup;
}
if (hid) {
如果HID 不为null,则通过acpi_ns_copy_device_id将bios中定义的HID 赋值给hardware_id,也就是说kernel中的hardware_id就是bios中的HID
next_id_string = acpi_ns_copy_device_id(&info->hardware_id,
hid, next_id_string);
if (acpi_ut_is_pci_root_bridge(hid->string)) {
info->flags |= ACPI_PCI_ROOT_BRIDGE;
}
}
if (uid) {
next_id_string = acpi_ns_copy_device_id(&info->unique_id,
uid, next_id_string);
}
}
再看
static void acpi_add_id(struct acpi_device_pnp *pnp, const char *dev_id)
{
struct acpi_hardware_id *id;
id = kmalloc(sizeof(*id), GFP_KERNEL);
if (!id)
return;
id->id = kstrdup_const(dev_id, GFP_KERNEL);
if (!id->id) {
kfree(id);
return;
}
将hid也就是hardware_id 保存到device的pnp->ids
list_add_tail(&id->list, &pnp->ids);
pnp->type.hardware_id = 1;
}
回到acpi_add_single_object 中继续调用acpi_device_add
首先通过
list_for_each_entry(acpi_device_bus_id, &acpi_bus_id_list, node) {
if (!strcmp(acpi_device_bus_id->bus_id,
acpi_device_hid(device))) {
acpi_device_bus_id->instance_no++;
found = 1;
kfree(new_bus_id);
break;
}
}
找到是否有HID匹配,也就是说这里的acpi_device_bus_id->bus_id 其实就是等于HID。通过acpi_device_hid 就会得到当前设备的HID
const char *acpi_device_hid(struct acpi_device *device)
{
struct acpi_hardware_id *hid;
if (list_empty(&device->pnp.ids))
return dummy_hid;
hid = list_first_entry(&device->pnp.ids, struct acpi_hardware_id, list);
return hid->id;
}
原来就是查device->pnp.ids,也就是想得到这个device的acpi_hardware_id。
回到acpi_device_add 中通过dev_set_name 来设置在/sys/devices/XXX下面的name
dev_set_name(&device->dev, "%s:%02x", acpi_device_bus_id->bus_id, acpi_device_bus_id->instance_no);
通过前面的分析应该很容易得出这里的acpi_device_bus_id->bus_id 就是bios中定义的HID
/sys/devices/ 下的设备name就是bios中定义的HID
最新推荐文章于 2025-07-02 22:25:39 发布