xref: /freebsd/sys/dev/hyperv/input/hv_kbd.c (revision 4db78cacdee1b6f3b7880eb8c5560e8edaf91698)
1 /*-
2  * Copyright (c) 2017 Microsoft Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice unmodified, this list of conditions, and the following
10  *    disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
30 #include <sys/param.h>
31 #include <sys/kernel.h>
32 #include <sys/conf.h>
33 #include <sys/uio.h>
34 #include <sys/bus.h>
35 #include <sys/malloc.h>
36 #include <sys/mbuf.h>
37 #include <sys/module.h>
38 #include <sys/lock.h>
39 #include <sys/taskqueue.h>
40 #include <sys/selinfo.h>
41 #include <sys/sysctl.h>
42 #include <sys/poll.h>
43 #include <sys/proc.h>
44 #include <sys/queue.h>
45 #include <sys/kthread.h>
46 #include <sys/syscallsubr.h>
47 #include <sys/sysproto.h>
48 #include <sys/sema.h>
49 #include <sys/signal.h>
50 #include <sys/syslog.h>
51 #include <sys/systm.h>
52 #include <sys/mutex.h>
53 #include <sys/callout.h>
54 
55 #include <sys/kbio.h>
56 #include <dev/kbd/kbdreg.h>
57 #include <dev/kbd/kbdtables.h>
58 
59 #include "dev/hyperv/input/hv_kbdc.h"
60 
61 #define HVKBD_MTX_LOCK(_m) do {		\
62 	mtx_lock(_m);			\
63 } while (0)
64 
65 #define HVKBD_MTX_UNLOCK(_m) do {	\
66 	mtx_unlock(_m);			\
67 } while (0)
68 
69 #define HVKBD_MTX_ASSERT(_m, _t) do {	\
70 	mtx_assert(_m, _t);		\
71 } while (0)
72 
73 #define	HVKBD_LOCK()		HVKBD_MTX_LOCK(&Giant)
74 #define	HVKBD_UNLOCK()		HVKBD_MTX_UNLOCK(&Giant)
75 #define	HVKBD_LOCK_ASSERT()	HVKBD_MTX_ASSERT(&Giant, MA_OWNED)
76 
77 #define HVKBD_FLAG_POLLING	0x00000002
78 
79 /* early keyboard probe, not supported */
80 static int
81 hvkbd_configure(int flags)
82 {
83 	return (0);
84 }
85 
86 /* detect a keyboard, not used */
87 static int
88 hvkbd_probe(int unit, void *arg, int flags)
89 {
90 	return (ENXIO);
91 }
92 
93 /* reset and initialize the device, not used */
94 static int
95 hvkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
96 {
97 	DEBUG_HVKBD(*kbdp, "%s\n", __func__);
98 	return (ENXIO);
99 }
100 
101 /* test the interface to the device, not used */
102 static int
103 hvkbd_test_if(keyboard_t *kbd)
104 {
105 	DEBUG_HVKBD(kbd, "%s\n", __func__);
106 	return (0);
107 }
108 
109 /* finish using this keyboard, not used */
110 static int
111 hvkbd_term(keyboard_t *kbd)
112 {
113 	DEBUG_HVKBD(kbd, "%s\n", __func__);
114 	return (ENXIO);
115 }
116 
117 /* keyboard interrupt routine, not used */
118 static int
119 hvkbd_intr(keyboard_t *kbd, void *arg)
120 {
121 	DEBUG_HVKBD(kbd, "%s\n", __func__);
122 	return (0);
123 }
124 
125 /* lock the access to the keyboard, not used */
126 static int
127 hvkbd_lock(keyboard_t *kbd, int lock)
128 {
129 	DEBUG_HVKBD(kbd, "%s\n", __func__);
130 	return (1);
131 }
132 
133 /* save the internal state, not used */
134 static int
135 hvkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
136 {
137 	DEBUG_HVKBD(kbd,"%s\n",  __func__);
138 	return (len == 0) ? 1 : -1;
139 }
140 
141 /* set the internal state, not used */
142 static int
143 hvkbd_set_state(keyboard_t *kbd, void *buf, size_t len)
144 {
145 	DEBUG_HVKBD(kbd, "%s\n", __func__);
146 	return (EINVAL);
147 }
148 
149 static int
150 hvkbd_poll(keyboard_t *kbd, int on)
151 {
152 	hv_kbd_sc *sc = kbd->kb_data;
153 
154 	HVKBD_LOCK();
155 	/*
156 	 * Keep a reference count on polling to allow recursive
157 	 * cngrab() during a panic for example.
158 	 */
159 	if (on)
160 		sc->sc_polling++;
161 	else if (sc->sc_polling > 0)
162 		sc->sc_polling--;
163 
164 	if (sc->sc_polling != 0) {
165 		sc->sc_flags |= HVKBD_FLAG_POLLING;
166 	} else {
167 		sc->sc_flags &= ~HVKBD_FLAG_POLLING;
168 	}
169 	HVKBD_UNLOCK();
170 	return (0);
171 }
172 
173 /*
174  * Enable the access to the device; until this function is called,
175  * the client cannot read from the keyboard.
176  */
177 static int
178 hvkbd_enable(keyboard_t *kbd)
179 {
180 	HVKBD_LOCK();
181 	KBD_ACTIVATE(kbd);
182 	HVKBD_UNLOCK();
183 	return (0);
184 }
185 
186 /* disallow the access to the device */
187 static int
188 hvkbd_disable(keyboard_t *kbd)
189 {
190 	DEBUG_HVKBD(kbd, "%s\n", __func__);
191 	HVKBD_LOCK();
192 	KBD_DEACTIVATE(kbd);
193 	HVKBD_UNLOCK();
194 	return (0);
195 }
196 
197 static void
198 hvkbd_do_poll(hv_kbd_sc *sc, uint8_t wait)
199 {
200 	while (!hv_kbd_prod_is_ready(sc)) {
201 		hv_kbd_read_channel(sc->hs_chan, sc);
202 		if (!wait)
203 			break;
204 	}
205 }
206 
207 /* check if data is waiting */
208 /* Currently unused. */
209 static int
210 hvkbd_check(keyboard_t *kbd)
211 {
212 	DEBUG_HVKBD(kbd, "%s\n", __func__);
213 	return (0);
214 }
215 
216 /* check if char is waiting */
217 static int
218 hvkbd_check_char_locked(keyboard_t *kbd)
219 {
220 	HVKBD_LOCK_ASSERT();
221 	if (!KBD_IS_ACTIVE(kbd))
222 		return (FALSE);
223 
224 	hv_kbd_sc *sc = kbd->kb_data;
225 	if (sc->sc_flags & HVKBD_FLAG_POLLING)
226 		hvkbd_do_poll(sc, 0);
227 	if (hv_kbd_prod_is_ready(sc)) {
228 		return (TRUE);
229 	}
230 	return (FALSE);
231 }
232 
233 static int
234 hvkbd_check_char(keyboard_t *kbd)
235 {
236 	int result;
237 
238 	HVKBD_LOCK();
239 	result = hvkbd_check_char_locked(kbd);
240 	HVKBD_UNLOCK();
241 
242 	return (result);
243 }
244 
245 /* read char from the keyboard */
246 static uint32_t
247 hvkbd_read_char_locked(keyboard_t *kbd, int wait)
248 {
249 	uint32_t scancode = NOKEY;
250 	keystroke ks;
251 	hv_kbd_sc *sc = kbd->kb_data;
252 	HVKBD_LOCK_ASSERT();
253 
254 	if (!KBD_IS_ACTIVE(kbd) || !hv_kbd_prod_is_ready(sc))
255 		return (NOKEY);
256 	if (sc->sc_mode == K_RAW) {
257 		if (hv_kbd_fetch_top(sc, &ks)) {
258 			return (NOKEY);
259 		}
260 		if ((ks.info & IS_E0) || (ks.info & IS_E1)) {
261 			/**
262 			 * Emulate the generation of E0 or E1 scancode,
263 			 * the real scancode will be consumed next time.
264 			 */
265 			if (ks.info & IS_E0) {
266 				scancode = XTKBD_EMUL0;
267 				ks.info &= ~IS_E0;
268 			} else if (ks.info & IS_E1) {
269 				scancode = XTKBD_EMUL1;
270 				ks.info &= ~IS_E1;
271 			}
272 			/**
273 			 * Change the top item to avoid encountering
274 			 * E0 or E1 twice.
275 			 */
276 			hv_kbd_modify_top(sc, &ks);
277 		} else if (ks.info & IS_UNICODE) {
278 			/**
279 			 * XXX: Hyperv host send unicode to VM through
280 			 * 'Type clipboard text', the mapping from
281 			 * unicode to scancode depends on the keymap.
282 			 * It is so complicated that we do not plan to
283 			 * support it yet.
284 			 */
285 			if (bootverbose)
286 				device_printf(sc->dev, "Unsupported unicode\n");
287 			hv_kbd_remove_top(sc);
288 			return (NOKEY);
289 		} else {
290 			scancode = ks.makecode;
291 			if (ks.info & IS_BREAK) {
292 				scancode |= XTKBD_RELEASE;
293 			}
294 			hv_kbd_remove_top(sc);
295 		}
296 	} else {
297 		if (bootverbose)
298 			device_printf(sc->dev, "Unsupported mode: %d\n", sc->sc_mode);
299 	}
300 	++kbd->kb_count;
301 	DEBUG_HVKBD(kbd, "read scan: 0x%x\n", scancode);
302 	return scancode;
303 }
304 
305 /* Currently wait is always false. */
306 static uint32_t
307 hvkbd_read_char(keyboard_t *kbd, int wait)
308 {
309 	uint32_t keycode;
310 
311 	HVKBD_LOCK();
312 	keycode = hvkbd_read_char_locked(kbd, wait);
313 	HVKBD_UNLOCK();
314 
315 	return (keycode);
316 }
317 
318 /* clear the internal state of the keyboard */
319 static void
320 hvkbd_clear_state(keyboard_t *kbd)
321 {
322 	hv_kbd_sc *sc = kbd->kb_data;
323 	sc->sc_state &= LOCK_MASK;	/* preserve locking key state */
324 	sc->sc_flags &= ~HVKBD_FLAG_POLLING;
325 }
326 
327 static int
328 hvkbd_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg)
329 {
330 	int i;
331 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
332     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
333         int ival;
334 #endif
335 	hv_kbd_sc *sc = kbd->kb_data;
336 	switch (cmd) {
337 	case KDGKBMODE:
338 		*(int *)arg = sc->sc_mode;
339 		break;
340 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
341     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
342 	case _IO('K', 7):
343 		ival = IOCPARM_IVAL(arg);
344 		arg = (caddr_t)&ival;
345 		/* FALLTHROUGH */
346 #endif
347 	case KDSKBMODE:		/* set keyboard mode */
348 		DEBUG_HVKBD(kbd, "expected mode: %x\n", *(int *)arg);
349 		switch (*(int *)arg) {
350 		case K_XLATE:
351 			if (sc->sc_mode != K_XLATE) {
352 				/* make lock key state and LED state match */
353 				sc->sc_state &= ~LOCK_MASK;
354 				sc->sc_state |= KBD_LED_VAL(kbd);
355 			}
356 			/* FALLTHROUGH */
357 		case K_RAW:
358 		case K_CODE:
359 			if (sc->sc_mode != *(int *)arg) {
360 				DEBUG_HVKBD(kbd, "mod changed to %x\n", *(int *)arg);
361 				if ((sc->sc_flags & HVKBD_FLAG_POLLING) == 0)
362 					hvkbd_clear_state(kbd);
363 				sc->sc_mode = *(int *)arg;
364 			}
365 			break;
366 		default:
367 			return (EINVAL);
368 		}
369 		break;
370 	case KDGKBSTATE:	/* get lock key state */
371 		*(int *)arg = sc->sc_state & LOCK_MASK;
372 		break;
373 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
374     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
375 	case _IO('K', 20):
376 		ival = IOCPARM_IVAL(arg);
377 		arg = (caddr_t)&ival;
378 		/* FALLTHROUGH */
379 #endif
380 	case KDSKBSTATE:		/* set lock key state */
381 		if (*(int *)arg & ~LOCK_MASK) {
382 			return (EINVAL);
383 		}
384 		sc->sc_state &= ~LOCK_MASK;
385 		sc->sc_state |= *(int *)arg;
386 		return hvkbd_ioctl_locked(kbd, KDSETLED, arg);
387 	case KDGETLED:			/* get keyboard LED */
388 		*(int *)arg = KBD_LED_VAL(kbd);
389 		break;
390 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
391     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
392 	case _IO('K', 66):
393 		ival = IOCPARM_IVAL(arg);
394 		arg = (caddr_t)&ival;
395 		/* FALLTHROUGH */
396 #endif
397 	case KDSETLED:			/* set keyboard LED */
398 		/* NOTE: lock key state in "sc_state" won't be changed */
399 		if (*(int *)arg & ~LOCK_MASK)
400 			return (EINVAL);
401 
402 		i = *(int *)arg;
403 
404 		/* replace CAPS LED with ALTGR LED for ALTGR keyboards */
405 		if (sc->sc_mode == K_XLATE &&
406 		    kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
407 			if (i & ALKED)
408 				i |= CLKED;
409 			else
410 				i &= ~CLKED;
411 		}
412 		if (KBD_HAS_DEVICE(kbd)) {
413 			DEBUG_HVSC(sc, "setled 0x%x\n", *(int *)arg);
414 		}
415 
416 		KBD_LED_VAL(kbd) = *(int *)arg;
417 		break;
418 	default:
419 		return (genkbd_commonioctl(kbd, cmd, arg));
420 	}
421 	return (0);
422 }
423 
424 /* some useful control functions */
425 static int
426 hvkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
427 {
428 	DEBUG_HVKBD(kbd, "%s: %lx start\n", __func__, cmd);
429 	HVKBD_LOCK();
430 	int ret = hvkbd_ioctl_locked(kbd, cmd, arg);
431 	HVKBD_UNLOCK();
432 	DEBUG_HVKBD(kbd, "%s: %lx end %d\n", __func__, cmd, ret);
433 	return (ret);
434 }
435 
436 /* read one byte from the keyboard if it's allowed */
437 /* Currently unused. */
438 static int
439 hvkbd_read(keyboard_t *kbd, int wait)
440 {
441 	DEBUG_HVKBD(kbd, "%s\n", __func__);
442 	HVKBD_LOCK_ASSERT();
443 	if (!KBD_IS_ACTIVE(kbd))
444 		return (-1);
445 	return hvkbd_read_char_locked(kbd, wait);
446 }
447 
448 static keyboard_switch_t hvkbdsw = {
449 	hvkbd_probe,		/* not used */
450 	hvkbd_init,
451 	hvkbd_term,		/* not used */
452 	hvkbd_intr,		/* not used */
453 	hvkbd_test_if,		/* not used */
454 	hvkbd_enable,
455 	hvkbd_disable,
456 	hvkbd_read,
457 	hvkbd_check,
458 	hvkbd_read_char,
459 	hvkbd_check_char,
460 	hvkbd_ioctl,
461 	hvkbd_lock,		/* not used */
462 	hvkbd_clear_state,
463 	hvkbd_get_state,	/* not used */
464 	hvkbd_set_state,	/* not used */
465 	genkbd_get_fkeystr,
466 	hvkbd_poll,
467 	genkbd_diag,
468 };
469 
470 KEYBOARD_DRIVER(hvkbd, hvkbdsw, hvkbd_configure);
471 
472 void
473 hv_kbd_intr(hv_kbd_sc *sc)
474 {
475 	uint32_t c;
476 	if ((sc->sc_flags & HVKBD_FLAG_POLLING) != 0)
477 		return;
478 
479 	if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
480 	    KBD_IS_BUSY(&sc->sc_kbd)) {
481 		/* let the callback function process the input */
482 		(sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
483 		    sc->sc_kbd.kb_callback.kc_arg);
484 	} else {
485 		/* read and discard the input, no one is waiting for it */
486 		do {
487 			c = hvkbd_read_char(&sc->sc_kbd, 0);
488 		} while (c != NOKEY);
489 	}
490 }
491 
492 int
493 hvkbd_driver_load(module_t mod, int what, void *arg)
494 {
495 	switch (what) {
496 	case MOD_LOAD:
497 		kbd_add_driver(&hvkbd_kbd_driver);
498 		break;
499 	case MOD_UNLOAD:
500 		kbd_delete_driver(&hvkbd_kbd_driver);
501 		break;
502 	}
503 	return (0);
504 }
505 
506 int
507 hv_kbd_drv_attach(device_t dev)
508 {
509 	hv_kbd_sc *sc = device_get_softc(dev);
510 	int unit = device_get_unit(dev);
511 	keyboard_t *kbd = &sc->sc_kbd;
512 	keyboard_switch_t *sw;
513 	sw = kbd_get_switch(HVKBD_DRIVER_NAME);
514 	if (sw == NULL) {
515 		return (ENXIO);
516 	}
517 
518 	kbd_init_struct(kbd, HVKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
519 	kbd->kb_data = (void *)sc;
520 	kbd_set_maps(kbd, &key_map, &accent_map, fkey_tab, nitems(fkey_tab));
521 	KBD_FOUND_DEVICE(kbd);
522 	hvkbd_clear_state(kbd);
523 	KBD_PROBE_DONE(kbd);
524 	KBD_INIT_DONE(kbd);
525 	sc->sc_mode = K_RAW;
526 	(*sw->enable)(kbd);
527 
528 	if (kbd_register(kbd) < 0) {
529 		goto detach;
530 	}
531 	KBD_CONFIG_DONE(kbd);
532 #ifdef KBD_INSTALL_CDEV
533         if (kbd_attach(kbd)) {
534 		goto detach;
535 	}
536 #endif
537 	if (bootverbose) {
538 		genkbd_diag(kbd, bootverbose);
539 	}
540 	return (0);
541 detach:
542 	hv_kbd_drv_detach(dev);
543 	return (ENXIO);
544 }
545 
546 int
547 hv_kbd_drv_detach(device_t dev)
548 {
549 	int error = 0;
550 	hv_kbd_sc *sc = device_get_softc(dev);
551 	hvkbd_disable(&sc->sc_kbd);
552 	if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
553 		error = kbd_unregister(&sc->sc_kbd);
554 		if (error) {
555 			device_printf(dev, "WARNING: kbd_unregister() "
556 			    "returned non-zero! (ignored)\n");
557 		}
558 	}
559 #ifdef KBD_INSTALL_CDEV
560 	error = kbd_detach(&sc->sc_kbd);
561 #endif
562 	return (error);
563 }
564 
565