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