Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright (C) 2014, VMware, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Twin device code is hugely inspired by the ALPS driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *   Dmitry Torokhov <dmitry.torokhov@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *   Thomas Hellstrom <thellstrom@vmware.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/serio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/libps2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/hypervisor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/vmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "psmouse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include "vmmouse.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define VMMOUSE_PROTO_MAGIC			0x564D5868U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * Main commands supported by the vmmouse hypervisor port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define VMMOUSE_PROTO_CMD_GETVERSION		10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA	39
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS	40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND	41
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT   86
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define VMMOUSE_CMD_ENABLE			0x45414552U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #define VMMOUSE_CMD_DISABLE			0x000000f5U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define VMMOUSE_CMD_REQUEST_RELATIVE		0x4c455252U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define VMMOUSE_CMD_REQUEST_ABSOLUTE		0x53424152U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define VMMOUSE_ERROR				0xffff0000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define VMMOUSE_VERSION_ID			0x3442554aU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define VMMOUSE_RELATIVE_PACKET			0x00010000U
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define VMMOUSE_LEFT_BUTTON			0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define VMMOUSE_RIGHT_BUTTON			0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define VMMOUSE_MIDDLE_BUTTON			0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * VMMouse Restrict command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) #define VMMOUSE_RESTRICT_ANY                    0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define VMMOUSE_RESTRICT_CPL0                   0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define VMMOUSE_RESTRICT_IOPL                   0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define VMMOUSE_MAX_X                           0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) #define VMMOUSE_MAX_Y                           0xFFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) #define VMMOUSE_VENDOR "VMware"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define VMMOUSE_NAME   "VMMouse"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * struct vmmouse_data - private data structure for the vmmouse driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * @abs_dev: "Absolute" device used to report absolute mouse movement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * @phys: Physical path for the absolute device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * @dev_name: Name attribute name for the absolute device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) struct vmmouse_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct input_dev *abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	char phys[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	char dev_name[128];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  * Hypervisor-specific bi-directional communication channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * implementing the vmmouse protocol. Should never execute on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * bare metal hardware.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) ({							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	unsigned long __dummy1, __dummy2;		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	__asm__ __volatile__ (VMWARE_HYPERCALL :	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		"=a"(out1),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		"=b"(out2),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		"=c"(out3),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		"=d"(out4),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		"=S"(__dummy1),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		"=D"(__dummy2) :			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		"a"(VMMOUSE_PROTO_MAGIC),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		"b"(in1),				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		"c"(VMMOUSE_PROTO_CMD_##cmd),		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		"d"(0) :			        \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		"memory");		                \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * vmmouse_report_button - report button state on the correct input device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * @psmouse:  Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * @abs_dev:  The absolute input device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  * @rel_dev:  The relative input device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  * @pref_dev: The preferred device for reporting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * @code:     Button code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * @value:    Button value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  * Report @value and @code on @pref_dev, unless the button is already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)  * pressed on the other device, in which case the state is reported on that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void vmmouse_report_button(struct psmouse *psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 				  struct input_dev *abs_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 				  struct input_dev *rel_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 				  struct input_dev *pref_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				  unsigned int code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	if (test_bit(code, abs_dev->key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		pref_dev = abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	else if (test_bit(code, rel_dev->key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		pref_dev = rel_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	input_report_key(pref_dev, code, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)  * vmmouse_report_events - process events on the vmmouse communications channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)  * This function pulls events from the vmmouse communications channel and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)  * reports them on the correct (absolute or relative) input device. When the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)  * communications channel is drained, or if we've processed more than 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * psmouse commands, the function returns PSMOUSE_FULL_PACKET. If there is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * host- or synchronization error, the function returns PSMOUSE_BAD_DATA in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * the hope that the caller will reset the communications channel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static psmouse_ret_t vmmouse_report_events(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct input_dev *rel_dev = psmouse->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	struct vmmouse_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct input_dev *abs_dev = priv->abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct input_dev *pref_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	u32 status, x, y, z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	u32 dummy1, dummy2, dummy3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	unsigned int queue_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	unsigned int count = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	while (count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		/* See if we have motion data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 		VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			    status, dummy1, dummy2, dummy3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		if ((status & VMMOUSE_ERROR) == VMMOUSE_ERROR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			psmouse_err(psmouse, "failed to fetch status data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			 * After a few attempts this will result in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			 * reconnect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		queue_length = status & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		if (queue_length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 		if (queue_length % 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 			psmouse_err(psmouse, "invalid queue length\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			return PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		/* Now get it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 		VMMOUSE_CMD(ABSPOINTER_DATA, 4, status, x, y, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		 * And report what we've got. Prefer to report button
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		 * events on the same device where we report motion events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		 * This doesn't work well with the mouse wheel, though. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		 * below. Ideally we would want to report that on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		 * preferred device as well.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		if (status & VMMOUSE_RELATIVE_PACKET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 			pref_dev = rel_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 			input_report_rel(rel_dev, REL_X, (s32)x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 			input_report_rel(rel_dev, REL_Y, -(s32)y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			pref_dev = abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 			input_report_abs(abs_dev, ABS_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			input_report_abs(abs_dev, ABS_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		/* Xorg seems to ignore wheel events on absolute devices */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 		input_report_rel(rel_dev, REL_WHEEL, -(s8)((u8) z));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		vmmouse_report_button(psmouse, abs_dev, rel_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 				      pref_dev, BTN_LEFT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 				      status & VMMOUSE_LEFT_BUTTON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		vmmouse_report_button(psmouse, abs_dev, rel_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 				      pref_dev, BTN_RIGHT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 				      status & VMMOUSE_RIGHT_BUTTON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		vmmouse_report_button(psmouse, abs_dev, rel_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 				      pref_dev, BTN_MIDDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 				      status & VMMOUSE_MIDDLE_BUTTON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		input_sync(abs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		input_sync(rel_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	return PSMOUSE_FULL_PACKET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)  * vmmouse_process_byte - process data on the ps/2 channel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)  * When the ps/2 channel indicates that there is vmmouse data available,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)  * call vmmouse channel processing. Otherwise, continue to accept bytes. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)  * there is a synchronization or communication data error, return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)  * PSMOUSE_BAD_DATA in the hope that the caller will reset the mouse.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static psmouse_ret_t vmmouse_process_byte(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	unsigned char *packet = psmouse->packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	switch (psmouse->pktcnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		return (packet[0] & 0x8) == 0x8 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 			PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return PSMOUSE_GOOD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		return vmmouse_report_events(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  * vmmouse_disable - Disable vmmouse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)  * Tries to disable vmmouse mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static void vmmouse_disable(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	u32 dummy1, dummy2, dummy3, dummy4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_DISABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		    dummy1, dummy2, dummy3, dummy4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	VMMOUSE_CMD(ABSPOINTER_STATUS, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		    status, dummy1, dummy2, dummy3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if ((status & VMMOUSE_ERROR) != VMMOUSE_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		psmouse_warn(psmouse, "failed to disable vmmouse device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)  * vmmouse_enable - Enable vmmouse and request absolute mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)  * Tries to enable vmmouse mode. Performs basic checks and requests
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)  * absolute vmmouse mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)  * Returns 0 on success, -ENODEV on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int vmmouse_enable(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	u32 status, version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	u32 dummy1, dummy2, dummy3, dummy4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	 * Try enabling the device. If successful, we should be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	 * read valid version ID back from it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		    dummy1, dummy2, dummy3, dummy4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	 * See if version ID can be retrieved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	VMMOUSE_CMD(ABSPOINTER_STATUS, 0, status, dummy1, dummy2, dummy3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if ((status & 0x0000ffff) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		psmouse_dbg(psmouse, "empty flags - assuming no device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	VMMOUSE_CMD(ABSPOINTER_DATA, 1 /* single item */,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		    version, dummy1, dummy2, dummy3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	if (version != VMMOUSE_VERSION_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		psmouse_dbg(psmouse, "Unexpected version value: %u vs %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 			    (unsigned) version, VMMOUSE_VERSION_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		vmmouse_disable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	 * Restrict ioport access, if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	VMMOUSE_CMD(ABSPOINTER_RESTRICT, VMMOUSE_RESTRICT_CPL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		    dummy1, dummy2, dummy3, dummy4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	VMMOUSE_CMD(ABSPOINTER_COMMAND, VMMOUSE_CMD_REQUEST_ABSOLUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		    dummy1, dummy2, dummy3, dummy4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)  * Array of supported hypervisors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static enum x86_hypervisor_type vmmouse_supported_hypervisors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	X86_HYPER_VMWARE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	X86_HYPER_KVM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)  * vmmouse_check_hypervisor - Check if we're running on a supported hypervisor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) static bool vmmouse_check_hypervisor(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	for (i = 0; i < ARRAY_SIZE(vmmouse_supported_hypervisors); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 		if (vmmouse_supported_hypervisors[i] == x86_hyper_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)  * vmmouse_detect - Probe whether vmmouse is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)  * @set_properties: Whether to set psmouse name and vendor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)  * Returns 0 if vmmouse channel is available. Negative error code if not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	u32 response, version, dummy1, dummy2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (!vmmouse_check_hypervisor()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		psmouse_dbg(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			    "VMMouse not running on supported hypervisor.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	/* Check if the device is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	response = ~VMMOUSE_PROTO_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	if (set_properties) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 		psmouse->vendor = VMMOUSE_VENDOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		psmouse->name = VMMOUSE_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		psmouse->model = version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)  * vmmouse_disconnect - Take down vmmouse driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)  * Takes down vmmouse driver and frees resources set up in vmmouse_init().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static void vmmouse_disconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	struct vmmouse_data *priv = psmouse->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	vmmouse_disable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	input_unregister_device(priv->abs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)  * vmmouse_reconnect - Reset the ps/2 - and vmmouse connections
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * Attempts to reset the mouse connections. Returns 0 on success and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * -1 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) static int vmmouse_reconnect(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 	vmmouse_disable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	error = vmmouse_enable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		psmouse_err(psmouse,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 			    "Unable to re-enable mouse when reconnecting, err: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			    error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)  * vmmouse_init - Initialize the vmmouse driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)  * @psmouse: Pointer to the psmouse struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)  * Requests the device and tries to enable vmmouse mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)  * If successful, sets up the input device for relative movement events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * It also allocates another input device and sets it up for absolute motion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  * events. Returns 0 on success and -1 on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int vmmouse_init(struct psmouse *psmouse)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	struct vmmouse_data *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	struct input_dev *rel_dev = psmouse->dev, *abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	error = vmmouse_enable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	abs_dev = input_allocate_device();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	if (!priv || !abs_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	priv->abs_dev = abs_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	psmouse->private = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	/* Set up and register absolute device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		 psmouse->ps2dev.serio->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	/* Mimic name setup for relative device in psmouse-base.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	snprintf(priv->dev_name, sizeof(priv->dev_name), "%s %s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 		 VMMOUSE_PSNAME, VMMOUSE_VENDOR, VMMOUSE_NAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	abs_dev->phys = priv->phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	abs_dev->name = priv->dev_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	abs_dev->id.bustype = BUS_I8042;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	abs_dev->id.vendor = 0x0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	abs_dev->id.product = PSMOUSE_VMMOUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	abs_dev->id.version = psmouse->model;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	/* Set absolute device capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	input_set_capability(abs_dev, EV_KEY, BTN_LEFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	input_set_capability(abs_dev, EV_KEY, BTN_RIGHT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	input_set_capability(abs_dev, EV_KEY, BTN_MIDDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	input_set_capability(abs_dev, EV_ABS, ABS_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	input_set_capability(abs_dev, EV_ABS, ABS_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	error = input_register_device(priv->abs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		goto init_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	/* Add wheel capability to the relative device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	input_set_capability(rel_dev, EV_REL, REL_WHEEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	psmouse->protocol_handler = vmmouse_process_byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	psmouse->disconnect = vmmouse_disconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	psmouse->reconnect = vmmouse_reconnect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) init_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	vmmouse_disable(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	psmouse_reset(psmouse);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	input_free_device(abs_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	kfree(priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	psmouse->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }