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 .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 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 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 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 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