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