platform/x86: think-lmi: Fix attribute name usage for non-compliant items
authorMark Pearson <mpearson-lenovo@squebb.ca>
Tue, 20 May 2025 00:50:18 +0000 (20:50 -0400)
committerIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Tue, 20 May 2025 09:40:03 +0000 (12:40 +0300)
A few, quite rare, WMI attributes have names that are not compatible with
filenames, e.g. "Intel VT for Directed I/O (VT-d)".
For these cases the '/' gets replaced with '\' for display, but doesn't
get switched again when doing the WMI access.

Fix this by keeping the original attribute name and using that for sending
commands to the BIOS

Fixes: a40cd7ef22fb ("platform/x86: think-lmi: Add WMI interface support on Lenovo platforms")
Signed-off-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Link: https://lore.kernel.org/r/20250520005027.3840705-1-mpearson-lenovo@squebb.ca
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
drivers/platform/x86/think-lmi.c
drivers/platform/x86/think-lmi.h

index 0fc275e461be4030e2886715f18cd7f36d96a602..00b1e7c79a3d1e95621701530ea5e11015414498 100644 (file)
@@ -1061,8 +1061,8 @@ static ssize_t current_value_store(struct kobject *kobj,
                        ret = -EINVAL;
                        goto out;
                }
-               set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
-                                       new_setting, tlmi_priv.pwd_admin->signature);
+               set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->name,
+                                   new_setting, tlmi_priv.pwd_admin->signature);
                if (!set_str) {
                        ret = -ENOMEM;
                        goto out;
@@ -1092,7 +1092,7 @@ static ssize_t current_value_store(struct kobject *kobj,
                                goto out;
                }
 
-               set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
+               set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->name,
                                    new_setting);
                if (!set_str) {
                        ret = -ENOMEM;
@@ -1120,11 +1120,11 @@ static ssize_t current_value_store(struct kobject *kobj,
                }
 
                if (auth_str)
-                       set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->display_name,
-                                       new_setting, auth_str);
+                       set_str = kasprintf(GFP_KERNEL, "%s,%s,%s", setting->name,
+                                           new_setting, auth_str);
                else
-                       set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->display_name,
-                                       new_setting);
+                       set_str = kasprintf(GFP_KERNEL, "%s,%s;", setting->name,
+                                           new_setting);
                if (!set_str) {
                        ret = -ENOMEM;
                        goto out;
@@ -1629,9 +1629,6 @@ static int tlmi_analyze(struct wmi_device *wdev)
                        continue;
                }
 
-               /* It is not allowed to have '/' for file name. Convert it into '\'. */
-               strreplace(item, '/', '\\');
-
                /* Remove the value part */
                strreplace(item, ',', '\0');
 
@@ -1644,11 +1641,16 @@ static int tlmi_analyze(struct wmi_device *wdev)
                }
                setting->wdev = wdev;
                setting->index = i;
+
+               strscpy(setting->name, item);
+               /* It is not allowed to have '/' for file name. Convert it into '\'. */
+               strreplace(item, '/', '\\');
                strscpy(setting->display_name, item);
+
                /* If BIOS selections supported, load those */
                if (tlmi_priv.can_get_bios_selections) {
-                       ret = tlmi_get_bios_selections(setting->display_name,
-                                       &setting->possible_values);
+                       ret = tlmi_get_bios_selections(setting->name,
+                                                      &setting->possible_values);
                        if (ret || !setting->possible_values)
                                pr_info("Error retrieving possible values for %d : %s\n",
                                                i, setting->display_name);
index a8045248222729d00dd337e4469b10c0b7c0d87d..9b014644d3161062bf458fad210bfc63404a5cde 100644 (file)
@@ -90,6 +90,7 @@ struct tlmi_attr_setting {
        struct kobject kobj;
        struct wmi_device *wdev;
        int index;
+       char name[TLMI_SETTINGS_MAXLEN];
        char display_name[TLMI_SETTINGS_MAXLEN];
        char *possible_values;
 };