Home | History | Annotate | Line # | Download | only in sun
kbd.c revision 1.26
      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