/*
 * Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors.
 *
 * Copyright (C) 2014, VMware, Inc. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * Twin device code is hugely inspired by the ALPS driver.
 * Authors:
 *   Dmitry Torokhov <dmitry.torokhov@gmail.com>
 *   Thomas Hellstrom <thellstrom@vmware.com>
 */

#include <linux/input.h>
#include <linux/serio.h>
#include <linux/libps2.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <asm/hypervisor.h>

#include "psmouse.h"
#include "vmmouse.h"

#define VMMOUSE_PROTO_MAGIC			0x564D5868U
#define VMMOUSE_PROTO_PORT			0x5658

/*
 * Main commands supported by the vmmouse hypervisor port.
 */
#define VMMOUSE_PROTO_CMD_GETVERSION		10
#define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA	39
#define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS	40
#define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND	41
#define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86

/*
 * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
 */
#define VMMOUSE_CMD_ENABLE			0x45414552U
#define VMMOUSE_CMD_DISABLE			0x000000f5U
#define VMMOUSE_CMD_REQUEST_RELATIVE		0x4c455252U
#define VMMOUSE_CMD_REQUEST_ABSOLUTE		0x53424152U

#define VMMOUSE_ERROR				0xffff0000U

#define VMMOUSE_VERSION_ID			0x3442554aU

#define VMMOUSE_RELATIVE_PACKET			0x00010000U

#define VMMOUSE_LEFT_BUTTON			0x20
#define VMMOUSE_RIGHT_BUTTON			0x10
#define VMMOUSE_MIDDLE_BUTTON			0x08

/*
 * VMMouse Restrict command
 */
#define VMMOUSE_RESTRICT_ANY                    0x00
#define VMMOUSE_RESTRICT_CPL0                   0x01
#define VMMOUSE_RESTRICT_IOPL                   0x02

#define VMMOUSE_MAX_X                           0xFFFF
#define VMMOUSE_MAX_Y                           0xFFFF

#define VMMOUSE_VENDOR "VMware"
#define VMMOUSE_NAME   "VMMouse"

/**
 * struct vmmouse_data - private data structure for the vmmouse driver
 *
 * @abs_dev: "Absolute" device used to report absolute mouse movement.
 * @phys: Physical path for the absolute device.
 * @dev_name: Name attribute name for the absolute device.
 */
struct vmmouse_data {
	struct input_dev *abs_dev;
	char phys[32];
	char dev_name[128];
};

/**
 * Hypervisor-specific bi-directional communication channel
 * implementing the vmmouse protocol. Should never execute on
 * bare metal hardware.
 */
#define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)	\
({							\
	unsigned long __dummy1, __dummy2;		\
	__asm__ __volatile__ ("inl %%dx" :		\
		"=a"(out1),				\
		"=b"(out2),				\
		"=c"(out3),				\
		"=d"(out4),				\
		"=S"(__dummy1),				\
		"=D"(__dummy2) :			\
		"a"(VMMOUSE_PROTO_MAGIC),		\
		"b"(in1),				\
		"c"(VMMOUSE_PROTO_CMD_##cmd),		\
		"d"(VMMOUSE_PROTO_PORT) :		\
		"memory");		                \
})

/**
 * vmmouse_report_button - report button state on the correct input device
 *
 * @psmouse:  Pointer to the psmouse struct
 * @abs_dev:  The absolute input device
 * @rel_dev:  The relative input device
 * @pref_dev: The preferred device for reporting
 * @code:     Button code
 * @value:    Button value
 *
 * Report @value and @code on @pref_dev, unless the button is already
 * pressed on the other device, in which case the state is reported on that
 * device.
 */
static void vmmouse_report_button(struct psmouse *psmouse,
				  struct input_dev *abs_dev,
				  struct input_dev *rel_dev,
				  struct input_dev *pref_dev,
				  unsigned int code, int value)
{
	if (test_bit(code, abs_dev->key))
		pref_dev = abs_dev;
	else if (test_bit(code, rel_dev->key))
		pref_dev = rel_dev;

	input_report_key(pref_dev, code, value);
}

/**
 * vmmouse_report_events - process events on the vmmouse communications channel
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * This function pulls events from the vmmouse communications channel and
 * reports them on the correct (absolute or relative) input device. When the
 * communications channel is drained, or if we've processed more than 255
 * psmouse commands, the function returns PSMOUSE_FULL_PACKET. If there is a
 * host- or synchronization error, the function returns PSMOUSE_BAD_DATA in
 * the hope that the caller will reset the communications channel.
 */
static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse)
{
	struct input_dev *rel_dev = psmouse->dev;
	struct vmmouse_data *priv = psmouse->private;
	struct input_dev *abs_dev = priv->abs_dev;
	struct input_dev *pref_dev;
	u32 status, x, y, z;
	u32 dummy1, dummy2, dummy3;
	unsigned int queue_length;
	unsigned int count = 255;

	while (count--) {
		/* See if we have motion data. */
		VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
			    status, dummy1, dummy2, dummy3);
		if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
			psmouse_err(psmouse, "failed to fetch status data\n");
			/*
			 * After a few attempts this will result in
			 * reconnect.
			 */
			return PSMOUSE_BAD_DATA;
		}

		queue_length = status & 0xffff;
		if (queue_length == 0)
			break;

		if (queue_length % 4) {
			psmouse_err(psmouse, "invalid queue length\n");
			return PSMOUSE_BAD_DATA;
		}

		/* Now get it */
		VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);

		/*
		 * And report what we've got. Prefer to report button
		 * events on the same device where we report motion events.
		 * This doesn't work well with the mouse wheel, though. See
		 * below. Ideally we would want to report that on the
		 * preferred device as well.
		 */
		if (status & VMMOUSE_RELATIVE_PACKET) {
			pref_dev = rel_dev;
			input_report_rel(rel_dev, REL_X, (s32)x);
			input_report_rel(rel_dev, REL_Y, -(s32)y);
		} else {
			pref_dev = abs_dev;
			input_report_abs(abs_dev, ABS_X, x);
			input_report_abs(abs_dev, ABS_Y, y);
		}

		/* Xorg seems to ignore wheel events on absolute devices */
		input_report_rel(rel_dev, REL_WHEEL, -(s8)((u8) z));

		vmmouse_report_button(psmouse, abs_dev, rel_dev,
				      pref_dev, BTN_LEFT,
				      status & VMMOUSE_LEFT_BUTTON);
		vmmouse_report_button(psmouse, abs_dev, rel_dev,
				      pref_dev, BTN_RIGHT,
				      status & VMMOUSE_RIGHT_BUTTON);
		vmmouse_report_button(psmouse, abs_dev, rel_dev,
				      pref_dev, BTN_MIDDLE,
				      status & VMMOUSE_MIDDLE_BUTTON);
		input_sync(abs_dev);
		input_sync(rel_dev);
	}

	return PSMOUSE_FULL_PACKET;
}

