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