lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  4 Mar 2013 14:30:43 -0700
From:	Toshi Kani <toshi.kani@...com>
To:	rjw@...k.pl
Cc:	linux-acpi@...r.kernel.org, linux-kernel@...r.kernel.org,
	yinghai@...nel.org, jiang.liu@...wei.com,
	isimatu.yasuaki@...fujitsu.com, Toshi Kani <toshi.kani@...com>
Subject: [PATCH 3/3] ACPI: Update PNPID match handling for notify

When installing/removing a notify handler to/from an ACPI device
object, ACPI core tries to match its associated scan handler to
see if it supports hotplug.  However, the matching logic of the
notify handler is different from the matching logic of attaching
a scan handler to an ACPI device object.  This patch updates the
matching logic of the notify handlers to be consistent with the
attach handling.

Signed-off-by: Toshi Kani <toshi.kani@...com>
---
 drivers/acpi/scan.c |   85 +++++++++++++++++++++++++++++++--------------------
 1 file changed, 52 insertions(+), 33 deletions(-)

diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index e9a71ed..3f6ec0d 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -1703,24 +1703,47 @@ static bool acpi_scan_handler_matching(struct acpi_scan_handler *handler,
 	return false;
 }
 
+static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr,
+					const struct acpi_device_id **matchid)
+{
+	struct acpi_scan_handler *handler;
+
+	list_for_each_entry(handler, &acpi_scan_handlers_list, list_node)
+		if (acpi_scan_handler_matching(handler, idstr, matchid))
+			return handler;
+
+	return NULL;
+}
+
 static acpi_status acpi_scan_hotplug_modify(acpi_handle handle,
 					    u32 lvl_not_used, void *data,
 					    void **ret_not_used)
 {
-	struct acpi_scan_handler *handler = data;
-	struct acpi_device_info *info;
+	struct acpi_device_pnp pnp = {};
+	struct acpi_scan_handler *tgt_handler = data, *handler;
+	struct acpi_hardware_id *hwid;
+	unsigned long long sta_not_used;
+	int type;
 	bool match = false;
 
-	if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
+	if (acpi_bus_type_and_status(handle, &type, &sta_not_used))
+		return AE_OK;
+
+	INIT_LIST_HEAD(&pnp.ids);
+	acpi_set_pnp_ids(handle, &pnp, type);
+
+	if (!pnp.type.hardware_id)
 		return AE_OK;
 
-	if (info->valid & ACPI_VALID_HID) {
-		char *idstr = info->hardware_id.string;
-		match = acpi_scan_handler_matching(handler, idstr, NULL);
+	list_for_each_entry(hwid, &pnp.ids, list) {
+		handler = acpi_scan_match_handler(hwid->id, NULL);
+		if (handler && handler == tgt_handler) {
+			match = true;
+			break;
+		}
 	}
-	kfree(info);
 	if (!match)
-		return AE_OK;
+		goto out;
 
 	if (handler->hotplug.enabled)
 		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
@@ -1729,6 +1752,8 @@ static acpi_status acpi_scan_hotplug_modify(acpi_handle handle,
 		acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
 					   acpi_hotplug_notify_cb);
 
+out:
+	acpi_free_pnp_ids(&pnp);
 	return AE_OK;
 }
 
@@ -1749,40 +1774,34 @@ void acpi_scan_hotplug_enabled(struct acpi_hotplug_profile *hotplug, bool val)
 	mutex_unlock(&acpi_scan_lock);
 }
 
-static struct acpi_scan_handler *acpi_scan_match_handler(char *idstr,
-					const struct acpi_device_id **matchid)
-{
-	struct acpi_scan_handler *handler;
-
-	list_for_each_entry(handler, &acpi_scan_handlers_list, list_node)
-		if (acpi_scan_handler_matching(handler, idstr, matchid))
-			return handler;
-
-	return NULL;
-}
-
-static void acpi_scan_init_hotplug(acpi_handle handle)
+static void acpi_scan_init_hotplug(acpi_handle handle, int type)
 {
-	struct acpi_device_info *info;
+	struct acpi_device_pnp pnp = {};
+	struct acpi_hardware_id *hwid;
 	struct acpi_scan_handler *handler;
 
-	if (ACPI_FAILURE(acpi_get_object_info(handle, &info)))
-		return;
+	INIT_LIST_HEAD(&pnp.ids);
+	acpi_set_pnp_ids(handle, &pnp, type);
 
-	if (!(info->valid & ACPI_VALID_HID)) {
-		kfree(info);
+	if (!pnp.type.hardware_id)
 		return;
-	}
 
 	/*
 	 * This relies on the fact that acpi_install_notify_handler() will not
 	 * install the same notify handler routine twice for the same handle.
 	 */
-	handler = acpi_scan_match_handler(info->hardware_id.string, NULL);
-	kfree(info);
-	if (handler && handler->hotplug.enabled)
-		acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY,
-					    acpi_hotplug_notify_cb, NULL);
+	list_for_each_entry(hwid, &pnp.ids, list) {
+		handler = acpi_scan_match_handler(hwid->id, NULL);
+		if (handler) {
+			if (handler->hotplug.enabled)
+				acpi_install_notify_handler(handle,
+					ACPI_SYSTEM_NOTIFY,
+					acpi_hotplug_notify_cb, NULL);
+			break;
+		}
+	}
+
+	acpi_free_pnp_ids(&pnp);
 }
 
 static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
@@ -1807,7 +1826,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used,
 		return AE_OK;
 	}
 
-	acpi_scan_init_hotplug(handle);
+	acpi_scan_init_hotplug(handle, type);
 
 	if (!(sta & ACPI_STA_DEVICE_PRESENT) &&
 	    !(sta & ACPI_STA_DEVICE_FUNCTIONING)) {
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