2 * Driver for Virtual PS/2 Mouse on VMware and QEMU hypervisors.
4 * Copyright (C) 2014, VMware, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by
8 * the Free Software Foundation.
10 * Twin device code is hugely inspired by the ALPS driver.
12 * Dmitry Torokhov <dmitry.torokhov@gmail.com>
13 * Thomas Hellstrom <thellstrom@vmware.com>
16 #include <linux/input.h>
17 #include <linux/serio.h>
18 #include <linux/libps2.h>
19 #include <linux/slab.h>
20 #include <linux/module.h>
21 #include <asm/hypervisor.h>
26 #define VMMOUSE_PROTO_MAGIC 0x564D5868U
27 #define VMMOUSE_PROTO_PORT 0x5658
30 * Main commands supported by the vmmouse hypervisor port.
32 #define VMMOUSE_PROTO_CMD_GETVERSION 10
33 #define VMMOUSE_PROTO_CMD_ABSPOINTER_DATA 39
34 #define VMMOUSE_PROTO_CMD_ABSPOINTER_STATUS 40
35 #define VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND 41
36 #define VMMOUSE_PROTO_CMD_ABSPOINTER_RESTRICT 86
39 * Subcommands for VMMOUSE_PROTO_CMD_ABSPOINTER_COMMAND
41 #define VMMOUSE_CMD_ENABLE 0x45414552U
42 #define VMMOUSE_CMD_DISABLE 0x000000f5U
43 #define VMMOUSE_CMD_REQUEST_RELATIVE 0x4c455252U
44 #define VMMOUSE_CMD_REQUEST_ABSOLUTE 0x53424152U
46 #define VMMOUSE_ERROR 0xffff0000U
48 #define VMMOUSE_VERSION_ID 0x3442554aU
50 #define VMMOUSE_RELATIVE_PACKET 0x00010000U
52 #define VMMOUSE_LEFT_BUTTON 0x20
53 #define VMMOUSE_RIGHT_BUTTON 0x10
54 #define VMMOUSE_MIDDLE_BUTTON 0x08
57 * VMMouse Restrict command
59 #define VMMOUSE_RESTRICT_ANY 0x00
60 #define VMMOUSE_RESTRICT_CPL0 0x01
61 #define VMMOUSE_RESTRICT_IOPL 0x02
63 #define VMMOUSE_MAX_X 0xFFFF
64 #define VMMOUSE_MAX_Y 0xFFFF
66 #define VMMOUSE_VENDOR "VMware"
67 #define VMMOUSE_NAME "VMMouse"
70 * struct vmmouse_data - private data structure for the vmmouse driver
72 * @abs_dev: "Absolute" device used to report absolute mouse movement.
73 * @phys: Physical path for the absolute device.
74 * @dev_name: Name attribute name for the absolute device.
77 struct input_dev
*abs_dev
;
83 * Hypervisor-specific bi-directional communication channel
84 * implementing the vmmouse protocol. Should never execute on
85 * bare metal hardware.
87 #define VMMOUSE_CMD(cmd, in1, out1, out2, out3, out4) \
89 unsigned long __dummy1, __dummy2; \
90 __asm__ __volatile__ ("inl %%dx" : \
97 "a"(VMMOUSE_PROTO_MAGIC), \
99 "c"(VMMOUSE_PROTO_CMD_##cmd), \
100 "d"(VMMOUSE_PROTO_PORT) : \
105 * vmmouse_report_button - report button state on the correct input device
107 * @psmouse: Pointer to the psmouse struct
108 * @abs_dev: The absolute input device
109 * @rel_dev: The relative input device
110 * @pref_dev: The preferred device for reporting
112 * @value: Button value
114 * Report @value and @code on @pref_dev, unless the button is already
115 * pressed on the other device, in which case the state is reported on that
118 static void vmmouse_report_button(struct psmouse
*psmouse
,
119 struct input_dev
*abs_dev
,
120 struct input_dev
*rel_dev
,
121 struct input_dev
*pref_dev
,
122 unsigned int code
, int value
)
124 if (test_bit(code
, abs_dev
->key
))
126 else if (test_bit(code
, rel_dev
->key
))
129 input_report_key(pref_dev
, code
, value
);
133 * vmmouse_report_events - process events on the vmmouse communications channel
135 * @psmouse: Pointer to the psmouse struct
137 * This function pulls events from the vmmouse communications channel and
138 * reports them on the correct (absolute or relative) input device. When the
139 * communications channel is drained, or if we've processed more than 255
140 * psmouse commands, the function returns PSMOUSE_FULL_PACKET. If there is a
141 * host- or synchronization error, the function returns PSMOUSE_BAD_DATA in
142 * the hope that the caller will reset the communications channel.
144 static psmouse_ret_t
vmmouse_report_events(struct psmouse
*psmouse
)
146 struct input_dev
*rel_dev
= psmouse
->dev
;
147 struct vmmouse_data
*priv
= psmouse
->private;
148 struct input_dev
*abs_dev
= priv
->abs_dev
;
149 struct input_dev
*pref_dev
;
151 u32 dummy1
, dummy2
, dummy3
;
152 unsigned int queue_length
;
153 unsigned int count
= 255;
156 /* See if we have motion data. */
157 VMMOUSE_CMD(ABSPOINTER_STATUS
, 0,
158 status
, dummy1
, dummy2
, dummy3
);
159 if ((status
& VMMOUSE_ERROR
) == VMMOUSE_ERROR
) {
160 psmouse_err(psmouse
, "failed to fetch status data\n");
162 * After a few attempts this will result in
165 return PSMOUSE_BAD_DATA
;
168 queue_length
= status
& 0xffff;
169 if (queue_length
== 0)
172 if (queue_length
% 4) {
173 psmouse_err(psmouse
, "invalid queue length\n");
174 return PSMOUSE_BAD_DATA
;
178 VMMOUSE_CMD(ABSPOINTER_DATA
, 4, status
, x
, y
, z
);
181 * And report what we've got. Prefer to report button
182 * events on the same device where we report motion events.
183 * This doesn't work well with the mouse wheel, though. See
184 * below. Ideally we would want to report that on the
185 * preferred device as well.
187 if (status
& VMMOUSE_RELATIVE_PACKET
) {
189 input_report_rel(rel_dev
, REL_X
, (s32
)x
);
190 input_report_rel(rel_dev
, REL_Y
, -(s32
)y
);
193 input_report_abs(abs_dev
, ABS_X
, x
);
194 input_report_abs(abs_dev
, ABS_Y
, y
);
197 /* Xorg seems to ignore wheel events on absolute devices */
198 input_report_rel(rel_dev
, REL_WHEEL
, -(s8
)((u8
) z
));
200 vmmouse_report_button(psmouse
, abs_dev
, rel_dev
,
202 status
& VMMOUSE_LEFT_BUTTON
);
203 vmmouse_report_button(psmouse
, abs_dev
, rel_dev
,
205 status
& VMMOUSE_RIGHT_BUTTON
);
206 vmmouse_report_button(psmouse
, abs_dev
, rel_dev
,
207 pref_dev
, BTN_MIDDLE
,
208 status
& VMMOUSE_MIDDLE_BUTTON
);
213 return PSMOUSE_FULL_PACKET
;
217 * vmmouse_process_byte - process data on the ps/2 channel
219 * @psmouse: Pointer to the psmouse struct
221 * When the ps/2 channel indicates that there is vmmouse data available,
222 * call vmmouse channel processing. Otherwise, continue to accept bytes. If
223 * there is a synchronization or communication data error, return
224 * PSMOUSE_BAD_DATA in the hope that the caller will reset the mouse.
226 static psmouse_ret_t
vmmouse_process_byte(struct psmouse
*psmouse
)
228 unsigned char *packet
= psmouse
->packet
;
230 switch (psmouse
->pktcnt
) {
232 return (packet
[0] & 0x8) == 0x8 ?
233 PSMOUSE_GOOD_DATA
: PSMOUSE_BAD_DATA
;
236 return PSMOUSE_GOOD_DATA
;
239 return vmmouse_report_events(psmouse
);
244 * vmmouse_disable - Disable vmmouse
246 * @psmouse: Pointer to the psmouse struct
248 * Tries to disable vmmouse mode.
250 static void vmmouse_disable(struct psmouse
*psmouse
)
253 u32 dummy1
, dummy2
, dummy3
, dummy4
;
255 VMMOUSE_CMD(ABSPOINTER_COMMAND
, VMMOUSE_CMD_DISABLE
,
256 dummy1
, dummy2
, dummy3
, dummy4
);
258 VMMOUSE_CMD(ABSPOINTER_STATUS
, 0,
259 status
, dummy1
, dummy2
, dummy3
);
261 if ((status
& VMMOUSE_ERROR
) != VMMOUSE_ERROR
)
262 psmouse_warn(psmouse
, "failed to disable vmmouse device\n");
266 * vmmouse_enable - Enable vmmouse and request absolute mode.
268 * @psmouse: Pointer to the psmouse struct
270 * Tries to enable vmmouse mode. Performs basic checks and requests
271 * absolute vmmouse mode.
272 * Returns 0 on success, -ENODEV on failure.
274 static int vmmouse_enable(struct psmouse
*psmouse
)
277 u32 dummy1
, dummy2
, dummy3
, dummy4
;
280 * Try enabling the device. If successful, we should be able to
281 * read valid version ID back from it.
283 VMMOUSE_CMD(ABSPOINTER_COMMAND
, VMMOUSE_CMD_ENABLE
,
284 dummy1
, dummy2
, dummy3
, dummy4
);
287 * See if version ID can be retrieved.
289 VMMOUSE_CMD(ABSPOINTER_STATUS
, 0, status
, dummy1
, dummy2
, dummy3
);
290 if ((status
& 0x0000ffff) == 0) {
291 psmouse_dbg(psmouse
, "empty flags - assuming no device\n");
295 VMMOUSE_CMD(ABSPOINTER_DATA
, 1 /* single item */,
296 version
, dummy1
, dummy2
, dummy3
);
297 if (version
!= VMMOUSE_VERSION_ID
) {
298 psmouse_dbg(psmouse
, "Unexpected version value: %u vs %u\n",
299 (unsigned) version
, VMMOUSE_VERSION_ID
);
300 vmmouse_disable(psmouse
);
305 * Restrict ioport access, if possible.
307 VMMOUSE_CMD(ABSPOINTER_RESTRICT
, VMMOUSE_RESTRICT_CPL0
,
308 dummy1
, dummy2
, dummy3
, dummy4
);
310 VMMOUSE_CMD(ABSPOINTER_COMMAND
, VMMOUSE_CMD_REQUEST_ABSOLUTE
,
311 dummy1
, dummy2
, dummy3
, dummy4
);
317 * Array of supported hypervisors.
319 static enum x86_hypervisor_type vmmouse_supported_hypervisors
[] = {
325 * vmmouse_check_hypervisor - Check if we're running on a supported hypervisor
327 static bool vmmouse_check_hypervisor(void)
331 for (i
= 0; i
< ARRAY_SIZE(vmmouse_supported_hypervisors
); i
++)
332 if (vmmouse_supported_hypervisors
[i
] == x86_hyper_type
)
339 * vmmouse_detect - Probe whether vmmouse is available
341 * @psmouse: Pointer to the psmouse struct
342 * @set_properties: Whether to set psmouse name and vendor
344 * Returns 0 if vmmouse channel is available. Negative error code if not.
346 int vmmouse_detect(struct psmouse
*psmouse
, bool set_properties
)
348 u32 response
, version
, dummy1
, dummy2
;
350 if (!vmmouse_check_hypervisor()) {
352 "VMMouse not running on supported hypervisor.\n");
356 /* Check if the device is present */
357 response
= ~VMMOUSE_PROTO_MAGIC
;
358 VMMOUSE_CMD(GETVERSION
, 0, version
, response
, dummy1
, dummy2
);
359 if (response
!= VMMOUSE_PROTO_MAGIC
|| version
== 0xffffffffU
)
362 if (set_properties
) {
363 psmouse
->vendor
= VMMOUSE_VENDOR
;
364 psmouse
->name
= VMMOUSE_NAME
;
365 psmouse
->model
= version
;
372 * vmmouse_disconnect - Take down vmmouse driver
374 * @psmouse: Pointer to the psmouse struct
376 * Takes down vmmouse driver and frees resources set up in vmmouse_init().
378 static void vmmouse_disconnect(struct psmouse
*psmouse
)
380 struct vmmouse_data
*priv
= psmouse
->private;
382 vmmouse_disable(psmouse
);
383 psmouse_reset(psmouse
);
384 input_unregister_device(priv
->abs_dev
);
389 * vmmouse_reconnect - Reset the ps/2 - and vmmouse connections
391 * @psmouse: Pointer to the psmouse struct
393 * Attempts to reset the mouse connections. Returns 0 on success and
396 static int vmmouse_reconnect(struct psmouse
*psmouse
)
400 psmouse_reset(psmouse
);
401 vmmouse_disable(psmouse
);
402 error
= vmmouse_enable(psmouse
);
405 "Unable to re-enable mouse when reconnecting, err: %d\n",
414 * vmmouse_init - Initialize the vmmouse driver
416 * @psmouse: Pointer to the psmouse struct
418 * Requests the device and tries to enable vmmouse mode.
419 * If successful, sets up the input device for relative movement events.
420 * It also allocates another input device and sets it up for absolute motion
421 * events. Returns 0 on success and -1 on failure.
423 int vmmouse_init(struct psmouse
*psmouse
)
425 struct vmmouse_data
*priv
;
426 struct input_dev
*rel_dev
= psmouse
->dev
, *abs_dev
;
429 psmouse_reset(psmouse
);
430 error
= vmmouse_enable(psmouse
);
434 priv
= kzalloc(sizeof(*priv
), GFP_KERNEL
);
435 abs_dev
= input_allocate_device();
436 if (!priv
|| !abs_dev
) {
441 priv
->abs_dev
= abs_dev
;
442 psmouse
->private = priv
;
444 /* Set up and register absolute device */
445 snprintf(priv
->phys
, sizeof(priv
->phys
), "%s/input1",
446 psmouse
->ps2dev
.serio
->phys
);
448 /* Mimic name setup for relative device in psmouse-base.c */
449 snprintf(priv
->dev_name
, sizeof(priv
->dev_name
), "%s %s %s",
450 VMMOUSE_PSNAME
, VMMOUSE_VENDOR
, VMMOUSE_NAME
);
451 abs_dev
->phys
= priv
->phys
;
452 abs_dev
->name
= priv
->dev_name
;
453 abs_dev
->id
.bustype
= BUS_I8042
;
454 abs_dev
->id
.vendor
= 0x0002;
455 abs_dev
->id
.product
= PSMOUSE_VMMOUSE
;
456 abs_dev
->id
.version
= psmouse
->model
;
457 abs_dev
->dev
.parent
= &psmouse
->ps2dev
.serio
->dev
;
459 /* Set absolute device capabilities */
460 input_set_capability(abs_dev
, EV_KEY
, BTN_LEFT
);
461 input_set_capability(abs_dev
, EV_KEY
, BTN_RIGHT
);
462 input_set_capability(abs_dev
, EV_KEY
, BTN_MIDDLE
);
463 input_set_capability(abs_dev
, EV_ABS
, ABS_X
);
464 input_set_capability(abs_dev
, EV_ABS
, ABS_Y
);
465 input_set_abs_params(abs_dev
, ABS_X
, 0, VMMOUSE_MAX_X
, 0, 0);
466 input_set_abs_params(abs_dev
, ABS_Y
, 0, VMMOUSE_MAX_Y
, 0, 0);
468 error
= input_register_device(priv
->abs_dev
);
472 /* Add wheel capability to the relative device */
473 input_set_capability(rel_dev
, EV_REL
, REL_WHEEL
);
475 psmouse
->protocol_handler
= vmmouse_process_byte
;
476 psmouse
->disconnect
= vmmouse_disconnect
;
477 psmouse
->reconnect
= vmmouse_reconnect
;
482 vmmouse_disable(psmouse
);
483 psmouse_reset(psmouse
);
484 input_free_device(abs_dev
);
486 psmouse
->private = NULL
;