xref: /csrg-svn/sys/sparc/dev/kbd.c (revision 55105)
1 /*
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)kbd.c	7.1 (Berkeley) 07/13/92
12  *
13  * from: $Header: kbd.c,v 1.15 92/07/09 07:59:27 torek Exp $ (LBL)
14  */
15 
16 /*
17  * Keyboard driver (/dev/kbd -- note that we do not have minor numbers
18  * [yet?]).  Translates incoming bytes to ASCII or to `firm_events' and
19  * passes them up to the appropriate reader.
20  */
21 
22 #include "sys/param.h"
23 #include "sys/conf.h"
24 #include "sys/device.h"
25 #include "sys/ioctl.h"
26 #include "sys/kernel.h"
27 #include "sys/proc.h"
28 #include "sys/syslog.h"
29 #include "sys/systm.h"
30 #include "sys/tty.h"
31 
32 #include "machine/autoconf.h"
33 
34 #include "vuid_event.h"
35 #include "event_var.h"
36 #include "kbd.h"
37 #include "kbio.h"
38 
39 /*
40  * Sun keyboard definitions (from Sprite).
41  * These apply to type 2, 3 and 4 keyboards.
42  */
43 #define	KEY_CODE(c)	((c) & KBD_KEYMASK)	/* keyboard code index */
44 #define	KEY_UP(c)	((c) & KBD_UP)		/* true => key went up */
45 
46 /*
47  * Each KEY_CODE(x) can be translated via the tables below.
48  * The result is either a valid ASCII value in [0..0x7f] or is one
49  * of the following `magic' values saying something interesting
50  * happened.  If LSHIFT or RSHIFT has changed state the next
51  * lookup should come from the appropriate table; if ALLUP is
52  * sent all keys (including both shifts and the control key) are
53  * now up, and the next byte is the keyboard ID code.
54  *
55  * These tables ignore all function keys (on the theory that if you
56  * want these keys, you should use a window system).  Note that
57  * `caps lock' is just mapped as `ignore' (so there!). (Only the
58  * type 3 and 4 keyboards have a caps lock key anyway.)
59  */
60 #define	KEY_MAGIC	0x80		/* flag => magic value */
61 #define	KEY_IGNORE	0x80
62 #define	KEY_L1		KEY_IGNORE
63 #define	KEY_CAPSLOCK	KEY_IGNORE
64 #define	KEY_LSHIFT	0x81
65 #define	KEY_RSHIFT	0x82
66 #define	KEY_CONTROL	0x83
67 #define	KEY_ALLUP	0x84		/* all keys are now up; also reset */
68 
69 /*
70  * Decode tables for type 2, 3, and 4 keyboards
71  * (stolen from Sprite; see also kbd.h).
72  */
73 static const u_char kbd_unshifted[] = {
74 /*   0 */	KEY_IGNORE,	KEY_L1,		KEY_IGNORE,	KEY_IGNORE,
75 /*   4 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
76 /*   8 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
77 /*  12 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
78 /*  16 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
79 /*  20 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
80 /*  24 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
81 /*  28 */	KEY_IGNORE,	'\033',		'1',		'2',
82 /*  32 */	'3',		'4',		'5',		'6',
83 /*  36 */	'7',		'8',		'9',		'0',
84 /*  40 */	'-',		'=',		'`',		'\b',
85 /*  44 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
86 /*  48 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
87 /*  52 */	KEY_IGNORE,	'\t',		'q',		'w',
88 /*  56 */	'e',		'r',		't',		'y',
89 /*  60 */	'u',		'i',		'o',		'p',
90 /*  64 */	'[',		']',		'\177',		KEY_IGNORE,
91 /*  68 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
92 /*  72 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
93 /*  76 */	KEY_CONTROL,	'a',		's',		'd',
94 /*  80 */	'f',		'g',		'h',		'j',
95 /*  84 */	'k',		'l',		';',		'\'',
96 /*  88 */	'\\',		'\r',		KEY_IGNORE,	KEY_IGNORE,
97 /*  92 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
98 /*  96 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_LSHIFT,
99 /* 100 */	'z',		'x',		'c',		'v',
100 /* 104 */	'b',		'n',		'm',		',',
101 /* 108 */	'.',		'/',		KEY_RSHIFT,	'\n',
102 /* 112 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
103 /* 116 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_CAPSLOCK,
104 /* 120 */	KEY_IGNORE,	' ',		KEY_IGNORE,	KEY_IGNORE,
105 /* 124 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_ALLUP,
106 };
107 
108 static const u_char kbd_shifted[] = {
109 /*   0 */	KEY_IGNORE,	KEY_L1,		KEY_IGNORE,	KEY_IGNORE,
110 /*   4 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
111 /*   8 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
112 /*  12 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
113 /*  16 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
114 /*  20 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
115 /*  24 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
116 /*  28 */	KEY_IGNORE,	'\033',		'!',		'@',
117 /*  32 */	'#',		'$',		'%',		'^',
118 /*  36 */	'&',		'*',		'(',		')',
119 /*  40 */	'_',		'+',		'~',		'\b',
120 /*  44 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
121 /*  48 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
122 /*  52 */	KEY_IGNORE,	'\t',		'Q',		'W',
123 /*  56 */	'E',		'R',		'T',		'Y',
124 /*  60 */	'U',		'I',		'O',		'P',
125 /*  64 */	'{',		'}',		'\177',		KEY_IGNORE,
126 /*  68 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
127 /*  72 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
128 /*  76 */	KEY_CONTROL,	'A',		'S',		'D',
129 /*  80 */	'F',		'G',		'H',		'J',
130 /*  84 */	'K',		'L',		':',		'"',
131 /*  88 */	'|',		'\r',		KEY_IGNORE,	KEY_IGNORE,
132 /*  92 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
133 /*  96 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_LSHIFT,
134 /* 100 */	'Z',		'X',		'C',		'V',
135 /* 104 */	'B',		'N',		'M',		'<',
136 /* 108 */	'>',		'?',		KEY_RSHIFT,	'\n',
137 /* 112 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,
138 /* 116 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_CAPSLOCK,
139 /* 120 */	KEY_IGNORE,	' ',		KEY_IGNORE,	KEY_IGNORE,
140 /* 124 */	KEY_IGNORE,	KEY_IGNORE,	KEY_IGNORE,	KEY_ALLUP,
141 };
142 
143 /*
144  * We need to remember the state of the keyboard's shift and control
145  * keys, and we need a per-type translation table.
146  */
147 struct kbd_state {
148 	const u_char *kbd_unshifted;	/* unshifted keys */
149 	const u_char *kbd_shifted;	/* shifted keys */
150 	const u_char *kbd_cur;	/* current keys (either of the preceding) */
151 	union {
152 		char	c[2];	/* left and right shift keys */
153 		short	s;	/* true => either shift key */
154 	} kbd_shift;
155 #define	kbd_lshift	kbd_shift.c[0]
156 #define	kbd_rshift	kbd_shift.c[1]
157 #define	kbd_anyshift	kbd_shift.s
158 	char	kbd_control;	/* true => ctrl down */
159 	char	kbd_click;	/* true => keyclick enabled */
160 	char	kbd_takeid;	/* take next byte as ID */
161 	u_char	kbd_id;		/* a place to store the ID */
162 };
163 
164 /*
165  * Keyboard driver state.  The ascii and kbd links go up and down and
166  * we just sit in the middle doing translation.  Note that it is possible
167  * to get just one of the two links, in which case /dev/kbd is unavailable.
168  * The downlink supplies us with `internal' open and close routines which
169  * will enable dataflow across the downlink.  We promise to call open when
170  * we are willing to take keystrokes, and to call close when we are not.
171  * If /dev/kbd is not the console tty input source, we do this whenever
172  * /dev/kbd is in use; otherwise we just leave it open forever.
173  */
174 struct kbd_softc {
175 	struct	tty *k_cons;		/* uplink for ASCII data to console */
176 	struct	tty *k_kbd;		/* downlink for output to keyboard */
177 	void	(*k_open) __P((struct tty *));	/* enable dataflow */
178 	void	(*k_close) __P((struct tty *));	/* disable dataflow */
179 	int	k_evmode;		/* set if we should produce events */
180 	struct	kbd_state k_state;	/* ASCII decode state */
181 	struct	evvar k_events;		/* event queue state */
182 } kbd_softc;
183 
184 /* Prototypes */
185 void	kbd_ascii(struct tty *);
186 void	kbd_serial(struct tty *, void (*)(), void (*)());
187 static	void kbd_getid(void *);
188 void	kbd_reset(struct kbd_state *);
189 static	int kbd_translate(int, struct kbd_state *);
190 void	kbd_rint(int);
191 int	kbdopen(dev_t, int, int, struct proc *);
192 int	kbdclose(dev_t, int, int, struct proc *);
193 int	kbdread(dev_t, struct uio *, int);
194 int	kbdwrite(dev_t, struct uio *, int);
195 int	kbdioctl(dev_t, int, caddr_t, int, struct proc *);
196 int	kbdselect(dev_t, int, struct proc *);
197 int	kbd_docmd(int, int);
198 
199 /*
200  * Attach the console keyboard ASCII (up-link) interface.
201  * This happens before kbd_serial.
202  */
203 void
204 kbd_ascii(struct tty *tp)
205 {
206 
207 	kbd_softc.k_cons = tp;
208 }
209 
210 /*
211  * Attach the console keyboard serial (down-link) interface.
212  * We pick up the initial keyboard clock state here as well.
213  */
214 void
215 kbd_serial(struct tty *tp, void (*iopen)(), void (*iclose)())
216 {
217 	register struct kbd_softc *k;
218 	register char *cp;
219 
220 	k = &kbd_softc;
221 	k->k_kbd = tp;
222 	k->k_open = iopen;
223 	k->k_close = iclose;
224 
225 	cp = getpropstring(optionsnode, "keyboard-click?");
226 	if (cp && strcmp(cp, "true") == 0)
227 		k->k_state.kbd_click = 1;
228 
229 	if (k->k_cons) {
230 		/*
231 		 * We supply keys for /dev/console.  Before we can
232 		 * do so, we have to ``open'' the line.  We also need
233 		 * the type, got by sending a RESET down the line ...
234 		 * but clists are not yet set up, so we use a timeout
235 		 * to try constantly until we can get the ID.  (gag)
236 		 */
237 		(*iopen)(tp);		/* never to be closed */
238 		kbd_getid(NULL);
239 	}
240 }
241 
242 /*
243  * Initial keyboard reset, to obtain ID and thus a translation table.
244  * We have to try again and again until the tty subsystem works.
245  */
246 static void
247 kbd_getid(void *arg)
248 {
249 	register struct kbd_softc *k;
250 	register struct tty *tp;
251 	register int retry;
252 	extern int cold;		/* XXX */
253 
254 	k = &kbd_softc;
255 	if (k->k_state.kbd_cur != NULL)
256 		return;
257 	tp = k->k_kbd;
258 	if (cold || ttyoutput(KBD_CMD_RESET, tp) >= 0)
259 		retry = 1;
260 	else {
261 		(*tp->t_oproc)(tp);
262 		retry = 2 * hz;
263 	}
264 	timeout(kbd_getid, NULL, retry);
265 }
266 
267 void
268 kbd_reset(register struct kbd_state *ks)
269 {
270 	/*
271 	 * On first identification, wake up anyone waiting for type
272 	 * and set up the table pointers.
273 	 */
274 	if (ks->kbd_unshifted == NULL) {
275 		wakeup((caddr_t)ks);
276 		ks->kbd_unshifted = kbd_unshifted;
277 		ks->kbd_shifted = kbd_shifted;
278 		ks->kbd_cur = ks->kbd_unshifted;
279 	}
280 
281 	/* Restore keyclick, if necessary */
282 	switch (ks->kbd_id) {
283 
284 	case KB_SUN2:
285 		/* Type 2 keyboards don't support keyclick */
286 		break;
287 
288 	case KB_SUN3:
289 		/* Type 3 keyboards come up with keyclick on */
290 		if (!ks->kbd_click)
291 			(void) kbd_docmd(KBD_CMD_NOCLICK, 0);
292 		break;
293 
294 	case KB_SUN4:
295 		/* Type 4 keyboards come up with keyclick off */
296 		if (ks->kbd_click)
297 			(void) kbd_docmd(KBD_CMD_CLICK, 0);
298 		break;
299 	}
300 }
301 
302 /*
303  * Turn keyboard up/down codes into ASCII.
304  */
305 static int
306 kbd_translate(register int c, register struct kbd_state *ks)
307 {
308 	register int down;
309 
310 	if (ks->kbd_cur == NULL) {
311 		/*
312 		 * Do not know how to translate yet.
313 		 * We will find out when a RESET comes along.
314 		 */
315 		return (-1);
316 	}
317 	down = !KEY_UP(c);
318 	c = ks->kbd_cur[KEY_CODE(c)];
319 	if (c & KEY_MAGIC) {
320 		switch (c) {
321 
322 		case KEY_LSHIFT:
323 			ks->kbd_lshift = down;
324 			break;
325 
326 		case KEY_RSHIFT:
327 			ks->kbd_rshift = down;
328 			break;
329 
330 		case KEY_ALLUP:
331 			ks->kbd_anyshift = 0;
332 			ks->kbd_control = 0;
333 			break;
334 
335 		case KEY_CONTROL:
336 			ks->kbd_control = down;
337 			/* FALLTHROUGH */
338 
339 		case KEY_IGNORE:
340 			return (-1);
341 
342 		default:
343 			panic("kbd_translate");
344 		}
345 		if (ks->kbd_anyshift)
346 			ks->kbd_cur = ks->kbd_shifted;
347 		else
348 			ks->kbd_cur = ks->kbd_unshifted;
349 		return (-1);
350 	}
351 	if (!down)
352 		return (-1);
353 	if (ks->kbd_control) {
354 		/* control space and unshifted control atsign return null */
355 		if (c == ' ' || c == '2')
356 			return (0);
357 		/* unshifted control hat */
358 		if (c == '6')
359 			return ('^' & 0x1f);
360 		/* standard controls */
361 		if (c >= '@' && c < 0x7f)
362 			return (c & 0x1f);
363 	}
364 	return (c);
365 }
366 
367 void
368 kbd_rint(register int c)
369 {
370 	register struct kbd_softc *k = &kbd_softc;
371 	register struct firm_event *fe;
372 	register int put;
373 
374 	/*
375 	 * Reset keyboard after serial port overrun, so we can resynch.
376 	 * The printf below should be shortened and/or replaced with a
377 	 * call to log() after this is tested (and how will we test it?!).
378 	 */
379 	if (c & (TTY_FE|TTY_PE)) {
380 		printf("keyboard input parity or framing error (0x%x)\n", c);
381 		(void) ttyoutput(KBD_CMD_RESET, k->k_kbd);
382 		(*k->k_kbd->t_oproc)(k->k_kbd);
383 		return;
384 	}
385 
386 	/* Read the keyboard id if we read a KBD_RESET last time */
387 	if (k->k_state.kbd_takeid) {
388 		k->k_state.kbd_takeid = 0;
389 		k->k_state.kbd_id = c;
390 		kbd_reset(&k->k_state);
391 		return;
392 	}
393 
394 	/* If we have been reset, setup to grab the keyboard id next time */
395 	if (c == KBD_RESET) {
396 		k->k_state.kbd_takeid = 1;
397 		return;
398 	}
399 
400 	/*
401 	 * If /dev/kbd is not connected in event mode, but we are sending
402 	 * data to /dev/console, translate and send upstream.  Note that
403 	 * we will get this while opening /dev/kbd if it is not already
404 	 * open and we do not know its type.
405 	 */
406 	if (!k->k_evmode) {
407 		c = kbd_translate(c, &k->k_state);
408 		if (c >= 0 && k->k_cons != NULL)
409 			ttyinput(c, k->k_cons);
410 		return;
411 	}
412 
413 	/*
414 	 * IDLEs confuse the MIT X11R4 server badly, so we must drop them.
415 	 * This is bad as it means the server will not automatically resync
416 	 * on all-up IDLEs, but I did not drop them before, and the server
417 	 * goes crazy when it comes time to blank the screen....
418 	 */
419 	if (c == KBD_IDLE)
420 		return;
421 
422 	/*
423 	 * Keyboard is generating events.  Turn this keystroke into an
424 	 * event and put it in the queue.  If the queue is full, the
425 	 * keystroke is lost (sorry!).
426 	 */
427 	put = k->k_events.ev_put;
428 	fe = &k->k_events.ev_q[put];
429 	put = (put + 1) % EV_QSIZE;
430 	if (put == k->k_events.ev_get) {
431 		log(LOG_WARNING, "keyboard event queue overflow\n"); /* ??? */
432 		return;
433 	}
434 	fe->id = KEY_CODE(c);
435 	fe->value = KEY_UP(c) ? VKEY_UP : VKEY_DOWN;
436 	fe->time = time;
437 	k->k_events.ev_put = put;
438 	EV_WAKEUP(&k->k_events);
439 }
440 
441 int
442 kbdopen(dev_t dev, int flags, int mode, struct proc *p)
443 {
444 	int s, error;
445 
446 	if (kbd_softc.k_events.ev_io)
447 		return (EBUSY);
448 	kbd_softc.k_events.ev_io = p;
449 	/*
450 	 * If no console keyboard, tell the device to open up, maybe for
451 	 * the first time.  Then make sure we know what kind of keyboard
452 	 * it is.
453 	 */
454 	if (kbd_softc.k_cons == NULL)
455 		(*kbd_softc.k_open)(kbd_softc.k_kbd);
456 	error = 0;
457 	s = spltty();
458 	if (kbd_softc.k_state.kbd_cur == NULL) {
459 		(void) ttyoutput(KBD_CMD_RESET, kbd_softc.k_kbd);
460 		error = tsleep((caddr_t)&kbd_softc.k_state, PZERO | PCATCH,
461 		    devopn, hz);
462 		if (error == EWOULDBLOCK)	/* no response */
463 			error = ENXIO;
464 	}
465 	splx(s);
466 	if (error) {
467 		kbd_softc.k_events.ev_io = NULL;
468 		return (error);
469 	}
470 	ev_init(&kbd_softc.k_events);
471 	return (0);
472 }
473 
474 int
475 kbdclose(dev_t dev, int flags, int mode, struct proc *p)
476 {
477 
478 	/*
479 	 * Turn off event mode, dump the queue, and close the keyboard
480 	 * unless it is supplying console input.
481 	 */
482 	kbd_softc.k_evmode = 0;
483 	ev_fini(&kbd_softc.k_events);
484 	if (kbd_softc.k_cons == NULL)
485 		(*kbd_softc.k_close)(kbd_softc.k_kbd);
486 	kbd_softc.k_events.ev_io = NULL;
487 	return (0);
488 }
489 
490 int
491 kbdread(dev_t dev, struct uio *uio, int flags)
492 {
493 
494 	return (ev_read(&kbd_softc.k_events, uio, flags));
495 }
496 
497 /* this routine should not exist, but is convenient to write here for now */
498 int
499 kbdwrite(dev_t dev, struct uio *uio, int flags)
500 {
501 
502 	return (EOPNOTSUPP);
503 }
504 
505 int
506 kbdioctl(dev_t dev, int cmd, register caddr_t data, int flag, struct proc *p)
507 {
508 	register struct kbd_softc *k = &kbd_softc;
509 
510 	switch (cmd) {
511 
512 	case KIOCTRANS:
513 		if (*(int *)data == TR_UNTRANS_EVENT)
514 			return (0);
515 		break;
516 
517 	case KIOCGTRANS:
518 		/*
519 		 * Get translation mode
520 		 */
521 		*(int *)data = TR_UNTRANS_EVENT;
522 		return (0);
523 
524 	case KIOCGETKEY:
525 		if (((struct kiockey *)data)->kio_station == 118) {
526 			/*
527 			 * This is X11 asking if a type 3 keyboard is
528 			 * really a type 3 keyboard.  Say yes.
529 			 */
530 			((struct kiockey *)data)->kio_entry = HOLE;
531 			return (0);
532 		}
533 		break;
534 
535 	case KIOCCMD:
536 		/*
537 		 * ``unimplemented commands are ignored'' (blech)
538 		 * so cannot check return value from kbd_docmd
539 		 */
540 #ifdef notyet
541 		while (kbd_docmd(*(int *)data, 1) == ENOSPC) /*ERESTART?*/
542 			(void) sleep((caddr_t)&lbolt, TTOPRI);
543 #else
544 		(void) kbd_docmd(*(int *)data, 1);
545 #endif
546 		return (0);
547 
548 	case KIOCTYPE:
549 		*(int *)data = k->k_state.kbd_id;
550 		return (0);
551 
552 	case KIOCSDIRECT:
553 		k->k_evmode = *(int *)data;
554 		return (0);
555 
556 	case FIONBIO:		/* we will remove this someday (soon???) */
557 		return (0);
558 
559 	case FIOASYNC:
560 		k->k_events.ev_async = *(int *)data != 0;
561 		return (0);
562 
563 	case TIOCSPGRP:
564 		if (*(int *)data != k->k_events.ev_io->p_pgid)
565 			return (EPERM);
566 		return (0);
567 
568 	default:
569 		return (ENOTTY);
570 	}
571 
572 	/*
573 	 * We identified the ioctl, but we do not handle it.
574 	 */
575 	return (EOPNOTSUPP);		/* misuse, but what the heck */
576 }
577 
578 int
579 kbdselect(dev_t dev, int rw, struct proc *p)
580 {
581 
582 	return (ev_select(&kbd_softc.k_events, rw, p));
583 }
584 
585 /*
586  * Execute a keyboard command; return 0 on success.
587  * If `isuser', force a small delay before output if output queue
588  * is flooding.  (The keyboard runs at 1200 baud, or 120 cps.)
589  */
590 int
591 kbd_docmd(int cmd, int isuser)
592 {
593 	register struct tty *tp = kbd_softc.k_kbd;
594 	register struct kbd_softc *k = &kbd_softc;
595 	int s;
596 
597 	if (tp == NULL)
598 		return (ENXIO);		/* ??? */
599 	switch (cmd) {
600 
601 	case KBD_CMD_BELL:
602 	case KBD_CMD_NOBELL:
603 		/* Supported by type 2, 3, and 4 keyboards */
604 		break;
605 
606 	case KBD_CMD_CLICK:
607 		/* Unsupported by type 2 keyboards */
608 		if (k->k_state.kbd_id != KB_SUN2) {
609 			k->k_state.kbd_click = 1;
610 			break;
611 		}
612 		return (EINVAL);
613 
614 	case KBD_CMD_NOCLICK:
615 		/* Unsupported by type 2 keyboards */
616 		if (k->k_state.kbd_id != KB_SUN2) {
617 			k->k_state.kbd_click = 0;
618 			break;
619 		}
620 		return (EINVAL);
621 
622 	default:
623 		return (EINVAL);	/* ENOTTY? EOPNOTSUPP? */
624 	}
625 
626 	if (isuser) {
627 		s = spltty();
628 		if (tp->t_outq.c_cc > 120)
629 			(void) tsleep((caddr_t)&lbolt, TTIPRI,
630 			    ttyout, 0);
631 		splx(s);
632 	}
633 	if (ttyoutput(cmd, tp) >= 0)
634 		return (ENOSPC);	/* ERESTART? */
635 	(*tp->t_oproc)(tp);
636 	return (0);
637 }
638