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