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