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
hvkbd_configure(int flags)81 hvkbd_configure(int flags)
82 {
83 return (0);
84 }
85
86 /* detect a keyboard, not used */
87 static int
hvkbd_probe(int unit,void * arg,int flags)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
hvkbd_init(int unit,keyboard_t ** kbdp,void * arg,int flags)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
hvkbd_test_if(keyboard_t * kbd)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
hvkbd_term(keyboard_t * kbd)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
hvkbd_intr(keyboard_t * kbd,void * arg)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
hvkbd_lock(keyboard_t * kbd,int lock)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
hvkbd_get_state(keyboard_t * kbd,void * buf,size_t len)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
hvkbd_set_state(keyboard_t * kbd,void * buf,size_t len)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
hvkbd_poll(keyboard_t * kbd,int on)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
hvkbd_enable(keyboard_t * kbd)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
hvkbd_disable(keyboard_t * kbd)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
hvkbd_do_poll(hv_kbd_sc * sc,uint8_t wait)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
hvkbd_check(keyboard_t * kbd)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
hvkbd_check_char_locked(keyboard_t * kbd)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
hvkbd_check_char(keyboard_t * kbd)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
hvkbd_read_char_locked(keyboard_t * kbd,int wait)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
hvkbd_read_char(keyboard_t * kbd,int wait)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
hvkbd_clear_state(keyboard_t * kbd)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
hvkbd_ioctl_locked(keyboard_t * kbd,u_long cmd,caddr_t arg)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
hvkbd_ioctl(keyboard_t * kbd,u_long cmd,caddr_t arg)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
hvkbd_read(keyboard_t * kbd,int wait)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 .probe = hvkbd_probe, /* not used */
450 .init = hvkbd_init,
451 .term = hvkbd_term, /* not used */
452 .intr = hvkbd_intr, /* not used */
453 .test_if = hvkbd_test_if, /* not used */
454 .enable = hvkbd_enable,
455 .disable = hvkbd_disable,
456 .read = hvkbd_read,
457 .check = hvkbd_check,
458 .read_char = hvkbd_read_char,
459 .check_char = hvkbd_check_char,
460 .ioctl = hvkbd_ioctl,
461 .lock = hvkbd_lock, /* not used */
462 .clear_state = hvkbd_clear_state,
463 .get_state = hvkbd_get_state, /* not used */
464 .set_state = hvkbd_set_state, /* not used */
465 .poll = hvkbd_poll,
466 };
467
468 KEYBOARD_DRIVER(hvkbd, hvkbdsw, hvkbd_configure);
469
470 void
hv_kbd_intr(hv_kbd_sc * sc)471 hv_kbd_intr(hv_kbd_sc *sc)
472 {
473 uint32_t c;
474 if ((sc->sc_flags & HVKBD_FLAG_POLLING) != 0)
475 return;
476
477 if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
478 KBD_IS_BUSY(&sc->sc_kbd)) {
479 /* let the callback function process the input */
480 (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
481 sc->sc_kbd.kb_callback.kc_arg);
482 } else {
483 /* read and discard the input, no one is waiting for it */
484 do {
485 c = hvkbd_read_char(&sc->sc_kbd, 0);
486 } while (c != NOKEY);
487 }
488 }
489
490 int
hvkbd_driver_load(module_t mod,int what,void * arg)491 hvkbd_driver_load(module_t mod, int what, void *arg)
492 {
493 switch (what) {
494 case MOD_LOAD:
495 kbd_add_driver(&hvkbd_kbd_driver);
496 break;
497 case MOD_UNLOAD:
498 kbd_delete_driver(&hvkbd_kbd_driver);
499 break;
500 }
501 return (0);
502 }
503
504 int
hv_kbd_drv_attach(device_t dev)505 hv_kbd_drv_attach(device_t dev)
506 {
507 hv_kbd_sc *sc = device_get_softc(dev);
508 int unit = device_get_unit(dev);
509 keyboard_t *kbd = &sc->sc_kbd;
510 keyboard_switch_t *sw;
511 sw = kbd_get_switch(HVKBD_DRIVER_NAME);
512 if (sw == NULL) {
513 return (ENXIO);
514 }
515
516 kbd_init_struct(kbd, HVKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
517 kbd->kb_data = (void *)sc;
518 kbd_set_maps(kbd, &key_map, &accent_map, fkey_tab, nitems(fkey_tab));
519 KBD_FOUND_DEVICE(kbd);
520 hvkbd_clear_state(kbd);
521 KBD_PROBE_DONE(kbd);
522 KBD_INIT_DONE(kbd);
523 sc->sc_mode = K_RAW;
524 (*sw->enable)(kbd);
525
526 if (kbd_register(kbd) < 0) {
527 goto detach;
528 }
529 KBD_CONFIG_DONE(kbd);
530 #ifdef KBD_INSTALL_CDEV
531 if (kbd_attach(kbd)) {
532 goto detach;
533 }
534 #endif
535 if (bootverbose) {
536 kbdd_diag(kbd, bootverbose);
537 }
538 return (0);
539 detach:
540 hv_kbd_drv_detach(dev);
541 return (ENXIO);
542 }
543
544 int
hv_kbd_drv_detach(device_t dev)545 hv_kbd_drv_detach(device_t dev)
546 {
547 int error = 0;
548 hv_kbd_sc *sc = device_get_softc(dev);
549 hvkbd_disable(&sc->sc_kbd);
550 if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
551 error = kbd_unregister(&sc->sc_kbd);
552 if (error) {
553 device_printf(dev, "WARNING: kbd_unregister() "
554 "returned non-zero! (ignored)\n");
555 }
556 }
557 #ifdef KBD_INSTALL_CDEV
558 error = kbd_detach(&sc->sc_kbd);
559 #endif
560 return (error);
561 }
562
563