summaryrefslogtreecommitdiff
path: root/drivers/platform/x86/think-lmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/platform/x86/think-lmi.c')
-rw-r--r--drivers/platform/x86/think-lmi.c256
1 files changed, 164 insertions, 92 deletions
diff --git a/drivers/platform/x86/think-lmi.c b/drivers/platform/x86/think-lmi.c
index 9345316b45db..00b1e7c79a3d 100644
--- a/drivers/platform/x86/think-lmi.c
+++ b/drivers/platform/x86/think-lmi.c
@@ -12,6 +12,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/acpi.h>
+#include <linux/array_size.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/mutex.h>
@@ -169,14 +170,12 @@ MODULE_PARM_DESC(debug_support, "Enable debug command support");
*/
#define LENOVO_CERT_THUMBPRINT_GUID "C59119ED-1C0D-4806-A8E9-59AA318176C4"
-#define TLMI_POP_PWD BIT(0) /* Supervisor */
-#define TLMI_PAP_PWD BIT(1) /* Power-on */
-#define TLMI_HDD_PWD BIT(2) /* HDD/NVME */
-#define TLMI_SMP_PWD BIT(6) /* System Management */
-#define TLMI_CERT BIT(7) /* Certificate Based */
-
-#define to_tlmi_pwd_setting(kobj) container_of(kobj, struct tlmi_pwd_setting, kobj)
-#define to_tlmi_attr_setting(kobj) container_of(kobj, struct tlmi_attr_setting, kobj)
+#define TLMI_POP_PWD BIT(0) /* Supervisor */
+#define TLMI_PAP_PWD BIT(1) /* Power-on */
+#define TLMI_HDD_PWD BIT(2) /* HDD/NVME */
+#define TLMI_SMP_PWD BIT(6) /* System Management */
+#define TLMI_CERT_SVC BIT(7) /* Admin Certificate Based */
+#define TLMI_CERT_SMC BIT(8) /* System Certificate Based */
static const struct tlmi_err_codes tlmi_errs[] = {
{"Success", 0},
@@ -195,9 +194,18 @@ static const char * const level_options[] = {
[TLMI_LEVEL_MASTER] = "master",
};
static struct think_lmi tlmi_priv;
-static const struct class *fw_attr_class;
static DEFINE_MUTEX(tlmi_mutex);
+static inline struct tlmi_pwd_setting *to_tlmi_pwd_setting(struct kobject *kobj)
+{
+ return container_of(kobj, struct tlmi_pwd_setting, kobj);
+}
+
+static inline struct tlmi_attr_setting *to_tlmi_attr_setting(struct kobject *kobj)
+{
+ return container_of(kobj, struct tlmi_attr_setting, kobj);
+}
+
/* Convert BIOS WMI error string to suitable error code */
static int tlmi_errstr_to_err(const char *errstr)
{
@@ -254,16 +262,11 @@ static int tlmi_simple_call(const char *guid, const char *arg)
return 0;
}
-/* Extract output string from WMI return buffer */
-static int tlmi_extract_output_string(const struct acpi_buffer *output,
- char **string)
+/* Extract output string from WMI return value */
+static int tlmi_extract_output_string(union acpi_object *obj, char **string)
{
- const union acpi_object *obj;
char *s;
- obj = output->pointer;
- if (!obj)
- return -ENOMEM;
if (obj->type != ACPI_TYPE_STRING || !obj->string.pointer)
return -EIO;
@@ -341,20 +344,18 @@ static int tlmi_opcode_setting(char *setting, const char *value)
return ret;
}
-static int tlmi_setting(int item, char **value, const char *guid_string)
+static int tlmi_setting(struct wmi_device *wdev, int item, char **value)
{
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- acpi_status status;
+ union acpi_object *obj;
int ret;
- status = wmi_query_block(guid_string, item, &output);
- if (ACPI_FAILURE(status)) {
- kfree(output.pointer);
+ obj = wmidev_block_query(wdev, item);
+ if (!obj)
return -EIO;
- }
- ret = tlmi_extract_output_string(&output, value);
- kfree(output.pointer);
+ ret = tlmi_extract_output_string(obj, value);
+ kfree(obj);
+
return ret;
}
@@ -362,19 +363,22 @@ static int tlmi_get_bios_selections(const char *item, char **value)
{
const struct acpi_buffer input = { strlen(item), (char *)item };
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
acpi_status status;
int ret;
status = wmi_evaluate_method(LENOVO_GET_BIOS_SELECTIONS_GUID,
0, 0, &input, &output);
-
- if (ACPI_FAILURE(status)) {
- kfree(output.pointer);
+ if (ACPI_FAILURE(status))
return -EIO;
- }
- ret = tlmi_extract_output_string(&output, value);
- kfree(output.pointer);
+ obj = output.pointer;
+ if (!obj)
+ return -ENODATA;
+
+ ret = tlmi_extract_output_string(obj, value);
+ kfree(obj);
+
return ret;
}
@@ -384,7 +388,7 @@ static ssize_t is_enabled_show(struct kobject *kobj, struct kobj_attribute *attr
{
struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
- return sysfs_emit(buf, "%d\n", setting->valid);
+ return sysfs_emit(buf, "%d\n", setting->pwd_enabled || setting->cert_installed);
}
static struct kobj_attribute auth_is_pass_set = __ATTR_RO(is_enabled);
@@ -462,7 +466,12 @@ static ssize_t new_password_store(struct kobject *kobj,
if (ret)
goto out;
- if (tlmi_priv.pwd_admin->valid) {
+ /*
+ * Note admin password is not always required if SMPControl enabled in BIOS,
+ * So only set if it's configured.
+ * Let BIOS figure it out - we'll get an error if operation is not permitted
+ */
+ if (tlmi_priv.pwd_admin->pwd_enabled && strlen(tlmi_priv.pwd_admin->password)) {
ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
tlmi_priv.pwd_admin->password);
if (ret)
@@ -517,6 +526,10 @@ static struct kobj_attribute auth_max_pass_length = __ATTR_RO(max_password_lengt
static ssize_t mechanism_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
+ struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
+
+ if (setting->cert_installed)
+ return sysfs_emit(buf, "certificate\n");
return sysfs_emit(buf, "password\n");
}
static struct kobj_attribute auth_mechanism = __ATTR_RO(mechanism);
@@ -637,6 +650,17 @@ static ssize_t level_store(struct kobject *kobj,
static struct kobj_attribute auth_level = __ATTR_RW(level);
+static char *cert_command(struct tlmi_pwd_setting *setting, const char *arg1, const char *arg2)
+{
+ /* Prepend with SVC or SMC if multicert supported */
+ if (tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT)
+ return kasprintf(GFP_KERNEL, "%s,%s,%s",
+ setting == tlmi_priv.pwd_admin ? "SVC" : "SMC",
+ arg1, arg2);
+ else
+ return kasprintf(GFP_KERNEL, "%s,%s", arg1, arg2);
+}
+
static ssize_t cert_thumbprint(char *buf, const char *arg, int count)
{
const struct acpi_buffer input = { strlen(arg), (char *)arg };
@@ -662,18 +686,35 @@ static ssize_t cert_thumbprint(char *buf, const char *arg, int count)
return count;
}
+static char *thumbtypes[] = {"Md5", "Sha1", "Sha256"};
+
static ssize_t certificate_thumbprint_show(struct kobject *kobj, struct kobj_attribute *attr,
char *buf)
{
struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
+ unsigned int i;
int count = 0;
+ char *wmistr;
if (!tlmi_priv.certificate_support || !setting->cert_installed)
return -EOPNOTSUPP;
- count += cert_thumbprint(buf, "Md5", count);
- count += cert_thumbprint(buf, "Sha1", count);
- count += cert_thumbprint(buf, "Sha256", count);
+ for (i = 0; i < ARRAY_SIZE(thumbtypes); i++) {
+ if (tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT) {
+ /* Format: 'SVC | SMC, Thumbtype' */
+ wmistr = kasprintf(GFP_KERNEL, "%s,%s",
+ setting == tlmi_priv.pwd_admin ? "SVC" : "SMC",
+ thumbtypes[i]);
+ } else {
+ /* Format: 'Thumbtype' */
+ wmistr = kasprintf(GFP_KERNEL, "%s", thumbtypes[i]);
+ }
+ if (!wmistr)
+ return -ENOMEM;
+ count += cert_thumbprint(buf, wmistr, count);
+ kfree(wmistr);
+ }
+
return count;
}
@@ -705,7 +746,7 @@ static ssize_t cert_to_password_store(struct kobject *kobj,
return -ENOMEM;
/* Format: 'Password,Signature' */
- auth_str = kasprintf(GFP_KERNEL, "%s,%s", passwd, setting->signature);
+ auth_str = cert_command(setting, passwd, setting->signature);
if (!auth_str) {
kfree_sensitive(passwd);
return -ENOMEM;
@@ -719,12 +760,19 @@ static ssize_t cert_to_password_store(struct kobject *kobj,
static struct kobj_attribute auth_cert_to_password = __ATTR_WO(cert_to_password);
+enum cert_install_mode {
+ TLMI_CERT_INSTALL,
+ TLMI_CERT_UPDATE,
+};
+
static ssize_t certificate_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t count)
{
struct tlmi_pwd_setting *setting = to_tlmi_pwd_setting(kobj);
+ enum cert_install_mode install_mode = TLMI_CERT_INSTALL;
char *auth_str, *new_cert;
+ char *signature;
char *guid;
int ret;
@@ -741,9 +789,9 @@ static ssize_t certificate_store(struct kobject *kobj,
return -EACCES;
/* Format: 'serial#, signature' */
- auth_str = kasprintf(GFP_KERNEL, "%s,%s",
- dmi_get_system_info(DMI_PRODUCT_SERIAL),
- setting->signature);
+ auth_str = cert_command(setting,
+ dmi_get_system_info(DMI_PRODUCT_SERIAL),
+ setting->signature);
if (!auth_str)
return -ENOMEM;
@@ -760,24 +808,44 @@ static ssize_t certificate_store(struct kobject *kobj,
if (setting->cert_installed) {
/* Certificate is installed so this is an update */
- if (!setting->signature || !setting->signature[0]) {
+ install_mode = TLMI_CERT_UPDATE;
+ /* If admin account enabled - need to use its signature */
+ if (tlmi_priv.pwd_admin->pwd_enabled)
+ signature = tlmi_priv.pwd_admin->signature;
+ else
+ signature = setting->signature;
+ } else { /* Cert install */
+ /* Check if SMC and SVC already installed */
+ if ((setting == tlmi_priv.pwd_system) && tlmi_priv.pwd_admin->cert_installed) {
+ /* This gets treated as a cert update */
+ install_mode = TLMI_CERT_UPDATE;
+ signature = tlmi_priv.pwd_admin->signature;
+ } else { /* Regular cert install */
+ install_mode = TLMI_CERT_INSTALL;
+ signature = setting->signature;
+ }
+ }
+
+ if (install_mode == TLMI_CERT_UPDATE) {
+ /* This is a certificate update */
+ if (!signature || !signature[0]) {
kfree(new_cert);
return -EACCES;
}
guid = LENOVO_UPDATE_BIOS_CERT_GUID;
/* Format: 'Certificate,Signature' */
- auth_str = kasprintf(GFP_KERNEL, "%s,%s",
- new_cert, setting->signature);
+ auth_str = cert_command(setting, new_cert, signature);
} else {
/* This is a fresh install */
- if (!setting->valid || !setting->password[0]) {
+ /* To set admin cert, a password must be enabled */
+ if ((setting == tlmi_priv.pwd_admin) &&
+ (!setting->pwd_enabled || !setting->password[0])) {
kfree(new_cert);
return -EACCES;
}
guid = LENOVO_SET_BIOS_CERT_GUID;
- /* Format: 'Certificate,Admin-password' */
- auth_str = kasprintf(GFP_KERNEL, "%s,%s",
- new_cert, setting->password);
+ /* Format: 'Certificate, password' */
+ auth_str = cert_command(setting, new_cert, setting->password);
}
kfree(new_cert);
if (!auth_str)
@@ -857,14 +925,19 @@ static umode_t auth_attr_is_visible(struct kobject *kobj,
return 0;
}
- /* We only display certificates on Admin account, if supported */
+ /* We only display certificates, if supported */
if (attr == &auth_certificate.attr ||
attr == &auth_signature.attr ||
attr == &auth_save_signature.attr ||
attr == &auth_cert_thumb.attr ||
attr == &auth_cert_to_password.attr) {
- if ((setting == tlmi_priv.pwd_admin) && tlmi_priv.certificate_support)
- return attr->mode;
+ if (tlmi_priv.certificate_support) {
+ if (setting == tlmi_priv.pwd_admin)
+ return attr->mode;
+ if ((tlmi_priv.pwdcfg.core.password_mode >= TLMI_PWDCFG_MODE_MULTICERT) &&
+ (setting == tlmi_priv.pwd_system))
+ return attr->mode;
+ }
return 0;
}
@@ -916,7 +989,7 @@ static ssize_t current_value_show(struct kobject *kobj, struct kobj_attribute *a
char *item, *value;
int ret;
- ret = tlmi_setting(setting->index, &item, LENOVO_BIOS_SETTING_GUID);
+ ret = tlmi_setting(setting->wdev, setting->index, &item);
if (ret)
return ret;
@@ -988,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;
@@ -1012,14 +1085,14 @@ static ssize_t current_value_store(struct kobject *kobj,
* Workstation's require the opcode to be set before changing the
* attribute.
*/
- if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+ if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
tlmi_priv.pwd_admin->password);
if (ret)
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;
@@ -1035,7 +1108,7 @@ static ssize_t current_value_store(struct kobject *kobj,
else
ret = tlmi_save_bios_settings("");
} else { /* old non-opcode based authentication method (deprecated) */
- if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+ if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
tlmi_priv.pwd_admin->password,
encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1047,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;
@@ -1208,7 +1281,7 @@ static ssize_t save_settings_store(struct kobject *kobj, struct kobj_attribute *
if (ret)
goto out;
} else if (tlmi_priv.opcode_support) {
- if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+ if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
ret = tlmi_opcode_setting("WmiOpcodePasswordAdmin",
tlmi_priv.pwd_admin->password);
if (ret)
@@ -1216,7 +1289,7 @@ static ssize_t save_settings_store(struct kobject *kobj, struct kobj_attribute *
}
ret = tlmi_save_bios_settings("");
} else { /* old non-opcode based authentication method (deprecated) */
- if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+ if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
tlmi_priv.pwd_admin->password,
encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1266,7 +1339,7 @@ static ssize_t debug_cmd_store(struct kobject *kobj, struct kobj_attribute *attr
if (!new_setting)
return -ENOMEM;
- if (tlmi_priv.pwd_admin->valid && tlmi_priv.pwd_admin->password[0]) {
+ if (tlmi_priv.pwd_admin->pwd_enabled && tlmi_priv.pwd_admin->password[0]) {
auth_str = kasprintf(GFP_KERNEL, "%s,%s,%s;",
tlmi_priv.pwd_admin->password,
encoding_options[tlmi_priv.pwd_admin->encoding],
@@ -1368,11 +1441,7 @@ static int tlmi_sysfs_init(void)
{
int i, ret;
- ret = fw_attributes_class_get(&fw_attr_class);
- if (ret)
- return ret;
-
- tlmi_priv.class_dev = device_create(fw_attr_class, NULL, MKDEV(0, 0),
+ tlmi_priv.class_dev = device_create(&firmware_attributes_class, NULL, MKDEV(0, 0),
NULL, "%s", "thinklmi");
if (IS_ERR(tlmi_priv.class_dev)) {
ret = PTR_ERR(tlmi_priv.class_dev);
@@ -1485,9 +1554,8 @@ static int tlmi_sysfs_init(void)
fail_create_attr:
tlmi_release_attr();
fail_device_created:
- device_destroy(fw_attr_class, MKDEV(0, 0));
+ device_destroy(&firmware_attributes_class, MKDEV(0, 0));
fail_class_created:
- fw_attributes_class_put();
return ret;
}
@@ -1501,7 +1569,7 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
if (!new_pwd)
return NULL;
- strscpy(new_pwd->kbdlang, "us", TLMI_LANG_MAXLEN);
+ strscpy(new_pwd->kbdlang, "us");
new_pwd->encoding = TLMI_ENCODING_ASCII;
new_pwd->pwd_type = pwd_type;
new_pwd->role = pwd_role;
@@ -1514,7 +1582,7 @@ static struct tlmi_pwd_setting *tlmi_create_auth(const char *pwd_type,
return new_pwd;
}
-static int tlmi_analyze(void)
+static int tlmi_analyze(struct wmi_device *wdev)
{
int i, ret;
@@ -1551,7 +1619,7 @@ static int tlmi_analyze(void)
char *item = NULL;
tlmi_priv.setting[i] = NULL;
- ret = tlmi_setting(i, &item, LENOVO_BIOS_SETTING_GUID);
+ ret = tlmi_setting(wdev, i, &item);
if (ret)
break;
if (!item)
@@ -1561,9 +1629,6 @@ static int tlmi_analyze(void)
continue;
}
- /* It is not allowed to have '/' for file name. Convert it into '\'. */
- strreplace(item, '/', '\\');
-
/* Remove the value part */
strreplace(item, ',', '\0');
@@ -1574,12 +1639,18 @@ static int tlmi_analyze(void)
kfree(item);
goto fail_clear_attr;
}
+ setting->wdev = wdev;
setting->index = i;
- strscpy(setting->display_name, item, TLMI_SETTINGS_MAXLEN);
+
+ 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);
@@ -1592,7 +1663,7 @@ static int tlmi_analyze(void)
*/
char *optitem, *optstart, *optend;
- if (!tlmi_setting(setting->index, &optitem, LENOVO_BIOS_SETTING_GUID)) {
+ if (!tlmi_setting(setting->wdev, setting->index, &optitem)) {
optstart = strstr(optitem, "[Optional:");
if (optstart) {
optstart += strlen("[Optional:");
@@ -1630,14 +1701,14 @@ static int tlmi_analyze(void)
goto fail_clear_attr;
if (tlmi_priv.pwdcfg.core.password_state & TLMI_PAP_PWD)
- tlmi_priv.pwd_admin->valid = true;
+ tlmi_priv.pwd_admin->pwd_enabled = true;
tlmi_priv.pwd_power = tlmi_create_auth("pop", "power-on");
if (!tlmi_priv.pwd_power)
goto fail_clear_attr;
if (tlmi_priv.pwdcfg.core.password_state & TLMI_POP_PWD)
- tlmi_priv.pwd_power->valid = true;
+ tlmi_priv.pwd_power->pwd_enabled = true;
if (tlmi_priv.opcode_support) {
tlmi_priv.pwd_system = tlmi_create_auth("smp", "system");
@@ -1645,7 +1716,7 @@ static int tlmi_analyze(void)
goto fail_clear_attr;
if (tlmi_priv.pwdcfg.core.password_state & TLMI_SMP_PWD)
- tlmi_priv.pwd_system->valid = true;
+ tlmi_priv.pwd_system->pwd_enabled = true;
tlmi_priv.pwd_hdd = tlmi_create_auth("hdd", "hdd");
if (!tlmi_priv.pwd_hdd)
@@ -1663,7 +1734,7 @@ static int tlmi_analyze(void)
/* Check if PWD is configured and set index to first drive found */
if (tlmi_priv.pwdcfg.ext.hdd_user_password ||
tlmi_priv.pwdcfg.ext.hdd_master_password) {
- tlmi_priv.pwd_hdd->valid = true;
+ tlmi_priv.pwd_hdd->pwd_enabled = true;
if (tlmi_priv.pwdcfg.ext.hdd_master_password)
tlmi_priv.pwd_hdd->index =
ffs(tlmi_priv.pwdcfg.ext.hdd_master_password) - 1;
@@ -1673,7 +1744,7 @@ static int tlmi_analyze(void)
}
if (tlmi_priv.pwdcfg.ext.nvme_user_password ||
tlmi_priv.pwdcfg.ext.nvme_master_password) {
- tlmi_priv.pwd_nvme->valid = true;
+ tlmi_priv.pwd_nvme->pwd_enabled = true;
if (tlmi_priv.pwdcfg.ext.nvme_master_password)
tlmi_priv.pwd_nvme->index =
ffs(tlmi_priv.pwdcfg.ext.nvme_master_password) - 1;
@@ -1684,10 +1755,12 @@ static int tlmi_analyze(void)
}
}
- if (tlmi_priv.certificate_support &&
- (tlmi_priv.pwdcfg.core.password_state & TLMI_CERT))
- tlmi_priv.pwd_admin->cert_installed = true;
-
+ if (tlmi_priv.certificate_support) {
+ tlmi_priv.pwd_admin->cert_installed =
+ tlmi_priv.pwdcfg.core.password_state & TLMI_CERT_SVC;
+ tlmi_priv.pwd_system->cert_installed =
+ tlmi_priv.pwdcfg.core.password_state & TLMI_CERT_SMC;
+ }
return 0;
fail_clear_attr:
@@ -1708,15 +1781,14 @@ fail_clear_attr:
static void tlmi_remove(struct wmi_device *wdev)
{
tlmi_release_attr();
- device_destroy(fw_attr_class, MKDEV(0, 0));
- fw_attributes_class_put();
+ device_destroy(&firmware_attributes_class, MKDEV(0, 0));
}
static int tlmi_probe(struct wmi_device *wdev, const void *context)
{
int ret;
- ret = tlmi_analyze();
+ ret = tlmi_analyze(wdev);
if (ret)
return ret;