Skip to contentSkip to conversation

Input: VMMouse driver

PATCH In review Thomas Hellstrom 2 participants 7 messages Apr 13, 2015 – May 18, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover Input: VMMouse driver

Hi!
The first patch adds a VMMouse protocol extension to the VMMouse driver. The second patch stops the Joydev driver from recognizing the VMMouse as a Joystick. There might perhaps be better ways of doing this, I'm open to suggestions.

Thanks,
Thomas Hellström

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#1 lore raw

PATCH 1/2 Input: Implement vmmouse driver v6

VMMouse enables low-latency mouse-cursor-movements for VMWare guests. By removing the guest cursor and using the host as a guest cursor the cursor movement appears instant although in reality there is some lag. To be able to do this, the host's view of the cursor position must exactly match the guest's view and an absolute pointer device is needed. Enter the VMMouse. While the VMMouse driver has historically been an Xorg user-space driver, implementing it as a kernel imput driver enables rootless Xorg and new compositing display servers for VMware guests.

v1: Initial version by Dmitry Torokhov
v2: Add an extra input device for relative events, integer sign fixes, some integer size changes. Code commenting. Minor cleanups.
v3: Revert some integer size changes. Make the extra device handle absolute events and the original device relative. Minor cleanups and typo fixes.
v4: Make vmmouse_report_button() more readable. Hardcode VMMOUSE_CMD input register constraints. Update Kconfig help. Don't report wheel capability on absolute device. Fix comment typos.
v5: Ditched.
v6: Add support for the vmmouse port access restriction command. Make sure ioport region request is done both in detect() and init(). Update commit message. Update MAINTAINERS file. Fix stub function declarations.

---
 MAINTAINERS                        |   8 +
 drivers/input/mouse/Kconfig        |  12 +
 drivers/input/mouse/Makefile       |   1 +
 drivers/input/mouse/psmouse-base.c |  17 ++
 drivers/input/mouse/psmouse.h      |   1 +
 drivers/input/mouse/vmmouse.c      | 499 +++++++++++++++++++++++++++++++++++++
 drivers/input/mouse/vmmouse.h      |  30 +++
 7 files changed, 568 insertions(+)
 create mode 100644 drivers/input/mouse/vmmouse.c
 create mode 100644 drivers/input/mouse/vmmouse.h
MAINTAINERS +8 -0
index 36cf100..14f374a 100644
@@ -10524,6 +10524,14 @@ L:	[email protected]
 S:	Maintained
 F:	drivers/misc/vmw_balloon.c
 
+VMWARE VMMOUSE SUBDRIVER
+M:	"VMware Graphics" <[email protected]>
+M:	"VMware, Inc." <[email protected]>
+L:	[email protected]
+S:	Maintained
+F:	drivers/input/mouse/vmmouse.c
+F:	drivers/input/mouse/vmmouse.h
+
 VMWARE VMXNET3 ETHERNET DRIVER
 M:	Shreyas Bhatewara <[email protected]>
 M:	"VMware, Inc." <[email protected]>
drivers/input/mouse/Kconfig +12 -0
index 4658b5d..7462d2f 100644
@@ -149,6 +149,18 @@ config MOUSE_PS2_FOCALTECH
 
 	  If unsure, say Y.
 
+config MOUSE_PS2_VMMOUSE
+	bool "Virtual mouse (vmmouse)"
+	depends on MOUSE_PS2 && X86 && HYPERVISOR_GUEST
+	help
+	  Say Y here if you are running under control of VMware hypervisor
+	  (ESXi, Workstation or Fusion). Also make sure that when you enable
+	  this option, you remove the xf86-input-vmmouse user-space driver
+	  or upgrade it to at least xf86-input-vmmouse 13.0.1, which doesn't
+	  load in the presence of an in-kernel vmmouse driver.
+
+	  If unsure, say N.
+
 config MOUSE_SERIAL
 	tristate "Serial mouse"
 	select SERIO
