1 /* $NetBSD: kbd.c,v 1.30 2002/05/13 09:42:12 pk 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.30 2002/05/13 09:42:12 pk 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 /* Check if a recipient has been configured */ 606 if (k->k_cc == NULL) 607 return (0); 608 609 switch (KEYSYM_CLASS(keysym)) { 610 611 case KEYSYM_ASCII: 612 data = KEYSYM_DATA(keysym); 613 if (ks->kbd_modbits & KBMOD_META_MASK) 614 data |= 0x80; 615 (*k->k_cc->cc_upstream)(data); 616 break; 617 618 case KEYSYM_STRING: 619 data = keysym & 0xF; 620 kbd_input_string(k, kbd_stringtab[data]); 621 break; 622 623 case KEYSYM_FUNC: 624 kbd_input_funckey(k, keysym); 625 break; 626 627 case KEYSYM_CLRMOD: 628 data = 1 << (keysym & 0x1F); 629 ks->kbd_modbits &= ~data; 630 break; 631 632 case KEYSYM_SETMOD: 633 data = 1 << (keysym & 0x1F); 634 ks->kbd_modbits |= data; 635 break; 636 637 case KEYSYM_INVMOD: 638 data = 1 << (keysym & 0x1F); 639 ks->kbd_modbits ^= data; 640 kbd_update_leds(k); 641 break; 642 643 case KEYSYM_ALL_UP: 644 ks->kbd_modbits &= ~0xFFFF; 645 break; 646 647 case KEYSYM_SPECIAL: 648 if (keysym == KEYSYM_NOP) 649 break; 650 /* fall through */ 651 default: 652 /* We could not handle it. */ 653 return (keysym); 654 } 655 return (0); 656 } 657 658 /* 659 * This is the autorepeat timeout function. 660 * Called at splsoftclock(). 661 */ 662 static void 663 kbd_repeat(arg) 664 void *arg; 665 { 666 struct kbd_softc *k = (struct kbd_softc *)arg; 667 int s = spltty(); 668 669 if (k->k_repeating && k->k_repeatsym >= 0) { 670 (void)kbd_input_keysym(k, k->k_repeatsym); 671 callout_reset(&k->k_repeat_ch, k->k_repeat_step, 672 kbd_repeat, k); 673 } 674 splx(s); 675 } 676 677 /* 678 * Called by our kbd_softint() routine on input, 679 * which passes the raw hardware scan codes. 680 * Called at spltty() 681 */ 682 void 683 kbd_input_raw(k, c) 684 struct kbd_softc *k; 685 int c; 686 { 687 struct kbd_state *ks = &k->k_state; 688 struct firm_event *fe; 689 int put, keysym; 690 691 /* XXX - Input errors already handled. */ 692 693 /* Are we expecting special input? */ 694 if (ks->kbd_expect) { 695 if (ks->kbd_expect & KBD_EXPECT_IDCODE) { 696 /* We read a KBD_RESET last time. */ 697 ks->kbd_id = c; 698 kbd_was_reset(k); 699 } 700 if (ks->kbd_expect & KBD_EXPECT_LAYOUT) { 701 /* We read a KBD_LAYOUT last time. */ 702 ks->kbd_layout = c; 703 kbd_new_layout(k); 704 } 705 ks->kbd_expect = 0; 706 return; 707 } 708 709 /* Is this one of the "special" input codes? */ 710 if (KBD_SPECIAL(c)) { 711 switch (c) { 712 case KBD_RESET: 713 ks->kbd_expect |= KBD_EXPECT_IDCODE; 714 /* Fake an "all-up" to resync. translation. */ 715 c = KBD_IDLE; 716 break; 717 718 case KBD_LAYOUT: 719 ks->kbd_expect |= KBD_EXPECT_LAYOUT; 720 return; 721 722 case KBD_ERROR: 723 log(LOG_WARNING, "%s: received error indicator\n", 724 k->k_dev.dv_xname); 725 return; 726 727 case KBD_IDLE: 728 /* Let this go to the translator. */ 729 break; 730 } 731 } 732 733 /* 734 * If /dev/kbd is not connected in event mode, 735 * translate and send upstream (to console). 736 */ 737 if (!k->k_evmode) { 738 739 /* Any input stops auto-repeat (i.e. key release). */ 740 if (k->k_repeating) { 741 k->k_repeating = 0; 742 callout_stop(&k->k_repeat_ch); 743 } 744 745 /* Translate this code to a keysym */ 746 keysym = kbd_code_to_keysym(ks, c); 747 748 /* Pass up to the next layer. */ 749 if (kbd_input_keysym(k, keysym)) { 750 log(LOG_WARNING, "%s: code=0x%x with mod=0x%x" 751 " produced unexpected keysym 0x%x\n", 752 k->k_dev.dv_xname, c, 753 ks->kbd_modbits, keysym); 754 /* No point in auto-repeat here. */ 755 return; 756 } 757 758 /* Does this symbol get auto-repeat? */ 759 if (KEYSYM_NOREPEAT(keysym)) 760 return; 761 762 /* Setup for auto-repeat after initial delay. */ 763 k->k_repeating = 1; 764 k->k_repeatsym = keysym; 765 callout_reset(&k->k_repeat_ch, k->k_repeat_start, 766 kbd_repeat, k); 767 return; 768 } 769 770 /* 771 * IDLEs confuse the MIT X11R4 server badly, so we must drop them. 772 * This is bad as it means the server will not automatically resync 773 * on all-up IDLEs, but I did not drop them before, and the server 774 * goes crazy when it comes time to blank the screen.... 775 */ 776 if (c == KBD_IDLE) 777 return; 778 779 /* 780 * Keyboard is generating events. Turn this keystroke into an 781 * event and put it in the queue. If the queue is full, the 782 * keystroke is lost (sorry!). 783 */ 784 put = k->k_events.ev_put; 785 fe = &k->k_events.ev_q[put]; 786 put = (put + 1) % EV_QSIZE; 787 if (put == k->k_events.ev_get) { 788 log(LOG_WARNING, "%s: event queue overflow\n", 789 k->k_dev.dv_xname); /* ??? */ 790 return; 791 } 792 fe->id = KEY_CODE(c); 793 fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN; 794 fe->time = time; 795 k->k_events.ev_put = put; 796 EV_WAKEUP(&k->k_events); 797 } 798 799 /****************************************************************/ 800 801 /* 802 * Open/close routines called upon opening /dev/console 803 * if we serve console input. 804 */ 805 int 806 kbd_cc_open(cc) 807 struct cons_channel *cc; 808 { 809 struct kbd_softc *k = (struct kbd_softc *)cc->cc_dev; 810 return (kbd_iopen(k)); 811 } 812 813 int 814 kbd_cc_close(cc) 815 struct cons_channel *cc; 816 { 817 struct kbd_softc *k = (struct kbd_softc *)cc->cc_dev; 818 return (kbd_iclose(k)); 819 } 820 821 /* 822 * Initialization to be done at first open. 823 * This is called from kbdopen() or kd_cc_open() 824 * Called with user context. 825 */ 826 int 827 kbd_iopen(k) 828 struct kbd_softc *k; 829 { 830 struct kbd_state *ks; 831 int error, s; 832 833 if (k == NULL) 834 return (ENXIO); 835 836 ks = &k->k_state; 837 838 /* Tolerate extra calls. */ 839 if (k->k_isopen) 840 return (0); 841 842 /* Open internal device */ 843 if (k->k_deviopen) 844 (*k->k_deviopen)((struct device *)k, FREAD|FWRITE); 845 846 s = spltty(); 847 848 /* Reset the keyboard and find out its type. */ 849 kbd_output(k, KBD_CMD_RESET); 850 kbd_start_tx(k); 851 kbd_drain_tx(k); 852 /* The wakeup for this is in kbd_was_reset(). */ 853 error = tsleep((caddr_t)&ks->kbd_id, 854 PZERO | PCATCH, devopn, hz); 855 if (error == EWOULDBLOCK) { /* no response */ 856 error = 0; 857 log(LOG_ERR, "%s: reset failed\n", 858 k->k_dev.dv_xname); 859 /* 860 * Allow the open anyway (to keep getty happy) 861 * but assume the "least common denominator". 862 */ 863 ks->kbd_id = KB_SUN2; 864 } 865 866 /* Initialize the table pointers for this type. */ 867 kbd_xlate_init(ks); 868 869 /* Earlier than type 4 does not know "layout". */ 870 if (ks->kbd_id < KB_SUN4) 871 goto out; 872 873 /* Ask for the layout. */ 874 kbd_output(k, KBD_CMD_GETLAYOUT); 875 kbd_start_tx(k); 876 kbd_drain_tx(k); 877 /* The wakeup for this is in kbd_new_layout(). */ 878 error = tsleep((caddr_t)&ks->kbd_layout, 879 PZERO | PCATCH, devopn, hz); 880 if (error == EWOULDBLOCK) { /* no response */ 881 error = 0; 882 log(LOG_ERR, "%s: no response to get_layout\n", 883 k->k_dev.dv_xname); 884 ks->kbd_layout = 0; 885 } 886 887 out: 888 splx(s); 889 890 if (error == 0) 891 k->k_isopen = 1; 892 893 return (error); 894 } 895 896 int 897 kbd_iclose(k) 898 struct kbd_softc *k; 899 { 900 /* For now: */ return (0); 901 } 902 903 /* 904 * Called by kbd_input_raw, at spltty() 905 */ 906 static void 907 kbd_was_reset(k) 908 struct kbd_softc *k; 909 { 910 struct kbd_state *ks = &k->k_state; 911 912 /* 913 * On first identification, wake up anyone waiting for type 914 * and set up the table pointers. 915 */ 916 wakeup((caddr_t)&ks->kbd_id); 917 918 /* Restore keyclick, if necessary */ 919 switch (ks->kbd_id) { 920 921 case KB_SUN2: 922 /* Type 2 keyboards don't support keyclick */ 923 break; 924 925 case KB_SUN3: 926 /* Type 3 keyboards come up with keyclick on */ 927 if (!ks->kbd_click) { 928 /* turn off the click */ 929 kbd_output(k, KBD_CMD_NOCLICK); 930 kbd_start_tx(k); 931 } 932 break; 933 934 case KB_SUN4: 935 /* Type 4 keyboards come up with keyclick off */ 936 if (ks->kbd_click) { 937 /* turn on the click */ 938 kbd_output(k, KBD_CMD_CLICK); 939 kbd_start_tx(k); 940 } 941 break; 942 } 943 944 /* LEDs are off after reset. */ 945 ks->kbd_leds = 0; 946 } 947 948 /* 949 * Called by kbd_input_raw, at spltty() 950 */ 951 static void 952 kbd_new_layout(k) 953 struct kbd_softc *k; 954 { 955 struct kbd_state *ks = &k->k_state; 956 957 /* 958 * On first identification, wake up anyone waiting for type 959 * and set up the table pointers. 960 */ 961 wakeup((caddr_t)&ks->kbd_layout); 962 963 /* XXX: switch decoding tables? */ 964 } 965 966 967 /* 968 * Wait for output to finish. 969 * Called at spltty(). Has user context. 970 */ 971 static int 972 kbd_drain_tx(k) 973 struct kbd_softc *k; 974 { 975 int error; 976 977 error = 0; 978 979 while (k->k_txflags & K_TXBUSY && !error) { 980 k->k_txflags |= K_TXWANT; 981 error = tsleep((caddr_t)&k->k_txflags, 982 PZERO | PCATCH, "kbdout", 0); 983 } 984 985 return (error); 986 } 987 988 /* 989 * Enqueue some output for the keyboard 990 * Called at spltty(). 991 */ 992 void 993 kbd_output(k, c) 994 struct kbd_softc *k; 995 int c; /* the data */ 996 { 997 int put; 998 999 put = k->k_tbput; 1000 k->k_tbuf[put] = (u_char)c; 1001 put = (put + 1) & KBD_TX_RING_MASK; 1002 1003 /* Would overrun if increment makes (put==get). */ 1004 if (put == k->k_tbget) { 1005 log(LOG_WARNING, "%s: output overrun\n", 1006 k->k_dev.dv_xname); 1007 } else { 1008 /* OK, really increment. */ 1009 k->k_tbput = put; 1010 } 1011 } 1012 1013 /* 1014 * Start the sending data from the output queue 1015 * Called at spltty(). 1016 */ 1017 void 1018 kbd_start_tx(k) 1019 struct kbd_softc *k; 1020 { 1021 int get; 1022 u_char c; 1023 1024 if (k->k_txflags & K_TXBUSY) 1025 return; 1026 1027 /* Is there anything to send? */ 1028 get = k->k_tbget; 1029 if (get == k->k_tbput) { 1030 /* Nothing to send. Wake drain waiters. */ 1031 if (k->k_txflags & K_TXWANT) { 1032 k->k_txflags &= ~K_TXWANT; 1033 wakeup((caddr_t)&k->k_txflags); 1034 } 1035 return; 1036 } 1037 1038 /* Have something to send. */ 1039 c = k->k_tbuf[get]; 1040 get = (get + 1) & KBD_TX_RING_MASK; 1041 k->k_tbget = get; 1042 k->k_txflags |= K_TXBUSY; 1043 1044 k->k_write_data(k, c); 1045 } 1046 1047 /* 1048 * Called at spltty by: 1049 * kbd_update_leds, kbd_iocsled 1050 */ 1051 static void 1052 kbd_set_leds(k, new_leds) 1053 struct kbd_softc *k; 1054 int new_leds; 1055 { 1056 struct kbd_state *ks = &k->k_state; 1057 1058 /* Don't send unless state changes. */ 1059 if (ks->kbd_leds == new_leds) 1060 return; 1061 1062 ks->kbd_leds = new_leds; 1063 1064 /* Only type 4 and later has LEDs anyway. */ 1065 if (ks->kbd_id < KB_SUN4) 1066 return; 1067 1068 kbd_output(k, KBD_CMD_SETLED); 1069 kbd_output(k, new_leds); 1070 kbd_start_tx(k); 1071 } 1072 1073 /* 1074 * Called at spltty by: 1075 * kbd_input_keysym 1076 */ 1077 static void 1078 kbd_update_leds(k) 1079 struct kbd_softc *k; 1080 { 1081 struct kbd_state *ks = &k->k_state; 1082 char leds; 1083 1084 leds = ks->kbd_leds; 1085 leds &= ~(LED_CAPS_LOCK|LED_NUM_LOCK); 1086 1087 if (ks->kbd_modbits & (1 << KBMOD_CAPSLOCK)) 1088 leds |= LED_CAPS_LOCK; 1089 if (ks->kbd_modbits & (1 << KBMOD_NUMLOCK)) 1090 leds |= LED_NUM_LOCK; 1091 1092 kbd_set_leds(k, leds); 1093 } 1094