All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jorge Lopez <jorgealtxwork@gmail.com>
To: hdegoede@redhat.com, platform-driver-x86@vger.kernel.org
Subject: [PATCH v4 5/6] HP BIOSCFG driver - set 4
Date: Thu, 20 Oct 2022 15:10:32 -0500	[thread overview]
Message-ID: <20221020201033.12790-6-jorge.lopez2@hp.com> (raw)
In-Reply-To: <20221020201033.12790-1-jorge.lopez2@hp.com>

The purpose for this patch is submit HP BIOSCFG driver to be list of
HP Linux kernel drivers.  The driver include a total of 12 files
broken in several patches.  This is set 4 of 4.

Signed-off-by: Jorge Lopez <jorge.lopez2@hp.com>

---
Based on the latest platform-drivers-x86.git/for-next
---
 .../x86/hp/hp-bioscfg/sureadmin-attributes.c  | 1014 +++++++++++++++++
 .../x86/hp/hp-bioscfg/surestart-attributes.c  |  145 +++
 2 files changed, 1159 insertions(+)
 create mode 100644 drivers/platform/x86/hp/hp-bioscfg/sureadmin-attributes.c
 create mode 100644 drivers/platform/x86/hp/hp-bioscfg/surestart-attributes.c

diff --git a/drivers/platform/x86/hp/hp-bioscfg/sureadmin-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/sureadmin-attributes.c
new file mode 100644
index 000000000000..5ad45cdddad9
--- /dev/null
+++ b/drivers/platform/x86/hp/hp-bioscfg/sureadmin-attributes.c
@@ -0,0 +1,1014 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Functions corresponding to sure admin object type attributes under
+ * BIOS for use with hp-bioscfg driver
+ *
+ *  Copyright (c) 2022 HP Development Company, L.P.
+ */
+
+#include "bioscfg.h"
+
+static int bios_settings_size;
+static int buf_alloc_size;
+static char *bios_settings_buffer;
+
+const char *hp_wmi_classes[] = {
+	"HPBIOS_BIOSString",
+	"HPBIOS_BIOSInteger",
+	"HPBIOS_BIOSEnumeration",
+	"HPBIOS_BIOSOrderedList",
+	"HPBIOS_BIOSPassword"
+};
+
+get_instance_id_for_attribute(string);
+get_instance_id_for_attribute(integer);
+get_instance_id_for_attribute(enumeration);
+get_instance_id_for_attribute(ordered_list);
+
+static ssize_t sure_admin_settings_write(struct file *filp, struct kobject *kobj,
+					 struct bin_attribute *attr,
+					 char *buf, loff_t off, size_t count)
+{
+	int status = 0;
+	char *part = NULL;
+	char *attr_name = NULL;
+	char *attr_value = NULL;
+	int part_len = 0;
+	unsigned short *buffer = NULL;
+	unsigned short *tmpstr = NULL;
+	int buffer_size = (count + strlen(UTF_PREFIX)) * sizeof(unsigned short);
+
+	buffer = kmalloc(buffer_size, GFP_KERNEL);
+	if (!buffer)
+		return -ENOMEM;
+
+	tmpstr = buffer;
+	part = strsep(&buf, ",");
+	if (!part) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+	// Save attr_name
+	attr_name = kmalloc(strlen(part) + 1, GFP_KERNEL);
+	if (!attr_name) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+	strncpy(attr_name, part, strlen(part));
+
+	tmpstr = ascii_to_utf16_unicode(tmpstr, part);
+	part = strsep(&buf, ",");
+	if (!part) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+
+	part_len = strlen(part);
+
+	/* Add extra buffer space when encountering an empty string */
+	if (!part_len) {
+		buffer_size += sizeof(unsigned short);
+		part_len += sizeof(unsigned short);
+	}
+
+	// Save attr_value
+	attr_value = kmalloc(part_len + 1, GFP_KERNEL);
+	if (!attr_value) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+	strncpy(attr_value, part, part_len);
+
+	tmpstr = ascii_to_utf16_unicode(tmpstr, part);
+	part = strsep(&buf, ",");
+	if (!part) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+	part_len = strlen(part) - 1;
+	part[part_len] = '\0';
+
+	if (strncmp(part, BEAM_PREFIX, strlen(BEAM_PREFIX)) == 0) {
+	       /*
+		* BEAM_PREFIX is append to buffer when a signature
+		* is provided and Sure Admin is enabled in BIOS
+		*/
+		// BEAM_PREFIX found, convert part to unicode
+		tmpstr = ascii_to_utf16_unicode(tmpstr, part);
+		// decrease buffer size allocated initially for UTF_PREFIX
+		buffer_size -= strlen(UTF_PREFIX) * sizeof(unsigned short);
+	} else {
+		/*
+		 * UTF-16 prefix is append to the * buffer when a BIOS
+		 * admin password is configured in BIOS
+		 */
+
+		// append UTF_PREFIX to part and then convert it to unicode
+		part = kasprintf(GFP_KERNEL, "%s%s", UTF_PREFIX, part);
+		if (!part)
+			goto exit_settings;
+
+		tmpstr = ascii_to_utf16_unicode(tmpstr, part);
+		kfree(part);
+	}
+
+	part = strsep(&buf, ",");
+	if (part) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+
+	status = hp_wmi_set_bios_setting(buffer, buffer_size);
+	if (ACPI_FAILURE(status)) {
+		status = -EINVAL;
+		goto exit_settings;
+	}
+
+	if (attr_name == NULL)
+		pr_warn("Name is null\n");
+	if (attr_value == NULL)
+		pr_warn("Value is null\n");
+
+	update_attribute_value(attr_name, attr_value);
+
+
+exit_settings:
+	kfree(buffer);
+	kfree(attr_name);
+	kfree(attr_value);
+
+	if (ACPI_SUCCESS(status))
+		return count;
+
+	return status;
+}
+
+int update_attribute_value(char *attr_name, char *attr_value)
+{
+	int instance = -EIO;
+	int int_val;
+	int ret;
+
+	if (!attr_name || !attr_value)
+		return -EIO;
+
+	/* update value for the attribute */
+	instance = get_instance_id_for_string(attr_name);
+	if (instance >= 0) {
+		strscpy(bioscfg_drv.string_data[instance].current_value,
+			attr_value,
+			sizeof(bioscfg_drv.string_data[instance].current_value));
+
+		/*
+		 * set pending reboot flag depending on
+		 * "RequiresPhysicalPresence" value
+		 */
+		if (bioscfg_drv.string_data[instance].requires_physical_presence)
+			bioscfg_drv.pending_reboot = TRUE;
+		goto exit_update_attribute;
+	}
+
+	instance = get_instance_id_for_integer(attr_name);
+	if (instance >= 0) {
+		ret = kstrtoint(attr_value, 10, &int_val);
+		if (!ret) {
+			bioscfg_drv.integer_data[instance].current_value = int_val;
+			/*
+			 * set pending reboot flag depending on
+			 * "RequiresPhysicalPresence" value
+			 */
+			if (bioscfg_drv.integer_data[instance].requires_physical_presence)
+				bioscfg_drv.pending_reboot = TRUE;
+		}
+
+		goto exit_update_attribute;
+	}
+
+	instance = get_instance_id_for_enumeration(attr_name);
+	if (instance >= 0) {
+		strscpy(bioscfg_drv.enumeration_data[instance].current_value,
+			attr_value,
+			sizeof(bioscfg_drv.enumeration_data[instance].current_value));
+		/*
+		 * set pending reboot flag depending on
+		 * "RequiresPhysicalPresence" value
+		 */
+		if (bioscfg_drv.enumeration_data[instance].requires_physical_presence)
+			bioscfg_drv.pending_reboot = TRUE;
+
+		goto exit_update_attribute;
+	}
+	instance = get_instance_id_for_ordered_list(attr_name);
+	if (instance >= 0) {
+		strscpy(bioscfg_drv.ordered_list_data[instance].current_value,
+			attr_value,
+			sizeof(bioscfg_drv.ordered_list_data[instance].current_value));
+
+		/*
+		 * set pending reboot flag depending on
+		 * "RequiresPhysicalPresence" value
+		 */
+		if (bioscfg_drv.ordered_list_data[instance].requires_physical_presence)
+			bioscfg_drv.pending_reboot = TRUE;
+	}
+
+exit_update_attribute:
+	return instance;
+}
+
+static ssize_t sure_admin_settings_read(struct file *filp, struct kobject *kobj,
+					struct bin_attribute *attr, char *buf,
+					loff_t off, size_t count)
+{
+	ssize_t ret;
+
+	/* clear the buffer when offset is pointing to the last position */
+	if (off >= bios_settings_size && bios_settings_size > 0) {
+		hp_bios_settings_free_buffer();
+		return 0;
+	}
+
+	/* clear the buffer whenever the read starts from the first position */
+	if (off == 0 && bios_settings_size > 0)
+		hp_bios_settings_free_buffer();
+
+	if (bios_settings_size == 0)
+		hp_bios_settings_fill_buffer();
+
+	mutex_lock(&bioscfg_drv.mutex);
+	ret = memory_read_from_buffer(buf, count, &off, bios_settings_buffer,
+				      bios_settings_size);
+	mutex_unlock(&bioscfg_drv.mutex);
+
+	return ret;
+}
+
+HPWMI_BINATTR_RW(sure_admin, settings, 0);
+
+static struct bin_attribute *sure_admin_binattrs[] = {
+	&sure_admin_settings,
+	NULL,
+};
+
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
+			 char *buf)
+{
+	return sprintf(buf, "sure-admin\n");
+}
+static struct kobj_attribute sure_admin_type = __ATTR_RO(type);
+
+static ssize_t display_name_language_code_show(struct kobject *kobj,
+					       struct kobj_attribute *attr,
+					       char *buf)
+{
+	return sprintf(buf, "%s\n", LANG_CODE_STR);
+}
+
+static struct kobj_attribute sure_admin_display_langcode =
+		__ATTR_RO(display_name_language_code);
+
+
+static ssize_t display_name_show(struct kobject *kobj,
+				 struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", SURE_ADMIN_DESC);
+}
+static struct kobj_attribute sure_admin_display_name = __ATTR_RO(display_name);
+
+static struct attribute *sure_admin_attrs[] = {
+	&sure_admin_display_name.attr,
+	&sure_admin_display_langcode.attr,
+	&sure_admin_type.attr,
+	NULL,
+};
+
+static const struct attribute_group sure_admin_attr_group = {
+	.attrs = sure_admin_attrs,
+	.bin_attrs = sure_admin_binattrs,
+};
+
+void exit_sure_admin_attributes(void)
+{
+	sysfs_remove_group(bioscfg_drv.sure_admin_attr_kobj, &sure_admin_attr_group);
+}
+
+int populate_sure_admin_data(struct kobject *attr_name_kobj)
+{
+	bioscfg_drv.sure_admin_attr_kobj = attr_name_kobj;
+	return sysfs_create_group(attr_name_kobj, &sure_admin_attr_group);
+}
+
+int hp_bios_settings_fill_buffer(void)
+{
+	int status = 0;
+	int initial_buffer_size = 20 * PAGE_SIZE;
+
+	mutex_lock(&bioscfg_drv.mutex);
+	bios_settings_buffer = kmalloc(initial_buffer_size, GFP_KERNEL);
+	mutex_unlock(&bioscfg_drv.mutex);
+	if (!bios_settings_buffer)
+		return -ENOMEM;
+
+	mutex_lock(&bioscfg_drv.mutex);
+	buf_alloc_size = ksize(bios_settings_buffer);
+	memset(bios_settings_buffer, 0x00, buf_alloc_size);
+	bios_settings_size = snprintf(bios_settings_buffer,
+					buf_alloc_size, "[\n");
+	mutex_unlock(&bioscfg_drv.mutex);
+
+	status = append_read_settings(HPWMI_STRING_TYPE,
+					   &bios_settings_buffer,
+					   &bios_settings_size,
+					   &buf_alloc_size);
+	if (ACPI_FAILURE(status))
+		pr_err("error 0x%x occurred retrieving string instances\n", status);
+
+	status = append_read_settings(HPWMI_INTEGER_TYPE,
+					   &bios_settings_buffer,
+					   &bios_settings_size,
+					   &buf_alloc_size);
+	if (ACPI_FAILURE(status))
+		pr_err("error 0x%x occurred retrieving integer instances\n", status);
+
+	status = append_read_settings(HPWMI_ENUMERATION_TYPE,
+					   &bios_settings_buffer,
+					   &bios_settings_size,
+					   &buf_alloc_size);
+	if (ACPI_FAILURE(status))
+		pr_err("error 0x%x occurred retrieving enumeration instances\n", status);
+
+	status = append_read_settings(HPWMI_ORDERED_LIST_TYPE,
+					   &bios_settings_buffer,
+					   &bios_settings_size,
+					   &buf_alloc_size);
+	if (ACPI_FAILURE(status))
+		pr_err("error 0x%x occurred retrieving ordered list instances\n", status);
+
+	status = append_read_settings(HPWMI_PASSWORD_TYPE,
+					   &bios_settings_buffer,
+					   &bios_settings_size,
+					   &buf_alloc_size);
+	if (ACPI_FAILURE(status))
+		pr_err("error 0x%x occurred retrieving password list instances\n", status);
+
+	mutex_lock(&bioscfg_drv.mutex);
+	/*
+	 * remove trailing comma
+	 */
+	if (bios_settings_size >= 3) {
+		if (bios_settings_buffer[bios_settings_size - 2] == ',')
+			bios_settings_buffer[bios_settings_size - 2] = ' ';
+	}
+	bios_settings_size = snprintf(bios_settings_buffer,
+					buf_alloc_size, "%s]\n",
+					bios_settings_buffer);
+	mutex_unlock(&bioscfg_drv.mutex);
+
+	return bios_settings_size;
+}
+
+int hp_bios_settings_free_buffer(void)
+{
+	mutex_lock(&bioscfg_drv.mutex);
+	kfree(bios_settings_buffer);
+	bios_settings_size = 0;
+	buf_alloc_size = 0;
+	mutex_unlock(&bioscfg_drv.mutex);
+
+	return 0;
+}
+int hp_bios_settings_realloc_buffer(char **buf, int *buf_size, int *alloc_size)
+{
+	int new_buffer_size;
+	char *new_buf = NULL;
+	int ret = 0;
+
+	if (*buf_size + PAGE_SIZE >= *alloc_size) {
+		new_buffer_size = buf_alloc_size + 2 * PAGE_SIZE;
+
+		mutex_lock(&bioscfg_drv.mutex);
+		new_buf = krealloc(*buf, new_buffer_size, GFP_KERNEL);
+		mutex_unlock(&bioscfg_drv.mutex);
+		if (new_buf) {
+			mutex_lock(&bioscfg_drv.mutex);
+			*buf = new_buf;
+			*alloc_size = ksize(new_buf);
+			mutex_unlock(&bioscfg_drv.mutex);
+		} else {
+			hp_bios_settings_free_buffer();
+			ret = -ENOMEM;
+		}
+	}
+
+	return ret;
+}
+
+int append_read_settings(enum hp_wmi_data_type type, char **buf,
+			 int *buf_size, int *alloc_size)
+{
+	int ret = 0;
+	int status = 0;
+	int instance = 0;
+	int instance_count = 0;
+
+	switch (type) {
+	case HPWMI_STRING_TYPE:
+		instance_count = bioscfg_drv.string_instances_count;
+		break;
+	case HPWMI_INTEGER_TYPE:
+		instance_count = bioscfg_drv.integer_instances_count;
+		break;
+	case HPWMI_ENUMERATION_TYPE:
+		instance_count = bioscfg_drv.enumeration_instances_count;
+		break;
+	case HPWMI_ORDERED_LIST_TYPE:
+		instance_count = bioscfg_drv.ordered_list_instances_count;
+		break;
+	case HPWMI_PASSWORD_TYPE:
+		instance_count = bioscfg_drv.password_instances_count;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/*
+	 * Query all the instances
+	 */
+	for (instance = 0; instance < instance_count; instance++) {
+		mutex_lock(&bioscfg_drv.mutex);
+		status = append_read_attributes(buf, *alloc_size,
+						     instance, type);
+		if (status > 0)
+			*buf_size = status;
+
+		mutex_unlock(&bioscfg_drv.mutex);
+
+		ret = hp_bios_settings_realloc_buffer(buf, buf_size,
+						      alloc_size);
+	}
+	return ret;
+}
+
+int append_read_attributes(char **buf, int alloc_size,
+			   int instance, enum hp_wmi_data_type type)
+{
+	int status = 0;
+
+	switch (type) {
+	case HPWMI_STRING_TYPE:
+		status = append_read_string_attributes(*buf, alloc_size,
+						       instance, type);
+		break;
+	case HPWMI_INTEGER_TYPE:
+		status = append_read_integer_attributes(*buf, alloc_size,
+							instance, type);
+		break;
+	case HPWMI_ENUMERATION_TYPE:
+		status = append_read_enumeration_attributes(*buf,
+							    alloc_size,
+							    instance, type);
+		break;
+	case HPWMI_ORDERED_LIST_TYPE:
+		status = append_read_ordered_list_attributes(*buf,
+							     alloc_size,
+							     instance, type);
+		break;
+	case HPWMI_PASSWORD_TYPE:
+		status = append_read_password_attributes(*buf,
+							 alloc_size,
+							 instance, type);
+		break;
+	default:
+		status = -EINVAL;
+		break;
+	}
+	return status;
+}
+
+
+int append_read_string_attributes(char *buf, int alloc_size,
+				  int instance,
+				  enum hp_wmi_data_type type)
+{
+	int buf_size;
+	char *part_tmp = NULL;
+	char *part = NULL;
+
+	if (type >= ARRAY_SIZE(hp_wmi_classes) || !buf)
+		return -EINVAL;
+
+	buf_size = snprintf(buf, alloc_size, "%s{\n", buf);
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Class\": \"%s\",\n",
+			    buf, hp_wmi_classes[type]);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Name\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].display_name);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Value\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].current_value);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Path\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].path);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsReadOnly\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].is_readonly);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"DisplayInUI\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].display_in_ui);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"RequiresPhysicalPresence\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].requires_physical_presence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Sequence\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].sequence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"PrerequisiteSize\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].prerequisitesize);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Prerequisites\": [\n", buf);
+
+	if (bioscfg_drv.string_data[instance].prerequisitesize) {
+		part_tmp = kstrdup(bioscfg_drv.string_data[instance].prerequisites,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"SecurityLevel\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].security_level);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"MinLength\": %d,\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].min_length);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"MaxLength\": %d\n",
+			    buf,
+			    bioscfg_drv.string_data[instance].max_length);
+
+	return snprintf(buf, alloc_size, "%s},\n", buf);
+}
+
+
+int append_read_integer_attributes(char *buf, int alloc_size,
+				   int instance,
+				   enum hp_wmi_data_type type)
+{
+	int buf_size;
+	char *part_tmp = NULL;
+	char *part = NULL;
+
+	if (type >= ARRAY_SIZE(hp_wmi_classes) || !buf)
+		return -EINVAL;
+
+	buf_size = snprintf(buf, alloc_size, "%s{\n", buf);
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Class\": \"%s\",\n",
+			    buf, hp_wmi_classes[type]);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Name\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].display_name);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Value\": \"%d\",\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].current_value);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Path\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].path);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsReadOnly\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].is_readonly);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"DisplayInUI\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].display_in_ui);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"RequiresPhysicalPresence\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].requires_physical_presence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Sequence\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].sequence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"PrerequisiteSize\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].prerequisitesize);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Prerequisites\": [\n", buf);
+
+	if (bioscfg_drv.integer_data[instance].prerequisitesize) {
+		part_tmp = kstrdup(bioscfg_drv.integer_data[instance].prerequisites,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"SecurityLevel\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].security_level);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"LowerBound\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].lower_bound);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"UpperBound\": %d,\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].upper_bound);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IntValue\": %d\n",
+			    buf,
+			    bioscfg_drv.integer_data[instance].scalar_increment);
+
+	return snprintf(buf, alloc_size, "%s},\n", buf);
+}
+
+int append_read_enumeration_attributes(char *buf, int alloc_size,
+				       int instance,
+				       enum hp_wmi_data_type type)
+{
+	int buf_size;
+	char *part_tmp = NULL;
+	char *part = NULL;
+
+	if (type >= ARRAY_SIZE(hp_wmi_classes) || !buf)
+		return -EINVAL;
+
+	buf_size = snprintf(buf, alloc_size, "%s{\n", buf);
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Class\": \"%s\",\n",
+			    buf, hp_wmi_classes[type]);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Name\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].display_name);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Path\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].path);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsReadOnly\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].is_readonly);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"DisplayInUI\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].display_in_ui);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"RequiresPhysicalPresence\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].requires_physical_presence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Sequence\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].sequence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"PrerequisiteSize\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].prerequisitesize);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Prerequisites\": [\n", buf);
+
+	if (bioscfg_drv.enumeration_data[instance].prerequisitesize) {
+		part_tmp = kstrdup(bioscfg_drv.enumeration_data[instance].prerequisites,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"SecurityLevel\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].security_level);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Value\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].current_value);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Size\": %d,\n",
+			    buf,
+			    bioscfg_drv.enumeration_data[instance].size);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"PossibleValues\": [\n", buf);
+
+	if (bioscfg_drv.enumeration_data[instance].size) {
+		part_tmp = kstrdup(bioscfg_drv.enumeration_data[instance].possible_values,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t]\n", buf);
+
+	return snprintf(buf, alloc_size, "%s},\n", buf);
+}
+
+int append_read_ordered_list_attributes(char *buf, int alloc_size,
+					int instance,
+					enum hp_wmi_data_type type)
+{
+	int buf_size;
+	char *part_tmp = NULL;
+	char *part = NULL;
+
+	if (type >= ARRAY_SIZE(hp_wmi_classes) || !buf)
+		return -EINVAL;
+
+	buf_size = snprintf(buf, alloc_size, "%s{\n", buf);
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Class\": \"%s\",\n",
+			    buf, hp_wmi_classes[type]);
+
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Name\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].display_name);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Value\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].current_value);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Path\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].path);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsReadOnly\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].is_readonly);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"DisplayInUI\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].display_in_ui);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"RequiresPhysicalPresence\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].requires_physical_presence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Sequence\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].sequence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"PrerequisiteSize\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].prerequisitesize);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Prerequisites\": [\n", buf);
+
+	if (bioscfg_drv.ordered_list_data[instance].prerequisitesize) {
+		part_tmp = kstrdup(bioscfg_drv.ordered_list_data[instance].prerequisites,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"SecurityLevel\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].security_level);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Size\": %d,\n",
+			    buf,
+			    bioscfg_drv.ordered_list_data[instance].size);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Elements\": [\n", buf);
+
+	if (bioscfg_drv.ordered_list_data[instance].size) {
+		part_tmp = kstrdup(bioscfg_drv.ordered_list_data[instance].elements,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t]\n", buf);
+
+	return snprintf(buf, alloc_size, "%s},\n", buf);
+}
+
+
+int append_read_password_attributes(char *buf, int alloc_size,
+				    int instance,
+				    enum hp_wmi_data_type type)
+{
+	int buf_size;
+	char *part_tmp = NULL;
+	char *part = NULL;
+
+	if (type >= ARRAY_SIZE(hp_wmi_classes) || !buf)
+		return -EINVAL;
+
+	buf_size = snprintf(buf, alloc_size, "%s{\n", buf);
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Class\": \"%s\",\n",
+			    buf, hp_wmi_classes[type]);
+
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Name\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].display_name);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Value\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].current_password);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Path\": \"%s\",\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].path);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsReadOnly\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].is_readonly);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"DisplayInUI\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].display_in_ui);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"RequiresPhysicalPresence\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].requires_physical_presence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Sequence\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].sequence);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"PrerequisiteSize\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].prerequisitesize);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"Prerequisites\": [\n", buf);
+
+	if (bioscfg_drv.password_data[instance].prerequisitesize) {
+		part_tmp = kstrdup(bioscfg_drv.password_data[instance].prerequisites,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"SecurityLevel\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].security_level);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"MinLength\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].min_password_length);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"MaxLength\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].max_password_length);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"Size\": %d,\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].encoding_size);
+
+	buf_size = snprintf(buf, alloc_size, "%s\t\"SupportedEncoding\": [\n", buf);
+
+	if (bioscfg_drv.password_data[instance].encoding_size) {
+		part_tmp = kstrdup(bioscfg_drv.password_data[instance].supported_encoding,
+				   GFP_KERNEL);
+		part = strsep(&part_tmp, ";");
+		while (part) {
+			buf_size = snprintf(buf, alloc_size, "%s\t\t\"%s\"", buf, part);
+			part = strsep(&part_tmp, ";");
+			if (part)
+				buf_size = snprintf(buf, alloc_size, "%s,\n", buf);
+			else
+				buf_size = snprintf(buf, alloc_size, "%s\n", buf);
+		}
+		kfree(part_tmp);
+		part_tmp = NULL;
+	}
+	buf_size = snprintf(buf, alloc_size, "%s\t],\n", buf);
+
+	buf_size = snprintf(buf, alloc_size,
+			    "%s\t\"IsSet\": %d\n",
+			    buf,
+			    bioscfg_drv.password_data[instance].is_enabled);
+
+	return snprintf(buf, alloc_size, "%s},\n", buf);
+}
diff --git a/drivers/platform/x86/hp/hp-bioscfg/surestart-attributes.c b/drivers/platform/x86/hp/hp-bioscfg/surestart-attributes.c
new file mode 100644
index 000000000000..41c5a549f2ca
--- /dev/null
+++ b/drivers/platform/x86/hp/hp-bioscfg/surestart-attributes.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Functions corresponding to sure start object type attributes under
+ * BIOS for use with hp-bioscfg driver
+ *
+ *  Copyright (c) 2022 HP Development Company, L.P.
+ */
+
+#include "bioscfg.h"
+#include <asm-generic/posix_types.h>
+
+#define LOG_MAX_ENTRIES	254
+#define LOG_ENTRY_SIZE	16
+
+/*
+ * audit_log_entry_count_show - Reports the number of
+ *				existing audit log entries available
+ *				to be read
+ *
+ * @kobj:  Pointer to a kernel object of things that show up as directory
+ *	   in the sysfs filesystem.
+ * @attr:  Pointer to list of attributes for the operation
+ * @buf:   Pointer to buffer
+ *
+ * Returns number of existing audit log entries available to be read,
+ *         audit log entry size, and maximum number of entries
+ *         supported. Otherwise, an HP WMI query specific error code
+ *         (which is negative)
+ *
+ *         [No of entries],[log entry size],[Max number of entries supported]
+ */
+static ssize_t audit_log_entry_count_show(struct kobject *kobj,
+					  struct kobj_attribute *attr, char *buf)
+{
+	int ret;
+	u32 count = 0;
+
+	ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG_COUNT, HPWMI_SURESTART,
+				   &count, 0, sizeof(count));
+	if (ret < 0)
+		return ret;
+
+	return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n", count, LOG_ENTRY_SIZE, LOG_MAX_ENTRIES);
+}
+
+/*
+ * audit_log_entries_show() - Return all entries found in log file
+ *
+ * @kobj:  Pointer to a kernel object of things that show up as
+ *	   directory in the sysfs filesystem.
+ * @attr:  Pointer to list of attributes for the operation
+ * @buf:   Pointer to buffer
+ *
+ * Returns number of bytes needed to read all audit logs entries to be read.
+ *         Otherwise, an HP WMI query specific error code (which is negative)
+ *	   -EFAULT if the audit logs size exceeds 4KB
+ *
+ */
+static ssize_t audit_log_entries_show(struct kobject *kobj,
+				      struct kobj_attribute *attr, char *buf)
+{
+	int ret;
+	int i;
+	u32 count = 0;
+
+	// Get the number of event logs
+	ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG_COUNT, HPWMI_SURESTART,
+				   &count, 1, 4);
+
+	/*
+	 * The show() api will not work if the audit logs ever go
+	 *  beyond 4KB
+	 */
+	if (count * LOG_ENTRY_SIZE > PAGE_SIZE)
+		return -EFAULT;
+
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * We are guaranteed the buffer is 4KB so today all the event
+	 * logs will fit
+	 */
+	for (i = 0; ((i < count) & (ret >= 0)); i++) {
+		*buf = (i + 1);
+		ret = hp_wmi_perform_query(HPWMI_SURESTART_GET_LOG,
+					   HPWMI_SURESTART,
+					   buf, 1, 128);
+		if (ret >= 0)
+			buf += LOG_ENTRY_SIZE;
+	}
+	return (count * LOG_ENTRY_SIZE);
+}
+
+static struct kobj_attribute sure_start_audit_log_entry_count = __ATTR_RO(audit_log_entry_count);
+struct kobj_attribute sure_start_audit_log_entries = __ATTR_RO(audit_log_entries);
+
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
+			 char *buf)
+{
+	return sprintf(buf, "sure-start\n");
+}
+static struct kobj_attribute sure_start_type = __ATTR_RO(type);
+
+static ssize_t display_name_language_code_show(struct kobject *kobj,
+					       struct kobj_attribute *attr,
+					       char *buf)
+{
+	return sprintf(buf, "%s\n", LANG_CODE_STR);
+}
+
+static struct kobj_attribute sure_start_display_langcode =
+		__ATTR_RO(display_name_language_code);
+
+
+static ssize_t display_name_show(struct kobject *kobj,
+				 struct kobj_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", SURE_START_DESC);
+}
+static struct kobj_attribute sure_start_display_name = __ATTR_RO(display_name);
+
+static struct attribute *sure_start_attrs[] = {
+	&sure_start_display_name.attr,
+	&sure_start_display_langcode.attr,
+	&sure_start_audit_log_entry_count.attr,
+	&sure_start_audit_log_entries.attr,
+	&sure_start_type.attr,
+	NULL,
+};
+
+static const struct attribute_group sure_start_attr_group = {
+	.attrs = sure_start_attrs,
+};
+
+void exit_sure_start_attributes(void)
+{
+	sysfs_remove_group(bioscfg_drv.sure_start_attr_kobj, &sure_start_attr_group);
+}
+
+int populate_sure_start_data(struct kobject *attr_name_kobj)
+{
+	bioscfg_drv.sure_start_attr_kobj = attr_name_kobj;
+	return sysfs_create_group(attr_name_kobj, &sure_start_attr_group);
+}
-- 
2.34.1


  parent reply	other threads:[~2022-10-20 20:10 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-20 20:10 [PATCH v4 0/6] Introduction of HP-BIOSCFG driver Jorge Lopez
2022-10-20 20:10 ` [PATCH v4 1/6] Moving existing HP drivers to a central location Jorge Lopez
2022-11-07 13:48   ` Hans de Goede
2022-11-08 21:36     ` Jorge Lopez
2022-10-20 20:10 ` [PATCH v4 2/6] Introduction of HP-BIOSCFG driver Jorge Lopez
2022-11-08 14:51   ` Hans de Goede
2022-11-09 17:24     ` Jorge Lopez
2022-11-09 18:10       ` Hans de Goede
2022-11-09 20:00         ` Jorge Lopez
2022-11-09 20:05           ` Hans de Goede
2022-11-09 20:52             ` Jorge Lopez
2022-11-09 20:55               ` Hans de Goede
2022-11-09 21:04                 ` Jorge Lopez
2022-11-09 21:11                   ` Hans de Goede
2022-11-09 21:26                     ` Jorge Lopez
2022-11-11 23:00     ` Jorge Lopez
2022-11-12  8:30       ` Hans de Goede
2022-11-14 14:13         ` Jorge Lopez
2022-10-20 20:10 ` [PATCH v4 3/6] HP BIOSCFG driver - set 2 Jorge Lopez
2022-10-20 20:10 ` [PATCH v4 4/6] HP BIOSCFG driver - set 3 Jorge Lopez
2022-10-20 20:10 ` Jorge Lopez [this message]
2022-10-20 20:10 ` [PATCH v4 6/6] HP BIOSCFG driver - remaining components Jorge Lopez
2022-11-08 14:59 ` [PATCH v4 0/6] Introduction of HP-BIOSCFG driver Hans de Goede
2022-11-08 21:38   ` Jorge Lopez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221020201033.12790-6-jorge.lopez2@hp.com \
    --to=jorgealtxwork@gmail.com \
    --cc=hdegoede@redhat.com \
    --cc=platform-driver-x86@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.