drivers/input/mouse/Makefile +1 -0
index 8a9c98e..793300b 100644
@@ -36,6 +36,7 @@ psmouse-$(CONFIG_MOUSE_PS2_SENTELIC)	+= sentelic.o
 psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT)	+= trackpoint.o
 psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT)	+= touchkit_ps2.o
 psmouse-$(CONFIG_MOUSE_PS2_CYPRESS)	+= cypress_ps2.o
+psmouse-$(CONFIG_MOUSE_PS2_VMMOUSE)	+= vmmouse.o
 
 elan_i2c-objs := elan_i2c_core.o
 elan_i2c-$(CONFIG_MOUSE_ELAN_I2C_I2C)	+= elan_i2c_i2c.o
drivers/input/mouse/psmouse-base.c +17 -0
index 8bc6123..a279744 100644
@@ -36,6 +36,7 @@
 #include "sentelic.h"
 #include "cypress_ps2.h"
 #include "focaltech.h"
+#include "vmmouse.h"
 
 #define DRIVER_DESC	"PS/2 mouse driver"
 
@@ -764,6 +765,13 @@ static int psmouse_extensions(struct psmouse *psmouse,
 		}
 	}
 
+	if (psmouse_do_detect(vmmouse_detect, psmouse, set_properties) == 0) {
+		if (max_proto > PSMOUSE_IMEX) {
+			if (!set_properties || vmmouse_init(psmouse) == 0)
+				return PSMOUSE_VMMOUSE;
+		}
+	}
+
 /*
  * Try Kensington ThinkingMouse (we try first, because synaptics probe
  * upsets the thinkingmouse).
@@ -1087,6 +1095,15 @@ static const struct psmouse_protocol psmouse_protocols[] = {
 		.init		= focaltech_init,
 	},
 #endif
+#ifdef CONFIG_MOUSE_PS2_VMMOUSE
+	{
+		.type		= PSMOUSE_VMMOUSE,
+		.name		= VMMOUSE_PSNAME,
+		.alias		= "vmmouse",
+		.detect		= vmmouse_detect,
+		.init		= vmmouse_init,
+	},
+#endif
 	{
 		.type		= PSMOUSE_AUTO,
 		.name		= "auto",
drivers/input/mouse/psmouse.h +1 -0
index d02e1bd..ad5a5a1 100644
@@ -103,6 +103,7 @@ enum psmouse_type {
 	PSMOUSE_SYNAPTICS_RELATIVE,
 	PSMOUSE_CYPRESS,
 	PSMOUSE_FOCALTECH,
+	PSMOUSE_VMMOUSE,
 	PSMOUSE_AUTO		/* This one should always be last */
 };
 
drivers/input/mouse/vmmouse.c new file +499 -0

499 lines not on this page · raw message

drivers/input/mouse/vmmouse.h new file +30 -0
new file mode 100644
index 0000000..6f12601
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+#ifndef _VMMOUSE_H
+#define _VMMOUSE_H
+
+#ifdef CONFIG_MOUSE_PS2_VMMOUSE
+#define VMMOUSE_PSNAME  "VirtualPS/2"
+
+int vmmouse_detect(struct psmouse *psmouse, bool set_properties);
+int vmmouse_init(struct psmouse *psmouse);
+#else
+static inline int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
+{
+	return -ENOSYS;
+}
+static inline int vmmouse_init(struct psmouse *psmouse)
+{
+	return -ENOSYS;
+}
+#endif
+
+#endif
Signature · 1 line
2.1.0
#2 lore raw

PATCH 2/2 Input: Allow devices to state that they aren't joysticks

In reply to Thomas Hellstrom

Sometimes the device driver knows that a device isn't a joystick. In those cases, allow the driver to ovveride joydev's guess.

---
 drivers/input/joydev.c        | 4 ++++
 drivers/input/mouse/vmmouse.c | 1 +
 include/linux/input.h         | 5 +++++
 3 files changed, 10 insertions(+)
