1 /* $NetBSD: kbd.c,v 1.22 1999/05/14 06:42:02 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This software was developed by the Computer Systems Engineering group 8 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 9 * contributed to Berkeley. 10 * 11 * All advertising materials mentioning features or use of this software 12 * must display the following acknowledgement: 13 * This product includes software developed by the University of 14 * California, Lawrence Berkeley Laboratory. 15 * 16 * Redistribution and use in source and binary forms, with or without 17 * modification, are permitted provided that the following conditions 18 * are met: 19 * 1. Redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer. 21 * 2. Redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution. 24 * 3. All advertising materials mentioning features or use of this software 25 * must display the following acknowledgement: 26 * This product includes software developed by the University of 27 * California, Berkeley and its contributors. 28 * 4. Neither the name of the University nor the names of its contributors 29 * may be used to endorse or promote products derived from this software 30 * without specific prior written permission. 31 * 32 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 35 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 40 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 41 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 42 * SUCH DAMAGE. 43 * 44 * @(#)kbd.c 8.2 (Berkeley) 10/30/93 45 */ 46 47 /* 48 * Keyboard driver (/dev/kbd -- note that we do not have minor numbers 49 * [yet?]). Translates incoming bytes to ASCII or to `firm_events' and 50 * passes them up to the appropriate reader. 51 */ 52 53 /* 54 * This is the "slave" driver that will be attached to 55 * the "zsc" driver for a Sun keyboard. 56 */ 57 58 #include <sys/param.h> 59 #include <sys/systm.h> 60 #include <sys/conf.h> 61 #include <sys/device.h> 62 #include <sys/ioctl.h> 63 #include <sys/kernel.h> 64 #include <sys/proc.h> 65 #include <sys/signal.h> 66 #include <sys/signalvar.h> 67 #include <sys/time.h> 68 #include <sys/syslog.h> 69 #include <sys/select.h> 70 #include <sys/poll.h> 71 72 #include <dev/ic/z8530reg.h> 73 #include <machine/z8530var.h> 74 #include <machine/vuid_event.h> 75 #include <machine/kbd.h> 76 #include <machine/kbio.h> 77 #include <dev/sun/event_var.h> 78 #include <dev/sun/kbd_xlate.h> 79 #include <dev/sun/kbdvar.h> 80 81 #include "locators.h" 82 83 /* 84 * Ideas: 85 * /dev/kbd is not a tty (plain device) 86 */ 87 88 /* Prototypes */ 89 static void kbd_new_layout(struct kbd_softc *k); 90 static void kbd_repeat(void *arg); 91 static void kbd_set_leds(struct kbd_softc *k, int leds); 92 static void kbd_update_leds(struct kbd_softc *k); 93 static void kbd_was_reset(struct kbd_softc *k); 94 static int kbd_drain_tx(struct kbd_softc *k); 95 96 cdev_decl(kbd); /* open, close, read, write, ioctl, stop, ... */ 97 98 extern struct cfdriver kbd_cd; 99 100 /**************************************************************** 101 * Entry points for /dev/kbd 102 * (open,close,read,write,...) 103 ****************************************************************/ 104 105 /* 106 * Open: 107 * Check exclusion, open actual device (_iopen), 108 * setup event channel, clear ASCII repeat stuff. 109 */ 110 int 111 kbdopen(dev, flags, mode, p) 112 dev_t dev; 113 int flags, mode; 114 struct proc *p; 115 { 116 struct kbd_softc *k; 117 int error, unit; 118 119 unit = minor(dev); 120 if (unit >= kbd_cd.cd_ndevs) 121 return (ENXIO); 122 k = kbd_cd.cd_devs[unit]; 123 if (k == NULL) 124 return (ENXIO); 125 126 /* Exclusive open required for /dev/kbd */ 127 if (k->k_events.ev_io) 128 return (EBUSY); 129 k->k_events.ev_io = p; 130 131 if ((error = kbd_iopen(unit)) != 0) { 132 k->k_events.ev_io = NULL; 133 return (error); 134 } 135 ev_init(&k->k_events); 136 k->k_evmode = 1; /* XXX: OK? */ 137 138 if (k->k_repeating) { 139 k->k_repeating = 0; 140 untimeout(kbd_repeat, k); 141 } 142 143 return (0); 144 } 145 146 /* 147 * Close: 148 * Turn off event mode, dump the queue, and close the keyboard 149 * unless it is supplying console input. 150 */ 151 int 152 kbdclose(dev, flags, mode, p) 153 dev_t dev; 154 int flags, mode; 155 struct proc *p; 156 { 157 struct kbd_softc *k; 158 159 k = kbd_cd.cd_devs[minor(dev)]; 160 k->k_evmode = 0; 161 ev_fini(&k->k_events); 162 k->k_events.ev_io = NULL; 163 return (0); 164 } 165 166 int 167 kbdread(dev, uio, flags) 168 dev_t dev; 169 struct uio *uio; 170 int flags; 171 { 172 struct kbd_softc *k; 173 174 k = kbd_cd.cd_devs[minor(dev)]; 175 return (ev_read(&k->k_events, uio, flags)); 176 } 177 178 /* this routine should not exist, but is convenient to write here for now */ 179 int 180 kbdwrite(dev, uio, flags) 181 dev_t dev; 182 struct uio *uio; 183 int flags; 184 { 185 186 return (EOPNOTSUPP); 187 } 188 189 int 190 kbdpoll(dev, events, p) 191 dev_t dev; 192 int events; 193 struct proc *p; 194 { 195 struct kbd_softc *k; 196 197 k = kbd_cd.cd_devs[minor(dev)]; 198 return (ev_poll(&k->k_events, events, p)); 199 } 200 201 202 static int kbd_iockeymap __P((struct kbd_state *ks, 203 u_long cmd, struct kiockeymap *kio)); 204 205 static int kbd_iocsled(struct kbd_softc *k, char *data); 206 207 #ifdef KIOCGETKEY 208 static int kbd_oldkeymap __P((struct kbd_state *ks, 209 u_long cmd, struct okiockey *okio)); 210 #endif 211 212 int 213 kbdioctl(dev, cmd, data, flag, p) 214 dev_t dev; 215 u_long cmd; 216 register caddr_t data; 217 int flag; 218 struct proc *p; 219 { 220 struct kbd_softc *k; 221 struct kbd_state *ks; 222 int error = 0; 223 224 k = kbd_cd.cd_devs[minor(dev)]; 225 ks = &k->k_state; 226 227 switch (cmd) { 228 229 case KIOCTRANS: /* Set translation mode */ 230 /* We only support "raw" mode on /dev/kbd */ 231 if (*(int *)data != TR_UNTRANS_EVENT) 232 error = EINVAL; 233 break; 234 235 case KIOCGTRANS: /* Get translation mode */ 236 /* We only support "raw" mode on /dev/kbd */ 237 *(int *)data = TR_UNTRANS_EVENT; 238 break; 239 240 #ifdef KIOCGETKEY 241 case KIOCGETKEY: /* Get keymap entry (old format) */ 242 error = kbd_oldkeymap(ks, cmd, (struct okiockey *)data); 243 break; 244 #endif KIOCGETKEY */ 245 246 case KIOCSKEY: /* Set keymap entry */ 247 /* fallthrough */ 248 case KIOCGKEY: /* Get keymap entry */ 249 error = kbd_iockeymap(ks, cmd, (struct kiockeymap *)data); 250 break; 251 252 case KIOCCMD: /* Send a command to the keyboard */ 253 error = kbd_docmd(*(int *)data, 1); 254 break; 255 256 case KIOCTYPE: /* Get keyboard type */ 257 *(int *)data = ks->kbd_id; 258 break; 259 260 case KIOCSDIRECT: /* where to send input */ 261 k->k_evmode = *(int *)data; 262 break; 263 264 case KIOCLAYOUT: /* Get keyboard layout */ 265 *(int *)data = ks->kbd_layout; 266 break; 267 268 case KIOCSLED: 269 error = kbd_iocsled(k, (char *)data); 270 break; 271 272 case KIOCGLED: 273 *(char *)data = ks->kbd_leds; 274 break; 275 276 case FIONBIO: /* we will remove this someday (soon???) */ 277 break; 278 279 case FIOASYNC: 280 k->k_events.ev_async = *(int *)data != 0; 281 break; 282 283 case TIOCSPGRP: 284 if (*(int *)data != k->k_events.ev_io->p_pgid) 285 error = EPERM; 286 break; 287 288 default: 289 error = ENOTTY; 290 break; 291 } 292 293 return (error); 294 } 295 296 /**************************************************************** 297 * ioctl helpers 298 ****************************************************************/ 299 300 /* 301 * Get/Set keymap entry 302 */ 303 static int 304 kbd_iockeymap(ks, cmd, kio) 305 struct kbd_state *ks; 306 u_long cmd; 307 struct kiockeymap *kio; 308 { 309 u_short *km; 310 u_int station; 311 312 switch (kio->kio_tablemask) { 313 case KIOC_NOMASK: 314 km = ks->kbd_k.k_normal; 315 break; 316 case KIOC_SHIFTMASK: 317 km = ks->kbd_k.k_shifted; 318 break; 319 case KIOC_CTRLMASK: 320 km = ks->kbd_k.k_control; 321 break; 322 case KIOC_UPMASK: 323 km = ks->kbd_k.k_release; 324 break; 325 default: 326 /* Silently ignore unsupported masks */ 327 return (0); 328 } 329 330 /* Range-check the table position. */ 331 station = kio->kio_station; 332 if (station >= KEYMAP_SIZE) 333 return (EINVAL); 334 335 switch (cmd) { 336 337 case KIOCGKEY: /* Get keymap entry */ 338 kio->kio_entry = km[station]; 339 break; 340 341 case KIOCSKEY: /* Set keymap entry */ 342 km[station] = kio->kio_entry; 343 break; 344 345 default: 346 return(ENOTTY); 347 } 348 return (0); 349 } 350 351 #ifdef KIOCGETKEY 352 /* 353 * Get/Set keymap entry, 354 * old format (compatibility) 355 */ 356 int 357 kbd_oldkeymap(ks, cmd, kio) 358 struct kbd_state *ks; 359 u_long cmd; 360 struct okiockey *kio; 361 { 362 int error = 0; 363 364 switch (cmd) { 365 366 case KIOCGETKEY: 367 if (kio->kio_station == 118) { 368 /* 369 * This is X11 asking if a type 3 keyboard is 370 * really a type 3 keyboard. Say yes, it is, 371 * by reporting key station 118 as a "hole". 372 * Note old (SunOS 3.5) definition of HOLE! 373 */ 374 kio->kio_entry = 0xA2; 375 break; 376 } 377 /* fall through */ 378 379 default: 380 error = ENOTTY; 381 break; 382 } 383 384 return (error); 385 } 386 #endif /* KIOCGETKEY */ 387 388 389 /* 390 * keyboard command ioctl 391 * ``unimplemented commands are ignored'' (blech) 392 * This is also export to the fb driver. 393 */ 394 int 395 kbd_docmd(cmd, isuser) 396 int cmd; 397 int isuser; 398 { 399 struct kbd_softc *k; 400 struct kbd_state *ks; 401 int error, s; 402 403 error = 0; 404 k = kbd_cd.cd_devs[0]; 405 ks = &k->k_state; 406 407 switch (cmd) { 408 409 case KBD_CMD_BELL: 410 case KBD_CMD_NOBELL: 411 /* Supported by type 2, 3, and 4 keyboards */ 412 break; 413 414 case KBD_CMD_CLICK: 415 case KBD_CMD_NOCLICK: 416 /* Unsupported by type 2 keyboards */ 417 if (ks->kbd_id <= KB_SUN2) 418 return (0); 419 ks->kbd_click = (cmd == KBD_CMD_CLICK); 420 break; 421 422 default: 423 return (0); 424 } 425 426 s = spltty(); 427 428 if (isuser) 429 error = kbd_drain_tx(k); 430 431 if (error == 0) { 432 kbd_output(k, cmd); 433 kbd_start_tx(k); 434 } 435 436 splx(s); 437 438 return (error); 439 } 440 441 /* 442 * Set LEDs ioctl. 443 */ 444 static int 445 kbd_iocsled(k, data) 446 struct kbd_softc *k; 447 char *data; 448 { 449 int leds, error, s; 450 451 leds = *data; 452 453 s = spltty(); 454 error = kbd_drain_tx(k); 455 if (error == 0) { 456 kbd_set_leds(k, leds); 457 } 458 splx(s); 459 460 return (error); 461 } 462 463 464 /**************************************************************** 465 * middle layers: 466 * - keysym to ASCII sequence 467 * - raw key codes to keysym 468 ****************************************************************/ 469 470 static void kbd_input_string __P((struct kbd_softc *, char *)); 471 static void kbd_input_funckey __P((struct kbd_softc *, int)); 472 static int kbd_input_keysym __P((struct kbd_softc *, int)); 473 474 /* 475 * Initialization done by either kdcninit or kbd_iopen 476 */ 477 void 478 kbd_xlate_init(ks) 479 struct kbd_state *ks; 480 { 481 struct keyboard *ktbls; 482 int id; 483 484 id = ks->kbd_id; 485 if (id < KBD_MIN_TYPE) 486 id = KBD_MIN_TYPE; 487 if (id > kbd_max_type) 488 id = kbd_max_type; 489 ktbls = keyboards[id]; 490 491 ks->kbd_k = *ktbls; /* struct assignment */ 492 ks->kbd_modbits = 0; 493 } 494 495 /* 496 * Turn keyboard up/down codes into a KEYSYM. 497 * Note that the "kd" driver uses this too! 498 */ 499 int 500 kbd_code_to_keysym(ks, c) 501 register struct kbd_state *ks; 502 register int c; 503 { 504 u_short *km; 505 int keysym; 506 507 /* 508 * Get keymap pointer. One of these: 509 * release, control, shifted, normal, ... 510 */ 511 if (KEY_UP(c)) 512 km = ks->kbd_k.k_release; 513 else if (ks->kbd_modbits & KBMOD_CTRL_MASK) 514 km = ks->kbd_k.k_control; 515 else if (ks->kbd_modbits & KBMOD_SHIFT_MASK) 516 km = ks->kbd_k.k_shifted; 517 else 518 km = ks->kbd_k.k_normal; 519 520 if (km == NULL) { 521 /* 522 * Do not know how to translate yet. 523 * We will find out when a RESET comes along. 524 */ 525 return (KEYSYM_NOP); 526 } 527 keysym = km[KEY_CODE(c)]; 528 529 /* 530 * Post-processing for Caps-lock 531 */ 532 if ((ks->kbd_modbits & (1 << KBMOD_CAPSLOCK)) && 533 (KEYSYM_CLASS(keysym) == KEYSYM_ASCII) ) 534 { 535 if (('a' <= keysym) && (keysym <= 'z')) 536 keysym -= ('a' - 'A'); 537 } 538 539 /* 540 * Post-processing for Num-lock. All "function" 541 * keysyms get indirected through another table. 542 * (XXX: Only if numlock on. Want off also!) 543 */ 544 if ((ks->kbd_modbits & (1 << KBMOD_NUMLOCK)) && 545 (KEYSYM_CLASS(keysym) == KEYSYM_FUNC) ) 546 { 547 keysym = kbd_numlock_map[keysym & 0x3F]; 548 } 549 550 return (keysym); 551 } 552 553 void 554 kbd_input_string(k, str) 555 struct kbd_softc *k; 556 char *str; 557 { 558 559 while (*str) { 560 kd_input(*str); 561 str++; 562 } 563 } 564 565 void 566 kbd_input_funckey(k, keysym) 567 struct kbd_softc *k; 568 register int keysym; 569 { 570 register int n; 571 char str[12]; 572 573 /* 574 * Format the F-key sequence and send as a string. 575 * XXX: Ugly compatibility mappings. 576 */ 577 n = 0xC0 + (keysym & 0x3F); 578 sprintf(str, "\033[%dz", n); 579 kbd_input_string(k, str); 580 } 581 582 /* 583 * This is called by kbd_input_raw() or by kb_repeat() 584 * to deliver ASCII input. Called at spltty(). 585 * 586 * Return zero on success, else the keysym that we 587 * could not handle (so the caller may complain). 588 */ 589 int 590 kbd_input_keysym(k, keysym) 591 struct kbd_softc *k; 592 register int keysym; 593 { 594 struct kbd_state *ks = &k->k_state; 595 register int data; 596 597 switch (KEYSYM_CLASS(keysym)) { 598 599 case KEYSYM_ASCII: 600 data = KEYSYM_DATA(keysym); 601 if (ks->kbd_modbits & KBMOD_META_MASK) 602 data |= 0x80; 603 kd_input(data); 604 break; 605 606 case KEYSYM_STRING: 607 data = keysym & 0xF; 608 kbd_input_string(k, kbd_stringtab[data]); 609 break; 610 611 case KEYSYM_FUNC: 612 kbd_input_funckey(k, keysym); 613 break; 614 615 case KEYSYM_CLRMOD: 616 data = 1 << (keysym & 0x1F); 617 ks->kbd_modbits &= ~data; 618 break; 619 620 case KEYSYM_SETMOD: 621 data = 1 << (keysym & 0x1F); 622 ks->kbd_modbits |= data; 623 break; 624 625 case KEYSYM_INVMOD: 626 data = 1 << (keysym & 0x1F); 627 ks->kbd_modbits ^= data; 628 kbd_update_leds(k); 629 break; 630 631 case KEYSYM_ALL_UP: 632 ks->kbd_modbits &= ~0xFFFF; 633 break; 634 635 case KEYSYM_SPECIAL: 636 if (keysym == KEYSYM_NOP) 637 break; 638 /* fall through */ 639 default: 640 /* We could not handle it. */ 641 return (keysym); 642 } 643 return (0); 644 } 645 646 /* 647 * This is the autorepeat timeout function. 648 * Called at splsoftclock(). 649 */ 650 static void 651 kbd_repeat(arg) 652 void *arg; 653 { 654 struct kbd_softc *k = (struct kbd_softc *)arg; 655 int s = spltty(); 656 657 if (k->k_repeating && k->k_repeatsym >= 0) { 658 (void)kbd_input_keysym(k, k->k_repeatsym); 659 timeout(kbd_repeat, k, k->k_repeat_step); 660 } 661 splx(s); 662 } 663 664 /* 665 * Called by our kbd_softint() routine on input, 666 * which passes the raw hardware scan codes. 667 * Called at spltty() 668 */ 669 void 670 kbd_input_raw(k, c) 671 struct kbd_softc *k; 672 register int c; 673 { 674 struct kbd_state *ks = &k->k_state; 675 struct firm_event *fe; 676 int put, keysym; 677 678 /* XXX - Input errors already handled. */ 679 680 /* Are we expecting special input? */ 681 if (ks->kbd_expect) { 682 if (ks->kbd_expect & KBD_EXPECT_IDCODE) { 683 /* We read a KBD_RESET last time. */ 684 ks->kbd_id = c; 685 kbd_was_reset(k); 686 } 687 if (ks->kbd_expect & KBD_EXPECT_LAYOUT) { 688 /* We read a KBD_LAYOUT last time. */ 689 ks->kbd_layout = c; 690 kbd_new_layout(k); 691 } 692 ks->kbd_expect = 0; 693 return; 694 } 695 696 /* Is this one of the "special" input codes? */ 697 if (KBD_SPECIAL(c)) { 698 switch (c) { 699 case KBD_RESET: 700 ks->kbd_expect |= KBD_EXPECT_IDCODE; 701 /* Fake an "all-up" to resync. translation. */ 702 c = KBD_IDLE; 703 break; 704 705 case KBD_LAYOUT: 706 ks->kbd_expect |= KBD_EXPECT_LAYOUT; 707 return; 708 709 case KBD_ERROR: 710 log(LOG_WARNING, "%s: received error indicator\n", 711 k->k_dev.dv_xname); 712 return; 713 714 case KBD_IDLE: 715 /* Let this go to the translator. */ 716 break; 717 } 718 } 719 720 /* 721 * If /dev/kbd is not connected in event mode, 722 * translate and send upstream (to console). 723 */ 724 if (!k->k_evmode) { 725 726 /* Any input stops auto-repeat (i.e. key release). */ 727 if (k->k_repeating) { 728 k->k_repeating = 0; 729 untimeout(kbd_repeat, k); 730 } 731 732 /* Translate this code to a keysym */ 733 keysym = kbd_code_to_keysym(ks, c); 734 735 /* Pass up to the next layer. */ 736 if (kbd_input_keysym(k, keysym)) { 737 log(LOG_WARNING, "%s: code=0x%x with mod=0x%x" 738 " produced unexpected keysym 0x%x\n", 739 k->k_dev.dv_xname, c, 740 ks->kbd_modbits, keysym); 741 /* No point in auto-repeat here. */ 742 return; 743 } 744 745 /* Does this symbol get auto-repeat? */ 746 if (KEYSYM_NOREPEAT(keysym)) 747 return; 748 749 /* Setup for auto-repeat after initial delay. */ 750 k->k_repeating = 1; 751 k->k_repeatsym = keysym; 752 timeout(kbd_repeat, k, k->k_repeat_start); 753 return; 754 } 755 756 /* 757 * IDLEs confuse the MIT X11R4 server badly, so we must drop them. 758 * This is bad as it means the server will not automatically resync 759 * on all-up IDLEs, but I did not drop them before, and the server 760 * goes crazy when it comes time to blank the screen.... 761 */ 762 if (c == KBD_IDLE) 763 return; 764 765 /* 766 * Keyboard is generating events. Turn this keystroke into an 767 * event and put it in the queue. If the queue is full, the 768 * keystroke is lost (sorry!). 769 */ 770 put = k->k_events.ev_put; 771 fe = &k->k_events.ev_q[put]; 772 put = (put + 1) % EV_QSIZE; 773 if (put == k->k_events.ev_get) { 774 log(LOG_WARNING, "%s: event queue overflow\n", 775 k->k_dev.dv_xname); /* ??? */ 776 return; 777 } 778 fe->id = KEY_CODE(c); 779 fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; 780 fe->time = time; 781 k->k_events.ev_put = put; 782 EV_WAKEUP(&k->k_events); 783 } 784 785 /**************************************************************** 786 * misc... 787 ****************************************************************/ 788 789 /* 790 * Initialization to be done at first open. 791 * This is called from kbdopen or kdopen (in kd.c) 792 * Called with user context. 793 */ 794 int 795 kbd_iopen(unit) 796 int unit; 797 { 798 struct kbd_softc *k; 799 struct kbd_state *ks; 800 int error, s; 801 802 if (unit >= kbd_cd.cd_ndevs) 803 return (ENXIO); 804 k = kbd_cd.cd_devs[unit]; 805 if (k == NULL) 806 return (ENXIO); 807 ks = &k->k_state; 808 error = 0; 809 810 /* Tolerate extra calls. */ 811 if (k->k_isopen) 812 return (error); 813 814 s = spltty(); 815 816 /* Reset the keyboard and find out its type. */ 817 kbd_output(k, KBD_CMD_RESET); 818 kbd_start_tx(k); 819 kbd_drain_tx(k); 820 /* The wakeup for this is in kbd_was_reset(). */ 821 error = tsleep((caddr_t)&ks->kbd_id, 822 PZERO | PCATCH, devopn, hz); 823 if (error == EWOULDBLOCK) { /* no response */ 824 error = 0; 825 log(LOG_ERR, "%s: reset failed\n", 826 k->k_dev.dv_xname); 827 /* 828 * Allow the open anyway (to keep getty happy) 829 * but assume the "least common denominator". 830 */ 831 ks->kbd_id = KB_SUN2; 832 } 833 834 /* Initialize the table pointers for this type. */ 835 kbd_xlate_init(ks); 836 837 /* Earlier than type 4 does not know "layout". */ 838 if (ks->kbd_id < KB_SUN4) 839 goto out; 840 841 /* Ask for the layout. */ 842 kbd_output(k, KBD_CMD_GETLAYOUT); 843 kbd_start_tx(k); 844 kbd_drain_tx(k); 845 /* The wakeup for this is in kbd_new_layout(). */ 846 error = tsleep((caddr_t)&ks->kbd_layout, 847 PZERO | PCATCH, devopn, hz); 848 if (error == EWOULDBLOCK) { /* no response */ 849 error = 0; 850 log(LOG_ERR, "%s: no response to get_layout\n", 851 k->k_dev.dv_xname); 852 ks->kbd_layout = 0; 853 } 854 855 out: 856 splx(s); 857 858 if (error == 0) 859 k->k_isopen = 1; 860 861 return error; 862 } 863 864 /* 865 * Called by kbd_input_raw, at spltty() 866 */ 867 static void 868 kbd_was_reset(k) 869 struct kbd_softc *k; 870 { 871 struct kbd_state *ks = &k->k_state; 872 873 /* 874 * On first identification, wake up anyone waiting for type 875 * and set up the table pointers. 876 */ 877 wakeup((caddr_t)&ks->kbd_id); 878 879 /* Restore keyclick, if necessary */ 880 switch (ks->kbd_id) { 881 882 case KB_SUN2: 883 /* Type 2 keyboards don't support keyclick */ 884 break; 885 886 case KB_SUN3: 887 /* Type 3 keyboards come up with keyclick on */ 888 if (!ks->kbd_click) { 889 /* turn off the click */ 890 kbd_output(k, KBD_CMD_NOCLICK); 891 kbd_start_tx(k); 892 } 893 break; 894 895 case KB_SUN4: 896 /* Type 4 keyboards come up with keyclick off */ 897 if (ks->kbd_click) { 898 /* turn on the click */ 899 kbd_output(k, KBD_CMD_CLICK); 900 kbd_start_tx(k); 901 } 902 break; 903 } 904 905 /* LEDs are off after reset. */ 906 ks->kbd_leds = 0; 907 } 908 909 /* 910 * Called by kbd_input_raw, at spltty() 911 */ 912 static void 913 kbd_new_layout(k) 914 struct kbd_softc *k; 915 { 916 struct kbd_state *ks = &k->k_state; 917 918 /* 919 * On first identification, wake up anyone waiting for type 920 * and set up the table pointers. 921 */ 922 wakeup((caddr_t)&ks->kbd_layout); 923 924 /* XXX: switch decoding tables? */ 925 } 926 927 928 /* 929 * Wait for output to finish. 930 * Called at spltty(). Has user context. 931 */ 932 static int 933 kbd_drain_tx(k) 934 struct kbd_softc *k; 935 { 936 int error; 937 938 error = 0; 939 940 while (k->k_txflags & K_TXBUSY) { 941 k->k_txflags |= K_TXWANT; 942 error = tsleep((caddr_t)&k->k_txflags, 943 PZERO | PCATCH, "kbdout", 0); 944 } 945 946 return (error); 947 } 948 949 /* 950 * Enqueue some output for the keyboard 951 * Called at spltty(). 952 */ 953 void 954 kbd_output(k, c) 955 struct kbd_softc *k; 956 int c; /* the data */ 957 { 958 int put; 959 960 put = k->k_tbput; 961 k->k_tbuf[put] = (u_char)c; 962 put = (put + 1) & KBD_TX_RING_MASK; 963 964 /* Would overrun if increment makes (put==get). */ 965 if (put == k->k_tbget) { 966 log(LOG_WARNING, "%s: output overrun\n", 967 k->k_dev.dv_xname); 968 } else { 969 /* OK, really increment. */ 970 k->k_tbput = put; 971 } 972 } 973 974 /* 975 * Start the sending data from the output queue 976 * Called at spltty(). 977 */ 978 void 979 kbd_start_tx(k) 980 struct kbd_softc *k; 981 { 982 int get; 983 u_char c; 984 985 if (k->k_txflags & K_TXBUSY) 986 return; 987 988 /* Is there anything to send? */ 989 get = k->k_tbget; 990 if (get == k->k_tbput) { 991 /* Nothing to send. Wake drain waiters. */ 992 if (k->k_txflags & K_TXWANT) { 993 k->k_txflags &= ~K_TXWANT; 994 wakeup((caddr_t)&k->k_txflags); 995 } 996 return; 997 } 998 999 /* Have something to send. */ 1000 c = k->k_tbuf[get]; 1001 get = (get + 1) & KBD_TX_RING_MASK; 1002 k->k_tbget = get; 1003 k->k_txflags |= K_TXBUSY; 1004 1005 k->k_write_data(k, c); 1006 } 1007 1008 /* 1009 * Called at spltty by: 1010 * kbd_update_leds, kbd_iocsled 1011 */ 1012 static void 1013 kbd_set_leds(k, new_leds) 1014 struct kbd_softc *k; 1015 int new_leds; 1016 { 1017 struct kbd_state *ks = &k->k_state; 1018 1019 /* Don't send unless state changes. */ 1020 if (ks->kbd_leds == new_leds) 1021 return; 1022 1023 ks->kbd_leds = new_leds; 1024 1025 /* Only type 4 and later has LEDs anyway. */ 1026 if (ks->kbd_id < KB_SUN4) 1027 return; 1028 1029 kbd_output(k, KBD_CMD_SETLED); 1030 kbd_output(k, new_leds); 1031 kbd_start_tx(k); 1032 } 1033 1034 /* 1035 * Called at spltty by: 1036 * kbd_input_keysym 1037 */ 1038 static void 1039 kbd_update_leds(k) 1040 struct kbd_softc *k; 1041 { 1042 struct kbd_state *ks = &k->k_state; 1043 register char leds; 1044 1045 leds = ks->kbd_leds; 1046 leds &= ~(LED_CAPS_LOCK|LED_NUM_LOCK); 1047 1048 if (ks->kbd_modbits & (1 << KBMOD_CAPSLOCK)) 1049 leds |= LED_CAPS_LOCK; 1050 if (ks->kbd_modbits & (1 << KBMOD_NUMLOCK)) 1051 leds |= LED_NUM_LOCK; 1052 1053 kbd_set_leds(k, leds); 1054 } 1055 1056