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