drivers/input/joydev.c +4 -0
index f362883..6add101 100644
@@ -750,6 +750,10 @@ static void joydev_cleanup(struct joydev *joydev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
+	/* Avoid devices that explicitly don't want to be joysticks */
+	if (dev->flags & INPUT_FLAG_NO_JOYSTICK)
+		return false;
+
 	/* Avoid touchpads and touchscreens */
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return false;
drivers/input/mouse/vmmouse.c +1 -0
index b3a6170..0fabe3d 100644
@@ -468,6 +468,7 @@ int vmmouse_init(struct psmouse *psmouse)
 	abs_dev->id.product = PSMOUSE_VMMOUSE;
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+	abs_dev->flags |= INPUT_FLAG_NO_JOYSTICK;
 
 	if (input_register_device(priv->abs_dev))
 		goto init_fail;
include/linux/input.h +5 -0
index 82ce323..516387e 100644
@@ -117,6 +117,7 @@ struct input_value {
  * @vals: array of values queued in the current frame
  * @devres_managed: indicates that devices is managed with devres framework
  *	and needs not be explicitly unregistered or freed.
+ * @flags: Device flags.
  */
 struct input_dev {
 	const char *name;
@@ -187,9 +188,13 @@ struct input_dev {
 	struct input_value *vals;
 
 	bool devres_managed;
+
+	u32 flags;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
+#define INPUT_FLAG_NO_JOYSTICK      (1 << 0)
+
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
  */
Signature · 1 line
2.1.0
#3 lore raw

Re: [PATCH 2/2] Input: Allow devices to state that they aren't joysticks

Hi, Dmitry & input list.

I noticed that patch 1 in this series (VMMouse support) has made it to Linus' tree. However, this patch seems to be missing. It's crucial for VMMouse since without it, a number of games will recognize the vmmouse as a joystick and
leave the cursor stuck in the upper left corner.
(The VMware USB absolute mouse has been disabled for Linux guests because of this).

Is there a chance we can have this patch in as well. An alternative that I've tested briefly is to add a fake
BTN_DIGI to the absolute device to trick joydev, but that's rather hackish and will probably cause future confusion.

Any feedback appreciated.

Thanks,
Thomas Hellström

Quoted 53 lines · Thomas Hellstrom

Sometimes the device driver knows that a device isn't a joystick. In those cases, allow the driver to ovveride joydev's guess.

---
 drivers/input/joydev.c        | 4 ++++
 drivers/input/mouse/vmmouse.c | 1 +
 include/linux/input.h         | 5 +++++
 3 files changed, 10 insertions(+)
drivers/input/joydev.c +4 -0
index f362883..6add101 100644
@@ -750,6 +750,10 @@ static void joydev_cleanup(struct joydev *joydev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
+	/* Avoid devices that explicitly don't want to be joysticks */
+	if (dev->flags & INPUT_FLAG_NO_JOYSTICK)
+		return false;
+
 	/* Avoid touchpads and touchscreens */
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return false;
drivers/input/mouse/vmmouse.c +1 -0
index b3a6170..0fabe3d 100644
@@ -468,6 +468,7 @@ int vmmouse_init(struct psmouse *psmouse)
 	abs_dev->id.product = PSMOUSE_VMMOUSE;
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+	abs_dev->flags |= INPUT_FLAG_NO_JOYSTICK;
 
 	if (input_register_device(priv->abs_dev))
 		goto init_fail;
include/linux/input.h +1 -0
index 82ce323..516387e 100644
@@ -117,6 +117,7 @@ struct input_value {
  * @vals: array of values queued in the current frame
  * @devres_managed: indicates that devices is managed with devres framework
  *	and needs not be explicitly unregistered or freed.
+ * @flags: Device flags.
  */
 struct input_dev {
 	const char *name;
@@ -187,9 +188,13 @@ struct input_dev {
 	struct input_value *vals;
 
 	bool devres_managed;

include/linux/input.h struct input_dev { · line 200

Quoted 10 lines
include/linux/input.h +4 -0
+
+	u32 flags;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
+#define INPUT_FLAG_NO_JOYSTICK      (1 << 0)
+
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
  */

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#4 lore raw

Re: [PATCH 2/2] Input: Allow devices to state that they aren't joysticks

Ping?

/Thomas

Quoted 80 lines · Thomas Hellstrom

Hi, Dmitry & input list.

I noticed that patch 1 in this series (VMMouse support) has made it to Linus' tree. However, this patch seems to be missing. It's crucial for VMMouse since without it, a number of games will recognize the vmmouse as a joystick and
leave the cursor stuck in the upper left corner.
(The VMware USB absolute mouse has been disabled for Linux guests because of this).

Is there a chance we can have this patch in as well. An alternative that I've tested briefly is to add a fake
BTN_DIGI to the absolute device to trick joydev, but that's rather hackish and will probably cause future confusion.

Any feedback appreciated.

Thanks,
Thomas Hellström

Quoted 58 lines · Thomas Hellstrom

Sometimes the device driver knows that a device isn't a joystick. In those cases, allow the driver to ovveride joydev's guess.

---
 drivers/input/joydev.c        | 4 ++++
 drivers/input/mouse/vmmouse.c | 1 +
 include/linux/input.h         | 5 +++++
 3 files changed, 10 insertions(+)
drivers/input/joydev.c +4 -0
index f362883..6add101 100644
@@ -750,6 +750,10 @@ static void joydev_cleanup(struct joydev *joydev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
+	/* Avoid devices that explicitly don't want to be joysticks */
+	if (dev->flags & INPUT_FLAG_NO_JOYSTICK)
+		return false;
+
 	/* Avoid touchpads and touchscreens */
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return false;
drivers/input/mouse/vmmouse.c +1 -0
index b3a6170..0fabe3d 100644
@@ -468,6 +468,7 @@ int vmmouse_init(struct psmouse *psmouse)
 	abs_dev->id.product = PSMOUSE_VMMOUSE;
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+	abs_dev->flags |= INPUT_FLAG_NO_JOYSTICK;
 
 	if (input_register_device(priv->abs_dev))
 		goto init_fail;
include/linux/input.h +3 -0
index 82ce323..516387e 100644
@@ -117,6 +117,7 @@ struct input_value {
  * @vals: array of values queued in the current frame
  * @devres_managed: indicates that devices is managed with devres framework
  *	and needs not be explicitly unregistered or freed.
+ * @flags: Device flags.
  */
 struct input_dev {
 	const char *name;
@@ -187,9 +188,13 @@ struct input_dev {
 	struct input_value *vals;
 
 	bool devres_managed;
+
+	u32 flags;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
Quoted 5 lines

include/linux/input.h struct input_dev { · line 200

Quoted 5 lines
include/linux/input.h +2 -0
+#define INPUT_FLAG_NO_JOYSTICK      (1 << 0)
+
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
  */

--
To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

maintainer
#5 lore raw

Re: [PATCH 2/2] Input: Allow devices to state that they aren't joysticks

In reply to Thomas Hellstrom
Quoted 2 lines · Thomas Hellstrom

Sometimes the device driver knows that a device isn't a joystick. In those cases, allow the driver to ovveride joydev's guess.

I'd rather not encode knowledge of various input handlers into individual input drivers. Maybe we should simply tell joydev not to bing to devices with ABS_X, ABS_Y and 3 primary mouse buttons (and no other events?).

Thanks.

Quoted 64 lines
---
 drivers/input/joydev.c        | 4 ++++
 drivers/input/mouse/vmmouse.c | 1 +
 include/linux/input.h         | 5 +++++
 3 files changed, 10 insertions(+)
drivers/input/joydev.c +4 -0
index f362883..6add101 100644
@@ -750,6 +750,10 @@ static void joydev_cleanup(struct joydev *joydev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
+	/* Avoid devices that explicitly don't want to be joysticks */
+	if (dev->flags & INPUT_FLAG_NO_JOYSTICK)
+		return false;
+
 	/* Avoid touchpads and touchscreens */
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return false;
drivers/input/mouse/vmmouse.c +1 -0
index b3a6170..0fabe3d 100644
@@ -468,6 +468,7 @@ int vmmouse_init(struct psmouse *psmouse)
 	abs_dev->id.product = PSMOUSE_VMMOUSE;
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+	abs_dev->flags |= INPUT_FLAG_NO_JOYSTICK;
 
 	if (input_register_device(priv->abs_dev))
 		goto init_fail;
include/linux/input.h +5 -0
index 82ce323..516387e 100644
@@ -117,6 +117,7 @@ struct input_value {
  * @vals: array of values queued in the current frame
  * @devres_managed: indicates that devices is managed with devres framework
  *	and needs not be explicitly unregistered or freed.
+ * @flags: Device flags.
  */
 struct input_dev {
 	const char *name;
@@ -187,9 +188,13 @@ struct input_dev {
 	struct input_value *vals;
 
 	bool devres_managed;
+
+	u32 flags;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
+#define INPUT_FLAG_NO_JOYSTICK      (1 << 0)
+
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
  */
Signature · 1 line
2.1.0
Signature · 1 line
Dmitry
#6 lore raw

Re: [PATCH 2/2] Input: Allow devices to state that they aren't joysticks

Quoted 5 lines · Dmitry Torokhov
Quoted 2 lines · Thomas Hellstrom

Sometimes the device driver knows that a device isn't a joystick. In those cases, allow the driver to ovveride joydev's guess.

I'd rather not encode knowledge of various input handlers into individual input drivers.

Good point.

Quoted 3 lines

Maybe we should simply tell joydev not to bing
to devices with ABS_X, ABS_Y and 3 primary mouse buttons (and no other events?).

IIRC the Xorg input people were a bit surprised over joydev's current guessing heuristics as well.
I'll try to code something like that up and send a patch.

Thanks,
Thomas

Quoted 66 lines

Thanks.

Quoted 63 lines
---
 drivers/input/joydev.c        | 4 ++++
 drivers/input/mouse/vmmouse.c | 1 +
 include/linux/input.h         | 5 +++++
 3 files changed, 10 insertions(+)
drivers/input/joydev.c +4 -0
index f362883..6add101 100644
@@ -750,6 +750,10 @@ static void joydev_cleanup(struct joydev *joydev)
 
 static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
 {
+	/* Avoid devices that explicitly don't want to be joysticks */
+	if (dev->flags & INPUT_FLAG_NO_JOYSTICK)
+		return false;
+
 	/* Avoid touchpads and touchscreens */
 	if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
 		return false;
drivers/input/mouse/vmmouse.c +1 -0
index b3a6170..0fabe3d 100644
@@ -468,6 +468,7 @@ int vmmouse_init(struct psmouse *psmouse)
 	abs_dev->id.product = PSMOUSE_VMMOUSE;
 	abs_dev->id.version = psmouse->model;
 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+	abs_dev->flags |= INPUT_FLAG_NO_JOYSTICK;
 
 	if (input_register_device(priv->abs_dev))
 		goto init_fail;
include/linux/input.h +5 -0
index 82ce323..516387e 100644
@@ -117,6 +117,7 @@ struct input_value {
  * @vals: array of values queued in the current frame
  * @devres_managed: indicates that devices is managed with devres framework
  *	and needs not be explicitly unregistered or freed.
+ * @flags: Device flags.
  */
 struct input_dev {
 	const char *name;
@@ -187,9 +188,13 @@ struct input_dev {
 	struct input_value *vals;
 
 	bool devres_managed;
+
+	u32 flags;
 };
 #define to_input_dev(d) container_of(d, struct input_dev, dev)
 
+#define INPUT_FLAG_NO_JOYSTICK      (1 << 0)
+
 /*
  * Verify that we are in sync with input_device_id mod_devicetable.h #defines
  */
Signature · 1 line
2.1.0