// SPDX-License-Identifier: GPL-2.0-only
/*
 *  WMI methods for use with dell-smbios
 *
 *  Copyright (c) 2017 Dell Inc.
 */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/dmi.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/uaccess.h>
#include <linux/wmi.h>
#include "dell-smbios.h"
#include "dell-wmi-descriptor.h"

static DEFINE_MUTEX(call_mutex);
static DEFINE_MUTEX(list_mutex);
static int wmi_supported;

struct misc_bios_flags_structure {
	struct dmi_header header;
	u16 flags0;
} __packed;
#define FLAG_HAS_ACPI_WMI 0x02

#define DELL_WMI_SMBIOS_GUID "A80593CE-A997-11DA-B012-B622A1EF5492"

struct wmi_smbios_priv {
	struct dell_wmi_smbios_buffer *buf;
	struct list_head list;
	struct wmi_device *wdev;
	struct device *child;
	u32 req_buf_size;
};
static LIST_HEAD(wmi_list);

static inline struct wmi_smbios_priv *get_first_smbios_priv(void)
{
	return list_first_entry_or_null(&wmi_list,
					struct wmi_smbios_priv,
					list);
}

static int run_smbios_call(struct wmi_device *wdev)
{
	struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
	struct wmi_smbios_priv *priv;
	struct acpi_buffer input;
	union acpi_object *obj;
	acpi_status status;

	priv = dev_get_drvdata(&wdev->dev);
	input.length = priv->req_buf_size - sizeof(u64);
	input.pointer = &priv->buf->std;

	dev_dbg(&wdev->dev, "evaluating: %u/%u [%x,%x,%x,%x]\n",
		priv->buf->std.cmd_class, priv->buf->std.cmd_select,
		priv->buf->std.input[0], priv->buf->std.input[1],
		priv->buf->std.input[2], priv->buf->std.input[3]);

	status = wmidev_evaluate_method(wdev, 0, 1, &input, &output);
	if (ACPI_FAILURE(status))
		return -EIO;
	obj = (union acpi_object *)output.pointer;
	if (obj->type != ACPI_TYPE_BUFFER) {
		dev_dbg(&wdev->dev, "received type: %d\n", obj->type);
		if (obj->type == ACPI_TYPE_INTEGER)
			dev_dbg(&wdev->dev, "SMBIOS call failed: %llu\n",
				obj->integer.value);
		return -EIO;
	}
	memcpy(&priv->buf->std, obj->buffer.pointer, obj->buffer.length);
	dev_dbg(&wdev->dev, "result: [%08x,%08x,%08x,%08x]\n",
		priv->buf->std.output[0], priv->buf->std.output[1],
		priv->buf->std.output[2], priv->buf->std.output[3]);
	kfree(output.pointer);

	return 0;
}

static int dell_smbios_wmi_call(struct calling_interface_buffer *buffer)
{
	struct wmi_smbios_priv *priv;
	size_t difference;
	size_t size;
	int ret;

	mutex_lock(&call_mutex);
	priv = get_first_smbios_priv();
	if (!priv) {
		ret = -ENODEV;
		goto out_wmi_call;
	}

	size = sizeof(struct calling_interface_buffer);
	difference = priv->req_buf_size - sizeof(u64) - size;

	memset(&priv->buf->ext, 0, difference);
	memcpy(&priv->buf->std, buffer, size);
	ret = run_smbios_call(priv->wdev);
	memcpy(buffer, &priv->buf->std, size);
out_wmi_call:
	mutex_unlock(&call_mutex);

	return ret;
}

static long dell_smbios_wmi_filter(struct wmi_device *wdev, unsigned int cmd,
				   struct wmi_ioctl_buffer *arg)
{
	struct wmi_smbios_priv *priv;
	int ret = 0;

	switch (cmd) {
	case DELL_WMI_SMBIOS_CMD:
		mutex_lock(&call_mutex);
		priv = dev_get_drvdata(&wdev->dev);
		if (!priv) {
			ret = -ENODEV;
			goto fail_smbios_cmd;
		}
		memcpy(priv->buf, arg, priv->req_buf_size);
		if (dell_smbios_call_filter(&wdev->dev, &priv->buf->std)) {
			dev_err(&wdev->dev, "Invalid call %d/%d:%8x\n",
				priv->buf->std.cmd_class,
				priv->buf->std.cmd_select,
				priv->buf->std.input[0]);
			ret = -EFAULT;
			goto fail_smbios_cmd;
		}
		ret = run_smbios_call(priv->wdev);
		if (ret)
			goto fail_smbios_cmd;
		memcpy(arg, priv->buf, priv->req_buf_size);
fail_smbios_cmd:
		mutex_unlock(&call_mutex);
		break;
	default:
		ret = -ENOIOCTLCMD;
	}
	return ret;
}

