hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/platform/x86/wmi.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * ACPI-WMI mapping driver
34 *
....@@ -11,24 +12,6 @@
1112 * WMI bus infrastructure by Andrew Lutomirski and Darren Hart:
1213 * Copyright (C) 2015 Andrew Lutomirski
1314 * Copyright (C) 2017 VMware, Inc. All Rights Reserved.
14
- *
15
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16
- *
17
- * This program is free software; you can redistribute it and/or modify
18
- * it under the terms of the GNU General Public License as published by
19
- * the Free Software Foundation; either version 2 of the License, or (at
20
- * your option) any later version.
21
- *
22
- * This program is distributed in the hope that it will be useful, but
23
- * WITHOUT ANY WARRANTY; without even the implied warranty of
24
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25
- * General Public License for more details.
26
- *
27
- * You should have received a copy of the GNU General Public License along
28
- * with this program; if not, write to the Free Software Foundation, Inc.,
29
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
30
- *
31
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3215 */
3316
3417 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -46,6 +29,7 @@
4629 #include <linux/uaccess.h>
4730 #include <linux/uuid.h>
4831 #include <linux/wmi.h>
32
+#include <linux/fs.h>
4933 #include <uapi/linux/wmi.h>
5034
5135 ACPI_MODULE_NAME("wmi");
....@@ -56,7 +40,7 @@
5640 static LIST_HEAD(wmi_block_list);
5741
5842 struct guid_block {
59
- char guid[16];
43
+ guid_t guid;
6044 union {
6145 char object_id[2];
6246 struct {
....@@ -127,23 +111,52 @@
127111
128112 static bool find_guid(const char *guid_string, struct wmi_block **out)
129113 {
130
- uuid_le guid_input;
114
+ guid_t guid_input;
131115 struct wmi_block *wblock;
132116 struct guid_block *block;
133117
134
- if (uuid_le_to_bin(guid_string, &guid_input))
118
+ if (guid_parse(guid_string, &guid_input))
135119 return false;
136120
137121 list_for_each_entry(wblock, &wmi_block_list, list) {
138122 block = &wblock->gblock;
139123
140
- if (memcmp(block->guid, &guid_input, 16) == 0) {
124
+ if (guid_equal(&block->guid, &guid_input)) {
141125 if (out)
142126 *out = wblock;
143127 return true;
144128 }
145129 }
146130 return false;
131
+}
132
+
133
+static bool guid_parse_and_compare(const char *string, const guid_t *guid)
134
+{
135
+ guid_t guid_input;
136
+
137
+ if (guid_parse(string, &guid_input))
138
+ return false;
139
+
140
+ return guid_equal(&guid_input, guid);
141
+}
142
+
143
+static const void *find_guid_context(struct wmi_block *wblock,
144
+ struct wmi_driver *wdriver)
145
+{
146
+ const struct wmi_device_id *id;
147
+
148
+ if (wblock == NULL || wdriver == NULL)
149
+ return NULL;
150
+ if (wdriver->id_table == NULL)
151
+ return NULL;
152
+
153
+ id = wdriver->id_table;
154
+ while (*id->guid_string) {
155
+ if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
156
+ return id->context;
157
+ id++;
158
+ }
159
+ return NULL;
147160 }
148161
149162 static int get_subobj_info(acpi_handle handle, const char *pathname,
....@@ -196,7 +209,7 @@
196209 /**
197210 * set_required_buffer_size - Sets the buffer size needed for performing IOCTL
198211 * @wdev: A wmi bus device from a driver
199
- * @instance: Instance index
212
+ * @length: Required buffer size
200213 *
201214 * Allocates memory needed for buffer, stores the buffer size in that memory
202215 */
....@@ -216,8 +229,8 @@
216229 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
217230 * @instance: Instance index
218231 * @method_id: Method ID to call
219
- * &in: Buffer containing input for the method call
220
- * &out: Empty buffer to return the method results
232
+ * @in: Buffer containing input for the method call
233
+ * @out: Empty buffer to return the method results
221234 *
222235 * Call an ACPI-WMI method
223236 */
....@@ -238,8 +251,8 @@
238251 * @wdev: A wmi bus device from a driver
239252 * @instance: Instance index
240253 * @method_id: Method ID to call
241
- * &in: Buffer containing input for the method call
242
- * &out: Empty buffer to return the method results
254
+ * @in: Buffer containing input for the method call
255
+ * @out: Empty buffer to return the method results
243256 *
244257 * Call an ACPI-WMI method
245258 */
....@@ -335,9 +348,7 @@
335348 * expensive, but have no corresponding WCxx method. So we
336349 * should not fail if this happens.
337350 */
338
- if (acpi_has_method(handle, wc_method))
339
- wc_status = acpi_execute_simple_method(handle,
340
- wc_method, 1);
351
+ wc_status = acpi_execute_simple_method(handle, wc_method, 1);
341352 }
342353
343354 strcpy(method, "WQ");
....@@ -367,7 +378,7 @@
367378 * wmi_query_block - Return contents of a WMI block (deprecated)
368379 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
369380 * @instance: Instance index
370
- * &out: Empty buffer to return the contents of the data block to
381
+ * @out: Empty buffer to return the contents of the data block to
371382 *
372383 * Return the contents of an ACPI-WMI data block to a buffer
373384 */
....@@ -402,7 +413,7 @@
402413 * wmi_set_block - Write to a WMI block
403414 * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
404415 * @instance: Instance index
405
- * &in: Buffer containing new values for the data block
416
+ * @in: Buffer containing new values for the data block
406417 *
407418 * Write the contents of the input buffer to an ACPI-WMI data block
408419 */
....@@ -453,7 +464,7 @@
453464
454465 static void wmi_dump_wdg(const struct guid_block *g)
455466 {
456
- pr_info("%pUL:\n", g->guid);
467
+ pr_info("%pUL:\n", &g->guid);
457468 if (g->flags & ACPI_WMI_EVENT)
458469 pr_info("\tnotify_id: 0x%02X\n", g->notify_id);
459470 else
....@@ -513,6 +524,7 @@
513524
514525 /**
515526 * wmi_install_notify_handler - Register handler for WMI events
527
+ * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
516528 * @handler: Function to handle notifications
517529 * @data: Data to be returned to handler when event is fired
518530 *
....@@ -523,18 +535,18 @@
523535 {
524536 struct wmi_block *block;
525537 acpi_status status = AE_NOT_EXIST;
526
- uuid_le guid_input;
538
+ guid_t guid_input;
527539
528540 if (!guid || !handler)
529541 return AE_BAD_PARAMETER;
530542
531
- if (uuid_le_to_bin(guid, &guid_input))
543
+ if (guid_parse(guid, &guid_input))
532544 return AE_BAD_PARAMETER;
533545
534546 list_for_each_entry(block, &wmi_block_list, list) {
535547 acpi_status wmi_status;
536548
537
- if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
549
+ if (guid_equal(&block->gblock.guid, &guid_input)) {
538550 if (block->handler &&
539551 block->handler != wmi_notify_debug)
540552 return AE_ALREADY_ACQUIRED;
....@@ -555,6 +567,7 @@
555567
556568 /**
557569 * wmi_uninstall_notify_handler - Unregister handler for WMI events
570
+ * @guid: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
558571 *
559572 * Unregister handler for events sent to the ACPI-WMI mapper device.
560573 */
....@@ -562,18 +575,18 @@
562575 {
563576 struct wmi_block *block;
564577 acpi_status status = AE_NOT_EXIST;
565
- uuid_le guid_input;
578
+ guid_t guid_input;
566579
567580 if (!guid)
568581 return AE_BAD_PARAMETER;
569582
570
- if (uuid_le_to_bin(guid, &guid_input))
583
+ if (guid_parse(guid, &guid_input))
571584 return AE_BAD_PARAMETER;
572585
573586 list_for_each_entry(block, &wmi_block_list, list) {
574587 acpi_status wmi_status;
575588
576
- if (memcmp(block->gblock.guid, &guid_input, 16) == 0) {
589
+ if (guid_equal(&block->gblock.guid, &guid_input)) {
577590 if (!block->handler ||
578591 block->handler == wmi_notify_debug)
579592 return AE_NULL_ENTRY;
....@@ -609,7 +622,6 @@
609622 {
610623 struct acpi_object_list input;
611624 union acpi_object params[1];
612
- struct guid_block *gblock;
613625 struct wmi_block *wblock;
614626
615627 input.count = 1;
....@@ -618,7 +630,7 @@
618630 params[0].integer.value = event;
619631
620632 list_for_each_entry(wblock, &wmi_block_list, list) {
621
- gblock = &wblock->gblock;
633
+ struct guid_block *gblock = &wblock->gblock;
622634
623635 if ((gblock->flags & ACPI_WMI_EVENT) &&
624636 (gblock->notify_id == event))
....@@ -642,6 +654,25 @@
642654 }
643655 EXPORT_SYMBOL_GPL(wmi_has_guid);
644656
657
+/**
658
+ * wmi_get_acpi_device_uid() - Get _UID name of ACPI device that defines GUID
659
+ * @guid_string: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba
660
+ *
661
+ * Find the _UID of ACPI device associated with this WMI GUID.
662
+ *
663
+ * Return: The ACPI _UID field value or NULL if the WMI GUID was not found
664
+ */
665
+char *wmi_get_acpi_device_uid(const char *guid_string)
666
+{
667
+ struct wmi_block *wblock = NULL;
668
+
669
+ if (!find_guid(guid_string, &wblock))
670
+ return NULL;
671
+
672
+ return acpi_device_uid(wblock->acpi_device);
673
+}
674
+EXPORT_SYMBOL_GPL(wmi_get_acpi_device_uid);
675
+
645676 static struct wmi_block *dev_to_wblock(struct device *dev)
646677 {
647678 return container_of(dev, struct wmi_block, dev.dev);
....@@ -660,7 +691,7 @@
660691 {
661692 struct wmi_block *wblock = dev_to_wblock(dev);
662693
663
- return sprintf(buf, "wmi:%pUL\n", wblock->gblock.guid);
694
+ return sprintf(buf, "wmi:%pUL\n", &wblock->gblock.guid);
664695 }
665696 static DEVICE_ATTR_RO(modalias);
666697
....@@ -669,7 +700,7 @@
669700 {
670701 struct wmi_block *wblock = dev_to_wblock(dev);
671702
672
- return sprintf(buf, "%pUL\n", wblock->gblock.guid);
703
+ return sprintf(buf, "%pUL\n", &wblock->gblock.guid);
673704 }
674705 static DEVICE_ATTR_RO(guid);
675706
....@@ -752,10 +783,10 @@
752783 {
753784 struct wmi_block *wblock = dev_to_wblock(dev);
754785
755
- if (add_uevent_var(env, "MODALIAS=wmi:%pUL", wblock->gblock.guid))
786
+ if (add_uevent_var(env, "MODALIAS=wmi:%pUL", &wblock->gblock.guid))
756787 return -ENOMEM;
757788
758
- if (add_uevent_var(env, "WMI_GUID=%pUL", wblock->gblock.guid))
789
+ if (add_uevent_var(env, "WMI_GUID=%pUL", &wblock->gblock.guid))
759790 return -ENOMEM;
760791
761792 return 0;
....@@ -778,12 +809,8 @@
778809 if (id == NULL)
779810 return 0;
780811
781
- while (id->guid_string) {
782
- uuid_le driver_guid;
783
-
784
- if (WARN_ON(uuid_le_to_bin(id->guid_string, &driver_guid)))
785
- continue;
786
- if (!memcmp(&driver_guid, wblock->gblock.guid, 16))
812
+ while (*id->guid_string) {
813
+ if (guid_parse_and_compare(id->guid_string, &wblock->gblock.guid))
787814 return 1;
788815
789816 id++;
....@@ -896,7 +923,7 @@
896923 .read = wmi_char_read,
897924 .open = wmi_char_open,
898925 .unlocked_ioctl = wmi_ioctl,
899
- .compat_ioctl = wmi_ioctl,
926
+ .compat_ioctl = compat_ptr_ioctl,
900927 };
901928
902929 static int wmi_dev_probe(struct device *dev)
....@@ -911,7 +938,8 @@
911938 dev_warn(dev, "failed to enable device -- probing anyway\n");
912939
913940 if (wdriver->probe) {
914
- ret = wdriver->probe(dev_to_wdev(dev));
941
+ ret = wdriver->probe(dev_to_wdev(dev),
942
+ find_guid_context(wblock, wdriver));
915943 if (ret != 0)
916944 goto probe_failure;
917945 }
....@@ -997,26 +1025,25 @@
9971025 .remove = wmi_dev_remove,
9981026 };
9991027
1000
-static struct device_type wmi_type_event = {
1028
+static const struct device_type wmi_type_event = {
10011029 .name = "event",
10021030 .groups = wmi_event_groups,
10031031 .release = wmi_dev_release,
10041032 };
10051033
1006
-static struct device_type wmi_type_method = {
1034
+static const struct device_type wmi_type_method = {
10071035 .name = "method",
10081036 .groups = wmi_method_groups,
10091037 .release = wmi_dev_release,
10101038 };
10111039
1012
-static struct device_type wmi_type_data = {
1040
+static const struct device_type wmi_type_data = {
10131041 .name = "data",
10141042 .groups = wmi_data_groups,
10151043 .release = wmi_dev_release,
10161044 };
10171045
10181046 static int wmi_create_device(struct device *wmi_bus_dev,
1019
- const struct guid_block *gblock,
10201047 struct wmi_block *wblock,
10211048 struct acpi_device *device)
10221049 {
....@@ -1024,12 +1051,12 @@
10241051 char method[5];
10251052 int result;
10261053
1027
- if (gblock->flags & ACPI_WMI_EVENT) {
1054
+ if (wblock->gblock.flags & ACPI_WMI_EVENT) {
10281055 wblock->dev.dev.type = &wmi_type_event;
10291056 goto out_init;
10301057 }
10311058
1032
- if (gblock->flags & ACPI_WMI_METHOD) {
1059
+ if (wblock->gblock.flags & ACPI_WMI_METHOD) {
10331060 wblock->dev.dev.type = &wmi_type_method;
10341061 mutex_init(&wblock->char_mutex);
10351062 goto out_init;
....@@ -1079,7 +1106,7 @@
10791106 wblock->dev.dev.bus = &wmi_bus_type;
10801107 wblock->dev.dev.parent = wmi_bus_dev;
10811108
1082
- dev_set_name(&wblock->dev.dev, "%pUL", gblock->guid);
1109
+ dev_set_name(&wblock->dev.dev, "%pUL", &wblock->gblock.guid);
10831110
10841111 device_initialize(&wblock->dev.dev);
10851112
....@@ -1099,13 +1126,12 @@
10991126 }
11001127 }
11011128
1102
-static bool guid_already_parsed(struct acpi_device *device,
1103
- const u8 *guid)
1129
+static bool guid_already_parsed(struct acpi_device *device, const guid_t *guid)
11041130 {
11051131 struct wmi_block *wblock;
11061132
11071133 list_for_each_entry(wblock, &wmi_block_list, list) {
1108
- if (memcmp(wblock->gblock.guid, guid, 16) == 0) {
1134
+ if (guid_equal(&wblock->gblock.guid, guid)) {
11091135 /*
11101136 * Because we historically didn't track the relationship
11111137 * between GUIDs and ACPI nodes, we don't know whether
....@@ -1160,7 +1186,7 @@
11601186 * case yet, so for now, we'll just ignore the duplicate
11611187 * for device creation.
11621188 */
1163
- if (guid_already_parsed(device, gblock[i].guid))
1189
+ if (guid_already_parsed(device, &gblock[i].guid))
11641190 continue;
11651191
11661192 wblock = kzalloc(sizeof(struct wmi_block), GFP_KERNEL);
....@@ -1172,7 +1198,7 @@
11721198 wblock->acpi_device = device;
11731199 wblock->gblock = gblock[i];
11741200
1175
- retval = wmi_create_device(wmi_bus_dev, &gblock[i], wblock, device);
1201
+ retval = wmi_create_device(wmi_bus_dev, wblock, device);
11761202 if (retval) {
11771203 kfree(wblock);
11781204 continue;
....@@ -1197,7 +1223,7 @@
11971223 retval = device_add(&wblock->dev.dev);
11981224 if (retval) {
11991225 dev_err(wmi_bus_dev, "failed to register %pUL\n",
1200
- wblock->gblock.guid);
1226
+ &wblock->gblock.guid);
12011227 if (debug_event)
12021228 wmi_method_enable(wblock, 0);
12031229 list_del(&wblock->list);
....@@ -1257,12 +1283,11 @@
12571283 static void acpi_wmi_notify_handler(acpi_handle handle, u32 event,
12581284 void *context)
12591285 {
1260
- struct guid_block *block;
12611286 struct wmi_block *wblock;
12621287 bool found_it = false;
12631288
12641289 list_for_each_entry(wblock, &wmi_block_list, list) {
1265
- block = &wblock->gblock;
1290
+ struct guid_block *block = &wblock->gblock;
12661291
12671292 if (wblock->acpi_device->handle == handle &&
12681293 (block->flags & ACPI_WMI_EVENT) &&
....@@ -1310,10 +1335,8 @@
13101335 wblock->handler(event, wblock->handler_data);
13111336 }
13121337
1313
- if (debug_event) {
1314
- pr_info("DEBUG Event GUID: %pUL\n",
1315
- wblock->gblock.guid);
1316
- }
1338
+ if (debug_event)
1339
+ pr_info("DEBUG Event GUID: %pUL\n", &wblock->gblock.guid);
13171340
13181341 acpi_bus_generate_netlink_event(
13191342 wblock->acpi_device->pnp.device_class,