// SPDX-License-Identifier: GPL-2.0
/*
 * Functions corresponding to SET methods under BIOS attributes interface GUID for use
 * with dell-wmi-sysman
 *
 *  Copyright (c) 2020 Dell Inc.
 */

#include <linux/wmi.h>
#include "dell-wmi-sysman.h"

#define SETDEFAULTVALUES_METHOD_ID					0x02
#define SETBIOSDEFAULTS_METHOD_ID					0x03
#define SETATTRIBUTE_METHOD_ID						0x04

static int call_biosattributes_interface(struct wmi_device *wdev, char *in_args, size_t size,
					int method_id)
{
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
	struct acpi_buffer input;
	union acpi_object *obj;
	acpi_status status;
	int ret = -EIO;

	input.length =  (acpi_size) size;
	input.pointer = in_args;
	status = wmidev_evaluate_method(wdev, 0, method_id, &input, &output);
	if (ACPI_FAILURE(status))
		return -EIO;
	obj = (union acpi_object *)output.pointer;
	if (obj->type == ACPI_TYPE_INTEGER)
		ret = obj->integer.value;

	if (wmi_priv.pending_changes == 0) {
		wmi_priv.pending_changes = 1;
		/* let userland know it may need to check reboot pending again */
		kobject_uevent(&wmi_priv.class_dev->kobj, KOBJ_CHANGE);
	}
	kfree(output.pointer);
	return map_wmi_error(ret);
}

/**
 * set_attribute() - Update an attribute value
 * @a_name: The attribute name
 * @a_value: The attribute value
 *
 * Sets an attribute to new value
 */
int set_attribute(const char *a_name, const char *a_value)
{
	size_t security_area_size, buffer_size;
	size_t a_name_size, a_value_size;
	char *buffer = NULL, *start;
	int ret;

	mutex_lock(&wmi_priv.mutex);
	if (!wmi_priv.bios_attr_wdev) {
		ret = -ENODEV;
		goto out;
	}

	/* build/calculate buffer */
	security_area_size = calculate_security_buffer(wmi_priv.current_admin_password);
	a_name_size = calculate_string_buffer(a_name);
	a_value_size = calculate_string_buffer(a_value);
	buffer_size = security_area_size + a_name_size + a_value_size;
	buffer = kzalloc(buffer_size, GFP_KERNEL);
	if (!buffer) {
		ret = -ENOMEM;
		goto out;
	}

	/* build security area */
	populate_security_buffer(buffer, wmi_priv.current_admin_password);

	/* build variables to set */
	start = buffer + security_area_size;
	ret = populate_string_buffer(start, a_name_size, a_name);
	if (ret < 0)
		goto out;
	start += ret;
	ret = populate_string_buffer(start, a_value_size, a_value);
	if (ret < 0)
		goto out;

	print_hex_dump_bytes("set attribute data: ", DUMP_PREFIX_NONE, buffer, buffer_size);
	ret = call_biosattributes_interface(wmi_priv.bios_attr_wdev,
					    buffer, buffer_size,
					    SETATTRIBUTE_METHOD_ID);
	if (ret == -EOPNOTSUPP)
		dev_err(&wmi_priv.bios_attr_wdev->dev, "admin password must be configured\n");
	else if (ret == -EACCES)
		dev_err(&wmi_priv.bios_attr_wdev->dev, "invalid password\n");

out:
	kfree(buffer);
	mutex_unlock(&wmi_priv.mutex);
	return ret;
}

/**
 * set_bios_defaults() - Resets BIOS defaults
 * @deftype: the type of BIOS value reset to issue.
 *
 * Resets BIOS defaults
 */
int set_bios_defaults(u8 deftype)
{
	size_t security_area_size, buffer_size;
	size_t integer_area_size = sizeof(u8);
	char *buffer = NULL;
	u8 *defaultType;
	int ret;

	mutex_lock(&wmi_priv.mutex);
	if (!wmi_priv.bios_attr_wdev) {
		ret = -ENODEV;
		goto out;
	}

	security_area_size = calculate_security_buffer(wmi_priv.current_admin_password);
	buffer_size = security_area_size + integer_area_size;
	buffer = kzalloc(buffer_size, GFP_KERNEL);
	if (!buffer) {
		ret = -ENOMEM;
		goto out;
	}

	/* build security area */
	populate_security_buffer(buffer, wmi_priv.current_admin_password);

	defaultType = buffer + security_area_size;
	*defaultType = deftype;

	ret = call_biosattributes_interface(wmi_priv.bios_attr_wdev, buffer, buffer_size,
					    SETBIOSDEFAULTS_METHOD_ID);
	if (ret)
		dev_err(&wmi_priv.bios_attr_wdev->dev, "reset BIOS defaults failed: %d\n", ret);

	kfree(buffer);
out:
	mutex_unlock(&wmi_priv.mutex);
	return ret;
}

static int bios_attr_set_interface_probe(struct wmi_device *wdev, const void *context)
{
	mutex_lock(&wmi_priv.mutex);
	wmi_priv.bios_attr_wdev = wdev;
	mutex_unlock(&wmi_priv.mutex);
	return 0;
}

static void bios_attr_set_interface_remove(struct wmi_device *wdev)
{
	mutex_lock(&wmi_priv.mutex);
	wmi_priv.bios_attr_wdev = NULL;
	mutex_unlock(&wmi_priv.mutex);
}

static const struct wmi_device_id bios_attr_set_interface_id_table[] = {
	{ .guid_string = DELL_WMI_BIOS_ATTRIBUTES_INTERFACE_GUID },
	{ },
};
static struct wmi_driver bios_attr_set_interface_driver = {
	.driver = {
		.name = DRIVER_NAME
	},
	.probe = bios_attr_set_interface_probe,
	.remove = bios_attr_set_interface_remove,
	.id_table = bios_attr_set_interface_id_table,
};

int init_bios_attr_set_interface(void)
{
	return wmi_driver_register(&bios_attr_set_interface_driver);
}

void exit_bios_attr_set_interface(void)
{
	wmi_driver_unregister(&bios_attr_set_interface_driver);
}

MODULE_DEVICE_TABLE(wmi, bios_attr_set_interface_id_table);
