1 /* 2 * kbdmux.c 3 */ 4 5 /*- 6 * SPDX-License-Identifier: BSD-2-Clause 7 * 8 * Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * $Id: kbdmux.c,v 1.4 2005/07/14 17:38:35 max Exp $ 33 * $FreeBSD$ 34 */ 35 36 #include "opt_evdev.h" 37 #include "opt_kbd.h" 38 #include "opt_kbdmux.h" 39 40 #include <sys/param.h> 41 #include <sys/bus.h> 42 #include <sys/conf.h> 43 #include <sys/consio.h> 44 #include <sys/fcntl.h> 45 #include <sys/kbio.h> 46 #include <sys/kernel.h> 47 #include <sys/limits.h> 48 #include <sys/lock.h> 49 #include <sys/malloc.h> 50 #include <sys/module.h> 51 #include <sys/mutex.h> 52 #include <sys/poll.h> 53 #include <sys/proc.h> 54 #include <sys/queue.h> 55 #include <sys/selinfo.h> 56 #include <sys/systm.h> 57 #include <sys/taskqueue.h> 58 #include <sys/uio.h> 59 #include <dev/kbd/kbdreg.h> 60 61 /* the initial key map, accent map and fkey strings */ 62 #ifdef KBDMUX_DFLT_KEYMAP 63 #define KBD_DFLT_KEYMAP 64 #include "kbdmuxmap.h" 65 #endif 66 67 #include <dev/kbd/kbdtables.h> 68 69 #ifdef EVDEV_SUPPORT 70 #include <dev/evdev/evdev.h> 71 #include <dev/evdev/input.h> 72 #endif 73 74 #define KEYBOARD_NAME "kbdmux" 75 76 MALLOC_DECLARE(M_KBDMUX); 77 MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor"); 78 79 /***************************************************************************** 80 ***************************************************************************** 81 ** Keyboard state 82 ***************************************************************************** 83 *****************************************************************************/ 84 85 #define KBDMUX_Q_SIZE 512 /* input queue size */ 86 87 /* 88 * XXX 89 * For now rely on Giant mutex to protect our data structures. 90 * Just like the rest of keyboard drivers and syscons(4) do. 91 * Note that callout is initialized as not MP-safe to make sure 92 * Giant is held. 93 */ 94 95 #if 0 /* not yet */ 96 #define KBDMUX_LOCK_DECL_GLOBAL \ 97 struct mtx ks_lock 98 #define KBDMUX_LOCK_INIT(s) \ 99 mtx_init(&(s)->ks_lock, "kbdmux", NULL, MTX_DEF|MTX_RECURSE) 100 #define KBDMUX_LOCK_DESTROY(s) \ 101 mtx_destroy(&(s)->ks_lock) 102 #define KBDMUX_LOCK(s) \ 103 mtx_lock(&(s)->ks_lock) 104 #define KBDMUX_UNLOCK(s) \ 105 mtx_unlock(&(s)->ks_lock) 106 #define KBDMUX_LOCK_ASSERT(s, w) \ 107 mtx_assert(&(s)->ks_lock, (w)) 108 #else 109 #define KBDMUX_LOCK_DECL_GLOBAL 110 111 #define KBDMUX_LOCK_INIT(s) 112 113 #define KBDMUX_LOCK_DESTROY(s) 114 115 #define KBDMUX_LOCK(s) 116 117 #define KBDMUX_UNLOCK(s) 118 119 #define KBDMUX_LOCK_ASSERT(s, w) 120 121 #endif /* not yet */ 122 123 /* 124 * kbdmux keyboard 125 */ 126 struct kbdmux_kbd 127 { 128 keyboard_t *kbd; /* keyboard */ 129 SLIST_ENTRY(kbdmux_kbd) next; /* link to next */ 130 }; 131 132 typedef struct kbdmux_kbd kbdmux_kbd_t; 133 134 /* 135 * kbdmux state 136 */ 137 struct kbdmux_state 138 { 139 char ks_inq[KBDMUX_Q_SIZE]; /* input chars queue */ 140 unsigned int ks_inq_start; 141 unsigned int ks_inq_length; 142 struct task ks_task; /* interrupt task */ 143 struct callout ks_timo; /* timeout handler */ 144 #define TICKS (hz) /* rate */ 145 146 int ks_flags; /* flags */ 147 #define COMPOSE (1 << 0) /* compose char flag */ 148 149 int ks_polling; /* poll nesting count */ 150 int ks_mode; /* K_XLATE, K_RAW, K_CODE */ 151 int ks_state; /* state */ 152 int ks_accents; /* accent key index (> 0) */ 153 u_int ks_composed_char; /* composed char code */ 154 u_char ks_prefix; /* AT scan code prefix */ 155 156 #ifdef EVDEV_SUPPORT 157 struct evdev_dev * ks_evdev; 158 int ks_evdev_state; 159 #endif 160 161 SLIST_HEAD(, kbdmux_kbd) ks_kbds; /* keyboards */ 162 163 KBDMUX_LOCK_DECL_GLOBAL; 164 }; 165 166 typedef struct kbdmux_state kbdmux_state_t; 167 168 /***************************************************************************** 169 ***************************************************************************** 170 ** Helper functions 171 ***************************************************************************** 172 *****************************************************************************/ 173 174 static task_fn_t kbdmux_kbd_intr; 175 static callout_func_t kbdmux_kbd_intr_timo; 176 static kbd_callback_func_t kbdmux_kbd_event; 177 178 static void 179 kbdmux_kbd_putc(kbdmux_state_t *state, char c) 180 { 181 unsigned int p; 182 183 if (state->ks_inq_length == KBDMUX_Q_SIZE) 184 return; 185 186 p = (state->ks_inq_start + state->ks_inq_length) % KBDMUX_Q_SIZE; 187 state->ks_inq[p] = c; 188 state->ks_inq_length++; 189 } 190 191 static int 192 kbdmux_kbd_getc(kbdmux_state_t *state) 193 { 194 unsigned char c; 195 196 if (state->ks_inq_length == 0) 197 return (-1); 198 199 c = state->ks_inq[state->ks_inq_start]; 200 state->ks_inq_start = (state->ks_inq_start + 1) % KBDMUX_Q_SIZE; 201 state->ks_inq_length--; 202 203 return (c); 204 } 205 206 /* 207 * Interrupt handler task 208 */ 209 void 210 kbdmux_kbd_intr(void *xkbd, int pending) 211 { 212 keyboard_t *kbd = (keyboard_t *) xkbd; 213 214 kbdd_intr(kbd, NULL); 215 } 216 217 /* 218 * Schedule interrupt handler on timeout. Called with locked state. 219 */ 220 void 221 kbdmux_kbd_intr_timo(void *xstate) 222 { 223 kbdmux_state_t *state = (kbdmux_state_t *) xstate; 224 225 /* queue interrupt task if needed */ 226 if (state->ks_inq_length > 0) 227 taskqueue_enqueue(taskqueue_swi_giant, &state->ks_task); 228 229 /* re-schedule timeout */ 230 callout_schedule(&state->ks_timo, TICKS); 231 } 232 233 /* 234 * Process event from one of our keyboards 235 */ 236 static int 237 kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg) 238 { 239 kbdmux_state_t *state = (kbdmux_state_t *) arg; 240 241 switch (event) { 242 case KBDIO_KEYINPUT: { 243 int c; 244 245 KBDMUX_LOCK(state); 246 247 /* 248 * Read all chars from the keyboard 249 * 250 * Turns out that atkbd(4) check_char() method may return 251 * "true" while read_char() method returns NOKEY. If this 252 * happens we could stuck in the loop below. Avoid this 253 * by breaking out of the loop if read_char() method returns 254 * NOKEY. 255 */ 256 257 while (kbdd_check_char(kbd)) { 258 c = kbdd_read_char(kbd, 0); 259 if (c == NOKEY) 260 break; 261 if (c == ERRKEY) 262 continue; /* XXX ring bell */ 263 if (!KBD_IS_BUSY(kbd)) 264 continue; /* not open - discard the input */ 265 266 kbdmux_kbd_putc(state, c); 267 } 268 269 /* queue interrupt task if needed */ 270 if (state->ks_inq_length > 0) 271 taskqueue_enqueue(taskqueue_swi_giant, &state->ks_task); 272 273 KBDMUX_UNLOCK(state); 274 } break; 275 276 case KBDIO_UNLOADING: { 277 kbdmux_kbd_t *k; 278 279 KBDMUX_LOCK(state); 280 281 SLIST_FOREACH(k, &state->ks_kbds, next) 282 if (k->kbd == kbd) 283 break; 284 285 if (k != NULL) { 286 kbd_release(k->kbd, &k->kbd); 287 SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next); 288 289 k->kbd = NULL; 290 291 free(k, M_KBDMUX); 292 } 293 294 KBDMUX_UNLOCK(state); 295 } break; 296 297 default: 298 return (EINVAL); 299 /* NOT REACHED */ 300 } 301 302 return (0); 303 } 304 305 /**************************************************************************** 306 **************************************************************************** 307 ** Keyboard driver 308 **************************************************************************** 309 ****************************************************************************/ 310 311 static int kbdmux_configure(int flags); 312 static kbd_probe_t kbdmux_probe; 313 static kbd_init_t kbdmux_init; 314 static kbd_term_t kbdmux_term; 315 static kbd_intr_t kbdmux_intr; 316 static kbd_test_if_t kbdmux_test_if; 317 static kbd_enable_t kbdmux_enable; 318 static kbd_disable_t kbdmux_disable; 319 static kbd_read_t kbdmux_read; 320 static kbd_check_t kbdmux_check; 321 static kbd_read_char_t kbdmux_read_char; 322 static kbd_check_char_t kbdmux_check_char; 323 static kbd_ioctl_t kbdmux_ioctl; 324 static kbd_lock_t kbdmux_lock; 325 static void kbdmux_clear_state_locked(kbdmux_state_t *state); 326 static kbd_clear_state_t kbdmux_clear_state; 327 static kbd_get_state_t kbdmux_get_state; 328 static kbd_set_state_t kbdmux_set_state; 329 static kbd_poll_mode_t kbdmux_poll; 330 331 static keyboard_switch_t kbdmuxsw = { 332 .probe = kbdmux_probe, 333 .init = kbdmux_init, 334 .term = kbdmux_term, 335 .intr = kbdmux_intr, 336 .test_if = kbdmux_test_if, 337 .enable = kbdmux_enable, 338 .disable = kbdmux_disable, 339 .read = kbdmux_read, 340 .check = kbdmux_check, 341 .read_char = kbdmux_read_char, 342 .check_char = kbdmux_check_char, 343 .ioctl = kbdmux_ioctl, 344 .lock = kbdmux_lock, 345 .clear_state = kbdmux_clear_state, 346 .get_state = kbdmux_get_state, 347 .set_state = kbdmux_set_state, 348 .poll = kbdmux_poll, 349 }; 350 351 #ifdef EVDEV_SUPPORT 352 static evdev_event_t kbdmux_ev_event; 353 354 static const struct evdev_methods kbdmux_evdev_methods = { 355 .ev_event = kbdmux_ev_event, 356 }; 357 #endif 358 359 /* 360 * Return the number of found keyboards 361 */ 362 static int 363 kbdmux_configure(int flags) 364 { 365 return (1); 366 } 367 368 /* 369 * Detect a keyboard 370 */ 371 static int 372 kbdmux_probe(int unit, void *arg, int flags) 373 { 374 if (resource_disabled(KEYBOARD_NAME, unit)) 375 return (ENXIO); 376 377 return (0); 378 } 379 380 /* 381 * Reset and initialize the keyboard (stolen from atkbd.c) 382 */ 383 static int 384 kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags) 385 { 386 keyboard_t *kbd = NULL; 387 kbdmux_state_t *state = NULL; 388 keymap_t *keymap = NULL; 389 accentmap_t *accmap = NULL; 390 fkeytab_t *fkeymap = NULL; 391 int error, needfree, fkeymap_size, delay[2]; 392 #ifdef EVDEV_SUPPORT 393 struct evdev_dev *evdev; 394 char phys_loc[NAMELEN]; 395 #endif 396 397 if (*kbdp == NULL) { 398 *kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO); 399 state = malloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO); 400 keymap = malloc(sizeof(key_map), M_KBDMUX, M_NOWAIT); 401 accmap = malloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT); 402 fkeymap = malloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT); 403 fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]); 404 needfree = 1; 405 406 if ((kbd == NULL) || (state == NULL) || (keymap == NULL) || 407 (accmap == NULL) || (fkeymap == NULL)) { 408 error = ENOMEM; 409 goto bad; 410 } 411 412 KBDMUX_LOCK_INIT(state); 413 TASK_INIT(&state->ks_task, 0, kbdmux_kbd_intr, (void *) kbd); 414 callout_init(&state->ks_timo, 1); 415 SLIST_INIT(&state->ks_kbds); 416 } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) { 417 return (0); 418 } else { 419 kbd = *kbdp; 420 state = (kbdmux_state_t *) kbd->kb_data; 421 keymap = kbd->kb_keymap; 422 accmap = kbd->kb_accentmap; 423 fkeymap = kbd->kb_fkeytab; 424 fkeymap_size = kbd->kb_fkeytab_size; 425 needfree = 0; 426 } 427 428 if (!KBD_IS_PROBED(kbd)) { 429 /* XXX assume 101/102 keys keyboard */ 430 kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, 0, 0); 431 bcopy(&key_map, keymap, sizeof(key_map)); 432 bcopy(&accent_map, accmap, sizeof(accent_map)); 433 bcopy(fkey_tab, fkeymap, 434 imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); 435 kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); 436 kbd->kb_data = (void *)state; 437 438 KBD_FOUND_DEVICE(kbd); 439 KBD_PROBE_DONE(kbd); 440 441 KBDMUX_LOCK(state); 442 kbdmux_clear_state_locked(state); 443 state->ks_mode = K_XLATE; 444 KBDMUX_UNLOCK(state); 445 } 446 447 if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { 448 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY; 449 450 kbdmux_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); 451 452 delay[0] = kbd->kb_delay1; 453 delay[1] = kbd->kb_delay2; 454 kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); 455 456 #ifdef EVDEV_SUPPORT 457 /* register as evdev provider */ 458 evdev = evdev_alloc(); 459 evdev_set_name(evdev, "System keyboard multiplexer"); 460 snprintf(phys_loc, NAMELEN, KEYBOARD_NAME"%d", unit); 461 evdev_set_phys(evdev, phys_loc); 462 evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0); 463 evdev_set_methods(evdev, kbd, &kbdmux_evdev_methods); 464 evdev_support_event(evdev, EV_SYN); 465 evdev_support_event(evdev, EV_KEY); 466 evdev_support_event(evdev, EV_LED); 467 evdev_support_event(evdev, EV_REP); 468 evdev_support_all_known_keys(evdev); 469 evdev_support_led(evdev, LED_NUML); 470 evdev_support_led(evdev, LED_CAPSL); 471 evdev_support_led(evdev, LED_SCROLLL); 472 473 if (evdev_register_mtx(evdev, &Giant)) 474 evdev_free(evdev); 475 else 476 state->ks_evdev = evdev; 477 state->ks_evdev_state = 0; 478 #endif 479 480 KBD_INIT_DONE(kbd); 481 } 482 483 if (!KBD_IS_CONFIGURED(kbd)) { 484 if (kbd_register(kbd) < 0) { 485 error = ENXIO; 486 goto bad; 487 } 488 489 KBD_CONFIG_DONE(kbd); 490 491 callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, state); 492 } 493 494 return (0); 495 bad: 496 if (needfree) { 497 if (state != NULL) 498 free(state, M_KBDMUX); 499 if (keymap != NULL) 500 free(keymap, M_KBDMUX); 501 if (accmap != NULL) 502 free(accmap, M_KBDMUX); 503 if (fkeymap != NULL) 504 free(fkeymap, M_KBDMUX); 505 if (kbd != NULL) { 506 free(kbd, M_KBDMUX); 507 *kbdp = NULL; /* insure ref doesn't leak to caller */ 508 } 509 } 510 511 return (error); 512 } 513 514 /* 515 * Finish using this keyboard 516 */ 517 static int 518 kbdmux_term(keyboard_t *kbd) 519 { 520 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 521 kbdmux_kbd_t *k; 522 523 /* release all keyboards from the mux */ 524 KBDMUX_LOCK(state); 525 while ((k = SLIST_FIRST(&state->ks_kbds)) != NULL) { 526 kbd_release(k->kbd, &k->kbd); 527 SLIST_REMOVE_HEAD(&state->ks_kbds, next); 528 529 k->kbd = NULL; 530 531 free(k, M_KBDMUX); 532 } 533 KBDMUX_UNLOCK(state); 534 535 callout_drain(&state->ks_timo); 536 taskqueue_drain(taskqueue_swi_giant, &state->ks_task); 537 538 kbd_unregister(kbd); 539 540 #ifdef EVDEV_SUPPORT 541 evdev_free(state->ks_evdev); 542 #endif 543 544 KBDMUX_LOCK_DESTROY(state); 545 bzero(state, sizeof(*state)); 546 free(state, M_KBDMUX); 547 548 free(kbd->kb_keymap, M_KBDMUX); 549 free(kbd->kb_accentmap, M_KBDMUX); 550 free(kbd->kb_fkeytab, M_KBDMUX); 551 free(kbd, M_KBDMUX); 552 553 return (0); 554 } 555 556 /* 557 * Keyboard interrupt routine 558 */ 559 static int 560 kbdmux_intr(keyboard_t *kbd, void *arg) 561 { 562 int c; 563 564 if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { 565 /* let the callback function to process the input */ 566 (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, 567 kbd->kb_callback.kc_arg); 568 } else { 569 /* read and discard the input; no one is waiting for input */ 570 do { 571 c = kbdmux_read_char(kbd, FALSE); 572 } while (c != NOKEY); 573 } 574 575 return (0); 576 } 577 578 /* 579 * Test the interface to the device 580 */ 581 static int 582 kbdmux_test_if(keyboard_t *kbd) 583 { 584 return (0); 585 } 586 587 /* 588 * Enable the access to the device; until this function is called, 589 * the client cannot read from the keyboard. 590 */ 591 static int 592 kbdmux_enable(keyboard_t *kbd) 593 { 594 KBD_ACTIVATE(kbd); 595 return (0); 596 } 597 598 /* 599 * Disallow the access to the device 600 */ 601 static int 602 kbdmux_disable(keyboard_t *kbd) 603 { 604 KBD_DEACTIVATE(kbd); 605 return (0); 606 } 607 608 /* 609 * Read one byte from the keyboard if it's allowed 610 */ 611 static int 612 kbdmux_read(keyboard_t *kbd, int wait) 613 { 614 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 615 int c; 616 617 KBDMUX_LOCK(state); 618 c = kbdmux_kbd_getc(state); 619 KBDMUX_UNLOCK(state); 620 621 if (c != -1) 622 kbd->kb_count ++; 623 624 return (KBD_IS_ACTIVE(kbd)? c : -1); 625 } 626 627 /* 628 * Check if data is waiting 629 */ 630 static int 631 kbdmux_check(keyboard_t *kbd) 632 { 633 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 634 int ready; 635 636 if (!KBD_IS_ACTIVE(kbd)) 637 return (FALSE); 638 639 KBDMUX_LOCK(state); 640 ready = (state->ks_inq_length > 0) ? TRUE : FALSE; 641 KBDMUX_UNLOCK(state); 642 643 return (ready); 644 } 645 646 /* 647 * Read char from the keyboard (stolen from atkbd.c) 648 */ 649 static u_int 650 kbdmux_read_char(keyboard_t *kbd, int wait) 651 { 652 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 653 u_int action; 654 int scancode, keycode; 655 656 KBDMUX_LOCK(state); 657 658 next_code: 659 660 /* do we have a composed char to return? */ 661 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) { 662 action = state->ks_composed_char; 663 state->ks_composed_char = 0; 664 if (action > UCHAR_MAX) { 665 KBDMUX_UNLOCK(state); 666 667 return (ERRKEY); 668 } 669 670 KBDMUX_UNLOCK(state); 671 672 return (action); 673 } 674 675 /* see if there is something in the keyboard queue */ 676 scancode = kbdmux_kbd_getc(state); 677 if (scancode == -1) { 678 if (state->ks_polling != 0) { 679 kbdmux_kbd_t *k; 680 681 SLIST_FOREACH(k, &state->ks_kbds, next) { 682 while (kbdd_check_char(k->kbd)) { 683 scancode = kbdd_read_char(k->kbd, 0); 684 if (scancode == NOKEY) 685 break; 686 if (scancode == ERRKEY) 687 continue; 688 if (!KBD_IS_BUSY(k->kbd)) 689 continue; 690 691 kbdmux_kbd_putc(state, scancode); 692 } 693 } 694 695 if (state->ks_inq_length > 0) 696 goto next_code; 697 } 698 699 KBDMUX_UNLOCK(state); 700 return (NOKEY); 701 } 702 /* XXX FIXME: check for -1 if wait == 1! */ 703 704 kbd->kb_count ++; 705 706 #ifdef EVDEV_SUPPORT 707 /* push evdev event */ 708 if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX && state->ks_evdev != NULL) { 709 uint16_t key = evdev_scancode2key(&state->ks_evdev_state, 710 scancode); 711 712 if (key != KEY_RESERVED) { 713 evdev_push_event(state->ks_evdev, EV_KEY, 714 key, scancode & 0x80 ? 0 : 1); 715 evdev_sync(state->ks_evdev); 716 } 717 } 718 719 if (state->ks_evdev != NULL && evdev_is_grabbed(state->ks_evdev)) 720 return (NOKEY); 721 #endif 722 723 /* return the byte as is for the K_RAW mode */ 724 if (state->ks_mode == K_RAW) { 725 KBDMUX_UNLOCK(state); 726 return (scancode); 727 } 728 729 /* translate the scan code into a keycode */ 730 keycode = scancode & 0x7F; 731 switch (state->ks_prefix) { 732 case 0x00: /* normal scancode */ 733 switch(scancode) { 734 case 0xB8: /* left alt (compose key) released */ 735 if (state->ks_flags & COMPOSE) { 736 state->ks_flags &= ~COMPOSE; 737 if (state->ks_composed_char > UCHAR_MAX) 738 state->ks_composed_char = 0; 739 } 740 break; 741 case 0x38: /* left alt (compose key) pressed */ 742 if (!(state->ks_flags & COMPOSE)) { 743 state->ks_flags |= COMPOSE; 744 state->ks_composed_char = 0; 745 } 746 break; 747 case 0xE0: 748 case 0xE1: 749 state->ks_prefix = scancode; 750 goto next_code; 751 } 752 break; 753 case 0xE0: /* 0xE0 prefix */ 754 state->ks_prefix = 0; 755 switch (keycode) { 756 case 0x1C: /* right enter key */ 757 keycode = 0x59; 758 break; 759 case 0x1D: /* right ctrl key */ 760 keycode = 0x5A; 761 break; 762 case 0x35: /* keypad divide key */ 763 keycode = 0x5B; 764 break; 765 case 0x37: /* print scrn key */ 766 keycode = 0x5C; 767 break; 768 case 0x38: /* right alt key (alt gr) */ 769 keycode = 0x5D; 770 break; 771 case 0x46: /* ctrl-pause/break on AT 101 (see below) */ 772 keycode = 0x68; 773 break; 774 case 0x47: /* grey home key */ 775 keycode = 0x5E; 776 break; 777 case 0x48: /* grey up arrow key */ 778 keycode = 0x5F; 779 break; 780 case 0x49: /* grey page up key */ 781 keycode = 0x60; 782 break; 783 case 0x4B: /* grey left arrow key */ 784 keycode = 0x61; 785 break; 786 case 0x4D: /* grey right arrow key */ 787 keycode = 0x62; 788 break; 789 case 0x4F: /* grey end key */ 790 keycode = 0x63; 791 break; 792 case 0x50: /* grey down arrow key */ 793 keycode = 0x64; 794 break; 795 case 0x51: /* grey page down key */ 796 keycode = 0x65; 797 break; 798 case 0x52: /* grey insert key */ 799 keycode = 0x66; 800 break; 801 case 0x53: /* grey delete key */ 802 keycode = 0x67; 803 break; 804 /* the following 3 are only used on the MS "Natural" keyboard */ 805 case 0x5b: /* left Window key */ 806 keycode = 0x69; 807 break; 808 case 0x5c: /* right Window key */ 809 keycode = 0x6a; 810 break; 811 case 0x5d: /* menu key */ 812 keycode = 0x6b; 813 break; 814 case 0x5e: /* power key */ 815 keycode = 0x6d; 816 break; 817 case 0x5f: /* sleep key */ 818 keycode = 0x6e; 819 break; 820 case 0x63: /* wake key */ 821 keycode = 0x6f; 822 break; 823 case 0x64: /* [JP106USB] backslash, underscore */ 824 keycode = 0x73; 825 break; 826 default: /* ignore everything else */ 827 goto next_code; 828 } 829 break; 830 case 0xE1: /* 0xE1 prefix */ 831 /* 832 * The pause/break key on the 101 keyboard produces: 833 * E1-1D-45 E1-9D-C5 834 * Ctrl-pause/break produces: 835 * E0-46 E0-C6 (See above.) 836 */ 837 state->ks_prefix = 0; 838 if (keycode == 0x1D) 839 state->ks_prefix = 0x1D; 840 goto next_code; 841 /* NOT REACHED */ 842 case 0x1D: /* pause / break */ 843 state->ks_prefix = 0; 844 if (keycode != 0x45) 845 goto next_code; 846 keycode = 0x68; 847 break; 848 } 849 850 /* XXX assume 101/102 keys AT keyboard */ 851 switch (keycode) { 852 case 0x5c: /* print screen */ 853 if (state->ks_flags & ALTS) 854 keycode = 0x54; /* sysrq */ 855 break; 856 case 0x68: /* pause/break */ 857 if (state->ks_flags & CTLS) 858 keycode = 0x6c; /* break */ 859 break; 860 } 861 862 /* return the key code in the K_CODE mode */ 863 if (state->ks_mode == K_CODE) { 864 KBDMUX_UNLOCK(state); 865 return (keycode | (scancode & 0x80)); 866 } 867 868 /* compose a character code */ 869 if (state->ks_flags & COMPOSE) { 870 switch (keycode | (scancode & 0x80)) { 871 /* key pressed, process it */ 872 case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ 873 state->ks_composed_char *= 10; 874 state->ks_composed_char += keycode - 0x40; 875 if (state->ks_composed_char > UCHAR_MAX) { 876 KBDMUX_UNLOCK(state); 877 return (ERRKEY); 878 } 879 goto next_code; 880 case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ 881 state->ks_composed_char *= 10; 882 state->ks_composed_char += keycode - 0x47; 883 if (state->ks_composed_char > UCHAR_MAX) { 884 KBDMUX_UNLOCK(state); 885 return (ERRKEY); 886 } 887 goto next_code; 888 case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ 889 state->ks_composed_char *= 10; 890 state->ks_composed_char += keycode - 0x4E; 891 if (state->ks_composed_char > UCHAR_MAX) { 892 KBDMUX_UNLOCK(state); 893 return (ERRKEY); 894 } 895 goto next_code; 896 case 0x52: /* keypad 0 */ 897 state->ks_composed_char *= 10; 898 if (state->ks_composed_char > UCHAR_MAX) { 899 KBDMUX_UNLOCK(state); 900 return (ERRKEY); 901 } 902 goto next_code; 903 904 /* key released, no interest here */ 905 case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ 906 case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ 907 case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ 908 case 0xD2: /* keypad 0 */ 909 goto next_code; 910 911 case 0x38: /* left alt key */ 912 break; 913 914 default: 915 if (state->ks_composed_char > 0) { 916 state->ks_flags &= ~COMPOSE; 917 state->ks_composed_char = 0; 918 KBDMUX_UNLOCK(state); 919 return (ERRKEY); 920 } 921 break; 922 } 923 } 924 925 /* keycode to key action */ 926 action = genkbd_keyaction(kbd, keycode, scancode & 0x80, 927 &state->ks_state, &state->ks_accents); 928 if (action == NOKEY) 929 goto next_code; 930 931 KBDMUX_UNLOCK(state); 932 933 return (action); 934 } 935 936 /* 937 * Check if char is waiting 938 */ 939 static int 940 kbdmux_check_char(keyboard_t *kbd) 941 { 942 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 943 int ready; 944 945 if (!KBD_IS_ACTIVE(kbd)) 946 return (FALSE); 947 948 KBDMUX_LOCK(state); 949 950 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0)) 951 ready = TRUE; 952 else 953 ready = (state->ks_inq_length > 0) ? TRUE : FALSE; 954 955 KBDMUX_UNLOCK(state); 956 957 return (ready); 958 } 959 960 /* 961 * Keyboard ioctl's 962 */ 963 static int 964 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) 965 { 966 static int delays[] = { 967 250, 500, 750, 1000 968 }; 969 970 static int rates[] = { 971 34, 38, 42, 46, 50, 55, 59, 63, 972 68, 76, 84, 92, 100, 110, 118, 126, 973 136, 152, 168, 184, 200, 220, 236, 252, 974 272, 304, 336, 368, 400, 440, 472, 504 975 }; 976 977 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 978 kbdmux_kbd_t *k; 979 keyboard_info_t *ki; 980 int error = 0, mode; 981 #ifdef COMPAT_FREEBSD6 982 int ival; 983 #endif 984 985 if (state == NULL) 986 return (ENXIO); 987 988 switch (cmd) { 989 case KBADDKBD: /* add keyboard to the mux */ 990 ki = (keyboard_info_t *) arg; 991 992 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' || 993 strcmp(ki->kb_name, "*") == 0) 994 return (EINVAL); /* bad input */ 995 996 KBDMUX_LOCK(state); 997 998 SLIST_FOREACH(k, &state->ks_kbds, next) 999 if (k->kbd->kb_unit == ki->kb_unit && 1000 strcmp(k->kbd->kb_name, ki->kb_name) == 0) 1001 break; 1002 1003 if (k != NULL) { 1004 KBDMUX_UNLOCK(state); 1005 1006 return (0); /* keyboard already in the mux */ 1007 } 1008 1009 k = malloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO); 1010 if (k == NULL) { 1011 KBDMUX_UNLOCK(state); 1012 1013 return (ENOMEM); /* out of memory */ 1014 } 1015 1016 k->kbd = kbd_get_keyboard( 1017 kbd_allocate( 1018 ki->kb_name, 1019 ki->kb_unit, 1020 (void *) &k->kbd, 1021 kbdmux_kbd_event, (void *) state)); 1022 if (k->kbd == NULL) { 1023 KBDMUX_UNLOCK(state); 1024 free(k, M_KBDMUX); 1025 1026 return (EINVAL); /* bad keyboard */ 1027 } 1028 1029 kbdd_enable(k->kbd); 1030 kbdd_clear_state(k->kbd); 1031 1032 /* set K_RAW mode on slave keyboard */ 1033 mode = K_RAW; 1034 error = kbdd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode); 1035 if (error == 0) { 1036 /* set lock keys state on slave keyboard */ 1037 mode = state->ks_state & LOCK_MASK; 1038 error = kbdd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode); 1039 } 1040 1041 if (error != 0) { 1042 KBDMUX_UNLOCK(state); 1043 1044 kbd_release(k->kbd, &k->kbd); 1045 k->kbd = NULL; 1046 1047 free(k, M_KBDMUX); 1048 1049 return (error); /* could not set mode */ 1050 } 1051 1052 SLIST_INSERT_HEAD(&state->ks_kbds, k, next); 1053 1054 KBDMUX_UNLOCK(state); 1055 break; 1056 1057 case KBRELKBD: /* release keyboard from the mux */ 1058 ki = (keyboard_info_t *) arg; 1059 1060 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' || 1061 strcmp(ki->kb_name, "*") == 0) 1062 return (EINVAL); /* bad input */ 1063 1064 KBDMUX_LOCK(state); 1065 1066 SLIST_FOREACH(k, &state->ks_kbds, next) 1067 if (k->kbd->kb_unit == ki->kb_unit && 1068 strcmp(k->kbd->kb_name, ki->kb_name) == 0) 1069 break; 1070 1071 if (k != NULL) { 1072 error = kbd_release(k->kbd, &k->kbd); 1073 if (error == 0) { 1074 SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next); 1075 1076 k->kbd = NULL; 1077 1078 free(k, M_KBDMUX); 1079 } 1080 } else 1081 error = ENXIO; /* keyboard is not in the mux */ 1082 1083 KBDMUX_UNLOCK(state); 1084 break; 1085 1086 case KDGKBMODE: /* get kyboard mode */ 1087 KBDMUX_LOCK(state); 1088 *(int *)arg = state->ks_mode; 1089 KBDMUX_UNLOCK(state); 1090 break; 1091 1092 #ifdef COMPAT_FREEBSD6 1093 case _IO('K', 7): 1094 ival = IOCPARM_IVAL(arg); 1095 arg = (caddr_t)&ival; 1096 /* FALLTHROUGH */ 1097 #endif 1098 case KDSKBMODE: /* set keyboard mode */ 1099 KBDMUX_LOCK(state); 1100 1101 switch (*(int *)arg) { 1102 case K_XLATE: 1103 if (state->ks_mode != K_XLATE) { 1104 /* make lock key state and LED state match */ 1105 state->ks_state &= ~LOCK_MASK; 1106 state->ks_state |= KBD_LED_VAL(kbd); 1107 } 1108 /* FALLTHROUGH */ 1109 1110 case K_RAW: 1111 case K_CODE: 1112 if (state->ks_mode != *(int *)arg) { 1113 kbdmux_clear_state_locked(state); 1114 state->ks_mode = *(int *)arg; 1115 } 1116 break; 1117 1118 default: 1119 error = EINVAL; 1120 break; 1121 } 1122 1123 KBDMUX_UNLOCK(state); 1124 break; 1125 1126 case KDGETLED: /* get keyboard LED */ 1127 KBDMUX_LOCK(state); 1128 *(int *)arg = KBD_LED_VAL(kbd); 1129 KBDMUX_UNLOCK(state); 1130 break; 1131 1132 #ifdef COMPAT_FREEBSD6 1133 case _IO('K', 66): 1134 ival = IOCPARM_IVAL(arg); 1135 arg = (caddr_t)&ival; 1136 /* FALLTHROUGH */ 1137 #endif 1138 case KDSETLED: /* set keyboard LED */ 1139 KBDMUX_LOCK(state); 1140 1141 /* NOTE: lock key state in ks_state won't be changed */ 1142 if (*(int *)arg & ~LOCK_MASK) { 1143 KBDMUX_UNLOCK(state); 1144 1145 return (EINVAL); 1146 } 1147 1148 KBD_LED_VAL(kbd) = *(int *)arg; 1149 #ifdef EVDEV_SUPPORT 1150 if (state->ks_evdev != NULL && 1151 evdev_rcpt_mask & EVDEV_RCPT_KBDMUX) 1152 evdev_push_leds(state->ks_evdev, *(int *)arg); 1153 #endif 1154 /* KDSETLED on all slave keyboards */ 1155 SLIST_FOREACH(k, &state->ks_kbds, next) 1156 (void)kbdd_ioctl(k->kbd, KDSETLED, arg); 1157 1158 KBDMUX_UNLOCK(state); 1159 break; 1160 1161 case KDGKBSTATE: /* get lock key state */ 1162 KBDMUX_LOCK(state); 1163 *(int *)arg = state->ks_state & LOCK_MASK; 1164 KBDMUX_UNLOCK(state); 1165 break; 1166 1167 #ifdef COMPAT_FREEBSD6 1168 case _IO('K', 20): 1169 ival = IOCPARM_IVAL(arg); 1170 arg = (caddr_t)&ival; 1171 /* FALLTHROUGH */ 1172 #endif 1173 case KDSKBSTATE: /* set lock key state */ 1174 KBDMUX_LOCK(state); 1175 1176 if (*(int *)arg & ~LOCK_MASK) { 1177 KBDMUX_UNLOCK(state); 1178 1179 return (EINVAL); 1180 } 1181 1182 state->ks_state &= ~LOCK_MASK; 1183 state->ks_state |= *(int *)arg; 1184 1185 /* KDSKBSTATE on all slave keyboards */ 1186 SLIST_FOREACH(k, &state->ks_kbds, next) 1187 (void)kbdd_ioctl(k->kbd, KDSKBSTATE, arg); 1188 1189 KBDMUX_UNLOCK(state); 1190 1191 return (kbdmux_ioctl(kbd, KDSETLED, arg)); 1192 /* NOT REACHED */ 1193 1194 #ifdef COMPAT_FREEBSD6 1195 case _IO('K', 67): 1196 cmd = KDSETRAD; 1197 ival = IOCPARM_IVAL(arg); 1198 arg = (caddr_t)&ival; 1199 /* FALLTHROUGH */ 1200 #endif 1201 case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ 1202 case KDSETRAD: /* set keyboard repeat rate (old interface) */ 1203 KBDMUX_LOCK(state); 1204 1205 if (cmd == KDSETREPEAT) { 1206 int i; 1207 1208 /* lookup delay */ 1209 for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --) 1210 if (((int *)arg)[0] >= delays[i]) 1211 break; 1212 mode = i << 5; 1213 1214 /* lookup rate */ 1215 for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --) 1216 if (((int *)arg)[1] >= rates[i]) 1217 break; 1218 mode |= i; 1219 } else 1220 mode = *(int *)arg; 1221 1222 if (mode & ~0x7f) { 1223 KBDMUX_UNLOCK(state); 1224 1225 return (EINVAL); 1226 } 1227 1228 kbd->kb_delay1 = delays[(mode >> 5) & 3]; 1229 kbd->kb_delay2 = rates[mode & 0x1f]; 1230 #ifdef EVDEV_SUPPORT 1231 if (state->ks_evdev != NULL && 1232 evdev_rcpt_mask & EVDEV_RCPT_KBDMUX) 1233 evdev_push_repeats(state->ks_evdev, kbd); 1234 #endif 1235 /* perform command on all slave keyboards */ 1236 SLIST_FOREACH(k, &state->ks_kbds, next) 1237 (void)kbdd_ioctl(k->kbd, cmd, arg); 1238 1239 KBDMUX_UNLOCK(state); 1240 break; 1241 1242 case PIO_KEYMAP: /* set keyboard translation table */ 1243 case PIO_KEYMAPENT: /* set keyboard translation table entry */ 1244 case PIO_DEADKEYMAP: /* set accent key translation table */ 1245 #ifdef COMPAT_FREEBSD13 1246 case OPIO_KEYMAP: /* set keyboard translation table (compat) */ 1247 case OPIO_DEADKEYMAP: /* set accent key translation table (compat) */ 1248 KBDMUX_LOCK(state); 1249 state->ks_accents = 0; 1250 #endif /* COMPAT_FREEBSD13 */ 1251 1252 /* perform command on all slave keyboards */ 1253 SLIST_FOREACH(k, &state->ks_kbds, next) 1254 (void)kbdd_ioctl(k->kbd, cmd, arg); 1255 1256 KBDMUX_UNLOCK(state); 1257 /* FALLTHROUGH */ 1258 1259 default: 1260 error = genkbd_commonioctl(kbd, cmd, arg); 1261 break; 1262 } 1263 1264 return (error); 1265 } 1266 1267 /* 1268 * Lock the access to the keyboard 1269 */ 1270 static int 1271 kbdmux_lock(keyboard_t *kbd, int lock) 1272 { 1273 return (1); /* XXX */ 1274 } 1275 1276 /* 1277 * Clear the internal state of the keyboard 1278 */ 1279 static void 1280 kbdmux_clear_state_locked(kbdmux_state_t *state) 1281 { 1282 KBDMUX_LOCK_ASSERT(state, MA_OWNED); 1283 1284 state->ks_flags &= ~COMPOSE; 1285 state->ks_polling = 0; 1286 state->ks_state &= LOCK_MASK; /* preserve locking key state */ 1287 state->ks_accents = 0; 1288 state->ks_composed_char = 0; 1289 /* state->ks_prefix = 0; XXX */ 1290 state->ks_inq_length = 0; 1291 } 1292 1293 static void 1294 kbdmux_clear_state(keyboard_t *kbd) 1295 { 1296 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 1297 1298 KBDMUX_LOCK(state); 1299 kbdmux_clear_state_locked(state); 1300 KBDMUX_UNLOCK(state); 1301 } 1302 1303 /* 1304 * Save the internal state 1305 */ 1306 static int 1307 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len) 1308 { 1309 if (len == 0) 1310 return (sizeof(kbdmux_state_t)); 1311 if (len < sizeof(kbdmux_state_t)) 1312 return (-1); 1313 1314 bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */ 1315 1316 return (0); 1317 } 1318 1319 /* 1320 * Set the internal state 1321 */ 1322 static int 1323 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len) 1324 { 1325 if (len < sizeof(kbdmux_state_t)) 1326 return (ENOMEM); 1327 1328 bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */ 1329 1330 return (0); 1331 } 1332 1333 /* 1334 * Set polling 1335 */ 1336 static int 1337 kbdmux_poll(keyboard_t *kbd, int on) 1338 { 1339 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; 1340 kbdmux_kbd_t *k; 1341 1342 KBDMUX_LOCK(state); 1343 1344 if (on) 1345 state->ks_polling++; 1346 else 1347 state->ks_polling--; 1348 1349 /* set poll on slave keyboards */ 1350 SLIST_FOREACH(k, &state->ks_kbds, next) 1351 kbdd_poll(k->kbd, on); 1352 1353 KBDMUX_UNLOCK(state); 1354 1355 return (0); 1356 } 1357 1358 #ifdef EVDEV_SUPPORT 1359 static void 1360 kbdmux_ev_event(struct evdev_dev *evdev, uint16_t type, uint16_t code, 1361 int32_t value) 1362 { 1363 keyboard_t *kbd = evdev_get_softc(evdev); 1364 1365 if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX && 1366 (type == EV_LED || type == EV_REP)) { 1367 mtx_lock(&Giant); 1368 kbd_ev_event(kbd, type, code, value); 1369 mtx_unlock(&Giant); 1370 } 1371 } 1372 #endif 1373 1374 /***************************************************************************** 1375 ***************************************************************************** 1376 ** Module 1377 ***************************************************************************** 1378 *****************************************************************************/ 1379 1380 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure); 1381 1382 static int 1383 kbdmux_modevent(module_t mod, int type, void *data) 1384 { 1385 keyboard_switch_t *sw; 1386 keyboard_t *kbd; 1387 int error; 1388 1389 switch (type) { 1390 case MOD_LOAD: 1391 if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0) 1392 break; 1393 1394 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) { 1395 error = ENXIO; 1396 break; 1397 } 1398 1399 kbd = NULL; 1400 1401 if ((error = (*sw->probe)(0, NULL, 0)) != 0 || 1402 (error = (*sw->init)(0, &kbd, NULL, 0)) != 0) 1403 break; 1404 1405 #ifdef KBD_INSTALL_CDEV 1406 if ((error = kbd_attach(kbd)) != 0) { 1407 (*sw->term)(kbd); 1408 break; 1409 } 1410 #endif 1411 1412 if ((error = (*sw->enable)(kbd)) != 0) 1413 break; 1414 break; 1415 1416 case MOD_UNLOAD: 1417 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) { 1418 error = 0; 1419 break; 1420 } 1421 1422 kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0)); 1423 if (kbd != NULL) { 1424 (*sw->disable)(kbd); 1425 #ifdef KBD_INSTALL_CDEV 1426 kbd_detach(kbd); 1427 #endif 1428 (*sw->term)(kbd); 1429 } 1430 kbd_delete_driver(&kbdmux_kbd_driver); 1431 error = 0; 1432 break; 1433 1434 default: 1435 error = EOPNOTSUPP; 1436 break; 1437 } 1438 1439 return (error); 1440 } 1441 1442 DEV_MODULE(kbdmux, kbdmux_modevent, NULL); 1443 #ifdef EVDEV_SUPPORT 1444 MODULE_DEPEND(kbdmux, evdev, 1, 1, 1); 1445 #endif 1446