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