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 "opt_evdev.h"
31
32 #include <sys/param.h>
33 #include <sys/kernel.h>
34 #include <sys/conf.h>
35 #include <sys/uio.h>
36 #include <sys/bus.h>
37 #include <sys/malloc.h>
38 #include <sys/mbuf.h>
39 #include <sys/module.h>
40 #include <sys/limits.h>
41 #include <sys/lock.h>
42 #include <sys/taskqueue.h>
43 #include <sys/selinfo.h>
44 #include <sys/sysctl.h>
45 #include <sys/poll.h>
46 #include <sys/proc.h>
47 #include <sys/queue.h>
48 #include <sys/kthread.h>
49 #include <sys/syscallsubr.h>
50 #include <sys/sysproto.h>
51 #include <sys/sema.h>
52 #include <sys/signal.h>
53 #include <sys/syslog.h>
54 #include <sys/systm.h>
55 #include <sys/mutex.h>
56 #include <sys/callout.h>
57
58 #include <sys/kbio.h>
59 #include <dev/kbd/kbdreg.h>
60 #include <dev/kbd/kbdtables.h>
61
62 #ifdef EVDEV_SUPPORT
63 #include <dev/evdev/evdev.h>
64 #include <dev/evdev/input.h>
65 #endif
66
67 #include "dev/hyperv/input/hv_kbdc.h"
68
69 #define HVKBD_MTX_LOCK(_m) do { \
70 mtx_lock(_m); \
71 } while (0)
72
73 #define HVKBD_MTX_UNLOCK(_m) do { \
74 mtx_unlock(_m); \
75 } while (0)
76
77 #define HVKBD_MTX_ASSERT(_m, _t) do { \
78 mtx_assert(_m, _t); \
79 } while (0)
80
81 #define HVKBD_LOCK() HVKBD_MTX_LOCK(&Giant)
82 #define HVKBD_UNLOCK() HVKBD_MTX_UNLOCK(&Giant)
83 #define HVKBD_LOCK_ASSERT() HVKBD_MTX_ASSERT(&Giant, MA_OWNED)
84
85 #define HVKBD_FLAG_COMPOSE 0x00000001 /* compose char flag */
86 #define HVKBD_FLAG_POLLING 0x00000002
87
88 #ifdef EVDEV_SUPPORT
89 static evdev_event_t hvkbd_ev_event;
90
91 static const struct evdev_methods hvkbd_evdev_methods = {
92 .ev_event = hvkbd_ev_event,
93 };
94 #endif
95
96 /* early keyboard probe, not supported */
97 static int
98 hvkbd_configure(int flags)
99 {
100 return (0);
101 }
102
103 /* detect a keyboard, not used */
104 static int
105 hvkbd_probe(int unit, void *arg, int flags)
106 {
107 return (ENXIO);
108 }
109
110 /* reset and initialize the device, not used */
111 static int
112 hvkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
113 {
114 DEBUG_HVKBD(*kbdp, "%s\n", __func__);
115 return (ENXIO);
116 }
117
118 /* test the interface to the device, not used */
119 static int
120 hvkbd_test_if(keyboard_t *kbd)
121 {
122 DEBUG_HVKBD(kbd, "%s\n", __func__);
123 return (0);
124 }
125
126 /* finish using this keyboard, not used */
127 static int
128 hvkbd_term(keyboard_t *kbd)
129 {
130 DEBUG_HVKBD(kbd, "%s\n", __func__);
131 return (ENXIO);
132 }
133
134 /* keyboard interrupt routine, not used */
135 static int
136 hvkbd_intr(keyboard_t *kbd, void *arg)
137 {
138 DEBUG_HVKBD(kbd, "%s\n", __func__);
139 return (0);
140 }
141
142 /* lock the access to the keyboard, not used */
143 static int
144 hvkbd_lock(keyboard_t *kbd, int lock)
145 {
146 DEBUG_HVKBD(kbd, "%s\n", __func__);
147 return (1);
148 }
149
150 /* save the internal state, not used */
151 static int
152 hvkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
153 {
154 DEBUG_HVKBD(kbd,"%s\n", __func__);
155 return (len == 0) ? 1 : -1;
156 }
157
158 /* set the internal state, not used */
159 static int
160 hvkbd_set_state(keyboard_t *kbd, void *buf, size_t len)
161 {
162 DEBUG_HVKBD(kbd, "%s\n", __func__);
163 return (EINVAL);
164 }
165
166 static int
167 hvkbd_poll(keyboard_t *kbd, int on)
168 {
169 hv_kbd_sc *sc = kbd->kb_data;
170
171 HVKBD_LOCK();
172 /*
173 * Keep a reference count on polling to allow recursive
174 * cngrab() during a panic for example.
175 */
176 if (on)
177 sc->sc_polling++;
178 else if (sc->sc_polling > 0)
179 sc->sc_polling--;
180
181 if (sc->sc_polling != 0) {
182 sc->sc_flags |= HVKBD_FLAG_POLLING;
183 } else {
184 sc->sc_flags &= ~HVKBD_FLAG_POLLING;
185 }
186 HVKBD_UNLOCK();
187 return (0);
188 }
189
190 /*
191 * Enable the access to the device; until this function is called,
192 * the client cannot read from the keyboard.
193 */
194 static int
195 hvkbd_enable(keyboard_t *kbd)
196 {
197 HVKBD_LOCK();
198 KBD_ACTIVATE(kbd);
199 HVKBD_UNLOCK();
200 return (0);
201 }
202
203 /* disallow the access to the device */
204 static int
205 hvkbd_disable(keyboard_t *kbd)
206 {
207 DEBUG_HVKBD(kbd, "%s\n", __func__);
208 HVKBD_LOCK();
209 KBD_DEACTIVATE(kbd);
210 HVKBD_UNLOCK();
211 return (0);
212 }
213
214 static void
215 hvkbd_do_poll(hv_kbd_sc *sc, uint8_t wait)
216 {
217 while (!hv_kbd_prod_is_ready(sc)) {
218 hv_kbd_read_channel(sc->hs_chan, sc);
219 if (!wait)
220 break;
221 }
222 }
223
224 /* check if data is waiting */
225 /* Currently unused. */
226 static int
227 hvkbd_check(keyboard_t *kbd)
228 {
229 DEBUG_HVKBD(kbd, "%s\n", __func__);
230 return (0);
231 }
232
233 /* check if char is waiting */
234 static int
235 hvkbd_check_char_locked(keyboard_t *kbd)
236 {
237 HVKBD_LOCK_ASSERT();
238 if (!KBD_IS_ACTIVE(kbd))
239 return (FALSE);
240
241 hv_kbd_sc *sc = kbd->kb_data;
242 if (!(sc->sc_flags & HVKBD_FLAG_COMPOSE) && sc->sc_composed_char != 0)
243 return (TRUE);
244 if (sc->sc_flags & HVKBD_FLAG_POLLING)
245 hvkbd_do_poll(sc, 0);
246 if (hv_kbd_prod_is_ready(sc)) {
247 return (TRUE);
248 }
249 return (FALSE);
250 }
251
252 static int
253 hvkbd_check_char(keyboard_t *kbd)
254 {
255 int result;
256
257 HVKBD_LOCK();
258 result = hvkbd_check_char_locked(kbd);
259 HVKBD_UNLOCK();
260
261 return (result);
262 }
263
264 /* read char from the keyboard */
265 static uint32_t
266 hvkbd_read_char_locked(keyboard_t *kbd, int wait)
267 {
268 uint32_t scancode = NOKEY;
269 uint32_t action;
270 keystroke ks;
271 hv_kbd_sc *sc = kbd->kb_data;
272 int keycode;
273
274 HVKBD_LOCK_ASSERT();
275
276 if (!KBD_IS_ACTIVE(kbd) || !hv_kbd_prod_is_ready(sc))
277 return (NOKEY);
278
279 next_code:
280
281 /* do we have a composed char to return? */
282 if (!(sc->sc_flags & HVKBD_FLAG_COMPOSE) && sc->sc_composed_char > 0) {
283 action = sc->sc_composed_char;
284 sc->sc_composed_char = 0;
285 if (action > UCHAR_MAX) {
286 return (ERRKEY);
287 }
288 return (action);
289 }
290
291 if (hv_kbd_fetch_top(sc, &ks)) {
292 return (NOKEY);
293 }
294 if ((ks.info & IS_E0) || (ks.info & IS_E1)) {
295 /**
296 * Emulate the generation of E0 or E1 scancode,
297 * the real scancode will be consumed next time.
298 */
299 if (ks.info & IS_E0) {
300 scancode = XTKBD_EMUL0;
301 ks.info &= ~IS_E0;
302 } else if (ks.info & IS_E1) {
303 scancode = XTKBD_EMUL1;
304 ks.info &= ~IS_E1;
305 }
306 /**
307 * Change the top item to avoid encountering
308 * E0 or E1 twice.
309 */
310 hv_kbd_modify_top(sc, &ks);
311 } else if (ks.info & IS_UNICODE) {
312 /**
313 * XXX: Hyperv host send unicode to VM through
314 * 'Type clipboard text', the mapping from
315 * unicode to scancode depends on the keymap.
316 * It is so complicated that we do not plan to
317 * support it yet.
318 */
319 if (bootverbose)
320 device_printf(sc->dev, "Unsupported unicode\n");
321 hv_kbd_remove_top(sc);
322 return (NOKEY);
323 } else {
324 scancode = ks.makecode;
325 if (ks.info & IS_BREAK) {
326 scancode |= XTKBD_RELEASE;
327 }
328 hv_kbd_remove_top(sc);
329 }
330 #ifdef EVDEV_SUPPORT
331 /* push evdev event */
332 if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD &&
333 sc->ks_evdev != NULL) {
334 keycode = evdev_scancode2key(&sc->ks_evdev_state,
335 scancode);
336
337 if (keycode != KEY_RESERVED) {
338 evdev_push_event(sc->ks_evdev, EV_KEY,
339 (uint16_t)keycode, scancode & 0x80 ? 0 : 1);
340 evdev_sync(sc->ks_evdev);
341 }
342 }
343 if (sc->ks_evdev != NULL && evdev_is_grabbed(sc->ks_evdev))
344 return (NOKEY);
345 #endif
346 ++kbd->kb_count;
347 DEBUG_HVKBD(kbd, "read scan: 0x%x\n", scancode);
348
349 /* return the byte as is for the K_RAW mode */
350 if (sc->sc_mode == K_RAW)
351 return scancode;
352
353 /* translate the scan code into a keycode */
354 keycode = scancode & 0x7F;
355 switch (sc->sc_prefix) {
356 case 0x00: /* normal scancode */
357 switch(scancode) {
358 case 0xB8: /* left alt (compose key) released */
359 if (sc->sc_flags & HVKBD_FLAG_COMPOSE) {
360 sc->sc_flags &= ~HVKBD_FLAG_COMPOSE;
361 if (sc->sc_composed_char > UCHAR_MAX)
362 sc->sc_composed_char = 0;
363 }
364 break;
365 case 0x38: /* left alt (compose key) pressed */
366 if (!(sc->sc_flags & HVKBD_FLAG_COMPOSE)) {
367 sc->sc_flags |= HVKBD_FLAG_COMPOSE;
368 sc->sc_composed_char = 0;
369 }
370 break;
371 case 0xE0:
372 case 0xE1:
373 sc->sc_prefix = scancode;
374 goto next_code;
375 }
376 break;
377 case 0xE0: /* 0xE0 prefix */
378 sc->sc_prefix = 0;
379 switch (keycode) {
380 case 0x1C: /* right enter key */
381 keycode = 0x59;
382 break;
383 case 0x1D: /* right ctrl key */
384 keycode = 0x5A;
385 break;
386 case 0x35: /* keypad divide key */
387 keycode = 0x5B;
388 break;
389 case 0x37: /* print scrn key */
390 keycode = 0x5C;
391 break;
392 case 0x38: /* right alt key (alt gr) */
393 keycode = 0x5D;
394 break;
395 case 0x46: /* ctrl-pause/break on AT 101 (see below) */
396 keycode = 0x68;
397 break;
398 case 0x47: /* grey home key */
399 keycode = 0x5E;
400 break;
401 case 0x48: /* grey up arrow key */
402 keycode = 0x5F;
403 break;
404 case 0x49: /* grey page up key */
405 keycode = 0x60;
406 break;
407 case 0x4B: /* grey left arrow key */
408 keycode = 0x61;
409 break;
410 case 0x4D: /* grey right arrow key */
411 keycode = 0x62;
412 break;
413 case 0x4F: /* grey end key */
414 keycode = 0x63;
415 break;
416 case 0x50: /* grey down arrow key */
417 keycode = 0x64;
418 break;
419 case 0x51: /* grey page down key */
420 keycode = 0x65;
421 break;
422 case 0x52: /* grey insert key */
423 keycode = 0x66;
424 break;
425 case 0x53: /* grey delete key */
426 keycode = 0x67;
427 break;
428 /* the following 3 are only used on the MS "Natural" keyboard */
429 case 0x5b: /* left Window key */
430 keycode = 0x69;
431 break;
432 case 0x5c: /* right Window key */
433 keycode = 0x6a;
434 break;
435 case 0x5d: /* menu key */
436 keycode = 0x6b;
437 break;
438 case 0x5e: /* power key */
439 keycode = 0x6d;
440 break;
441 case 0x5f: /* sleep key */
442 keycode = 0x6e;
443 break;
444 case 0x63: /* wake key */
445 keycode = 0x6f;
446 break;
447 default: /* ignore everything else */
448 goto next_code;
449 }
450 break;
451 case 0xE1: /* 0xE1 prefix */
452 /*
453 * The pause/break key on the 101 keyboard produces:
454 * E1-1D-45 E1-9D-C5
455 * Ctrl-pause/break produces:
456 * E0-46 E0-C6 (See above.)
457 */
458 sc->sc_prefix = 0;
459 if (keycode == 0x1D)
460 sc->sc_prefix = 0x1D;
461 goto next_code;
462 /* NOT REACHED */
463 case 0x1D: /* pause / break */
464 sc->sc_prefix = 0;
465 if (keycode != 0x45)
466 goto next_code;
467 keycode = 0x68;
468 break;
469 }
470
471 /* XXX assume 101/102 keys AT keyboard */
472 switch (keycode) {
473 case 0x5c: /* print screen */
474 if (sc->sc_flags & ALTS)
475 keycode = 0x54; /* sysrq */
476 break;
477 case 0x68: /* pause/break */
478 if (sc->sc_flags & CTLS)
479 keycode = 0x6c; /* break */
480 break;
481 }
482
483 /* return the key code in the K_CODE mode */
484 if (sc->sc_mode == K_CODE)
485 return (keycode | (scancode & 0x80));
486
487 /* compose a character code */
488 if (sc->sc_flags & HVKBD_FLAG_COMPOSE) {
489 switch (keycode | (scancode & 0x80)) {
490 /* key pressed, process it */
491 case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
492 sc->sc_composed_char *= 10;
493 sc->sc_composed_char += keycode - 0x40;
494 if (sc->sc_composed_char > UCHAR_MAX)
495 return ERRKEY;
496 goto next_code;
497 case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
498 sc->sc_composed_char *= 10;
499 sc->sc_composed_char += keycode - 0x47;
500 if (sc->sc_composed_char > UCHAR_MAX)
501 return ERRKEY;
502 goto next_code;
503 case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
504 sc->sc_composed_char *= 10;
505 sc->sc_composed_char += keycode - 0x4E;
506 if (sc->sc_composed_char > UCHAR_MAX)
507 return ERRKEY;
508 goto next_code;
509 case 0x52: /* keypad 0 */
510 sc->sc_composed_char *= 10;
511 if (sc->sc_composed_char > UCHAR_MAX)
512 return ERRKEY;
513 goto next_code;
514
515 /* key released, no interest here */
516 case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */
517 case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */
518 case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */
519 case 0xD2: /* keypad 0 */
520 goto next_code;
521
522 case 0x38: /* left alt key */
523 break;
524
525 default:
526 if (sc->sc_composed_char > 0) {
527 sc->sc_flags &= ~HVKBD_FLAG_COMPOSE;
528 sc->sc_composed_char = 0;
529 return (ERRKEY);
530 }
531 break;
532 }
533 }
534
535 /* keycode to key action */
536 action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
537 &sc->sc_state, &sc->sc_accents);
538 if (action == NOKEY)
539 goto next_code;
540 else
541 return (action);
542 }
543
544 /* Currently wait is always false. */
545 static uint32_t
546 hvkbd_read_char(keyboard_t *kbd, int wait)
547 {
548 uint32_t keycode;
549
550 HVKBD_LOCK();
551 keycode = hvkbd_read_char_locked(kbd, wait);
552 HVKBD_UNLOCK();
553
554 return (keycode);
555 }
556
557 /* clear the internal state of the keyboard */
558 static void
559 hvkbd_clear_state(keyboard_t *kbd)
560 {
561 hv_kbd_sc *sc = kbd->kb_data;
562 sc->sc_state &= LOCK_MASK; /* preserve locking key state */
563 sc->sc_flags &= ~(HVKBD_FLAG_POLLING | HVKBD_FLAG_COMPOSE);
564 sc->sc_accents = 0;
565 sc->sc_composed_char = 0;
566 }
567
568 static int
569 hvkbd_ioctl_locked(keyboard_t *kbd, u_long cmd, caddr_t arg)
570 {
571 int i;
572 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
573 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
574 int ival;
575 #endif
576 hv_kbd_sc *sc = kbd->kb_data;
577 switch (cmd) {
578 case KDGKBMODE:
579 *(int *)arg = sc->sc_mode;
580 break;
581 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
582 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
583 case _IO('K', 7):
584 ival = IOCPARM_IVAL(arg);
585 arg = (caddr_t)&ival;
586 /* FALLTHROUGH */
587 #endif
588 case KDSKBMODE: /* set keyboard mode */
589 DEBUG_HVKBD(kbd, "expected mode: %x\n", *(int *)arg);
590 switch (*(int *)arg) {
591 case K_XLATE:
592 if (sc->sc_mode != K_XLATE) {
593 /* make lock key state and LED state match */
594 sc->sc_state &= ~LOCK_MASK;
595 sc->sc_state |= KBD_LED_VAL(kbd);
596 }
597 /* FALLTHROUGH */
598 case K_RAW:
599 case K_CODE:
600 if (sc->sc_mode != *(int *)arg) {
601 DEBUG_HVKBD(kbd, "mod changed to %x\n", *(int *)arg);
602 if ((sc->sc_flags & HVKBD_FLAG_POLLING) == 0)
603 hvkbd_clear_state(kbd);
604 sc->sc_mode = *(int *)arg;
605 }
606 break;
607 default:
608 return (EINVAL);
609 }
610 break;
611 case KDGKBSTATE: /* get lock key state */
612 *(int *)arg = sc->sc_state & LOCK_MASK;
613 break;
614 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
615 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
616 case _IO('K', 20):
617 ival = IOCPARM_IVAL(arg);
618 arg = (caddr_t)&ival;
619 /* FALLTHROUGH */
620 #endif
621 case KDSKBSTATE: /* set lock key state */
622 if (*(int *)arg & ~LOCK_MASK) {
623 return (EINVAL);
624 }
625 sc->sc_state &= ~LOCK_MASK;
626 sc->sc_state |= *(int *)arg;
627 return hvkbd_ioctl_locked(kbd, KDSETLED, arg);
628 case KDGETLED: /* get keyboard LED */
629 *(int *)arg = KBD_LED_VAL(kbd);
630 break;
631 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
632 defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
633 case _IO('K', 66):
634 ival = IOCPARM_IVAL(arg);
635 arg = (caddr_t)&ival;
636 /* FALLTHROUGH */
637 #endif
638 case KDSETLED: /* set keyboard LED */
639 /* NOTE: lock key state in "sc_state" won't be changed */
640 if (*(int *)arg & ~LOCK_MASK)
641 return (EINVAL);
642
643 i = *(int *)arg;
644
645 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
646 if (sc->sc_mode == K_XLATE &&
647 kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
648 if (i & ALKED)
649 i |= CLKED;
650 else
651 i &= ~CLKED;
652 }
653 if (KBD_HAS_DEVICE(kbd)) {
654 DEBUG_HVSC(sc, "setled 0x%x\n", *(int *)arg);
655 }
656
657 #ifdef EVDEV_SUPPORT
658 /* push LED states to evdev */
659 if (sc->ks_evdev != NULL &&
660 evdev_rcpt_mask & EVDEV_RCPT_HW_KBD)
661 evdev_push_leds(sc->ks_evdev, *(int *)arg);
662 #endif
663 KBD_LED_VAL(kbd) = *(int *)arg;
664 break;
665 case PIO_KEYMAP: /* set keyboard translation table */
666 case OPIO_KEYMAP: /* set keyboard translation table (compat) */
667 case PIO_KEYMAPENT: /* set keyboard translation table entry */
668 case PIO_DEADKEYMAP: /* set accent key translation table */
669 sc->sc_accents = 0;
670 /* FALLTHROUGH */
671 default:
672 return (genkbd_commonioctl(kbd, cmd, arg));
673 }
674 return (0);
675 }
676
677 /* some useful control functions */
678 static int
679 hvkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
680 {
681 DEBUG_HVKBD(kbd, "%s: %lx start\n", __func__, cmd);
682 HVKBD_LOCK();
683 int ret = hvkbd_ioctl_locked(kbd, cmd, arg);
684 HVKBD_UNLOCK();
685 DEBUG_HVKBD(kbd, "%s: %lx end %d\n", __func__, cmd, ret);
686 return (ret);
687 }
688
689 /* read one byte from the keyboard if it's allowed */
690 /* Currently unused. */
691 static int
692 hvkbd_read(keyboard_t *kbd, int wait)
693 {
694 DEBUG_HVKBD(kbd, "%s\n", __func__);
695 HVKBD_LOCK_ASSERT();
696 if (!KBD_IS_ACTIVE(kbd))
697 return (-1);
698 return hvkbd_read_char_locked(kbd, wait);
699 }
700
701 #ifdef EVDEV_SUPPORT
702 static void
703 hvkbd_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code,
704 int32_t value)
705 {
706 keyboard_t *kbd = evdev_get_softc(evdev);
707
708 if (evdev_rcpt_mask & EVDEV_RCPT_HW_KBD &&
709 (type == EV_LED || type == EV_REP)) {
710 mtx_lock(&Giant);
711 kbd_ev_event(kbd, type, code, value);
712 mtx_unlock(&Giant);
713 }
714 }
715 #endif
716
717 static keyboard_switch_t hvkbdsw = {
718 .probe = hvkbd_probe, /* not used */
719 .init = hvkbd_init,
720 .term = hvkbd_term, /* not used */
721 .intr = hvkbd_intr, /* not used */
722 .test_if = hvkbd_test_if, /* not used */
723 .enable = hvkbd_enable,
724 .disable = hvkbd_disable,
725 .read = hvkbd_read,
726 .check = hvkbd_check,
727 .read_char = hvkbd_read_char,
728 .check_char = hvkbd_check_char,
729 .ioctl = hvkbd_ioctl,
730 .lock = hvkbd_lock, /* not used */
731 .clear_state = hvkbd_clear_state,
732 .get_state = hvkbd_get_state, /* not used */
733 .set_state = hvkbd_set_state, /* not used */
734 .poll = hvkbd_poll,
735 };
736
737 KEYBOARD_DRIVER(hvkbd, hvkbdsw, hvkbd_configure);
738
739 void
740 hv_kbd_intr(hv_kbd_sc *sc)
741 {
742 uint32_t c;
743 if ((sc->sc_flags & HVKBD_FLAG_POLLING) != 0)
744 return;
745
746 if (KBD_IS_ACTIVE(&sc->sc_kbd) &&
747 KBD_IS_BUSY(&sc->sc_kbd)) {
748 /* let the callback function process the input */
749 (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT,
750 sc->sc_kbd.kb_callback.kc_arg);
751 } else {
752 /* read and discard the input, no one is waiting for it */
753 do {
754 c = hvkbd_read_char(&sc->sc_kbd, 0);
755 } while (c != NOKEY);
756 }
757 }
758
759 int
760 hvkbd_driver_load(module_t mod, int what, void *arg)
761 {
762 switch (what) {
763 case MOD_LOAD:
764 kbd_add_driver(&hvkbd_kbd_driver);
765 break;
766 case MOD_UNLOAD:
767 kbd_delete_driver(&hvkbd_kbd_driver);
768 break;
769 }
770 return (0);
771 }
772
773 int
774 hv_kbd_drv_attach(device_t dev)
775 {
776 hv_kbd_sc *sc = device_get_softc(dev);
777 int unit = device_get_unit(dev);
778 keyboard_t *kbd = &sc->sc_kbd;
779 keyboard_switch_t *sw;
780 #ifdef EVDEV_SUPPORT
781 struct evdev_dev *evdev;
782 #endif
783
784 sw = kbd_get_switch(HVKBD_DRIVER_NAME);
785 if (sw == NULL) {
786 return (ENXIO);
787 }
788
789 kbd_init_struct(kbd, HVKBD_DRIVER_NAME, KB_OTHER, unit, 0, 0, 0);
790 kbd->kb_data = (void *)sc;
791 kbd_set_maps(kbd, &key_map, &accent_map, fkey_tab, nitems(fkey_tab));
792 KBD_FOUND_DEVICE(kbd);
793 hvkbd_clear_state(kbd);
794 KBD_PROBE_DONE(kbd);
795 KBD_INIT_DONE(kbd);
796 sc->sc_mode = K_XLATE;
797 (*sw->enable)(kbd);
798
799 #ifdef EVDEV_SUPPORT
800 evdev = evdev_alloc();
801 evdev_set_name(evdev, "Hyper-V keyboard");
802 evdev_set_phys(evdev, device_get_nameunit(dev));
803 evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0);
804 evdev_set_methods(evdev, kbd, &hvkbd_evdev_methods);
805 evdev_support_event(evdev, EV_SYN);
806 evdev_support_event(evdev, EV_KEY);
807 evdev_support_event(evdev, EV_LED);
808 evdev_support_event(evdev, EV_REP);
809 evdev_support_all_known_keys(evdev);
810 evdev_support_led(evdev, LED_NUML);
811 evdev_support_led(evdev, LED_CAPSL);
812 evdev_support_led(evdev, LED_SCROLLL);
813 if (evdev_register_mtx(evdev, &Giant))
814 evdev_free(evdev);
815 else
816 sc->ks_evdev = evdev;
817 sc->ks_evdev_state = 0;
818 #endif
819
820 if (kbd_register(kbd) < 0) {
821 goto detach;
822 }
823 KBD_CONFIG_DONE(kbd);
824 #ifdef KBD_INSTALL_CDEV
825 if (kbd_attach(kbd)) {
826 goto detach;
827 }
828 #endif
829 if (bootverbose) {
830 kbdd_diag(kbd, bootverbose);
831 }
832 return (0);
833 detach:
834 hv_kbd_drv_detach(dev);
835 return (ENXIO);
836 }
837
838 int
839 hv_kbd_drv_detach(device_t dev)
840 {
841 int error = 0;
842 hv_kbd_sc *sc = device_get_softc(dev);
843 hvkbd_disable(&sc->sc_kbd);
844 #ifdef EVDEV_SUPPORT
845 evdev_free(sc->ks_evdev);
846 #endif
847 if (KBD_IS_CONFIGURED(&sc->sc_kbd)) {
848 error = kbd_unregister(&sc->sc_kbd);
849 if (error) {
850 device_printf(dev, "WARNING: kbd_unregister() "
851 "returned non-zero! (ignored)\n");
852 }
853 }
854 #ifdef KBD_INSTALL_CDEV
855 error = kbd_detach(&sc->sc_kbd);
856 #endif
857 return (error);
858 }
859
Cache object: 0ae25c35ed02bbd29cc7f827b40ffc3a
|