/**
 * vmmouse_process_byte - process data on the ps/2 channel
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * When the ps/2 channel indicates that there is vmmouse data available,
 * call vmmouse channel processing. Otherwise, continue to accept bytes. If
 * there is a synchronization or communication data error, return
 * PSMOUSE_BAD_DATA in the hope that the caller will reset the mouse.
 */
static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse)
{
	unsigned char *packet = psmouse->packet;

	switch (psmouse->pktcnt) {
	case 1:
		return (packet[0] & 0x8) == 0x8 ?
			PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;

	case 2:
		return PSMOUSE_GOOD_DATA;

	default:
		return vmmouse_report_events(psmouse);
	}
}

/**
 * vmmouse_disable - Disable vmmouse
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * Tries to disable vmmouse mode.
 */
static void vmmouse_disable(struct psmouse *psmouse)
{
	u32 status;
	u32 dummy1, dummy2, dummy3, dummy4;

	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
		    dummy1, dummy2, dummy3, dummy4);

	VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
		    status, dummy1, dummy2, dummy3);

	if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
		psmouse_warn(psmouse, "failed to disable vmmouse device\n");
}

/**
 * vmmouse_enable - Enable vmmouse and request absolute mode.
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * Tries to enable vmmouse mode. Performs basic checks and requests
 * absolute vmmouse mode.
 * Returns 0 on success, -ENODEV on failure.
 */
static int vmmouse_enable(struct psmouse *psmouse)
{
	u32 status, version;
	u32 dummy1, dummy2, dummy3, dummy4;

	/*
	 * Try enabling the device. If successful, we should be able to
	 * read valid version ID back from it.
	 */
	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
		    dummy1, dummy2, dummy3, dummy4);

	/*
	 * See if version ID can be retrieved.
	 */
	VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3);
	if ((status & 0x0000ffff) == 0) {
		psmouse_dbg(psmouse, "empty flags - assuming no device\n");
		return -ENXIO;
	}

	VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */,
		    version, dummy1, dummy2, dummy3);
	if (version != VMMOUSE_VERSION_ID) {
		psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n",
			    (unsigned) version, VMMOUSE_VERSION_ID);
		vmmouse_disable(psmouse);
		return -ENXIO;
	}

	/*
	 * Restrict ioport access, if possible.
	 */
	VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0,
		    dummy1, dummy2, dummy3, dummy4);

	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE,
		    dummy1, dummy2, dummy3, dummy4);

	return 0;
}

/*
 * Array of supported hypervisors.
 */
static const struct hypervisor_x86 *vmmouse_supported_hypervisors[] = {
	&x86_hyper_vmware,
#ifdef CONFIG_KVM_GUEST
	&x86_hyper_kvm,
#endif
};

