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