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