/**
 * vmmouse_check_hypervisor - Check if we're running on a supported hypervisor
 */
static bool vmmouse_check_hypervisor(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(vmmouse_supported_hypervisors); i++)
		if (vmmouse_supported_hypervisors[i] == x86_hyper)
			return true;

	return false;
}

/**
 * vmmouse_detect - Probe whether vmmouse is available
 *
 * @psmouse: Pointer to the psmouse struct
 * @set_properties: Whether to set psmouse name and vendor
 *
 * Returns 0 if vmmouse channel is available. Negative error code if not.
 */
int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
{
	u32 response, version, dummy1, dummy2;

	if (!vmmouse_check_hypervisor()) {
		psmouse_dbg(psmouse,
			    "VMMouse not running on supported hypervisor.\n");
		return -ENXIO;
	}

	/* Check if the device is present */
	response = ~VMMOUSE_PROTO_MAGIC;
	VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
		return -ENXIO;

	if (set_properties) {
		psmouse->vendor = VMMOUSE_VENDOR;
		psmouse->name = VMMOUSE_NAME;
		psmouse->model = version;
	}

	return 0;
}

/**
 * vmmouse_disconnect - Take down vmmouse driver
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * Takes down vmmouse driver and frees resources set up in vmmouse_init().
 */
static void vmmouse_disconnect(struct psmouse *psmouse)
{
	struct vmmouse_data *priv = psmouse->private;

	vmmouse_disable(psmouse);
	psmouse_reset(psmouse);
	input_unregister_device(priv->abs_dev);
	kfree(priv);
}

/**
 * vmmouse_reconnect - Reset the ps/2 - and vmmouse connections
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * Attempts to reset the mouse connections. Returns 0 on success and
 * -1 on failure.
 */
static int vmmouse_reconnect(struct psmouse *psmouse)
{
	int error;

	psmouse_reset(psmouse);
	vmmouse_disable(psmouse);
	error = vmmouse_enable(psmouse);
	if (error) {
		psmouse_err(psmouse,
			    "Unable to re-enable mouse when reconnecting, err: %d\n",
			    error);
		return error;
	}

	return 0;
}

/**
 * vmmouse_init - Initialize the vmmouse driver
 *
 * @psmouse: Pointer to the psmouse struct
 *
 * Requests the device and tries to enable vmmouse mode.
 * If successful, sets up the input device for relative movement events.
 * It also allocates another input device and sets it up for absolute motion
 * events. Returns 0 on success and -1 on failure.
 */
int vmmouse_init(struct psmouse *psmouse)
{
	struct vmmouse_data *priv;
	struct input_dev *rel_dev = psmouse->dev, *abs_dev;
	int error;

	psmouse_reset(psmouse);
	error = vmmouse_enable(psmouse);
	if (error)
		return error;

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	abs_dev = input_allocate_device();
	if (!priv || !abs_dev) {
		error = -ENOMEM;
		goto init_fail;
	}

	priv->abs_dev = abs_dev;
	psmouse->private = priv;

	/* Set up and register absolute device */
	snprintf(priv->phys, sizeof(priv->phys), "%s/input1",
		 psmouse->ps2dev.serio->phys);

	/* Mimic name setup for relative device in psmouse-base.c */
	snprintf(priv->dev_name, sizeof(priv->dev_name), "%s %s %s",
		 VMMOUSE_PSNAME, VMMOUSE_VENDOR, VMMOUSE_NAME);
	abs_dev->phys = priv->phys;
	abs_dev->name = priv->dev_name;
	abs_dev->id.bustype = BUS_I8042;
	abs_dev->id.vendor = 0x0002;
	abs_dev->id.product = PSMOUSE_VMMOUSE;
	abs_dev->id.version = psmouse->model;
	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;

	/* Set absolute device capabilities */
	input_set_capability(abs_dev, EV_KEY, BTN_LEFT);
	input_set_capability(abs_dev, EV_KEY, BTN_RIGHT);
	input_set_capability(abs_dev, EV_KEY, BTN_MIDDLE);
	input_set_capability(abs_dev, EV_ABS, ABS_X);
	input_set_capability(abs_dev, EV_ABS, ABS_Y);
	input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0);
	input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0);

	error = input_register_device(priv->abs_dev);
	if (error)
		goto init_fail;

	/* Add wheel capability to the relative device */
	input_set_capability(rel_dev, EV_REL, REL_WHEEL);

	psmouse->protocol_handler = vmmouse_process_byte;
	psmouse->disconnect = vmmouse_disconnect;
	psmouse->reconnect = vmmouse_reconnect;

	return 0;

init_fail:
	vmmouse_disable(psmouse);
	psmouse_reset(psmouse);
	input_free_device(abs_dev);
	kfree(priv);
	psmouse->private = NULL;

	return error;
}
