一般情况下在acpi_set_pnp_ids函数中通过bios传递的HID/CLD/UID/CLS/method/path等flags来识别不同的device。
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;
}
status = acpi_get_object_info(handle, &info);
if (ACPI_FAILURE(status)) {
pr_err(PREFIX "%s: Error reading device info\n",
__func__);
return;
}
//通过HID 识别device
if (info->valid & ACPI_VALID_HID) {
acpi_add_id(pnp, info->hardware_id.string);
pnp->type.platform_id = 1;
}
//通过CID 识别device
if (info->valid & ACPI_VALID_CID) {
cid_list = &info->compatible_id_list;
for (i = 0; i < cid_list->count; i++)
acpi_add_id(pnp, cid_list->ids[i].string);
}
//通过UID 识别device
if (info->valid & ACPI_VALID_UID)
pnp->unique_id = kstrdup(info->unique_id.string,
GFP_KERNEL);
if (info->valid & ACPI_VALID_CLS)
acpi_add_id(pnp, info->class_code.string);
kfree(info);
/*
* Some devices don't reliably have _HIDs & _CIDs, so add
* synthetic HIDs to make sure drivers can find them.
*/
//通过method来识别device
if (acpi_is_video_device(handle))
acpi_add_id(pnp, ACPI_VIDEO_HID);
else if (acpi_bay_match(handle))
acpi_add_id(pnp, ACPI_BAY_HID);
else if (acpi_dock_match(handle))
acpi_add_id(pnp, ACPI_DOCK_HID);
else if (acpi_ibm_smbus_match(handle))
acpi_add_id(pnp, ACPI_SMBUS_IBM_HID);
//通过path识别device
else if (list_empty(&pnp->ids) &&
acpi_object_is_system_bus(handle)) {
/* \_SB, \_TZ, LNXSYBUS */
acpi_add_id(pnp, ACPI_BUS_HID);
strcpy(pnp->device_name, ACPI_BUS_DEVICE_NAME);
strcpy(pnp->device_class, ACPI_BUS_CLASS);
}
break;
}
}
通过HID/CLD/UID/CLS识别device 比较好理解,先看看通过method来识别device
long acpi_is_video_device(acpi_handle handle)
{
long video_caps = 0;
//可见主要是通过判断这个handle是否有相关的method。
/* Is this device able to support video switching ? */
if (acpi_has_method(handle, "_DOD") || acpi_has_method(handle, "_DOS"))
video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING;
return video_caps;
}
再看看通过path识别device的
static bool acpi_object_is_system_bus(acpi_handle handle)
{
acpi_handle tmp;
if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_SB", &tmp)) &&
tmp == handle)
return true;
if (ACPI_SUCCESS(acpi_get_handle(NULL, "\\_TZ", &tmp)) &&
tmp == handle)
return true;
return false;
}
其中acpi_get_handle的原型如下:可见本例是通过\\_SB 这个路径下的handle是否等于要识别device的handle来确认是否是同一个device的
acpi_status acpi_get_handle(acpi_handle parent, acpi_string pathname,acpi_handle *ret_handle)
acpi_hardware_id可以通过HID/CLD/UID/CLS/method/path获得
最新推荐文章于 2024-03-22 13:38:01 发布