// SPDX-License-Identifier: GPL-2.0-only
/*
 *  Copyright (c) 2013, Microsoft Corporation.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/completion.h>
#include <linux/hyperv.h>
#include <linux/serio.h>
#include <linux/slab.h>

/*
 * Current version 1.0
 *
 */
#define SYNTH_KBD_VERSION_MAJOR 1
#define SYNTH_KBD_VERSION_MINOR	0
#define SYNTH_KBD_VERSION		(SYNTH_KBD_VERSION_MINOR | \
					 (SYNTH_KBD_VERSION_MAJOR << 16))


/*
 * Message types in the synthetic input protocol
 */
enum synth_kbd_msg_type {
	SYNTH_KBD_PROTOCOL_REQUEST = 1,
	SYNTH_KBD_PROTOCOL_RESPONSE = 2,
	SYNTH_KBD_EVENT = 3,
	SYNTH_KBD_LED_INDICATORS = 4,
};

/*
 * Basic message structures.
 */
struct synth_kbd_msg_hdr {
	__le32 type;
};

struct synth_kbd_msg {
	struct synth_kbd_msg_hdr header;
	char data[]; /* Enclosed message */
};

union synth_kbd_version {
	__le32 version;
};

/*
 * Protocol messages
 */
struct synth_kbd_protocol_request {
	struct synth_kbd_msg_hdr header;
	union synth_kbd_version version_requested;
};

#define PROTOCOL_ACCEPTED	BIT(0)
struct synth_kbd_protocol_response {
	struct synth_kbd_msg_hdr header;
	__le32 proto_status;
};

#define IS_UNICODE	BIT(0)
#define IS_BREAK	BIT(1)
#define IS_E0		BIT(2)
#define IS_E1		BIT(3)
struct synth_kbd_keystroke {
	struct synth_kbd_msg_hdr header;
	__le16 make_code;
	__le16 reserved0;
	__le32 info; /* Additional information */
};


#define HK_MAXIMUM_MESSAGE_SIZE 256

#define KBD_VSC_SEND_RING_BUFFER_SIZE	VMBUS_RING_SIZE(36 * 1024)
#define KBD_VSC_RECV_RING_BUFFER_SIZE	VMBUS_RING_SIZE(36 * 1024)

#define XTKBD_EMUL0     0xe0
#define XTKBD_EMUL1     0xe1
#define XTKBD_RELEASE   0x80


/*
 * Represents a keyboard device
 */
struct hv_kbd_dev {
	struct hv_device *hv_dev;
	struct serio *hv_serio;
	struct synth_kbd_protocol_request protocol_req;
	struct synth_kbd_protocol_response protocol_resp;
	/* Synchronize the request/response if needed */
	struct completion wait_event;
	spinlock_t lock; /* protects 'started' field */
	bool started;
};

static void hv_kbd_on_receive(struct hv_device *hv_dev,
			      struct synth_kbd_msg *msg, u32 msg_length)
{
	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
	struct synth_kbd_keystroke *ks_msg;
	u32 msg_type = __le32_to_cpu(msg->header.type);
	u32 info;
	u16 scan_code;

	switch (msg_type) {
	case SYNTH_KBD_PROTOCOL_RESPONSE:
		/*
		 * Validate the information provided by the host.
		 * If the host is giving us a bogus packet,
		 * drop the packet (hoping the problem
		 * goes away).
		 */
		if (msg_length < sizeof(struct synth_kbd_protocol_response)) {
			dev_err(&hv_dev->device,
				"Illegal protocol response packet (len: %d)\n",
				msg_length);
			break;
		}

		memcpy(&kbd_dev->protocol_resp, msg,
			sizeof(struct synth_kbd_protocol_response));
		complete(&kbd_dev->wait_event);
		break;

	case SYNTH_KBD_EVENT:
		/*
		 * Validate the information provided by the host.
		 * If the host is giving us a bogus packet,
		 * drop the packet (hoping the problem
		 * goes away).
		 */
		if (msg_length < sizeof(struct  synth_kbd_keystroke)) {
			dev_err(&hv_dev->device,
				"Illegal keyboard event packet (len: %d)\n",
				msg_length);
			break;
		}

		ks_msg = (struct synth_kbd_keystroke *)msg;
		info = __le32_to_cpu(ks_msg->info);

		/*
		 * Inject the information through the serio interrupt.
		 */
		scoped_guard(spinlock_irqsave, &kbd_dev->lock) {
			if (kbd_dev->started) {
				if (info & IS_E0)
					serio_interrupt(kbd_dev->hv_serio,
							XTKBD_EMUL0, 0);
				if (info & IS_E1)
					serio_interrupt(kbd_dev->hv_serio,
							XTKBD_EMUL1, 0);
				scan_code = __le16_to_cpu(ks_msg->make_code);
				if (info & IS_BREAK)
					scan_code |= XTKBD_RELEASE;

				serio_interrupt(kbd_dev->hv_serio,
						scan_code, 0);
			}
		}

		/*
		 * Only trigger a wakeup on key down, otherwise
		 * "echo freeze > /sys/power/state" can't really enter the
		 * state because the Enter-UP can trigger a wakeup at once.
		 */
		if (!(info & IS_BREAK))
			pm_wakeup_hard_event(&hv_dev->device);

		break;

	default:
		dev_err(&hv_dev->device,
			"unhandled message type %d\n", msg_type);
	}
}

