1 /*- 2 * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer as 10 * the first lines of this file unmodified. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_kbd.h" 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/conf.h> 38 #include <sys/fcntl.h> 39 #include <sys/tty.h> 40 #include <sys/poll.h> 41 #include <sys/priv.h> 42 #include <sys/proc.h> 43 #include <sys/sysctl.h> 44 #include <sys/uio.h> 45 46 #include <sys/kbio.h> 47 48 #include <dev/kbd/kbdreg.h> 49 50 #define KBD_INDEX(dev) minor(dev) 51 52 typedef struct genkbd_softc { 53 int gkb_flags; /* flag/status bits */ 54 #define KB_ASLEEP (1 << 0) 55 struct clist gkb_q; /* input queue */ 56 struct selinfo gkb_rsel; 57 } genkbd_softc_t; 58 59 static SLIST_HEAD(, keyboard_driver) keyboard_drivers = 60 SLIST_HEAD_INITIALIZER(keyboard_drivers); 61 62 SET_DECLARE(kbddriver_set, const keyboard_driver_t); 63 64 /* local arrays */ 65 66 /* 67 * We need at least one entry each in order to initialize a keyboard 68 * for the kernel console. The arrays will be increased dynamically 69 * when necessary. 70 */ 71 72 static int keyboards = 1; 73 static keyboard_t *kbd_ini; 74 static keyboard_t **keyboard = &kbd_ini; 75 static keyboard_switch_t *kbdsw_ini; 76 keyboard_switch_t **kbdsw = &kbdsw_ini; 77 78 static int keymap_restrict_change; 79 SYSCTL_NODE(_hw, OID_AUTO, kbd, CTLFLAG_RD, 0, "kbd"); 80 SYSCTL_INT(_hw_kbd, OID_AUTO, keymap_restrict_change, CTLFLAG_RW, 81 &keymap_restrict_change, 0, "restrict ability to change keymap"); 82 83 #define ARRAY_DELTA 4 84 85 static int 86 kbd_realloc_array(void) 87 { 88 keyboard_t **new_kbd; 89 keyboard_switch_t **new_kbdsw; 90 int newsize; 91 int s; 92 93 s = spltty(); 94 newsize = ((keyboards + ARRAY_DELTA)/ARRAY_DELTA)*ARRAY_DELTA; 95 new_kbd = malloc(sizeof(*new_kbd)*newsize, M_DEVBUF, M_NOWAIT|M_ZERO); 96 if (new_kbd == NULL) { 97 splx(s); 98 return (ENOMEM); 99 } 100 new_kbdsw = malloc(sizeof(*new_kbdsw)*newsize, M_DEVBUF, 101 M_NOWAIT|M_ZERO); 102 if (new_kbdsw == NULL) { 103 free(new_kbd, M_DEVBUF); 104 splx(s); 105 return (ENOMEM); 106 } 107 bcopy(keyboard, new_kbd, sizeof(*keyboard)*keyboards); 108 bcopy(kbdsw, new_kbdsw, sizeof(*kbdsw)*keyboards); 109 if (keyboards > 1) { 110 free(keyboard, M_DEVBUF); 111 free(kbdsw, M_DEVBUF); 112 } 113 keyboard = new_kbd; 114 kbdsw = new_kbdsw; 115 keyboards = newsize; 116 splx(s); 117 118 if (bootverbose) 119 printf("kbd: new array size %d\n", keyboards); 120 121 return (0); 122 } 123 124 /* 125 * Low-level keyboard driver functions 126 * Keyboard subdrivers, such as the AT keyboard driver and the USB keyboard 127 * driver, call these functions to initialize the keyboard_t structure 128 * and register it to the virtual keyboard driver `kbd'. 129 */ 130 131 /* initialize the keyboard_t structure */ 132 void 133 kbd_init_struct(keyboard_t *kbd, char *name, int type, int unit, int config, 134 int port, int port_size) 135 { 136 kbd->kb_flags = KB_NO_DEVICE; /* device has not been found */ 137 kbd->kb_name = name; 138 kbd->kb_type = type; 139 kbd->kb_unit = unit; 140 kbd->kb_config = config & ~KB_CONF_PROBE_ONLY; 141 kbd->kb_led = 0; /* unknown */ 142 kbd->kb_io_base = port; 143 kbd->kb_io_size = port_size; 144 kbd->kb_data = NULL; 145 kbd->kb_keymap = NULL; 146 kbd->kb_accentmap = NULL; 147 kbd->kb_fkeytab = NULL; 148 kbd->kb_fkeytab_size = 0; 149 kbd->kb_delay1 = KB_DELAY1; /* these values are advisory only */ 150 kbd->kb_delay2 = KB_DELAY2; 151 kbd->kb_count = 0L; 152 bzero(kbd->kb_lastact, sizeof(kbd->kb_lastact)); 153 } 154 155 void 156 kbd_set_maps(keyboard_t *kbd, keymap_t *keymap, accentmap_t *accmap, 157 fkeytab_t *fkeymap, int fkeymap_size) 158 { 159 kbd->kb_keymap = keymap; 160 kbd->kb_accentmap = accmap; 161 kbd->kb_fkeytab = fkeymap; 162 kbd->kb_fkeytab_size = fkeymap_size; 163 } 164 165 /* declare a new keyboard driver */ 166 int 167 kbd_add_driver(keyboard_driver_t *driver) 168 { 169 if (SLIST_NEXT(driver, link)) 170 return (EINVAL); 171 SLIST_INSERT_HEAD(&keyboard_drivers, driver, link); 172 return (0); 173 } 174 175 int 176 kbd_delete_driver(keyboard_driver_t *driver) 177 { 178 SLIST_REMOVE(&keyboard_drivers, driver, keyboard_driver, link); 179 SLIST_NEXT(driver, link) = NULL; 180 return (0); 181 } 182 183 /* register a keyboard and associate it with a function table */ 184 int 185 kbd_register(keyboard_t *kbd) 186 { 187 const keyboard_driver_t **list; 188 const keyboard_driver_t *p; 189 keyboard_t *mux; 190 keyboard_info_t ki; 191 int index; 192 193 mux = kbd_get_keyboard(kbd_find_keyboard("kbdmux", -1)); 194 195 for (index = 0; index < keyboards; ++index) { 196 if (keyboard[index] == NULL) 197 break; 198 } 199 if (index >= keyboards) { 200 if (kbd_realloc_array()) 201 return (-1); 202 } 203 204 kbd->kb_index = index; 205 KBD_UNBUSY(kbd); 206 KBD_VALID(kbd); 207 kbd->kb_active = 0; /* disabled until someone calls kbd_enable() */ 208 kbd->kb_token = NULL; 209 kbd->kb_callback.kc_func = NULL; 210 kbd->kb_callback.kc_arg = NULL; 211 212 SLIST_FOREACH(p, &keyboard_drivers, link) { 213 if (strcmp(p->name, kbd->kb_name) == 0) { 214 keyboard[index] = kbd; 215 kbdsw[index] = p->kbdsw; 216 217 if (mux != NULL) { 218 bzero(&ki, sizeof(ki)); 219 strcpy(ki.kb_name, kbd->kb_name); 220 ki.kb_unit = kbd->kb_unit; 221 222 (*kbdsw[mux->kb_index]->ioctl) 223 (mux, KBADDKBD, (caddr_t) &ki); 224 } 225 226 return (index); 227 } 228 } 229 SET_FOREACH(list, kbddriver_set) { 230 p = *list; 231 if (strcmp(p->name, kbd->kb_name) == 0) { 232 keyboard[index] = kbd; 233 kbdsw[index] = p->kbdsw; 234 235 if (mux != NULL) { 236 bzero(&ki, sizeof(ki)); 237 strcpy(ki.kb_name, kbd->kb_name); 238 ki.kb_unit = kbd->kb_unit; 239 240 (*kbdsw[mux->kb_index]->ioctl) 241 (mux, KBADDKBD, (caddr_t) &ki); 242 } 243 244 return (index); 245 } 246 } 247 248 return (-1); 249 } 250 251 int 252 kbd_unregister(keyboard_t *kbd) 253 { 254 int error; 255 int s; 256 257 if ((kbd->kb_index < 0) || (kbd->kb_index >= keyboards)) 258 return (ENOENT); 259 if (keyboard[kbd->kb_index] != kbd) 260 return (ENOENT); 261 262 s = spltty(); 263 if (KBD_IS_BUSY(kbd)) { 264 error = (*kbd->kb_callback.kc_func)(kbd, KBDIO_UNLOADING, 265 kbd->kb_callback.kc_arg); 266 if (error) { 267 splx(s); 268 return (error); 269 } 270 if (KBD_IS_BUSY(kbd)) { 271 splx(s); 272 return (EBUSY); 273 } 274 } 275 KBD_INVALID(kbd); 276 keyboard[kbd->kb_index] = NULL; 277 kbdsw[kbd->kb_index] = NULL; 278 279 splx(s); 280 return (0); 281 } 282 283 /* find a funciton table by the driver name */ 284 keyboard_switch_t 285 *kbd_get_switch(char *driver) 286 { 287 const keyboard_driver_t **list; 288 const keyboard_driver_t *p; 289 290 SLIST_FOREACH(p, &keyboard_drivers, link) { 291 if (strcmp(p->name, driver) == 0) 292 return (p->kbdsw); 293 } 294 SET_FOREACH(list, kbddriver_set) { 295 p = *list; 296 if (strcmp(p->name, driver) == 0) 297 return (p->kbdsw); 298 } 299 300 return (NULL); 301 } 302 303 /* 304 * Keyboard client functions 305 * Keyboard clients, such as the console driver `syscons' and the keyboard 306 * cdev driver, use these functions to claim and release a keyboard for 307 * exclusive use. 308 */ 309 310 /* 311 * find the keyboard specified by a driver name and a unit number 312 * starting at given index 313 */ 314 int 315 kbd_find_keyboard2(char *driver, int unit, int index) 316 { 317 int i; 318 319 if ((index < 0) || (index >= keyboards)) 320 return (-1); 321 322 for (i = index; i < keyboards; ++i) { 323 if (keyboard[i] == NULL) 324 continue; 325 if (!KBD_IS_VALID(keyboard[i])) 326 continue; 327 if (strcmp("*", driver) && strcmp(keyboard[i]->kb_name, driver)) 328 continue; 329 if ((unit != -1) && (keyboard[i]->kb_unit != unit)) 330 continue; 331 return (i); 332 } 333 334 return (-1); 335 } 336 337 /* find the keyboard specified by a driver name and a unit number */ 338 int 339 kbd_find_keyboard(char *driver, int unit) 340 { 341 return (kbd_find_keyboard2(driver, unit, 0)); 342 } 343 344 /* allocate a keyboard */ 345 int 346 kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func, 347 void *arg) 348 { 349 int index; 350 int s; 351 352 if (func == NULL) 353 return (-1); 354 355 s = spltty(); 356 index = kbd_find_keyboard(driver, unit); 357 if (index >= 0) { 358 if (KBD_IS_BUSY(keyboard[index])) { 359 splx(s); 360 return (-1); 361 } 362 keyboard[index]->kb_token = id; 363 KBD_BUSY(keyboard[index]); 364 keyboard[index]->kb_callback.kc_func = func; 365 keyboard[index]->kb_callback.kc_arg = arg; 366 (*kbdsw[index]->clear_state)(keyboard[index]); 367 } 368 splx(s); 369 return (index); 370 } 371 372 int 373 kbd_release(keyboard_t *kbd, void *id) 374 { 375 int error; 376 int s; 377 378 s = spltty(); 379 if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { 380 error = EINVAL; 381 } else if (kbd->kb_token != id) { 382 error = EPERM; 383 } else { 384 kbd->kb_token = NULL; 385 KBD_UNBUSY(kbd); 386 kbd->kb_callback.kc_func = NULL; 387 kbd->kb_callback.kc_arg = NULL; 388 (*kbdsw[kbd->kb_index]->clear_state)(kbd); 389 error = 0; 390 } 391 splx(s); 392 return (error); 393 } 394 395 int 396 kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func, 397 void *arg) 398 { 399 int error; 400 int s; 401 402 s = spltty(); 403 if (!KBD_IS_VALID(kbd) || !KBD_IS_BUSY(kbd)) { 404 error = EINVAL; 405 } else if (kbd->kb_token != id) { 406 error = EPERM; 407 } else if (func == NULL) { 408 error = EINVAL; 409 } else { 410 kbd->kb_callback.kc_func = func; 411 kbd->kb_callback.kc_arg = arg; 412 error = 0; 413 } 414 splx(s); 415 return (error); 416 } 417 418 /* get a keyboard structure */ 419 keyboard_t 420 *kbd_get_keyboard(int index) 421 { 422 if ((index < 0) || (index >= keyboards)) 423 return (NULL); 424 if (keyboard[index] == NULL) 425 return (NULL); 426 if (!KBD_IS_VALID(keyboard[index])) 427 return (NULL); 428 return (keyboard[index]); 429 } 430 431 /* 432 * The back door for the console driver; configure keyboards 433 * This function is for the kernel console to initialize keyboards 434 * at very early stage. 435 */ 436 437 int 438 kbd_configure(int flags) 439 { 440 const keyboard_driver_t **list; 441 const keyboard_driver_t *p; 442 443 SLIST_FOREACH(p, &keyboard_drivers, link) { 444 if (p->configure != NULL) 445 (*p->configure)(flags); 446 } 447 SET_FOREACH(list, kbddriver_set) { 448 p = *list; 449 if (p->configure != NULL) 450 (*p->configure)(flags); 451 } 452 453 return (0); 454 } 455 456 #ifdef KBD_INSTALL_CDEV 457 458 /* 459 * Virtual keyboard cdev driver functions 460 * The virtual keyboard driver dispatches driver functions to 461 * appropriate subdrivers. 462 */ 463 464 #define KBD_UNIT(dev) minor(dev) 465 466 static d_open_t genkbdopen; 467 static d_close_t genkbdclose; 468 static d_read_t genkbdread; 469 static d_write_t genkbdwrite; 470 static d_ioctl_t genkbdioctl; 471 static d_poll_t genkbdpoll; 472 473 474 static struct cdevsw kbd_cdevsw = { 475 .d_version = D_VERSION, 476 .d_flags = D_NEEDGIANT, 477 .d_open = genkbdopen, 478 .d_close = genkbdclose, 479 .d_read = genkbdread, 480 .d_write = genkbdwrite, 481 .d_ioctl = genkbdioctl, 482 .d_poll = genkbdpoll, 483 .d_name = "kbd", 484 }; 485 486 int 487 kbd_attach(keyboard_t *kbd) 488 { 489 490 if (kbd->kb_index >= keyboards) 491 return (EINVAL); 492 if (keyboard[kbd->kb_index] != kbd) 493 return (EINVAL); 494 495 kbd->kb_dev = make_dev(&kbd_cdevsw, kbd->kb_index, UID_ROOT, GID_WHEEL, 496 0600, "%s%r", kbd->kb_name, kbd->kb_unit); 497 make_dev_alias(kbd->kb_dev, "kbd%r", kbd->kb_index); 498 kbd->kb_dev->si_drv1 = malloc(sizeof(genkbd_softc_t), M_DEVBUF, 499 M_WAITOK | M_ZERO); 500 printf("kbd%d at %s%d\n", kbd->kb_index, kbd->kb_name, kbd->kb_unit); 501 return (0); 502 } 503 504 int 505 kbd_detach(keyboard_t *kbd) 506 { 507 508 if (kbd->kb_index >= keyboards) 509 return (EINVAL); 510 if (keyboard[kbd->kb_index] != kbd) 511 return (EINVAL); 512 513 free(kbd->kb_dev->si_drv1, M_DEVBUF); 514 destroy_dev(kbd->kb_dev); 515 516 return (0); 517 } 518 519 /* 520 * Generic keyboard cdev driver functions 521 * Keyboard subdrivers may call these functions to implement common 522 * driver functions. 523 */ 524 525 #define KB_QSIZE 512 526 #define KB_BUFSIZE 64 527 528 static kbd_callback_func_t genkbd_event; 529 530 static int 531 genkbdopen(struct cdev *dev, int mode, int flag, struct thread *td) 532 { 533 keyboard_t *kbd; 534 genkbd_softc_t *sc; 535 int s; 536 int i; 537 538 s = spltty(); 539 sc = dev->si_drv1; 540 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 541 if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { 542 splx(s); 543 return (ENXIO); 544 } 545 i = kbd_allocate(kbd->kb_name, kbd->kb_unit, sc, 546 genkbd_event, (void *)sc); 547 if (i < 0) { 548 splx(s); 549 return (EBUSY); 550 } 551 /* assert(i == kbd->kb_index) */ 552 /* assert(kbd == kbd_get_keyboard(i)) */ 553 554 /* 555 * NOTE: even when we have successfully claimed a keyboard, 556 * the device may still be missing (!KBD_HAS_DEVICE(kbd)). 557 */ 558 559 #if 0 560 bzero(&sc->gkb_q, sizeof(sc->gkb_q)); 561 #endif 562 clist_alloc_cblocks(&sc->gkb_q, KB_QSIZE, KB_QSIZE/2); /* XXX */ 563 splx(s); 564 565 return (0); 566 } 567 568 static int 569 genkbdclose(struct cdev *dev, int mode, int flag, struct thread *td) 570 { 571 keyboard_t *kbd; 572 genkbd_softc_t *sc; 573 int s; 574 575 /* 576 * NOTE: the device may have already become invalid. 577 * kbd == NULL || !KBD_IS_VALID(kbd) 578 */ 579 s = spltty(); 580 sc = dev->si_drv1; 581 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 582 if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { 583 /* XXX: we shall be forgiving and don't report error... */ 584 } else { 585 kbd_release(kbd, (void *)sc); 586 #if 0 587 clist_free_cblocks(&sc->gkb_q); 588 #endif 589 } 590 splx(s); 591 return (0); 592 } 593 594 static int 595 genkbdread(struct cdev *dev, struct uio *uio, int flag) 596 { 597 keyboard_t *kbd; 598 genkbd_softc_t *sc; 599 u_char buffer[KB_BUFSIZE]; 600 int len; 601 int error; 602 int s; 603 604 /* wait for input */ 605 s = spltty(); 606 sc = dev->si_drv1; 607 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 608 if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { 609 splx(s); 610 return (ENXIO); 611 } 612 while (sc->gkb_q.c_cc == 0) { 613 if (flag & O_NONBLOCK) { 614 splx(s); 615 return (EWOULDBLOCK); 616 } 617 sc->gkb_flags |= KB_ASLEEP; 618 error = tsleep(sc, PZERO | PCATCH, "kbdrea", 0); 619 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 620 if ((kbd == NULL) || !KBD_IS_VALID(kbd)) { 621 splx(s); 622 return (ENXIO); /* our keyboard has gone... */ 623 } 624 if (error) { 625 sc->gkb_flags &= ~KB_ASLEEP; 626 splx(s); 627 return (error); 628 } 629 } 630 splx(s); 631 632 /* copy as much input as possible */ 633 error = 0; 634 while (uio->uio_resid > 0) { 635 len = imin(uio->uio_resid, sizeof(buffer)); 636 len = q_to_b(&sc->gkb_q, buffer, len); 637 if (len <= 0) 638 break; 639 error = uiomove(buffer, len, uio); 640 if (error) 641 break; 642 } 643 644 return (error); 645 } 646 647 static int 648 genkbdwrite(struct cdev *dev, struct uio *uio, int flag) 649 { 650 keyboard_t *kbd; 651 652 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 653 if ((kbd == NULL) || !KBD_IS_VALID(kbd)) 654 return (ENXIO); 655 return (ENODEV); 656 } 657 658 static int 659 genkbdioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) 660 { 661 keyboard_t *kbd; 662 int error; 663 664 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 665 if ((kbd == NULL) || !KBD_IS_VALID(kbd)) 666 return (ENXIO); 667 error = (*kbdsw[kbd->kb_index]->ioctl)(kbd, cmd, arg); 668 if (error == ENOIOCTL) 669 error = ENODEV; 670 return (error); 671 } 672 673 static int 674 genkbdpoll(struct cdev *dev, int events, struct thread *td) 675 { 676 keyboard_t *kbd; 677 genkbd_softc_t *sc; 678 int revents; 679 int s; 680 681 revents = 0; 682 s = spltty(); 683 sc = dev->si_drv1; 684 kbd = kbd_get_keyboard(KBD_INDEX(dev)); 685 if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { 686 revents = POLLHUP; /* the keyboard has gone */ 687 } else if (events & (POLLIN | POLLRDNORM)) { 688 if (sc->gkb_q.c_cc > 0) 689 revents = events & (POLLIN | POLLRDNORM); 690 else 691 selrecord(td, &sc->gkb_rsel); 692 } 693 splx(s); 694 return (revents); 695 } 696 697 static int 698 genkbd_event(keyboard_t *kbd, int event, void *arg) 699 { 700 genkbd_softc_t *sc; 701 size_t len; 702 u_char *cp; 703 int mode; 704 int c; 705 706 /* assert(KBD_IS_VALID(kbd)) */ 707 sc = (genkbd_softc_t *)arg; 708 709 switch (event) { 710 case KBDIO_KEYINPUT: 711 break; 712 case KBDIO_UNLOADING: 713 /* the keyboard is going... */ 714 kbd_release(kbd, (void *)sc); 715 if (sc->gkb_flags & KB_ASLEEP) { 716 sc->gkb_flags &= ~KB_ASLEEP; 717 wakeup(sc); 718 } 719 selwakeuppri(&sc->gkb_rsel, PZERO); 720 return (0); 721 default: 722 return (EINVAL); 723 } 724 725 /* obtain the current key input mode */ 726 if ((*kbdsw[kbd->kb_index]->ioctl)(kbd, KDGKBMODE, (caddr_t)&mode)) 727 mode = K_XLATE; 728 729 /* read all pending input */ 730 while ((*kbdsw[kbd->kb_index]->check_char)(kbd)) { 731 c = (*kbdsw[kbd->kb_index]->read_char)(kbd, FALSE); 732 if (c == NOKEY) 733 continue; 734 if (c == ERRKEY) /* XXX: ring bell? */ 735 continue; 736 if (!KBD_IS_BUSY(kbd)) 737 /* the device is not open, discard the input */ 738 continue; 739 740 /* store the byte as is for K_RAW and K_CODE modes */ 741 if (mode != K_XLATE) { 742 putc(KEYCHAR(c), &sc->gkb_q); 743 continue; 744 } 745 746 /* K_XLATE */ 747 if (c & RELKEY) /* key release is ignored */ 748 continue; 749 750 /* process special keys; most of them are just ignored... */ 751 if (c & SPCLKEY) { 752 switch (KEYCHAR(c)) { 753 default: 754 /* ignore them... */ 755 continue; 756 case BTAB: /* a backtab: ESC [ Z */ 757 putc(0x1b, &sc->gkb_q); 758 putc('[', &sc->gkb_q); 759 putc('Z', &sc->gkb_q); 760 continue; 761 } 762 } 763 764 /* normal chars, normal chars with the META, function keys */ 765 switch (KEYFLAGS(c)) { 766 case 0: /* a normal char */ 767 putc(KEYCHAR(c), &sc->gkb_q); 768 break; 769 case MKEY: /* the META flag: prepend ESC */ 770 putc(0x1b, &sc->gkb_q); 771 putc(KEYCHAR(c), &sc->gkb_q); 772 break; 773 case FKEY | SPCLKEY: /* a function key, return string */ 774 cp = (*kbdsw[kbd->kb_index]->get_fkeystr)(kbd, 775 KEYCHAR(c), &len); 776 if (cp != NULL) { 777 while (len-- > 0) 778 putc(*cp++, &sc->gkb_q); 779 } 780 break; 781 } 782 } 783 784 /* wake up sleeping/polling processes */ 785 if (sc->gkb_q.c_cc > 0) { 786 if (sc->gkb_flags & KB_ASLEEP) { 787 sc->gkb_flags &= ~KB_ASLEEP; 788 wakeup(sc); 789 } 790 selwakeuppri(&sc->gkb_rsel, PZERO); 791 } 792 793 return (0); 794 } 795 796 #endif /* KBD_INSTALL_CDEV */ 797 798 /* 799 * Generic low-level keyboard functions 800 * The low-level functions in the keyboard subdriver may use these 801 * functions. 802 */ 803 804 #ifndef KBD_DISABLE_KEYMAP_LOAD 805 static int key_change_ok(struct keyent_t *, struct keyent_t *, struct thread *); 806 static int keymap_change_ok(keymap_t *, keymap_t *, struct thread *); 807 static int accent_change_ok(accentmap_t *, accentmap_t *, struct thread *); 808 static int fkey_change_ok(fkeytab_t *, fkeyarg_t *, struct thread *); 809 #endif 810 811 int 812 genkbd_commonioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) 813 { 814 keyarg_t *keyp; 815 fkeyarg_t *fkeyp; 816 int s; 817 int i; 818 #ifndef KBD_DISABLE_KEYMAP_LOAD 819 int error; 820 #endif 821 822 s = spltty(); 823 switch (cmd) { 824 825 case KDGKBINFO: /* get keyboard information */ 826 ((keyboard_info_t *)arg)->kb_index = kbd->kb_index; 827 i = imin(strlen(kbd->kb_name) + 1, 828 sizeof(((keyboard_info_t *)arg)->kb_name)); 829 bcopy(kbd->kb_name, ((keyboard_info_t *)arg)->kb_name, i); 830 ((keyboard_info_t *)arg)->kb_unit = kbd->kb_unit; 831 ((keyboard_info_t *)arg)->kb_type = kbd->kb_type; 832 ((keyboard_info_t *)arg)->kb_config = kbd->kb_config; 833 ((keyboard_info_t *)arg)->kb_flags = kbd->kb_flags; 834 break; 835 836 case KDGKBTYPE: /* get keyboard type */ 837 *(int *)arg = kbd->kb_type; 838 break; 839 840 case KDGETREPEAT: /* get keyboard repeat rate */ 841 ((int *)arg)[0] = kbd->kb_delay1; 842 ((int *)arg)[1] = kbd->kb_delay2; 843 break; 844 845 case GIO_KEYMAP: /* get keyboard translation table */ 846 bcopy(kbd->kb_keymap, arg, sizeof(*kbd->kb_keymap)); 847 break; 848 case PIO_KEYMAP: /* set keyboard translation table */ 849 #ifndef KBD_DISABLE_KEYMAP_LOAD 850 error = keymap_change_ok(kbd->kb_keymap, (keymap_t *)arg, 851 curthread); 852 if (error != 0) { 853 splx(s); 854 return (error); 855 } 856 bzero(kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); 857 bcopy(arg, kbd->kb_keymap, sizeof(*kbd->kb_keymap)); 858 break; 859 #else 860 splx(s); 861 return (ENODEV); 862 #endif 863 864 case GIO_KEYMAPENT: /* get keyboard translation table entry */ 865 keyp = (keyarg_t *)arg; 866 if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / 867 sizeof(kbd->kb_keymap->key[0])) { 868 splx(s); 869 return (EINVAL); 870 } 871 bcopy(&kbd->kb_keymap->key[keyp->keynum], &keyp->key, 872 sizeof(keyp->key)); 873 break; 874 case PIO_KEYMAPENT: /* set keyboard translation table entry */ 875 #ifndef KBD_DISABLE_KEYMAP_LOAD 876 keyp = (keyarg_t *)arg; 877 if (keyp->keynum >= sizeof(kbd->kb_keymap->key) / 878 sizeof(kbd->kb_keymap->key[0])) { 879 splx(s); 880 return (EINVAL); 881 } 882 error = key_change_ok(&kbd->kb_keymap->key[keyp->keynum], 883 &keyp->key, curthread); 884 if (error != 0) { 885 splx(s); 886 return (error); 887 } 888 bcopy(&keyp->key, &kbd->kb_keymap->key[keyp->keynum], 889 sizeof(keyp->key)); 890 break; 891 #else 892 splx(s); 893 return (ENODEV); 894 #endif 895 896 case GIO_DEADKEYMAP: /* get accent key translation table */ 897 bcopy(kbd->kb_accentmap, arg, sizeof(*kbd->kb_accentmap)); 898 break; 899 case PIO_DEADKEYMAP: /* set accent key translation table */ 900 #ifndef KBD_DISABLE_KEYMAP_LOAD 901 error = accent_change_ok(kbd->kb_accentmap, 902 (accentmap_t *)arg, curthread); 903 if (error != 0) { 904 splx(s); 905 return (error); 906 } 907 bcopy(arg, kbd->kb_accentmap, sizeof(*kbd->kb_accentmap)); 908 break; 909 #else 910 splx(s); 911 return (ENODEV); 912 #endif 913 914 case GETFKEY: /* get functionkey string */ 915 fkeyp = (fkeyarg_t *)arg; 916 if (fkeyp->keynum >= kbd->kb_fkeytab_size) { 917 splx(s); 918 return (EINVAL); 919 } 920 bcopy(kbd->kb_fkeytab[fkeyp->keynum].str, fkeyp->keydef, 921 kbd->kb_fkeytab[fkeyp->keynum].len); 922 fkeyp->flen = kbd->kb_fkeytab[fkeyp->keynum].len; 923 break; 924 case SETFKEY: /* set functionkey string */ 925 #ifndef KBD_DISABLE_KEYMAP_LOAD 926 fkeyp = (fkeyarg_t *)arg; 927 if (fkeyp->keynum >= kbd->kb_fkeytab_size) { 928 splx(s); 929 return (EINVAL); 930 } 931 error = fkey_change_ok(&kbd->kb_fkeytab[fkeyp->keynum], 932 fkeyp, curthread); 933 if (error != 0) { 934 splx(s); 935 return (error); 936 } 937 kbd->kb_fkeytab[fkeyp->keynum].len = imin(fkeyp->flen, MAXFK); 938 bcopy(fkeyp->keydef, kbd->kb_fkeytab[fkeyp->keynum].str, 939 kbd->kb_fkeytab[fkeyp->keynum].len); 940 break; 941 #else 942 splx(s); 943 return (ENODEV); 944 #endif 945 946 default: 947 splx(s); 948 return (ENOIOCTL); 949 } 950 951 splx(s); 952 return (0); 953 } 954 955 #ifndef KBD_DISABLE_KEYMAP_LOAD 956 #define RESTRICTED_KEY(key, i) \ 957 ((key->spcl & (0x80 >> i)) && \ 958 (key->map[i] == RBT || key->map[i] == SUSP || \ 959 key->map[i] == STBY || key->map[i] == DBG || \ 960 key->map[i] == PNC || key->map[i] == HALT || \ 961 key->map[i] == PDWN)) 962 963 static int 964 key_change_ok(struct keyent_t *oldkey, struct keyent_t *newkey, struct thread *td) 965 { 966 int i; 967 968 /* Low keymap_restrict_change means any changes are OK. */ 969 if (keymap_restrict_change <= 0) 970 return (0); 971 972 /* High keymap_restrict_change means only root can change the keymap. */ 973 if (keymap_restrict_change >= 2) { 974 for (i = 0; i < NUM_STATES; i++) 975 if (oldkey->map[i] != newkey->map[i]) 976 return priv_check(td, PRIV_KEYBOARD); 977 if (oldkey->spcl != newkey->spcl) 978 return priv_check(td, PRIV_KEYBOARD); 979 if (oldkey->flgs != newkey->flgs) 980 return priv_check(td, PRIV_KEYBOARD); 981 return (0); 982 } 983 984 /* Otherwise we have to see if any special keys are being changed. */ 985 for (i = 0; i < NUM_STATES; i++) { 986 /* 987 * If either the oldkey or the newkey action is restricted 988 * then we must make sure that the action doesn't change. 989 */ 990 if (!RESTRICTED_KEY(oldkey, i) && !RESTRICTED_KEY(newkey, i)) 991 continue; 992 if ((oldkey->spcl & (0x80 >> i)) == (newkey->spcl & (0x80 >> i)) 993 && oldkey->map[i] == newkey->map[i]) 994 continue; 995 return priv_check(td, PRIV_KEYBOARD); 996 } 997 998 return (0); 999 } 1000 1001 static int 1002 keymap_change_ok(keymap_t *oldmap, keymap_t *newmap, struct thread *td) 1003 { 1004 int keycode, error; 1005 1006 for (keycode = 0; keycode < NUM_KEYS; keycode++) { 1007 if ((error = key_change_ok(&oldmap->key[keycode], 1008 &newmap->key[keycode], td)) != 0) 1009 return (error); 1010 } 1011 return (0); 1012 } 1013 1014 static int 1015 accent_change_ok(accentmap_t *oldmap, accentmap_t *newmap, struct thread *td) 1016 { 1017 struct acc_t *oldacc, *newacc; 1018 int accent, i; 1019 1020 if (keymap_restrict_change <= 2) 1021 return (0); 1022 1023 if (oldmap->n_accs != newmap->n_accs) 1024 return priv_check(td, PRIV_KEYBOARD); 1025 1026 for (accent = 0; accent < oldmap->n_accs; accent++) { 1027 oldacc = &oldmap->acc[accent]; 1028 newacc = &newmap->acc[accent]; 1029 if (oldacc->accchar != newacc->accchar) 1030 return priv_check(td, PRIV_KEYBOARD); 1031 for (i = 0; i < NUM_ACCENTCHARS; ++i) { 1032 if (oldacc->map[i][0] != newacc->map[i][0]) 1033 return priv_check(td, PRIV_KEYBOARD); 1034 if (oldacc->map[i][0] == 0) /* end of table */ 1035 break; 1036 if (oldacc->map[i][1] != newacc->map[i][1]) 1037 return priv_check(td, PRIV_KEYBOARD); 1038 } 1039 } 1040 1041 return (0); 1042 } 1043 1044 static int 1045 fkey_change_ok(fkeytab_t *oldkey, fkeyarg_t *newkey, struct thread *td) 1046 { 1047 if (keymap_restrict_change <= 3) 1048 return (0); 1049 1050 if (oldkey->len != newkey->flen || 1051 bcmp(oldkey->str, newkey->keydef, oldkey->len) != 0) 1052 return priv_check(td, PRIV_KEYBOARD); 1053 1054 return (0); 1055 } 1056 #endif 1057 1058 /* get a pointer to the string associated with the given function key */ 1059 u_char 1060 *genkbd_get_fkeystr(keyboard_t *kbd, int fkey, size_t *len) 1061 { 1062 if (kbd == NULL) 1063 return (NULL); 1064 fkey -= F_FN; 1065 if (fkey > kbd->kb_fkeytab_size) 1066 return (NULL); 1067 *len = kbd->kb_fkeytab[fkey].len; 1068 return (kbd->kb_fkeytab[fkey].str); 1069 } 1070 1071 /* diagnostic dump */ 1072 static char 1073 *get_kbd_type_name(int type) 1074 { 1075 static struct { 1076 int type; 1077 char *name; 1078 } name_table[] = { 1079 { KB_84, "AT 84" }, 1080 { KB_101, "AT 101/102" }, 1081 { KB_OTHER, "generic" }, 1082 }; 1083 int i; 1084 1085 for (i = 0; i < sizeof(name_table)/sizeof(name_table[0]); ++i) { 1086 if (type == name_table[i].type) 1087 return (name_table[i].name); 1088 } 1089 return ("unknown"); 1090 } 1091 1092 void 1093 genkbd_diag(keyboard_t *kbd, int level) 1094 { 1095 if (level > 0) { 1096 printf("kbd%d: %s%d, %s (%d), config:0x%x, flags:0x%x", 1097 kbd->kb_index, kbd->kb_name, kbd->kb_unit, 1098 get_kbd_type_name(kbd->kb_type), kbd->kb_type, 1099 kbd->kb_config, kbd->kb_flags); 1100 if (kbd->kb_io_base > 0) 1101 printf(", port:0x%x-0x%x", kbd->kb_io_base, 1102 kbd->kb_io_base + kbd->kb_io_size - 1); 1103 printf("\n"); 1104 } 1105 } 1106 1107 #define set_lockkey_state(k, s, l) \ 1108 if (!((s) & l ## DOWN)) { \ 1109 int i; \ 1110 (s) |= l ## DOWN; \ 1111 (s) ^= l ## ED; \ 1112 i = (s) & LOCK_MASK; \ 1113 (*kbdsw[(k)->kb_index]->ioctl)((k), KDSETLED, (caddr_t)&i); \ 1114 } 1115 1116 static u_int 1117 save_accent_key(keyboard_t *kbd, u_int key, int *accents) 1118 { 1119 int i; 1120 1121 /* make an index into the accent map */ 1122 i = key - F_ACC + 1; 1123 if ((i > kbd->kb_accentmap->n_accs) 1124 || (kbd->kb_accentmap->acc[i - 1].accchar == 0)) { 1125 /* the index is out of range or pointing to an empty entry */ 1126 *accents = 0; 1127 return (ERRKEY); 1128 } 1129 1130 /* 1131 * If the same accent key has been hit twice, produce the accent 1132 * char itself. 1133 */ 1134 if (i == *accents) { 1135 key = kbd->kb_accentmap->acc[i - 1].accchar; 1136 *accents = 0; 1137 return (key); 1138 } 1139 1140 /* remember the index and wait for the next key */ 1141 *accents = i; 1142 return (NOKEY); 1143 } 1144 1145 static u_int 1146 make_accent_char(keyboard_t *kbd, u_int ch, int *accents) 1147 { 1148 struct acc_t *acc; 1149 int i; 1150 1151 acc = &kbd->kb_accentmap->acc[*accents - 1]; 1152 *accents = 0; 1153 1154 /* 1155 * If the accent key is followed by the space key, 1156 * produce the accent char itself. 1157 */ 1158 if (ch == ' ') 1159 return (acc->accchar); 1160 1161 /* scan the accent map */ 1162 for (i = 0; i < NUM_ACCENTCHARS; ++i) { 1163 if (acc->map[i][0] == 0) /* end of table */ 1164 break; 1165 if (acc->map[i][0] == ch) 1166 return (acc->map[i][1]); 1167 } 1168 /* this char cannot be accented... */ 1169 return (ERRKEY); 1170 } 1171 1172 int 1173 genkbd_keyaction(keyboard_t *kbd, int keycode, int up, int *shiftstate, 1174 int *accents) 1175 { 1176 struct keyent_t *key; 1177 int state = *shiftstate; 1178 int action; 1179 int f; 1180 int i; 1181 1182 i = keycode; 1183 f = state & (AGRS | ALKED); 1184 if ((f == AGRS1) || (f == AGRS2) || (f == ALKED)) 1185 i += ALTGR_OFFSET; 1186 key = &kbd->kb_keymap->key[i]; 1187 i = ((state & SHIFTS) ? 1 : 0) 1188 | ((state & CTLS) ? 2 : 0) 1189 | ((state & ALTS) ? 4 : 0); 1190 if (((key->flgs & FLAG_LOCK_C) && (state & CLKED)) 1191 || ((key->flgs & FLAG_LOCK_N) && (state & NLKED)) ) 1192 i ^= 1; 1193 1194 if (up) { /* break: key released */ 1195 action = kbd->kb_lastact[keycode]; 1196 kbd->kb_lastact[keycode] = NOP; 1197 switch (action) { 1198 case LSHA: 1199 if (state & SHIFTAON) { 1200 set_lockkey_state(kbd, state, ALK); 1201 state &= ~ALKDOWN; 1202 } 1203 action = LSH; 1204 /* FALL THROUGH */ 1205 case LSH: 1206 state &= ~SHIFTS1; 1207 break; 1208 case RSHA: 1209 if (state & SHIFTAON) { 1210 set_lockkey_state(kbd, state, ALK); 1211 state &= ~ALKDOWN; 1212 } 1213 action = RSH; 1214 /* FALL THROUGH */ 1215 case RSH: 1216 state &= ~SHIFTS2; 1217 break; 1218 case LCTRA: 1219 if (state & SHIFTAON) { 1220 set_lockkey_state(kbd, state, ALK); 1221 state &= ~ALKDOWN; 1222 } 1223 action = LCTR; 1224 /* FALL THROUGH */ 1225 case LCTR: 1226 state &= ~CTLS1; 1227 break; 1228 case RCTRA: 1229 if (state & SHIFTAON) { 1230 set_lockkey_state(kbd, state, ALK); 1231 state &= ~ALKDOWN; 1232 } 1233 action = RCTR; 1234 /* FALL THROUGH */ 1235 case RCTR: 1236 state &= ~CTLS2; 1237 break; 1238 case LALTA: 1239 if (state & SHIFTAON) { 1240 set_lockkey_state(kbd, state, ALK); 1241 state &= ~ALKDOWN; 1242 } 1243 action = LALT; 1244 /* FALL THROUGH */ 1245 case LALT: 1246 state &= ~ALTS1; 1247 break; 1248 case RALTA: 1249 if (state & SHIFTAON) { 1250 set_lockkey_state(kbd, state, ALK); 1251 state &= ~ALKDOWN; 1252 } 1253 action = RALT; 1254 /* FALL THROUGH */ 1255 case RALT: 1256 state &= ~ALTS2; 1257 break; 1258 case ASH: 1259 state &= ~AGRS1; 1260 break; 1261 case META: 1262 state &= ~METAS1; 1263 break; 1264 case NLK: 1265 state &= ~NLKDOWN; 1266 break; 1267 case CLK: 1268 #ifndef PC98 1269 state &= ~CLKDOWN; 1270 #else 1271 state &= ~CLKED; 1272 i = state & LOCK_MASK; 1273 (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED, 1274 (caddr_t)&i); 1275 #endif 1276 break; 1277 case SLK: 1278 state &= ~SLKDOWN; 1279 break; 1280 case ALK: 1281 state &= ~ALKDOWN; 1282 break; 1283 case NOP: 1284 /* release events of regular keys are not reported */ 1285 *shiftstate &= ~SHIFTAON; 1286 return (NOKEY); 1287 } 1288 *shiftstate = state & ~SHIFTAON; 1289 return (SPCLKEY | RELKEY | action); 1290 } else { /* make: key pressed */ 1291 action = key->map[i]; 1292 state &= ~SHIFTAON; 1293 if (key->spcl & (0x80 >> i)) { 1294 /* special keys */ 1295 if (kbd->kb_lastact[keycode] == NOP) 1296 kbd->kb_lastact[keycode] = action; 1297 if (kbd->kb_lastact[keycode] != action) 1298 action = NOP; 1299 switch (action) { 1300 /* LOCKING KEYS */ 1301 case NLK: 1302 set_lockkey_state(kbd, state, NLK); 1303 break; 1304 case CLK: 1305 #ifndef PC98 1306 set_lockkey_state(kbd, state, CLK); 1307 #else 1308 state |= CLKED; 1309 i = state & LOCK_MASK; 1310 (*kbdsw[kbd->kb_index]->ioctl)(kbd, KDSETLED, 1311 (caddr_t)&i); 1312 #endif 1313 break; 1314 case SLK: 1315 set_lockkey_state(kbd, state, SLK); 1316 break; 1317 case ALK: 1318 set_lockkey_state(kbd, state, ALK); 1319 break; 1320 /* NON-LOCKING KEYS */ 1321 case SPSC: case RBT: case SUSP: case STBY: 1322 case DBG: case NEXT: case PREV: case PNC: 1323 case HALT: case PDWN: 1324 *accents = 0; 1325 break; 1326 case BTAB: 1327 *accents = 0; 1328 action |= BKEY; 1329 break; 1330 case LSHA: 1331 state |= SHIFTAON; 1332 action = LSH; 1333 /* FALL THROUGH */ 1334 case LSH: 1335 state |= SHIFTS1; 1336 break; 1337 case RSHA: 1338 state |= SHIFTAON; 1339 action = RSH; 1340 /* FALL THROUGH */ 1341 case RSH: 1342 state |= SHIFTS2; 1343 break; 1344 case LCTRA: 1345 state |= SHIFTAON; 1346 action = LCTR; 1347 /* FALL THROUGH */ 1348 case LCTR: 1349 state |= CTLS1; 1350 break; 1351 case RCTRA: 1352 state |= SHIFTAON; 1353 action = RCTR; 1354 /* FALL THROUGH */ 1355 case RCTR: 1356 state |= CTLS2; 1357 break; 1358 case LALTA: 1359 state |= SHIFTAON; 1360 action = LALT; 1361 /* FALL THROUGH */ 1362 case LALT: 1363 state |= ALTS1; 1364 break; 1365 case RALTA: 1366 state |= SHIFTAON; 1367 action = RALT; 1368 /* FALL THROUGH */ 1369 case RALT: 1370 state |= ALTS2; 1371 break; 1372 case ASH: 1373 state |= AGRS1; 1374 break; 1375 case META: 1376 state |= METAS1; 1377 break; 1378 case NOP: 1379 *shiftstate = state; 1380 return (NOKEY); 1381 default: 1382 /* is this an accent (dead) key? */ 1383 *shiftstate = state; 1384 if (action >= F_ACC && action <= L_ACC) { 1385 action = save_accent_key(kbd, action, 1386 accents); 1387 switch (action) { 1388 case NOKEY: 1389 case ERRKEY: 1390 return (action); 1391 default: 1392 if (state & METAS) 1393 return (action | MKEY); 1394 else 1395 return (action); 1396 } 1397 /* NOT REACHED */ 1398 } 1399 /* other special keys */ 1400 if (*accents > 0) { 1401 *accents = 0; 1402 return (ERRKEY); 1403 } 1404 if (action >= F_FN && action <= L_FN) 1405 action |= FKEY; 1406 /* XXX: return fkey string for the FKEY? */ 1407 return (SPCLKEY | action); 1408 } 1409 *shiftstate = state; 1410 return (SPCLKEY | action); 1411 } else { 1412 /* regular keys */ 1413 kbd->kb_lastact[keycode] = NOP; 1414 *shiftstate = state; 1415 if (*accents > 0) { 1416 /* make an accented char */ 1417 action = make_accent_char(kbd, action, accents); 1418 if (action == ERRKEY) 1419 return (action); 1420 } 1421 if (state & METAS) 1422 action |= MKEY; 1423 return (action); 1424 } 1425 } 1426 /* NOT REACHED */ 1427 } 1428