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