static void hv_kbd_handle_received_packet(struct hv_device *hv_dev,
					  struct vmpacket_descriptor *desc,
					  u32 bytes_recvd,
					  u64 req_id)
{
	struct synth_kbd_msg *msg;
	u32 msg_sz;

	switch (desc->type) {
	case VM_PKT_COMP:
		break;

	case VM_PKT_DATA_INBAND:
		/*
		 * We have a packet that has "inband" data. The API used
		 * for retrieving the packet guarantees that the complete
		 * packet is read. So, minimally, we should be able to
		 * parse the payload header safely (assuming that the host
		 * can be trusted.  Trusting the host seems to be a
		 * reasonable assumption because in a virtualized
		 * environment there is not whole lot you can do if you
		 * don't trust the host.
		 *
		 * Nonetheless, let us validate if the host can be trusted
		 * (in a trivial way).  The interesting aspect of this
		 * validation is how do you recover if we discover that the
		 * host is not to be trusted? Simply dropping the packet, I
		 * don't think is an appropriate recovery.  In the interest
		 * of failing fast, it may be better to crash the guest.
		 * For now, I will just drop the packet!
		 */

		msg_sz = bytes_recvd - (desc->offset8 << 3);
		if (msg_sz <= sizeof(struct synth_kbd_msg_hdr)) {
			/*
			 * Drop the packet and hope
			 * the problem magically goes away.
			 */
			dev_err(&hv_dev->device,
				"Illegal packet (type: %d, tid: %llx, size: %d)\n",
				desc->type, req_id, msg_sz);
			break;
		}

		msg = (void *)desc + (desc->offset8 << 3);
		hv_kbd_on_receive(hv_dev, msg, msg_sz);
		break;

	default:
		dev_err(&hv_dev->device,
			"unhandled packet type %d, tid %llx len %d\n",
			desc->type, req_id, bytes_recvd);
		break;
	}
}

static void hv_kbd_on_channel_callback(void *context)
{
	struct vmpacket_descriptor *desc;
	struct hv_device *hv_dev = context;
	u32 bytes_recvd;
	u64 req_id;

	foreach_vmbus_pkt(desc, hv_dev->channel) {
		bytes_recvd = desc->len8 * 8;
		req_id = desc->trans_id;

		hv_kbd_handle_received_packet(hv_dev, desc, bytes_recvd,
					      req_id);
	}
}

static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev)
{
	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);
	struct synth_kbd_protocol_request *request;
	struct synth_kbd_protocol_response *response;
	u32 proto_status;
	int error;

	reinit_completion(&kbd_dev->wait_event);

	request = &kbd_dev->protocol_req;
	memset(request, 0, sizeof(struct synth_kbd_protocol_request));
	request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST);
	request->version_requested.version = __cpu_to_le32(SYNTH_KBD_VERSION);

	error = vmbus_sendpacket(hv_dev->channel, request,
				 sizeof(struct synth_kbd_protocol_request),
				 (unsigned long)request,
				 VM_PKT_DATA_INBAND,
				 VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
	if (error)
		return error;

	if (!wait_for_completion_timeout(&kbd_dev->wait_event, 10 * HZ))
		return -ETIMEDOUT;

	response = &kbd_dev->protocol_resp;
	proto_status = __le32_to_cpu(response->proto_status);
	if (!(proto_status & PROTOCOL_ACCEPTED)) {
		dev_err(&hv_dev->device,
			"synth_kbd protocol request failed (version %d)\n",
		        SYNTH_KBD_VERSION);
		return -ENODEV;
	}

	return 0;
}

