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