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