static int hv_kbd_start(struct serio *serio)
{
	struct hv_kbd_dev *kbd_dev = serio->port_data;

	guard(spinlock_irqsave)(&kbd_dev->lock);

	kbd_dev->started = true;

	return 0;
}

static void hv_kbd_stop(struct serio *serio)
{
	struct hv_kbd_dev *kbd_dev = serio->port_data;

	guard(spinlock_irqsave)(&kbd_dev->lock);

	kbd_dev->started = false;
}

static int hv_kbd_probe(struct hv_device *hv_dev,
			const struct hv_vmbus_device_id *dev_id)
{
	struct hv_kbd_dev *kbd_dev;
	struct serio *hv_serio;
	int error;

	kbd_dev = kzalloc(sizeof(*kbd_dev), GFP_KERNEL);
	hv_serio = kzalloc(sizeof(*hv_serio), GFP_KERNEL);
	if (!kbd_dev || !hv_serio) {
		error = -ENOMEM;
		goto err_free_mem;
	}

	kbd_dev->hv_dev = hv_dev;
	kbd_dev->hv_serio = hv_serio;
	spin_lock_init(&kbd_dev->lock);
	init_completion(&kbd_dev->wait_event);
	hv_set_drvdata(hv_dev, kbd_dev);

	hv_serio->dev.parent  = &hv_dev->device;
	hv_serio->id.type = SERIO_8042_XL;
	hv_serio->port_data = kbd_dev;
	strscpy(hv_serio->name, dev_name(&hv_dev->device),
		sizeof(hv_serio->name));
	strscpy(hv_serio->phys, dev_name(&hv_dev->device),
		sizeof(hv_serio->phys));

	hv_serio->start = hv_kbd_start;
	hv_serio->stop = hv_kbd_stop;

	error = vmbus_open(hv_dev->channel,
			   KBD_VSC_SEND_RING_BUFFER_SIZE,
			   KBD_VSC_RECV_RING_BUFFER_SIZE,
			   NULL, 0,
			   hv_kbd_on_channel_callback,
			   hv_dev);
	if (error)
		goto err_free_mem;

	error = hv_kbd_connect_to_vsp(hv_dev);
	if (error)
		goto err_close_vmbus;

	serio_register_port(kbd_dev->hv_serio);

	device_init_wakeup(&hv_dev->device, true);

	return 0;

err_close_vmbus:
	vmbus_close(hv_dev->channel);
err_free_mem:
	kfree(hv_serio);
	kfree(kbd_dev);
	return error;
}

static void hv_kbd_remove(struct hv_device *hv_dev)
{
	struct hv_kbd_dev *kbd_dev = hv_get_drvdata(hv_dev);

	serio_unregister_port(kbd_dev->hv_serio);
	vmbus_close(hv_dev->channel);
	kfree(kbd_dev);

	hv_set_drvdata(hv_dev, NULL);
}

static int hv_kbd_suspend(struct hv_device *hv_dev)
{
	vmbus_close(hv_dev->channel);

	return 0;
}

static int hv_kbd_resume(struct hv_device *hv_dev)
{
	int ret;

	ret = vmbus_open(hv_dev->channel,
			 KBD_VSC_SEND_RING_BUFFER_SIZE,
			 KBD_VSC_RECV_RING_BUFFER_SIZE,
			 NULL, 0,
			 hv_kbd_on_channel_callback,
			 hv_dev);
	if (ret == 0)
		ret = hv_kbd_connect_to_vsp(hv_dev);

	return ret;
}

static const struct hv_vmbus_device_id id_table[] = {
	/* Keyboard guid */
	{ HV_KBD_GUID, },
	{ },
};

MODULE_DEVICE_TABLE(vmbus, id_table);

static struct  hv_driver hv_kbd_drv = {
	.name = KBUILD_MODNAME,
	.id_table = id_table,
	.probe = hv_kbd_probe,
	.remove = hv_kbd_remove,
	.suspend = hv_kbd_suspend,
	.resume = hv_kbd_resume,
	.driver = {
		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
	},
};

static int __init hv_kbd_init(void)
{
	return vmbus_driver_register(&hv_kbd_drv);
}

static void __exit hv_kbd_exit(void)
{
	vmbus_driver_unregister(&hv_kbd_drv);
}

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Microsoft Hyper-V Synthetic Keyboard Driver");

module_init(hv_kbd_init);
module_exit(hv_kbd_exit);
