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