kbd.c revision 1.23 1 /* $NetBSD: kbd.c,v 1.23 2000/03/19 12:50:43 pk 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(k->k_cc)) != 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 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 struct kbd_state *ks;
502 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 (*k->k_cc->cc_upstream)(*str);
561 str++;
562 }
563 }
564
565 void
566 kbd_input_funckey(k, keysym)
567 struct kbd_softc *k;
568 int keysym;
569 {
570 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 int keysym;
593 {
594 struct kbd_state *ks = &k->k_state;
595 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 (*k->k_cc->cc_upstream)(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 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 && k->k_isconsole) {
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(cc)
796 struct cons_channel *cc;
797 {
798 struct kbd_softc *k = (struct kbd_softc *)cc->cc_dev;
799 struct kbd_state *ks;
800 int error, s;
801
802 if (k == NULL)
803 return (ENXIO);
804
805 ks = &k->k_state;
806
807 /* Tolerate extra calls. */
808 if (k->k_isopen)
809 return (0);
810
811 s = spltty();
812
813 /* Reset the keyboard and find out its type. */
814 kbd_output(k, KBD_CMD_RESET);
815 kbd_start_tx(k);
816 kbd_drain_tx(k);
817 /* The wakeup for this is in kbd_was_reset(). */
818 error = tsleep((caddr_t)&ks->kbd_id,
819 PZERO | PCATCH, devopn, hz);
820 if (error == EWOULDBLOCK) { /* no response */
821 error = 0;
822 log(LOG_ERR, "%s: reset failed\n",
823 k->k_dev.dv_xname);
824 /*
825 * Allow the open anyway (to keep getty happy)
826 * but assume the "least common denominator".
827 */
828 ks->kbd_id = KB_SUN2;
829 }
830
831 /* Initialize the table pointers for this type. */
832 kbd_xlate_init(ks);
833
834 /* Earlier than type 4 does not know "layout". */
835 if (ks->kbd_id < KB_SUN4)
836 goto out;
837
838 /* Ask for the layout. */
839 kbd_output(k, KBD_CMD_GETLAYOUT);
840 kbd_start_tx(k);
841 kbd_drain_tx(k);
842 /* The wakeup for this is in kbd_new_layout(). */
843 error = tsleep((caddr_t)&ks->kbd_layout,
844 PZERO | PCATCH, devopn, hz);
845 if (error == EWOULDBLOCK) { /* no response */
846 error = 0;
847 log(LOG_ERR, "%s: no response to get_layout\n",
848 k->k_dev.dv_xname);
849 ks->kbd_layout = 0;
850 }
851
852 out:
853 splx(s);
854
855 if (error == 0)
856 k->k_isopen = 1;
857
858 return (error);
859 }
860
861 int
862 kbd_iclose(cc)
863 struct cons_channel *cc;
864 {
865 /* For now: */ return (0);
866 }
867
868 /*
869 * Called by kbd_input_raw, at spltty()
870 */
871 static void
872 kbd_was_reset(k)
873 struct kbd_softc *k;
874 {
875 struct kbd_state *ks = &k->k_state;
876
877 /*
878 * On first identification, wake up anyone waiting for type
879 * and set up the table pointers.
880 */
881 wakeup((caddr_t)&ks->kbd_id);
882
883 /* Restore keyclick, if necessary */
884 switch (ks->kbd_id) {
885
886 case KB_SUN2:
887 /* Type 2 keyboards don't support keyclick */
888 break;
889
890 case KB_SUN3:
891 /* Type 3 keyboards come up with keyclick on */
892 if (!ks->kbd_click) {
893 /* turn off the click */
894 kbd_output(k, KBD_CMD_NOCLICK);
895 kbd_start_tx(k);
896 }
897 break;
898
899 case KB_SUN4:
900 /* Type 4 keyboards come up with keyclick off */
901 if (ks->kbd_click) {
902 /* turn on the click */
903 kbd_output(k, KBD_CMD_CLICK);
904 kbd_start_tx(k);
905 }
906 break;
907 }
908
909 /* LEDs are off after reset. */
910 ks->kbd_leds = 0;
911 }
912
913 /*
914 * Called by kbd_input_raw, at spltty()
915 */
916 static void
917 kbd_new_layout(k)
918 struct kbd_softc *k;
919 {
920 struct kbd_state *ks = &k->k_state;
921
922 /*
923 * On first identification, wake up anyone waiting for type
924 * and set up the table pointers.
925 */
926 wakeup((caddr_t)&ks->kbd_layout);
927
928 /* XXX: switch decoding tables? */
929 }
930
931
932 /*
933 * Wait for output to finish.
934 * Called at spltty(). Has user context.
935 */
936 static int
937 kbd_drain_tx(k)
938 struct kbd_softc *k;
939 {
940 int error;
941
942 error = 0;
943
944 while (k->k_txflags & K_TXBUSY) {
945 k->k_txflags |= K_TXWANT;
946 error = tsleep((caddr_t)&k->k_txflags,
947 PZERO | PCATCH, "kbdout", 0);
948 }
949
950 return (error);
951 }
952
953 /*
954 * Enqueue some output for the keyboard
955 * Called at spltty().
956 */
957 void
958 kbd_output(k, c)
959 struct kbd_softc *k;
960 int c; /* the data */
961 {
962 int put;
963
964 put = k->k_tbput;
965 k->k_tbuf[put] = (u_char)c;
966 put = (put + 1) & KBD_TX_RING_MASK;
967
968 /* Would overrun if increment makes (put==get). */
969 if (put == k->k_tbget) {
970 log(LOG_WARNING, "%s: output overrun\n",
971 k->k_dev.dv_xname);
972 } else {
973 /* OK, really increment. */
974 k->k_tbput = put;
975 }
976 }
977
978 /*
979 * Start the sending data from the output queue
980 * Called at spltty().
981 */
982 void
983 kbd_start_tx(k)
984 struct kbd_softc *k;
985 {
986 int get;
987 u_char c;
988
989 if (k->k_txflags & K_TXBUSY)
990 return;
991
992 /* Is there anything to send? */
993 get = k->k_tbget;
994 if (get == k->k_tbput) {
995 /* Nothing to send. Wake drain waiters. */
996 if (k->k_txflags & K_TXWANT) {
997 k->k_txflags &= ~K_TXWANT;
998 wakeup((caddr_t)&k->k_txflags);
999 }
1000 return;
1001 }
1002
1003 /* Have something to send. */
1004 c = k->k_tbuf[get];
1005 get = (get + 1) & KBD_TX_RING_MASK;
1006 k->k_tbget = get;
1007 k->k_txflags |= K_TXBUSY;
1008
1009 k->k_write_data(k, c);
1010 }
1011
1012 /*
1013 * Called at spltty by:
1014 * kbd_update_leds, kbd_iocsled
1015 */
1016 static void
1017 kbd_set_leds(k, new_leds)
1018 struct kbd_softc *k;
1019 int new_leds;
1020 {
1021 struct kbd_state *ks = &k->k_state;
1022
1023 /* Don't send unless state changes. */
1024 if (ks->kbd_leds == new_leds)
1025 return;
1026
1027 ks->kbd_leds = new_leds;
1028
1029 /* Only type 4 and later has LEDs anyway. */
1030 if (ks->kbd_id < KB_SUN4)
1031 return;
1032
1033 kbd_output(k, KBD_CMD_SETLED);
1034 kbd_output(k, new_leds);
1035 kbd_start_tx(k);
1036 }
1037
1038 /*
1039 * Called at spltty by:
1040 * kbd_input_keysym
1041 */
1042 static void
1043 kbd_update_leds(k)
1044 struct kbd_softc *k;
1045 {
1046 struct kbd_state *ks = &k->k_state;
1047 char leds;
1048
1049 leds = ks->kbd_leds;
1050 leds &= ~(LED_CAPS_LOCK|LED_NUM_LOCK);
1051
1052 if (ks->kbd_modbits & (1 << KBMOD_CAPSLOCK))
1053 leds |= LED_CAPS_LOCK;
1054 if (ks->kbd_modbits & (1 << KBMOD_NUMLOCK))
1055 leds |= LED_NUM_LOCK;
1056
1057 kbd_set_leds(k, leds);
1058 }
1059