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