static int dell_smbios_wmi_probe(struct wmi_device *wdev, const void *context)
{
	struct wmi_driver *wdriver =
		container_of(wdev->dev.driver, struct wmi_driver, driver);
	struct wmi_smbios_priv *priv;
	u32 hotfix;
	int count;
	int ret;

	ret = dell_wmi_get_descriptor_valid();
	if (ret)
		return ret;

	priv = devm_kzalloc(&wdev->dev, sizeof(struct wmi_smbios_priv),
			    GFP_KERNEL);
	if (!priv)
		return -ENOMEM;

	/* WMI buffer size will be either 4k or 32k depending on machine */
	if (!dell_wmi_get_size(&priv->req_buf_size))
		return -EPROBE_DEFER;

	/* some SMBIOS calls fail unless BIOS contains hotfix */
	if (!dell_wmi_get_hotfix(&hotfix))
		return -EPROBE_DEFER;
	if (!hotfix) {
		dev_warn(&wdev->dev,
			"WMI SMBIOS userspace interface not supported(%u), try upgrading to a newer BIOS\n",
			hotfix);
		wdriver->filter_callback = NULL;
	}

	/* add in the length object we will use internally with ioctl */
	priv->req_buf_size += sizeof(u64);
	ret = set_required_buffer_size(wdev, priv->req_buf_size);
	if (ret)
		return ret;

	count = get_order(priv->req_buf_size);
	priv->buf = (void *)__get_free_pages(GFP_KERNEL, count);
	if (!priv->buf)
		return -ENOMEM;

	/* ID is used by dell-smbios to set priority of drivers */
	wdev->dev.id = 1;
	ret = dell_smbios_register_device(&wdev->dev, &dell_smbios_wmi_call);
	if (ret)
		goto fail_register;

	priv->wdev = wdev;
	dev_set_drvdata(&wdev->dev, priv);
	mutex_lock(&list_mutex);
	list_add_tail(&priv->list, &wmi_list);
	mutex_unlock(&list_mutex);

	return 0;

fail_register:
	free_pages((unsigned long)priv->buf, count);
	return ret;
}

static void dell_smbios_wmi_remove(struct wmi_device *wdev)
{
	struct wmi_smbios_priv *priv = dev_get_drvdata(&wdev->dev);
	int count;

	mutex_lock(&call_mutex);
	mutex_lock(&list_mutex);
	list_del(&priv->list);
	mutex_unlock(&list_mutex);
	dell_smbios_unregister_device(&wdev->dev);
	count = get_order(priv->req_buf_size);
	free_pages((unsigned long)priv->buf, count);
	mutex_unlock(&call_mutex);
}

static const struct wmi_device_id dell_smbios_wmi_id_table[] = {
	{ .guid_string = DELL_WMI_SMBIOS_GUID },
	{ },
};

static void parse_b1_table(const struct dmi_header *dm)
{
	struct misc_bios_flags_structure *flags =
	container_of(dm, struct misc_bios_flags_structure, header);

	/* 4 bytes header, 8 bytes flags */
	if (dm->length < 12)
		return;
	if (dm->handle != 0xb100)
		return;
	if ((flags->flags0 & FLAG_HAS_ACPI_WMI))
		wmi_supported = 1;
}

static void find_b1(const struct dmi_header *dm, void *dummy)
{
	switch (dm->type) {
	case 0xb1: /* misc bios flags */
		parse_b1_table(dm);
		break;
	}
}

static struct wmi_driver dell_smbios_wmi_driver = {
	.driver = {
		.name = "dell-smbios",
	},
	.probe = dell_smbios_wmi_probe,
	.remove = dell_smbios_wmi_remove,
	.id_table = dell_smbios_wmi_id_table,
	.filter_callback = dell_smbios_wmi_filter,
};

int init_dell_smbios_wmi(void)
{
	dmi_walk(find_b1, NULL);

	if (!wmi_supported)
		return -ENODEV;

	return wmi_driver_register(&dell_smbios_wmi_driver);
}

void exit_dell_smbios_wmi(void)
{
	wmi_driver_unregister(&dell_smbios_wmi_driver);
}

MODULE_DEVICE_TABLE(wmi, dell_smbios_wmi_id_table);
