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