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 * $Id: $ 27 */ 28 29 #include "atkbd.h" 30 #include "opt_kbd.h" 31 #include "opt_devfs.h" 32 33 #if NATKBD > 0 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/conf.h> 39 #include <sys/proc.h> 40 #include <sys/tty.h> 41 #include <sys/fcntl.h> 42 #include <sys/malloc.h> 43 44 #include <dev/kbd/kbdreg.h> 45 #include <dev/kbd/atkbdreg.h> 46 #include <dev/kbd/atkbdcreg.h> 47 48 #ifndef __i386__ 49 50 #define ATKBD_SOFTC(unit) \ 51 ((atkbd_softc_t *)devclass_get_softc(atkbd_devclass, unit)) 52 53 #else /* __i386__ */ 54 55 #include <i386/isa/isa.h> 56 #include <i386/isa/isa_device.h> 57 58 extern struct isa_driver atkbddriver; /* XXX: a kludge; see below */ 59 60 static atkbd_softc_t *atkbd_softc[NATKBD]; 61 62 #define ATKBD_SOFTC(unit) atkbd_softc[(unit)] 63 64 #endif /* __i386__ */ 65 66 static timeout_t atkbd_timeout; 67 68 #ifdef KBD_INSTALL_CDEV 69 70 static d_open_t atkbdopen; 71 static d_close_t atkbdclose; 72 static d_read_t atkbdread; 73 static d_ioctl_t atkbdioctl; 74 static d_poll_t atkbdpoll; 75 76 static struct cdevsw atkbd_cdevsw = { 77 atkbdopen, atkbdclose, atkbdread, nowrite, 78 atkbdioctl, nostop, nullreset, nodevtotty, 79 atkbdpoll, nommap, NULL, ATKBD_DRIVER_NAME, 80 NULL, -1, 81 }; 82 83 #endif /* KBD_INSTALL_CDEV */ 84 85 #ifdef __i386__ 86 87 atkbd_softc_t 88 *atkbd_get_softc(int unit) 89 { 90 atkbd_softc_t *sc; 91 92 if (unit >= sizeof(atkbd_softc)/sizeof(atkbd_softc[0])) 93 return NULL; 94 sc = atkbd_softc[unit]; 95 if (sc == NULL) { 96 sc = atkbd_softc[unit] 97 = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); 98 if (sc == NULL) 99 return NULL; 100 bzero(sc, sizeof(*sc)); 101 } 102 return sc; 103 } 104 105 #endif /* __i386__ */ 106 107 int 108 atkbd_probe_unit(int unit, atkbd_softc_t *sc, int port, int irq, int flags) 109 { 110 keyboard_switch_t *sw; 111 int args[2]; 112 113 if (sc->flags & ATKBD_ATTACHED) 114 return 0; 115 116 sw = kbd_get_switch(ATKBD_DRIVER_NAME); 117 if (sw == NULL) 118 return ENXIO; 119 120 args[0] = port; 121 args[1] = irq; 122 return (*sw->probe)(unit, &sc->kbd, args, flags); 123 } 124 125 int 126 atkbd_attach_unit(int unit, atkbd_softc_t *sc) 127 { 128 keyboard_switch_t *sw; 129 int error; 130 131 if (sc->flags & ATKBD_ATTACHED) 132 return 0; 133 134 sw = kbd_get_switch(ATKBD_DRIVER_NAME); 135 if (sw == NULL) 136 return ENXIO; 137 138 /* reset, initialize and enable the device */ 139 error = (*sw->init)(sc->kbd); 140 if (error) 141 return ENXIO; 142 (*sw->enable)(sc->kbd); 143 144 #ifdef KBD_INSTALL_CDEV 145 /* attach a virtual keyboard cdev */ 146 error = kbd_attach(makedev(0, ATKBD_MKMINOR(unit)), sc->kbd, 147 &atkbd_cdevsw); 148 if (error) 149 return error; 150 #endif 151 152 /* 153 * This is a kludge to compensate for lost keyboard interrupts. 154 * A similar code used to be in syscons. See below. XXX 155 */ 156 atkbd_timeout(sc->kbd); 157 158 if (bootverbose) 159 (*sw->diag)(sc->kbd, bootverbose); 160 161 sc->flags |= ATKBD_ATTACHED; 162 return 0; 163 } 164 165 static void 166 atkbd_timeout(void *arg) 167 { 168 keyboard_t *kbd; 169 int s; 170 171 /* The following comments are extracted from syscons.c (1.287) */ 172 /* 173 * With release 2.1 of the Xaccel server, the keyboard is left 174 * hanging pretty often. Apparently an interrupt from the 175 * keyboard is lost, and I don't know why (yet). 176 * This ugly hack calls scintr if input is ready for the keyboard 177 * and conveniently hides the problem. XXX 178 */ 179 /* 180 * Try removing anything stuck in the keyboard controller; whether 181 * it's a keyboard scan code or mouse data. `scintr()' doesn't 182 * read the mouse data directly, but `kbdio' routines will, as a 183 * side effect. 184 */ 185 s = spltty(); 186 kbd = (keyboard_t *)arg; 187 if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) { 188 /* 189 * We have seen the lock flag is not set. Let's reset 190 * the flag early, otherwise the LED update routine fails 191 * which may want the lock during the interrupt routine. 192 */ 193 (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE); 194 if ((*kbdsw[kbd->kb_index]->check_char)(kbd)) 195 (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); 196 } 197 splx(s); 198 timeout(atkbd_timeout, arg, hz/10); 199 } 200 201 /* cdev driver functions */ 202 203 #ifdef KBD_INSTALL_CDEV 204 205 static int 206 atkbdopen(dev_t dev, int flag, int mode, struct proc *p) 207 { 208 atkbd_softc_t *sc; 209 int unit; 210 211 unit = ATKBD_UNIT(dev); 212 if ((unit >= NATKBD) || ((sc = ATKBD_SOFTC(unit)) == NULL)) 213 return ENXIO; 214 if (mode & (FWRITE | O_CREAT | O_APPEND | O_TRUNC)) 215 return ENODEV; 216 217 /* FIXME: set the initial input mode (K_XLATE?) and lock state? */ 218 return genkbdopen(&sc->gensc, sc->kbd, flag, mode, p); 219 } 220 221 static int 222 atkbdclose(dev_t dev, int flag, int mode, struct proc *p) 223 { 224 atkbd_softc_t *sc; 225 226 sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); 227 return genkbdclose(&sc->gensc, sc->kbd, flag, mode, p); 228 } 229 230 static int 231 atkbdread(dev_t dev, struct uio *uio, int flag) 232 { 233 atkbd_softc_t *sc; 234 235 sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); 236 return genkbdread(&sc->gensc, sc->kbd, uio, flag); 237 } 238 239 static int 240 atkbdioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p) 241 { 242 atkbd_softc_t *sc; 243 244 sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); 245 return genkbdioctl(&sc->gensc, sc->kbd, cmd, arg, flag, p); 246 } 247 248 static int 249 atkbdpoll(dev_t dev, int event, struct proc *p) 250 { 251 atkbd_softc_t *sc; 252 253 sc = ATKBD_SOFTC(ATKBD_UNIT(dev)); 254 return genkbdpoll(&sc->gensc, sc->kbd, event, p); 255 } 256 257 #endif /* KBD_INSTALL_CDEV */ 258 259 /* LOW-LEVEL */ 260 261 #include <machine/limits.h> 262 #include <machine/console.h> 263 #include <machine/clock.h> 264 265 #define ATKBD_DEFAULT 0 266 267 typedef struct atkbd_state { 268 KBDC kbdc; /* keyboard controller */ 269 /* XXX: don't move this field; pcvt 270 * expects `kbdc' to be the first 271 * field in this structure. */ 272 int ks_mode; /* input mode (K_XLATE,K_RAW,K_CODE) */ 273 int ks_flags; /* flags */ 274 #define COMPOSE (1 << 0) 275 int ks_state; /* shift/lock key state */ 276 int ks_accents; /* accent key index (> 0) */ 277 u_int ks_composed_char; /* composed char code (> 0) */ 278 u_char ks_prefix; /* AT scan code prefix */ 279 } atkbd_state_t; 280 281 /* keyboard driver declaration */ 282 static int atkbd_configure(int flags); 283 static kbd_probe_t atkbd_probe; 284 static kbd_init_t atkbd_init; 285 static kbd_term_t atkbd_term; 286 static kbd_intr_t atkbd_intr; 287 static kbd_test_if_t atkbd_test_if; 288 static kbd_enable_t atkbd_enable; 289 static kbd_disable_t atkbd_disable; 290 static kbd_read_t atkbd_read; 291 static kbd_check_t atkbd_check; 292 static kbd_read_char_t atkbd_read_char; 293 static kbd_check_char_t atkbd_check_char; 294 static kbd_ioctl_t atkbd_ioctl; 295 static kbd_lock_t atkbd_lock; 296 static kbd_clear_state_t atkbd_clear_state; 297 static kbd_get_state_t atkbd_get_state; 298 static kbd_set_state_t atkbd_set_state; 299 300 keyboard_switch_t atkbdsw = { 301 atkbd_probe, 302 atkbd_init, 303 atkbd_term, 304 atkbd_intr, 305 atkbd_test_if, 306 atkbd_enable, 307 atkbd_disable, 308 atkbd_read, 309 atkbd_check, 310 atkbd_read_char, 311 atkbd_check_char, 312 atkbd_ioctl, 313 atkbd_lock, 314 atkbd_clear_state, 315 atkbd_get_state, 316 atkbd_set_state, 317 genkbd_get_fkeystr, 318 genkbd_diag, 319 }; 320 321 KEYBOARD_DRIVER(atkbd, atkbdsw, atkbd_configure); 322 323 /* local functions */ 324 static int setup_kbd_port(KBDC kbdc, int port, int intr); 325 static int get_kbd_echo(KBDC kbdc); 326 static int probe_keyboard(KBDC kbdc, int flags); 327 static int init_keyboard(KBDC kbdc, int *type, int flags); 328 static int write_kbd(KBDC kbdc, int command, int data); 329 static int get_kbd_id(KBDC kbdc); 330 331 /* local variables */ 332 333 /* the initial key map, accent map and fkey strings */ 334 #include <i386/isa/kbdtables.h> 335 336 /* structures for the default keyboard */ 337 static keyboard_t default_kbd; 338 static atkbd_state_t default_kbd_state; 339 static keymap_t default_keymap; 340 static accentmap_t default_accentmap; 341 static fkeytab_t default_fkeytab[NUM_FKEYS]; 342 343 /* 344 * The back door to the keyboard driver! 345 * This function is called by the console driver, via the kbdio module, 346 * to tickle keyboard drivers when the low-level console is being initialized. 347 * Almost nothing in the kernel has been initialied yet. Try to probe 348 * keyboards if possible. 349 * NOTE: because of the way the low-level conole is initialized, this routine 350 * may be called more than once!! 351 */ 352 static int 353 atkbd_configure(int flags) 354 { 355 keyboard_t *kbd; 356 KBDC kbdc; 357 int arg[2]; 358 #ifdef __i386__ 359 struct isa_device *dev; 360 361 /* XXX: a kludge to obtain the device configuration flags */ 362 dev = find_isadev(isa_devtab_tty, &atkbddriver, 0); 363 if (dev != NULL) 364 flags |= dev->id_flags; 365 #endif 366 367 /* probe the keyboard controller */ 368 atkbdc_configure(); 369 370 /* probe the default keyboard */ 371 arg[0] = -1; 372 arg[1] = -1; 373 if (atkbd_probe(ATKBD_DEFAULT, &kbd, arg, flags)) 374 return 0; 375 376 /* initialize it */ 377 kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc; 378 if (!(flags & KB_CONF_PROBE_ONLY) && !KBD_IS_PROBED(kbd)) { 379 if (KBD_HAS_DEVICE(kbd) 380 && init_keyboard(kbdc, &kbd->kb_type, flags) 381 && (flags & KB_CONF_FAIL_IF_NO_KBD)) 382 return 0; 383 KBD_INIT_DONE(kbd); 384 } 385 386 /* and register */ 387 if (!KBD_IS_CONFIGURED(kbd)) { 388 if (kbd_register(kbd) < 0) 389 return 0; 390 KBD_CONFIG_DONE(kbd); 391 } 392 393 return 1; /* return the number of found keyboards */ 394 } 395 396 /* low-level functions */ 397 398 /* initialize the keyboard_t structure and try to detect a keyboard */ 399 static int 400 atkbd_probe(int unit, keyboard_t **kbdp, void *arg, int flags) 401 { 402 keyboard_t *kbd; 403 atkbd_state_t *state; 404 keymap_t *keymap; 405 accentmap_t *accmap; 406 fkeytab_t *fkeymap; 407 int fkeymap_size; 408 KBDC kbdc; 409 int *data = (int *)arg; 410 411 /* XXX */ 412 if (unit == ATKBD_DEFAULT) { 413 *kbdp = kbd = &default_kbd; 414 if (KBD_IS_PROBED(kbd)) 415 return 0; 416 state = &default_kbd_state; 417 keymap = &default_keymap; 418 accmap = &default_accentmap; 419 fkeymap = default_fkeytab; 420 fkeymap_size = 421 sizeof(default_fkeytab)/sizeof(default_fkeytab[0]); 422 } else if (*kbdp == NULL) { 423 *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT); 424 if (kbd == NULL) 425 return ENOMEM; 426 bzero(kbd, sizeof(*kbd)); 427 state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT); 428 keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT); 429 accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT); 430 fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT); 431 fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]); 432 if ((state == NULL) || (keymap == NULL) || (accmap == NULL) 433 || (fkeymap == NULL)) { 434 if (state != NULL) 435 free(state, M_DEVBUF); 436 if (keymap != NULL) 437 free(keymap, M_DEVBUF); 438 if (accmap != NULL) 439 free(accmap, M_DEVBUF); 440 if (fkeymap != NULL) 441 free(fkeymap, M_DEVBUF); 442 free(kbd, M_DEVBUF); 443 return ENOMEM; 444 } 445 bzero(state, sizeof(*state)); 446 } else if (KBD_IS_PROBED(*kbdp)) { 447 return 0; 448 } else { 449 kbd = *kbdp; 450 state = (atkbd_state_t *)kbd->kb_data; 451 bzero(state, sizeof(*state)); 452 keymap = kbd->kb_keymap; 453 accmap = kbd->kb_accentmap; 454 fkeymap = kbd->kb_fkeytab; 455 fkeymap_size = kbd->kb_fkeytab_size; 456 } 457 458 state->kbdc = kbdc = kbdc_open(data[0]); 459 if (kbdc == NULL) 460 return ENXIO; 461 kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags, data[0], 462 IO_KBDSIZE); 463 bcopy(&key_map, keymap, sizeof(key_map)); 464 bcopy(&accent_map, accmap, sizeof(accent_map)); 465 bcopy(fkey_tab, fkeymap, 466 imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab))); 467 kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size); 468 kbd->kb_data = (void *)state; 469 470 if (probe_keyboard(kbdc, flags)) { 471 if (flags & KB_CONF_FAIL_IF_NO_KBD) 472 return ENXIO; 473 } else { 474 KBD_FOUND_DEVICE(kbd); 475 } 476 atkbd_clear_state(kbd); 477 state->ks_mode = K_XLATE; 478 /* 479 * FIXME: set the initial value for lock keys in ks_state 480 * according to the BIOS data? 481 */ 482 483 KBD_PROBE_DONE(kbd); 484 return 0; 485 } 486 487 /* reset and initialize the device */ 488 static int 489 atkbd_init(keyboard_t *kbd) 490 { 491 KBDC kbdc; 492 493 if ((kbd == NULL) || !KBD_IS_PROBED(kbd)) 494 return ENXIO; /* shouldn't happen */ 495 kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc; 496 if (kbdc == NULL) 497 return ENXIO; /* shouldn't happen */ 498 499 if (!KBD_IS_INITIALIZED(kbd)) { 500 if (KBD_HAS_DEVICE(kbd) 501 && init_keyboard(kbdc, &kbd->kb_type, kbd->kb_config) 502 && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) 503 return ENXIO; 504 atkbd_ioctl(kbd, KDSETLED, 505 (caddr_t)&((atkbd_state_t *)(kbd->kb_data))->ks_state); 506 KBD_INIT_DONE(kbd); 507 } 508 if (!KBD_IS_CONFIGURED(kbd)) { 509 if (kbd_register(kbd) < 0) 510 return ENXIO; 511 KBD_CONFIG_DONE(kbd); 512 } 513 514 return 0; 515 } 516 517 /* finish using this keyboard */ 518 static int 519 atkbd_term(keyboard_t *kbd) 520 { 521 kbd_unregister(kbd); 522 return 0; 523 } 524 525 /* keyboard interrupt routine */ 526 static int 527 atkbd_intr(keyboard_t *kbd, void *arg) 528 { 529 atkbd_state_t *state; 530 int c; 531 532 if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { 533 /* let the callback function to process the input */ 534 (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, 535 kbd->kb_callback.kc_arg); 536 } else { 537 /* read and discard the input; no one is waiting for input */ 538 do { 539 c = atkbd_read_char(kbd, FALSE); 540 } while (c != NOKEY); 541 542 if (!KBD_HAS_DEVICE(kbd)) { 543 /* 544 * The keyboard was not detected before; 545 * it must have been reconnected! 546 */ 547 state = (atkbd_state_t *)kbd->kb_data; 548 init_keyboard(state->kbdc, &kbd->kb_type, 549 kbd->kb_config); 550 atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); 551 KBD_FOUND_DEVICE(kbd); 552 } 553 } 554 return 0; 555 } 556 557 /* test the interface to the device */ 558 static int 559 atkbd_test_if(keyboard_t *kbd) 560 { 561 int error; 562 int s; 563 564 error = 0; 565 empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10); 566 s = spltty(); 567 if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc)) 568 error = EIO; 569 else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0) 570 error = EIO; 571 splx(s); 572 573 return error; 574 } 575 576 /* 577 * Enable the access to the device; until this function is called, 578 * the client cannot read from the keyboard. 579 */ 580 static int 581 atkbd_enable(keyboard_t *kbd) 582 { 583 int s; 584 585 s = spltty(); 586 KBD_ACTIVATE(kbd); 587 splx(s); 588 return 0; 589 } 590 591 /* disallow the access to the device */ 592 static int 593 atkbd_disable(keyboard_t *kbd) 594 { 595 int s; 596 597 s = spltty(); 598 KBD_DEACTIVATE(kbd); 599 splx(s); 600 return 0; 601 } 602 603 /* read one byte from the keyboard if it's allowed */ 604 static int 605 atkbd_read(keyboard_t *kbd, int wait) 606 { 607 int c; 608 609 if (wait) 610 c = read_kbd_data(((atkbd_state_t *)kbd->kb_data)->kbdc); 611 else 612 c = read_kbd_data_no_wait(((atkbd_state_t *)kbd->kb_data)->kbdc); 613 return (KBD_IS_ACTIVE(kbd) ? c : -1); 614 } 615 616 /* check if data is waiting */ 617 static int 618 atkbd_check(keyboard_t *kbd) 619 { 620 if (!KBD_IS_ACTIVE(kbd)) 621 return FALSE; 622 return kbdc_data_ready(((atkbd_state_t *)kbd->kb_data)->kbdc); 623 } 624 625 /* read char from the keyboard */ 626 static u_int 627 atkbd_read_char(keyboard_t *kbd, int wait) 628 { 629 atkbd_state_t *state; 630 u_int action; 631 int scancode; 632 int keycode; 633 634 state = (atkbd_state_t *)kbd->kb_data; 635 next_code: 636 /* do we have a composed char to return? */ 637 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) { 638 action = state->ks_composed_char; 639 state->ks_composed_char = 0; 640 if (action > UCHAR_MAX) 641 return ERRKEY; 642 return action; 643 } 644 645 /* see if there is something in the keyboard port */ 646 if (wait) { 647 do { 648 scancode = read_kbd_data(state->kbdc); 649 } while (scancode == -1); 650 } else { 651 scancode = read_kbd_data_no_wait(state->kbdc); 652 if (scancode == -1) 653 return NOKEY; 654 } 655 656 /* return the byte as is for the K_RAW mode */ 657 if (state->ks_mode == K_RAW) 658 return scancode; 659 660 /* translate the scan code into a keycode */ 661 keycode = scancode & 0x7F; 662 switch (state->ks_prefix) { 663 case 0x00: /* normal scancode */ 664 switch(scancode) { 665 case 0xB8: /* left alt (compose key) released */ 666 if (state->ks_flags & COMPOSE) { 667 state->ks_flags &= ~COMPOSE; 668 if (state->ks_composed_char > UCHAR_MAX) 669 state->ks_composed_char = 0; 670 } 671 break; 672 case 0x38: /* left alt (compose key) pressed */ 673 if (!(state->ks_flags & COMPOSE)) { 674 state->ks_flags |= COMPOSE; 675 state->ks_composed_char = 0; 676 } 677 break; 678 case 0xE0: 679 case 0xE1: 680 state->ks_prefix = scancode; 681 goto next_code; 682 } 683 break; 684 case 0xE0: /* 0xE0 prefix */ 685 state->ks_prefix = 0; 686 switch (keycode) { 687 case 0x1C: /* right enter key */ 688 keycode = 0x59; 689 break; 690 case 0x1D: /* right ctrl key */ 691 keycode = 0x5A; 692 break; 693 case 0x35: /* keypad divide key */ 694 keycode = 0x5B; 695 break; 696 case 0x37: /* print scrn key */ 697 keycode = 0x5C; 698 break; 699 case 0x38: /* right alt key (alt gr) */ 700 keycode = 0x5D; 701 break; 702 case 0x47: /* grey home key */ 703 keycode = 0x5E; 704 break; 705 case 0x48: /* grey up arrow key */ 706 keycode = 0x5F; 707 break; 708 case 0x49: /* grey page up key */ 709 keycode = 0x60; 710 break; 711 case 0x4B: /* grey left arrow key */ 712 keycode = 0x61; 713 break; 714 case 0x4D: /* grey right arrow key */ 715 keycode = 0x62; 716 break; 717 case 0x4F: /* grey end key */ 718 keycode = 0x63; 719 break; 720 case 0x50: /* grey down arrow key */ 721 keycode = 0x64; 722 break; 723 case 0x51: /* grey page down key */ 724 keycode = 0x65; 725 break; 726 case 0x52: /* grey insert key */ 727 keycode = 0x66; 728 break; 729 case 0x53: /* grey delete key */ 730 keycode = 0x67; 731 break; 732 /* the following 3 are only used on the MS "Natural" keyboard */ 733 case 0x5b: /* left Window key */ 734 keycode = 0x69; 735 break; 736 case 0x5c: /* right Window key */ 737 keycode = 0x6a; 738 break; 739 case 0x5d: /* menu key */ 740 keycode = 0x6b; 741 break; 742 default: /* ignore everything else */ 743 goto next_code; 744 } 745 break; 746 case 0xE1: /* 0xE1 prefix */ 747 state->ks_prefix = 0; 748 if (keycode == 0x1D) 749 state->ks_prefix = 0x1D; 750 goto next_code; 751 /* NOT REACHED */ 752 case 0x1D: /* pause / break */ 753 state->ks_prefix = 0; 754 if (keycode != 0x45) 755 goto next_code; 756 keycode = 0x68; 757 break; 758 } 759 760 /* return the key code in the K_CODE mode */ 761 if (state->ks_mode == K_CODE) 762 return (keycode | (scancode & 0x80)); 763 764 /* compose a character code */ 765 if (state->ks_flags & COMPOSE) { 766 switch (scancode) { 767 /* key pressed, process it */ 768 case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */ 769 state->ks_composed_char *= 10; 770 state->ks_composed_char += scancode - 0x40; 771 if (state->ks_composed_char > UCHAR_MAX) 772 return ERRKEY; 773 goto next_code; 774 case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */ 775 state->ks_composed_char *= 10; 776 state->ks_composed_char += scancode - 0x47; 777 if (state->ks_composed_char > UCHAR_MAX) 778 return ERRKEY; 779 goto next_code; 780 case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */ 781 state->ks_composed_char *= 10; 782 state->ks_composed_char += scancode - 0x4E; 783 if (state->ks_composed_char > UCHAR_MAX) 784 return ERRKEY; 785 goto next_code; 786 case 0x52: /* keypad 0 */ 787 state->ks_composed_char *= 10; 788 if (state->ks_composed_char > UCHAR_MAX) 789 return ERRKEY; 790 goto next_code; 791 792 /* key released, no interest here */ 793 case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */ 794 case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */ 795 case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */ 796 case 0xD2: /* keypad 0 */ 797 goto next_code; 798 799 case 0x38: /* left alt key */ 800 break; 801 802 default: 803 if (state->ks_composed_char > 0) { 804 state->ks_flags &= ~COMPOSE; 805 state->ks_composed_char = 0; 806 return ERRKEY; 807 } 808 break; 809 } 810 } 811 812 /* keycode to key action */ 813 action = genkbd_keyaction(kbd, keycode, scancode & 0x80, 814 &state->ks_state, &state->ks_accents); 815 if (action == NOKEY) 816 goto next_code; 817 else 818 return action; 819 } 820 821 /* check if char is waiting */ 822 static int 823 atkbd_check_char(keyboard_t *kbd) 824 { 825 atkbd_state_t *state; 826 827 if (!KBD_IS_ACTIVE(kbd)) 828 return FALSE; 829 state = (atkbd_state_t *)kbd->kb_data; 830 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) 831 return TRUE; 832 return kbdc_data_ready(state->kbdc); 833 } 834 835 /* some useful control functions */ 836 static int 837 atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) 838 { 839 /* trasnlate LED_XXX bits into the device specific bits */ 840 static u_char ledmap[8] = { 841 0, 4, 2, 6, 1, 5, 3, 7, 842 }; 843 atkbd_state_t *state = kbd->kb_data; 844 int error; 845 int s; 846 int i; 847 848 s = spltty(); 849 switch (cmd) { 850 851 case KDGKBMODE: /* get keyboard mode */ 852 *(int *)arg = state->ks_mode; 853 break; 854 case KDSKBMODE: /* set keyboard mode */ 855 switch (*(int *)arg) { 856 case K_XLATE: 857 if (state->ks_mode != K_XLATE) { 858 /* make lock key state and LED state match */ 859 state->ks_state &= ~LOCK_MASK; 860 state->ks_state |= KBD_LED_VAL(kbd); 861 } 862 /* FALL THROUGH */ 863 case K_RAW: 864 case K_CODE: 865 if (state->ks_mode != *(int *)arg) { 866 atkbd_clear_state(kbd); 867 state->ks_mode = *(int *)arg; 868 } 869 break; 870 default: 871 splx(s); 872 return EINVAL; 873 } 874 break; 875 876 case KDGETLED: /* get keyboard LED */ 877 *(int *)arg = KBD_LED_VAL(kbd); 878 break; 879 case KDSETLED: /* set keyboard LED */ 880 /* NOTE: lock key state in ks_state won't be changed */ 881 if (*(int *)arg & ~LOCK_MASK) { 882 splx(s); 883 return EINVAL; 884 } 885 i = *(int *)arg; 886 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ 887 if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) { 888 if (i & ALKED) 889 i |= CLKED; 890 else 891 i &= ~CLKED; 892 } 893 if (KBD_HAS_DEVICE(kbd)) { 894 error = write_kbd(state->kbdc, KBDC_SET_LEDS, 895 ledmap[i & LED_MASK]); 896 if (error) { 897 splx(s); 898 return error; 899 } 900 } 901 KBD_LED_VAL(kbd) = *(int *)arg; 902 break; 903 904 case KDGKBSTATE: /* get lock key state */ 905 *(int *)arg = state->ks_state & LOCK_MASK; 906 break; 907 case KDSKBSTATE: /* set lock key state */ 908 if (*(int *)arg & ~LOCK_MASK) { 909 splx(s); 910 return EINVAL; 911 } 912 state->ks_state &= ~LOCK_MASK; 913 state->ks_state |= *(int *)arg; 914 splx(s); 915 /* set LEDs and quit */ 916 return atkbd_ioctl(kbd, KDSETLED, arg); 917 918 case KDSETRAD: /* set keyboard repeat rate */ 919 splx(s); 920 if (!KBD_HAS_DEVICE(kbd)) 921 return 0; 922 return write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, 923 *(int *)arg); 924 925 case PIO_KEYMAP: /* set keyboard translation table */ 926 case PIO_KEYMAPENT: /* set keyboard translation table entry */ 927 case PIO_DEADKEYMAP: /* set accent key translation table */ 928 state->ks_accents = 0; 929 /* FALL THROUGH */ 930 default: 931 splx(s); 932 return genkbd_commonioctl(kbd, cmd, arg); 933 } 934 935 splx(s); 936 return 0; 937 } 938 939 /* lock the access to the keyboard */ 940 static int 941 atkbd_lock(keyboard_t *kbd, int lock) 942 { 943 return kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc, lock); 944 } 945 946 /* clear the internal state of the keyboard */ 947 static void 948 atkbd_clear_state(keyboard_t *kbd) 949 { 950 atkbd_state_t *state; 951 952 state = (atkbd_state_t *)kbd->kb_data; 953 state->ks_flags = 0; 954 state->ks_state &= LOCK_MASK; /* preserve locking key state */ 955 state->ks_accents = 0; 956 state->ks_composed_char = 0; 957 #if 0 958 state->ks_prefix = 0; /* XXX */ 959 #endif 960 } 961 962 /* save the internal state */ 963 static int 964 atkbd_get_state(keyboard_t *kbd, void *buf, size_t len) 965 { 966 if (len == 0) 967 return sizeof(atkbd_state_t); 968 if (len < sizeof(atkbd_state_t)) 969 return -1; 970 bcopy(kbd->kb_data, buf, sizeof(atkbd_state_t)); 971 return 0; 972 } 973 974 /* set the internal state */ 975 static int 976 atkbd_set_state(keyboard_t *kbd, void *buf, size_t len) 977 { 978 if (len < sizeof(atkbd_state_t)) 979 return ENOMEM; 980 if (((atkbd_state_t *)kbd->kb_data)->kbdc 981 != ((atkbd_state_t *)buf)->kbdc) 982 return ENOMEM; 983 bcopy(buf, kbd->kb_data, sizeof(atkbd_state_t)); 984 return 0; 985 } 986 987 /* local functions */ 988 989 static int 990 setup_kbd_port(KBDC kbdc, int port, int intr) 991 { 992 if (!set_controller_command_byte(kbdc, 993 KBD_KBD_CONTROL_BITS, 994 ((port) ? KBD_ENABLE_KBD_PORT : KBD_DISABLE_KBD_PORT) 995 | ((intr) ? KBD_ENABLE_KBD_INT : KBD_DISABLE_KBD_INT))) 996 return 1; 997 return 0; 998 } 999 1000 static int 1001 get_kbd_echo(KBDC kbdc) 1002 { 1003 /* enable the keyboard port, but disable the keyboard intr. */ 1004 if (setup_kbd_port(kbdc, TRUE, FALSE)) 1005 /* CONTROLLER ERROR: there is very little we can do... */ 1006 return ENXIO; 1007 1008 /* see if something is present */ 1009 write_kbd_command(kbdc, KBDC_ECHO); 1010 if (read_kbd_data(kbdc) != KBD_ECHO) { 1011 empty_both_buffers(kbdc, 10); 1012 test_controller(kbdc); 1013 test_kbd_port(kbdc); 1014 return ENXIO; 1015 } 1016 1017 /* enable the keyboard port and intr. */ 1018 if (setup_kbd_port(kbdc, TRUE, TRUE)) { 1019 /* 1020 * CONTROLLER ERROR 1021 * This is serious; the keyboard intr is left disabled! 1022 */ 1023 return ENXIO; 1024 } 1025 1026 return 0; 1027 } 1028 1029 static int 1030 probe_keyboard(KBDC kbdc, int flags) 1031 { 1032 /* 1033 * Don't try to print anything in this function. The low-level 1034 * console may not have been initialized yet... 1035 */ 1036 int err; 1037 int c; 1038 int m; 1039 1040 if (!kbdc_lock(kbdc, TRUE)) { 1041 /* driver error? */ 1042 return ENXIO; 1043 } 1044 1045 /* flush any noise in the buffer */ 1046 empty_both_buffers(kbdc, 10); 1047 1048 /* save the current keyboard controller command byte */ 1049 m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS; 1050 c = get_controller_command_byte(kbdc); 1051 if (c == -1) { 1052 /* CONTROLLER ERROR */ 1053 kbdc_set_device_mask(kbdc, m); 1054 kbdc_lock(kbdc, FALSE); 1055 return ENXIO; 1056 } 1057 1058 /* 1059 * The keyboard may have been screwed up by the boot block. 1060 * We may just be able to recover from error by testing the controller 1061 * and the keyboard port. The controller command byte needs to be 1062 * saved before this recovery operation, as some controllers seem 1063 * to set the command byte to particular values. 1064 */ 1065 test_controller(kbdc); 1066 test_kbd_port(kbdc); 1067 1068 err = get_kbd_echo(kbdc); 1069 if (err == 0) { 1070 kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS); 1071 } else { 1072 if (c != -1) 1073 /* try to restore the command byte as before */ 1074 set_controller_command_byte(kbdc, 0xff, c); 1075 kbdc_set_device_mask(kbdc, m); 1076 } 1077 1078 kbdc_lock(kbdc, FALSE); 1079 return err; 1080 } 1081 1082 static int 1083 init_keyboard(KBDC kbdc, int *type, int flags) 1084 { 1085 int codeset; 1086 int id; 1087 int c; 1088 1089 if (!kbdc_lock(kbdc, TRUE)) { 1090 /* driver error? */ 1091 return EIO; 1092 } 1093 1094 /* save the current controller command byte */ 1095 empty_both_buffers(kbdc, 10); 1096 c = get_controller_command_byte(kbdc); 1097 if (c == -1) { 1098 /* CONTROLLER ERROR */ 1099 kbdc_lock(kbdc, FALSE); 1100 printf("atkbd: unable to get the current command byte value.\n"); 1101 return EIO; 1102 } 1103 if (bootverbose) 1104 printf("atkbd: the current kbd controller command byte %04x\n", 1105 c); 1106 #if 0 1107 /* override the keyboard lock switch */ 1108 c |= KBD_OVERRIDE_KBD_LOCK; 1109 #endif 1110 1111 /* enable the keyboard port, but disable the keyboard intr. */ 1112 if (setup_kbd_port(kbdc, TRUE, FALSE)) { 1113 /* CONTROLLER ERROR: there is very little we can do... */ 1114 printf("atkbd: unable to set the command byte.\n"); 1115 kbdc_lock(kbdc, FALSE); 1116 return EIO; 1117 } 1118 1119 /* 1120 * Check if we have an XT keyboard before we attempt to reset it. 1121 * The procedure assumes that the keyboard and the controller have 1122 * been set up properly by BIOS and have not been messed up 1123 * during the boot process. 1124 */ 1125 codeset = -1; 1126 if (flags & KB_CONF_ALT_SCANCODESET) 1127 /* the user says there is a XT keyboard */ 1128 codeset = 1; 1129 #ifdef KBD_DETECT_XT_KEYBOARD 1130 else if ((c & KBD_TRANSLATION) == 0) { 1131 /* SET_SCANCODE_SET is not always supported; ignore error */ 1132 if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0) 1133 == KBD_ACK) 1134 codeset = read_kbd_data(kbdc); 1135 } 1136 if (bootverbose) 1137 printf("atkbd: scancode set %d\n", codeset); 1138 #endif /* KBD_DETECT_XT_KEYBOARD */ 1139 1140 *type = KB_OTHER; 1141 id = get_kbd_id(kbdc); 1142 switch(id) { 1143 case 0x41ab: 1144 case 0x83ab: 1145 *type = KB_101; 1146 break; 1147 case -1: /* AT 84 keyboard doesn't return ID */ 1148 *type = KB_84; 1149 break; 1150 default: 1151 break; 1152 } 1153 if (bootverbose) 1154 printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type); 1155 1156 /* reset keyboard hardware */ 1157 if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) { 1158 /* 1159 * KEYBOARD ERROR 1160 * Keyboard reset may fail either because the keyboard 1161 * doen't exist, or because the keyboard doesn't pass 1162 * the self-test, or the keyboard controller on the 1163 * motherboard and the keyboard somehow fail to shake hands. 1164 * It is just possible, particularly in the last case, 1165 * that the keyoard controller may be left in a hung state. 1166 * test_controller() and test_kbd_port() appear to bring 1167 * the keyboard controller back (I don't know why and how, 1168 * though.) 1169 */ 1170 empty_both_buffers(kbdc, 10); 1171 test_controller(kbdc); 1172 test_kbd_port(kbdc); 1173 /* 1174 * We could disable the keyboard port and interrupt... but, 1175 * the keyboard may still exist (see above). 1176 */ 1177 set_controller_command_byte(kbdc, 0xff, c); 1178 kbdc_lock(kbdc, FALSE); 1179 if (bootverbose) 1180 printf("atkbd: failed to reset the keyboard.\n"); 1181 return EIO; 1182 } 1183 1184 /* 1185 * Allow us to set the XT_KEYBD flag in UserConfig so that keyboards 1186 * such as those on the IBM ThinkPad laptop computers can be used 1187 * with the standard console driver. 1188 */ 1189 if (codeset == 1) { 1190 if (send_kbd_command_and_data(kbdc, 1191 KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) { 1192 /* XT kbd doesn't need scan code translation */ 1193 c &= ~KBD_TRANSLATION; 1194 } else { 1195 /* 1196 * KEYBOARD ERROR 1197 * The XT kbd isn't usable unless the proper scan 1198 * code set is selected. 1199 */ 1200 set_controller_command_byte(kbdc, 0xff, c); 1201 kbdc_lock(kbdc, FALSE); 1202 printf("atkbd: unable to set the XT keyboard mode.\n"); 1203 return EIO; 1204 } 1205 } 1206 1207 /* enable the keyboard port and intr. */ 1208 if (!set_controller_command_byte(kbdc, 1209 KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK, 1210 (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK)) 1211 | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) { 1212 /* 1213 * CONTROLLER ERROR 1214 * This is serious; we are left with the disabled 1215 * keyboard intr. 1216 */ 1217 set_controller_command_byte(kbdc, 0xff, c); 1218 kbdc_lock(kbdc, FALSE); 1219 printf("atkbd: unable to enable the keyboard port and intr.\n"); 1220 return EIO; 1221 } 1222 1223 kbdc_lock(kbdc, FALSE); 1224 return 0; 1225 } 1226 1227 static int 1228 write_kbd(KBDC kbdc, int command, int data) 1229 { 1230 int s; 1231 1232 /* prevent the timeout routine from polling the keyboard */ 1233 if (!kbdc_lock(kbdc, TRUE)) 1234 return EBUSY; 1235 1236 /* disable the keyboard and mouse interrupt */ 1237 s = spltty(); 1238 #if 0 1239 c = get_controller_command_byte(kbdc); 1240 if ((c == -1) 1241 || !set_controller_command_byte(kbdc, 1242 kbdc_get_device_mask(kbdc), 1243 KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT 1244 | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) { 1245 /* CONTROLLER ERROR */ 1246 kbdc_lock(kbdc, FALSE); 1247 splx(s); 1248 return EIO; 1249 } 1250 /* 1251 * Now that the keyboard controller is told not to generate 1252 * the keyboard and mouse interrupts, call `splx()' to allow 1253 * the other tty interrupts. The clock interrupt may also occur, 1254 * but the timeout routine (`scrn_timer()') will be blocked 1255 * by the lock flag set via `kbdc_lock()' 1256 */ 1257 splx(s); 1258 #endif 1259 1260 if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK) 1261 send_kbd_command(kbdc, KBDC_ENABLE_KBD); 1262 1263 #if 0 1264 /* restore the interrupts */ 1265 if (!set_controller_command_byte(kbdc, 1266 kbdc_get_device_mask(kbdc), 1267 c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { 1268 /* CONTROLLER ERROR */ 1269 } 1270 #else 1271 splx(s); 1272 #endif 1273 kbdc_lock(kbdc, FALSE); 1274 1275 return 0; 1276 } 1277 1278 static int 1279 get_kbd_id(KBDC kbdc) 1280 { 1281 int id1, id2; 1282 1283 empty_both_buffers(kbdc, 10); 1284 id1 = id2 = -1; 1285 if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) != KBD_ACK) 1286 return -1; 1287 1288 DELAY(10000); /* 10 msec delay */ 1289 id1 = read_kbd_data(kbdc); 1290 if (id1 != -1) 1291 id2 = read_kbd_data(kbdc); 1292 1293 if ((id1 == -1) || (id2 == -1)) { 1294 empty_both_buffers(kbdc, 10); 1295 test_controller(kbdc); 1296 test_kbd_port(kbdc); 1297 return -1; 1298 } 1299 return ((id2 << 8) | id1); 1300 } 1301 1302 #endif /* NATKBD > 0 */ 1303