]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/atkbdc/atkbd.c
Merge OpenSSL 1.0.1j.
[FreeBSD/FreeBSD.git] / sys / dev / atkbdc / atkbd.c
1 /*-
2  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer as
10  *    the first lines of this file unmodified.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_compat.h"
32 #include "opt_kbd.h"
33 #include "opt_atkbd.h"
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/bus.h>
39 #include <sys/eventhandler.h>
40 #include <sys/proc.h>
41 #include <sys/limits.h>
42 #include <sys/malloc.h>
43
44 #include <machine/bus.h>
45 #include <machine/resource.h>
46
47 #if defined(__i386__) || defined(__amd64__)
48 #include <machine/md_var.h>
49 #include <machine/psl.h>
50 #include <compat/x86bios/x86bios.h>
51 #include <machine/pc/bios.h>
52
53 #include <vm/vm.h>
54 #include <vm/pmap.h>
55 #include <vm/vm_param.h>
56
57 #include <isa/isareg.h>
58 #endif /* __i386__ || __amd64__ */
59
60 #include <sys/kbio.h>
61 #include <dev/kbd/kbdreg.h>
62 #include <dev/atkbdc/atkbdreg.h>
63 #include <dev/atkbdc/atkbdcreg.h>
64
65 typedef struct atkbd_state {
66         KBDC            kbdc;           /* keyboard controller */
67         int             ks_mode;        /* input mode (K_XLATE,K_RAW,K_CODE) */
68         int             ks_flags;       /* flags */
69 #define COMPOSE         (1 << 0)
70         int             ks_polling;
71         int             ks_state;       /* shift/lock key state */
72         int             ks_accents;     /* accent key index (> 0) */
73         u_int           ks_composed_char; /* composed char code (> 0) */
74         u_char          ks_prefix;      /* AT scan code prefix */
75         struct callout  ks_timer;
76 } atkbd_state_t;
77
78 static void             atkbd_timeout(void *arg);
79 static void             atkbd_shutdown_final(void *v);
80
81 int
82 atkbd_probe_unit(device_t dev, int irq, int flags)
83 {
84         keyboard_switch_t *sw;
85         int args[2];
86         int error;
87
88         sw = kbd_get_switch(ATKBD_DRIVER_NAME);
89         if (sw == NULL)
90                 return ENXIO;
91
92         args[0] = device_get_unit(device_get_parent(dev));
93         args[1] = irq;
94         error = (*sw->probe)(device_get_unit(dev), args, flags);
95         if (error)
96                 return error;
97         return 0;
98 }
99
100 int
101 atkbd_attach_unit(device_t dev, keyboard_t **kbd, int irq, int flags)
102 {
103         keyboard_switch_t *sw;
104         atkbd_state_t *state;
105         int args[2];
106         int error;
107         int unit;
108
109         sw = kbd_get_switch(ATKBD_DRIVER_NAME);
110         if (sw == NULL)
111                 return ENXIO;
112
113         /* reset, initialize and enable the device */
114         unit = device_get_unit(dev);
115         args[0] = device_get_unit(device_get_parent(dev));
116         args[1] = irq;
117         *kbd = NULL;
118         error = (*sw->probe)(unit, args, flags);
119         if (error)
120                 return error;
121         error = (*sw->init)(unit, kbd, args, flags);
122         if (error)
123                 return error;
124         (*sw->enable)(*kbd);
125
126 #ifdef KBD_INSTALL_CDEV
127         /* attach a virtual keyboard cdev */
128         error = kbd_attach(*kbd);
129         if (error)
130                 return error;
131 #endif
132
133         /*
134          * This is a kludge to compensate for lost keyboard interrupts.
135          * A similar code used to be in syscons. See below. XXX
136          */
137         state = (atkbd_state_t *)(*kbd)->kb_data;
138         callout_init(&state->ks_timer, 0);
139         atkbd_timeout(*kbd);
140
141         if (bootverbose)
142                 (*sw->diag)(*kbd, bootverbose);
143
144         EVENTHANDLER_REGISTER(shutdown_final, atkbd_shutdown_final, *kbd,
145             SHUTDOWN_PRI_DEFAULT);
146
147         return 0;
148 }
149
150 static void
151 atkbd_timeout(void *arg)
152 {
153         atkbd_state_t *state;
154         keyboard_t *kbd;
155         int s;
156
157         /*
158          * The original text of the following comments are extracted 
159          * from syscons.c (1.287)
160          * 
161          * With release 2.1 of the Xaccel server, the keyboard is left
162          * hanging pretty often. Apparently an interrupt from the
163          * keyboard is lost, and I don't know why (yet).
164          * This ugly hack calls the low-level interrupt routine if input
165          * is ready for the keyboard and conveniently hides the problem. XXX
166          *
167          * Try removing anything stuck in the keyboard controller; whether
168          * it's a keyboard scan code or mouse data. The low-level
169          * interrupt routine doesn't read the mouse data directly, 
170          * but the keyboard controller driver will, as a side effect.
171          */
172         /*
173          * And here is bde's original comment about this:
174          *
175          * This is necessary to handle edge triggered interrupts - if we
176          * returned when our IRQ is high due to unserviced input, then there
177          * would be no more keyboard IRQs until the keyboard is reset by
178          * external powers.
179          *
180          * The keyboard apparently unwedges the irq in most cases.
181          */
182         s = spltty();
183         kbd = (keyboard_t *)arg;
184         if (kbdd_lock(kbd, TRUE)) {
185                 /*
186                  * We have seen the lock flag is not set. Let's reset
187                  * the flag early, otherwise the LED update routine fails
188                  * which may want the lock during the interrupt routine.
189                  */
190                 kbdd_lock(kbd, FALSE);
191                 if (kbdd_check_char(kbd))
192                         kbdd_intr(kbd, NULL);
193         }
194         splx(s);
195         state = (atkbd_state_t *)kbd->kb_data;
196         callout_reset(&state->ks_timer, hz / 10, atkbd_timeout, arg);
197 }
198
199 /* LOW-LEVEL */
200
201 #define ATKBD_DEFAULT   0
202
203 /* keyboard driver declaration */
204 static int              atkbd_configure(int flags);
205 static kbd_probe_t      atkbd_probe;
206 static kbd_init_t       atkbd_init;
207 static kbd_term_t       atkbd_term;
208 static kbd_intr_t       atkbd_intr;
209 static kbd_test_if_t    atkbd_test_if;
210 static kbd_enable_t     atkbd_enable;
211 static kbd_disable_t    atkbd_disable;
212 static kbd_read_t       atkbd_read;
213 static kbd_check_t      atkbd_check;
214 static kbd_read_char_t  atkbd_read_char;
215 static kbd_check_char_t atkbd_check_char;
216 static kbd_ioctl_t      atkbd_ioctl;
217 static kbd_lock_t       atkbd_lock;
218 static kbd_clear_state_t atkbd_clear_state;
219 static kbd_get_state_t  atkbd_get_state;
220 static kbd_set_state_t  atkbd_set_state;
221 static kbd_poll_mode_t  atkbd_poll;
222
223 static keyboard_switch_t atkbdsw = {
224         atkbd_probe,
225         atkbd_init,
226         atkbd_term,
227         atkbd_intr,
228         atkbd_test_if,
229         atkbd_enable,
230         atkbd_disable,
231         atkbd_read,
232         atkbd_check,
233         atkbd_read_char,
234         atkbd_check_char,
235         atkbd_ioctl,
236         atkbd_lock,
237         atkbd_clear_state,
238         atkbd_get_state,
239         atkbd_set_state,
240         genkbd_get_fkeystr,
241         atkbd_poll,
242         genkbd_diag,
243 };
244
245 KEYBOARD_DRIVER(atkbd, atkbdsw, atkbd_configure);
246
247 /* local functions */
248 static int              get_typematic(keyboard_t *kbd);
249 static int              setup_kbd_port(KBDC kbdc, int port, int intr);
250 static int              get_kbd_echo(KBDC kbdc);
251 static int              probe_keyboard(KBDC kbdc, int flags);
252 static int              init_keyboard(KBDC kbdc, int *type, int flags);
253 static int              write_kbd(KBDC kbdc, int command, int data);
254 static int              get_kbd_id(KBDC kbdc);
255 static int              typematic(int delay, int rate);
256 static int              typematic_delay(int delay);
257 static int              typematic_rate(int rate);
258
259 /* local variables */
260
261 /* the initial key map, accent map and fkey strings */
262 #ifdef ATKBD_DFLT_KEYMAP
263 #define KBD_DFLT_KEYMAP
264 #include "atkbdmap.h"
265 #endif
266 #include <dev/kbd/kbdtables.h>
267
268 /* structures for the default keyboard */
269 static keyboard_t       default_kbd;
270 static atkbd_state_t    default_kbd_state;
271 static keymap_t         default_keymap;
272 static accentmap_t      default_accentmap;
273 static fkeytab_t        default_fkeytab[NUM_FKEYS];
274
275 /* 
276  * The back door to the keyboard driver!
277  * This function is called by the console driver, via the kbdio module,
278  * to tickle keyboard drivers when the low-level console is being initialized.
279  * Almost nothing in the kernel has been initialied yet.  Try to probe
280  * keyboards if possible.
281  * NOTE: because of the way the low-level console is initialized, this routine
282  * may be called more than once!!
283  */
284 static int
285 atkbd_configure(int flags)
286 {
287         keyboard_t *kbd;
288         int arg[2];
289         int i;
290
291         /*
292          * Probe the keyboard controller, if not present or if the driver
293          * is disabled, unregister the keyboard if any.
294          */
295         if (atkbdc_configure() != 0 ||
296             resource_disabled("atkbd", ATKBD_DEFAULT)) {
297                 i = kbd_find_keyboard(ATKBD_DRIVER_NAME, ATKBD_DEFAULT);
298                 if (i >= 0) {
299                         kbd = kbd_get_keyboard(i);
300                         kbd_unregister(kbd);
301                         kbd->kb_flags &= ~KB_REGISTERED;
302                 }
303                 return 0;
304         }
305         
306         /* XXX: a kludge to obtain the device configuration flags */
307         if (resource_int_value("atkbd", ATKBD_DEFAULT, "flags", &i) == 0)
308                 flags |= i;
309
310         /* probe the default keyboard */
311         arg[0] = -1;
312         arg[1] = -1;
313         kbd = NULL;
314         if (atkbd_probe(ATKBD_DEFAULT, arg, flags))
315                 return 0;
316         if (atkbd_init(ATKBD_DEFAULT, &kbd, arg, flags))
317                 return 0;
318
319         /* return the number of found keyboards */
320         return 1;
321 }
322
323 /* low-level functions */
324
325 /* detect a keyboard */
326 static int
327 atkbd_probe(int unit, void *arg, int flags)
328 {
329         KBDC kbdc;
330         int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
331
332         /* XXX */
333         if (unit == ATKBD_DEFAULT) {
334                 if (KBD_IS_PROBED(&default_kbd))
335                         return 0;
336         }
337
338         kbdc = atkbdc_open(data[0]);
339         if (kbdc == NULL)
340                 return ENXIO;
341         if (probe_keyboard(kbdc, flags)) {
342                 if (flags & KB_CONF_FAIL_IF_NO_KBD)
343                         return ENXIO;
344         }
345         return 0;
346 }
347
348 /* reset and initialize the device */
349 static int
350 atkbd_init(int unit, keyboard_t **kbdp, void *arg, int flags)
351 {
352         keyboard_t *kbd;
353         atkbd_state_t *state;
354         keymap_t *keymap;
355         accentmap_t *accmap;
356         fkeytab_t *fkeymap;
357         int fkeymap_size;
358         int delay[2];
359         int *data = (int *)arg; /* data[0]: controller, data[1]: irq */
360         int error, needfree;
361
362         /* XXX */
363         if (unit == ATKBD_DEFAULT) {
364                 *kbdp = kbd = &default_kbd;
365                 if (KBD_IS_INITIALIZED(kbd) && KBD_IS_CONFIGURED(kbd))
366                         return 0;
367                 state = &default_kbd_state;
368                 keymap = &default_keymap;
369                 accmap = &default_accentmap;
370                 fkeymap = default_fkeytab;
371                 fkeymap_size =
372                         sizeof(default_fkeytab)/sizeof(default_fkeytab[0]);
373                 needfree = 0;
374         } else if (*kbdp == NULL) {
375                 *kbdp = kbd = malloc(sizeof(*kbd), M_DEVBUF, M_NOWAIT | M_ZERO);
376                 state = malloc(sizeof(*state), M_DEVBUF, M_NOWAIT | M_ZERO);
377                 /* NB: these will always be initialized 'cuz !KBD_IS_PROBED */
378                 keymap = malloc(sizeof(key_map), M_DEVBUF, M_NOWAIT);
379                 accmap = malloc(sizeof(accent_map), M_DEVBUF, M_NOWAIT);
380                 fkeymap = malloc(sizeof(fkey_tab), M_DEVBUF, M_NOWAIT);
381                 fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
382                 needfree = 1;
383                 if ((kbd == NULL) || (state == NULL) || (keymap == NULL)
384                      || (accmap == NULL) || (fkeymap == NULL)) {
385                         error = ENOMEM;
386                         goto bad;
387                 }
388         } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
389                 return 0;
390         } else {
391                 kbd = *kbdp;
392                 state = (atkbd_state_t *)kbd->kb_data;
393                 bzero(state, sizeof(*state));
394                 keymap = kbd->kb_keymap;
395                 accmap = kbd->kb_accentmap;
396                 fkeymap = kbd->kb_fkeytab;
397                 fkeymap_size = kbd->kb_fkeytab_size;
398                 needfree = 0;
399         }
400
401         if (!KBD_IS_PROBED(kbd)) {
402                 state->kbdc = atkbdc_open(data[0]);
403                 if (state->kbdc == NULL) {
404                         error = ENXIO;
405                         goto bad;
406                 }
407                 kbd_init_struct(kbd, ATKBD_DRIVER_NAME, KB_OTHER, unit, flags,
408                                 0, 0);
409                 bcopy(&key_map, keymap, sizeof(key_map));
410                 bcopy(&accent_map, accmap, sizeof(accent_map));
411                 bcopy(fkey_tab, fkeymap,
412                     imin(fkeymap_size * sizeof(fkeymap[0]), sizeof(fkey_tab)));
413                 kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
414                 kbd->kb_data = (void *)state;
415         
416                 if (probe_keyboard(state->kbdc, flags)) { /* shouldn't happen */
417                         if (flags & KB_CONF_FAIL_IF_NO_KBD) {
418                                 error = ENXIO;
419                                 goto bad;
420                         }
421                 } else {
422                         KBD_FOUND_DEVICE(kbd);
423                 }
424                 atkbd_clear_state(kbd);
425                 state->ks_mode = K_XLATE;
426                 /* 
427                  * FIXME: set the initial value for lock keys in ks_state
428                  * according to the BIOS data?
429                  */
430                 KBD_PROBE_DONE(kbd);
431         }
432         if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
433                 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
434                 if (KBD_HAS_DEVICE(kbd)
435                     && init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config)
436                     && (kbd->kb_config & KB_CONF_FAIL_IF_NO_KBD)) {
437                         kbd_unregister(kbd);
438                         error = ENXIO;
439                         goto bad;
440                 }
441                 atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
442                 get_typematic(kbd);
443                 delay[0] = kbd->kb_delay1;
444                 delay[1] = kbd->kb_delay2;
445                 atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
446                 KBD_INIT_DONE(kbd);
447         }
448         if (!KBD_IS_CONFIGURED(kbd)) {
449                 if (kbd_register(kbd) < 0) {
450                         error = ENXIO;
451                         goto bad;
452                 }
453                 KBD_CONFIG_DONE(kbd);
454         }
455
456         return 0;
457 bad:
458         if (needfree) {
459                 if (state != NULL)
460                         free(state, M_DEVBUF);
461                 if (keymap != NULL)
462                         free(keymap, M_DEVBUF);
463                 if (accmap != NULL)
464                         free(accmap, M_DEVBUF);
465                 if (fkeymap != NULL)
466                         free(fkeymap, M_DEVBUF);
467                 if (kbd != NULL) {
468                         free(kbd, M_DEVBUF);
469                         *kbdp = NULL;   /* insure ref doesn't leak to caller */
470                 }
471         }
472         return error;
473 }
474
475 /* finish using this keyboard */
476 static int
477 atkbd_term(keyboard_t *kbd)
478 {
479         atkbd_state_t *state = (atkbd_state_t *)kbd->kb_data;
480
481         kbd_unregister(kbd);
482         callout_drain(&state->ks_timer);
483         return 0;
484 }
485
486 /* keyboard interrupt routine */
487 static int
488 atkbd_intr(keyboard_t *kbd, void *arg)
489 {
490         atkbd_state_t *state = (atkbd_state_t *)kbd->kb_data;
491         int delay[2];
492         int c;
493
494         if (!KBD_HAS_DEVICE(kbd)) {
495                 /*
496                  * The keyboard was not detected before;
497                  * it must have been reconnected!
498                  */
499                 init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config);
500                 KBD_FOUND_DEVICE(kbd);
501                 atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
502                 get_typematic(kbd);
503                 delay[0] = kbd->kb_delay1;
504                 delay[1] = kbd->kb_delay2;
505                 atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
506         }
507
508         if (state->ks_polling)
509                 return 0;
510
511         if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
512                 /* let the callback function to process the input */
513                 (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
514                                             kbd->kb_callback.kc_arg);
515         } else {
516                 /* read and discard the input; no one is waiting for input */
517                 do {
518                         c = atkbd_read_char(kbd, FALSE);
519                 } while (c != NOKEY);
520         }
521         return 0;
522 }
523
524 /* test the interface to the device */
525 static int
526 atkbd_test_if(keyboard_t *kbd)
527 {
528         int error;
529         int s;
530
531         error = 0;
532         empty_both_buffers(((atkbd_state_t *)kbd->kb_data)->kbdc, 10);
533         s = spltty();
534         if (!test_controller(((atkbd_state_t *)kbd->kb_data)->kbdc))
535                 error = EIO;
536         else if (test_kbd_port(((atkbd_state_t *)kbd->kb_data)->kbdc) != 0)
537                 error = EIO;
538         splx(s);
539
540         return error;
541 }
542
543 /* 
544  * Enable the access to the device; until this function is called,
545  * the client cannot read from the keyboard.
546  */
547 static int
548 atkbd_enable(keyboard_t *kbd)
549 {
550         int s;
551
552         s = spltty();
553         KBD_ACTIVATE(kbd);
554         splx(s);
555         return 0;
556 }
557
558 /* disallow the access to the device */
559 static int
560 atkbd_disable(keyboard_t *kbd)
561 {
562         int s;
563
564         s = spltty();
565         KBD_DEACTIVATE(kbd);
566         splx(s);
567         return 0;
568 }
569
570 /* read one byte from the keyboard if it's allowed */
571 static int
572 atkbd_read(keyboard_t *kbd, int wait)
573 {
574         int c;
575
576         if (wait)
577                 c = read_kbd_data(((atkbd_state_t *)kbd->kb_data)->kbdc);
578         else
579                 c = read_kbd_data_no_wait(((atkbd_state_t *)kbd->kb_data)->kbdc);
580         if (c != -1)
581                 ++kbd->kb_count;
582         return (KBD_IS_ACTIVE(kbd) ? c : -1);
583 }
584
585 /* check if data is waiting */
586 static int
587 atkbd_check(keyboard_t *kbd)
588 {
589         if (!KBD_IS_ACTIVE(kbd))
590                 return FALSE;
591         return kbdc_data_ready(((atkbd_state_t *)kbd->kb_data)->kbdc);
592 }
593
594 /* read char from the keyboard */
595 static u_int
596 atkbd_read_char(keyboard_t *kbd, int wait)
597 {
598         atkbd_state_t *state;
599         u_int action;
600         int scancode;
601         int keycode;
602
603         state = (atkbd_state_t *)kbd->kb_data;
604 next_code:
605         /* do we have a composed char to return? */
606         if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
607                 action = state->ks_composed_char;
608                 state->ks_composed_char = 0;
609                 if (action > UCHAR_MAX)
610                         return ERRKEY;
611                 return action;
612         }
613
614         /* see if there is something in the keyboard port */
615         if (wait) {
616                 do {
617                         scancode = read_kbd_data(state->kbdc);
618                 } while (scancode == -1);
619         } else {
620                 scancode = read_kbd_data_no_wait(state->kbdc);
621                 if (scancode == -1)
622                         return NOKEY;
623         }
624         ++kbd->kb_count;
625
626 #if KBDIO_DEBUG >= 10
627         printf("atkbd_read_char(): scancode:0x%x\n", scancode);
628 #endif
629
630         /* return the byte as is for the K_RAW mode */
631         if (state->ks_mode == K_RAW)
632                 return scancode;
633
634         /* translate the scan code into a keycode */
635         keycode = scancode & 0x7F;
636         switch (state->ks_prefix) {
637         case 0x00:      /* normal scancode */
638                 switch(scancode) {
639                 case 0xB8:      /* left alt (compose key) released */
640                         if (state->ks_flags & COMPOSE) {
641                                 state->ks_flags &= ~COMPOSE;
642                                 if (state->ks_composed_char > UCHAR_MAX)
643                                         state->ks_composed_char = 0;
644                         }
645                         break;
646                 case 0x38:      /* left alt (compose key) pressed */
647                         if (!(state->ks_flags & COMPOSE)) {
648                                 state->ks_flags |= COMPOSE;
649                                 state->ks_composed_char = 0;
650                         }
651                         break;
652                 case 0xE0:
653                 case 0xE1:
654                         state->ks_prefix = scancode;
655                         goto next_code;
656                 }
657                 break;
658         case 0xE0:              /* 0xE0 prefix */
659                 state->ks_prefix = 0;
660                 switch (keycode) {
661                 case 0x1C:      /* right enter key */
662                         keycode = 0x59;
663                         break;
664                 case 0x1D:      /* right ctrl key */
665                         keycode = 0x5A;
666                         break;
667                 case 0x35:      /* keypad divide key */
668                         keycode = 0x5B;
669                         break;
670                 case 0x37:      /* print scrn key */
671                         keycode = 0x5C;
672                         break;
673                 case 0x38:      /* right alt key (alt gr) */
674                         keycode = 0x5D;
675                         break;
676                 case 0x46:      /* ctrl-pause/break on AT 101 (see below) */
677                         keycode = 0x68;
678                         break;
679                 case 0x47:      /* grey home key */
680                         keycode = 0x5E;
681                         break;
682                 case 0x48:      /* grey up arrow key */
683                         keycode = 0x5F;
684                         break;
685                 case 0x49:      /* grey page up key */
686                         keycode = 0x60;
687                         break;
688                 case 0x4B:      /* grey left arrow key */
689                         keycode = 0x61;
690                         break;
691                 case 0x4D:      /* grey right arrow key */
692                         keycode = 0x62;
693                         break;
694                 case 0x4F:      /* grey end key */
695                         keycode = 0x63;
696                         break;
697                 case 0x50:      /* grey down arrow key */
698                         keycode = 0x64;
699                         break;
700                 case 0x51:      /* grey page down key */
701                         keycode = 0x65;
702                         break;
703                 case 0x52:      /* grey insert key */
704                         keycode = 0x66;
705                         break;
706                 case 0x53:      /* grey delete key */
707                         keycode = 0x67;
708                         break;
709                         /* the following 3 are only used on the MS "Natural" keyboard */
710                 case 0x5b:      /* left Window key */
711                         keycode = 0x69;
712                         break;
713                 case 0x5c:      /* right Window key */
714                         keycode = 0x6a;
715                         break;
716                 case 0x5d:      /* menu key */
717                         keycode = 0x6b;
718                         break;
719                 case 0x5e:      /* power key */
720                         keycode = 0x6d;
721                         break;
722                 case 0x5f:      /* sleep key */
723                         keycode = 0x6e;
724                         break;
725                 case 0x63:      /* wake key */
726                         keycode = 0x6f;
727                         break;
728                 default:        /* ignore everything else */
729                         goto next_code;
730                 }
731                 break;
732         case 0xE1:      /* 0xE1 prefix */
733                 /* 
734                  * The pause/break key on the 101 keyboard produces:
735                  * E1-1D-45 E1-9D-C5
736                  * Ctrl-pause/break produces:
737                  * E0-46 E0-C6 (See above.)
738                  */
739                 state->ks_prefix = 0;
740                 if (keycode == 0x1D)
741                         state->ks_prefix = 0x1D;
742                 goto next_code;
743                 /* NOT REACHED */
744         case 0x1D:      /* pause / break */
745                 state->ks_prefix = 0;
746                 if (keycode != 0x45)
747                         goto next_code;
748                 keycode = 0x68;
749                 break;
750         }
751
752         if (kbd->kb_type == KB_84) {
753                 switch (keycode) {
754                 case 0x37:      /* *(numpad)/print screen */
755                         if (state->ks_flags & SHIFTS)
756                                 keycode = 0x5c; /* print screen */
757                         break;
758                 case 0x45:      /* num lock/pause */
759                         if (state->ks_flags & CTLS)
760                                 keycode = 0x68; /* pause */
761                         break;
762                 case 0x46:      /* scroll lock/break */
763                         if (state->ks_flags & CTLS)
764                                 keycode = 0x6c; /* break */
765                         break;
766                 }
767         } else if (kbd->kb_type == KB_101) {
768                 switch (keycode) {
769                 case 0x5c:      /* print screen */
770                         if (state->ks_flags & ALTS)
771                                 keycode = 0x54; /* sysrq */
772                         break;
773                 case 0x68:      /* pause/break */
774                         if (state->ks_flags & CTLS)
775                                 keycode = 0x6c; /* break */
776                         break;
777                 }
778         }
779
780         /* return the key code in the K_CODE mode */
781         if (state->ks_mode == K_CODE)
782                 return (keycode | (scancode & 0x80));
783
784         /* compose a character code */
785         if (state->ks_flags & COMPOSE) {
786                 switch (keycode | (scancode & 0x80)) {
787                 /* key pressed, process it */
788                 case 0x47: case 0x48: case 0x49:        /* keypad 7,8,9 */
789                         state->ks_composed_char *= 10;
790                         state->ks_composed_char += keycode - 0x40;
791                         if (state->ks_composed_char > UCHAR_MAX)
792                                 return ERRKEY;
793                         goto next_code;
794                 case 0x4B: case 0x4C: case 0x4D:        /* keypad 4,5,6 */
795                         state->ks_composed_char *= 10;
796                         state->ks_composed_char += keycode - 0x47;
797                         if (state->ks_composed_char > UCHAR_MAX)
798                                 return ERRKEY;
799                         goto next_code;
800                 case 0x4F: case 0x50: case 0x51:        /* keypad 1,2,3 */
801                         state->ks_composed_char *= 10;
802                         state->ks_composed_char += keycode - 0x4E;
803                         if (state->ks_composed_char > UCHAR_MAX)
804                                 return ERRKEY;
805                         goto next_code;
806                 case 0x52:                              /* keypad 0 */
807                         state->ks_composed_char *= 10;
808                         if (state->ks_composed_char > UCHAR_MAX)
809                                 return ERRKEY;
810                         goto next_code;
811
812                 /* key released, no interest here */
813                 case 0xC7: case 0xC8: case 0xC9:        /* keypad 7,8,9 */
814                 case 0xCB: case 0xCC: case 0xCD:        /* keypad 4,5,6 */
815                 case 0xCF: case 0xD0: case 0xD1:        /* keypad 1,2,3 */
816                 case 0xD2:                              /* keypad 0 */
817                         goto next_code;
818
819                 case 0x38:                              /* left alt key */
820                         break;
821
822                 default:
823                         if (state->ks_composed_char > 0) {
824                                 state->ks_flags &= ~COMPOSE;
825                                 state->ks_composed_char = 0;
826                                 return ERRKEY;
827                         }
828                         break;
829                 }
830         }
831
832         /* keycode to key action */
833         action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
834                                   &state->ks_state, &state->ks_accents);
835         if (action == NOKEY)
836                 goto next_code;
837         else
838                 return action;
839 }
840
841 /* check if char is waiting */
842 static int
843 atkbd_check_char(keyboard_t *kbd)
844 {
845         atkbd_state_t *state;
846
847         if (!KBD_IS_ACTIVE(kbd))
848                 return FALSE;
849         state = (atkbd_state_t *)kbd->kb_data;
850         if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0))
851                 return TRUE;
852         return kbdc_data_ready(state->kbdc);
853 }
854
855 /* some useful control functions */
856 static int
857 atkbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
858 {
859         /* translate LED_XXX bits into the device specific bits */
860         static u_char ledmap[8] = {
861                 0, 4, 2, 6, 1, 5, 3, 7,
862         };
863         atkbd_state_t *state = kbd->kb_data;
864         int error;
865         int s;
866         int i;
867 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
868     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
869         int ival;
870 #endif
871
872         s = spltty();
873         switch (cmd) {
874
875         case KDGKBMODE:         /* get keyboard mode */
876                 *(int *)arg = state->ks_mode;
877                 break;
878 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
879     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
880         case _IO('K', 7):
881                 ival = IOCPARM_IVAL(arg);
882                 arg = (caddr_t)&ival;
883                 /* FALLTHROUGH */
884 #endif
885         case KDSKBMODE:         /* set keyboard mode */
886                 switch (*(int *)arg) {
887                 case K_XLATE:
888                         if (state->ks_mode != K_XLATE) {
889                                 /* make lock key state and LED state match */
890                                 state->ks_state &= ~LOCK_MASK;
891                                 state->ks_state |= KBD_LED_VAL(kbd);
892                         }
893                         /* FALLTHROUGH */
894                 case K_RAW:
895                 case K_CODE:
896                         if (state->ks_mode != *(int *)arg) {
897                                 atkbd_clear_state(kbd);
898                                 state->ks_mode = *(int *)arg;
899                         }
900                         break;
901                 default:
902                         splx(s);
903                         return EINVAL;
904                 }
905                 break;
906
907         case KDGETLED:          /* get keyboard LED */
908                 *(int *)arg = KBD_LED_VAL(kbd);
909                 break;
910 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
911     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
912         case _IO('K', 66):
913                 ival = IOCPARM_IVAL(arg);
914                 arg = (caddr_t)&ival;
915                 /* FALLTHROUGH */
916 #endif
917         case KDSETLED:          /* set keyboard LED */
918                 /* NOTE: lock key state in ks_state won't be changed */
919                 if (*(int *)arg & ~LOCK_MASK) {
920                         splx(s);
921                         return EINVAL;
922                 }
923                 i = *(int *)arg;
924                 /* replace CAPS LED with ALTGR LED for ALTGR keyboards */
925                 if (state->ks_mode == K_XLATE &&
926                     kbd->kb_keymap->n_keys > ALTGR_OFFSET) {
927                         if (i & ALKED)
928                                 i |= CLKED;
929                         else
930                                 i &= ~CLKED;
931                 }
932                 if (KBD_HAS_DEVICE(kbd)) {
933                         error = write_kbd(state->kbdc, KBDC_SET_LEDS,
934                                           ledmap[i & LED_MASK]);
935                         if (error) {
936                                 splx(s);
937                                 return error;
938                         }
939                 }
940                 KBD_LED_VAL(kbd) = *(int *)arg;
941                 break;
942
943         case KDGKBSTATE:        /* get lock key state */
944                 *(int *)arg = state->ks_state & LOCK_MASK;
945                 break;
946 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
947     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
948         case _IO('K', 20):
949                 ival = IOCPARM_IVAL(arg);
950                 arg = (caddr_t)&ival;
951                 /* FALLTHROUGH */
952 #endif
953         case KDSKBSTATE:        /* set lock key state */
954                 if (*(int *)arg & ~LOCK_MASK) {
955                         splx(s);
956                         return EINVAL;
957                 }
958                 state->ks_state &= ~LOCK_MASK;
959                 state->ks_state |= *(int *)arg;
960                 splx(s);
961                 /* set LEDs and quit */
962                 return atkbd_ioctl(kbd, KDSETLED, arg);
963
964         case KDSETREPEAT:       /* set keyboard repeat rate (new interface) */
965                 splx(s);
966                 if (!KBD_HAS_DEVICE(kbd))
967                         return 0;
968                 i = typematic(((int *)arg)[0], ((int *)arg)[1]);
969                 error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, i);
970                 if (error == 0) {
971                         kbd->kb_delay1 = typematic_delay(i);
972                         kbd->kb_delay2 = typematic_rate(i);
973                 }
974                 return error;
975
976 #if defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD5) || \
977     defined(COMPAT_FREEBSD4) || defined(COMPAT_43)
978         case _IO('K', 67):
979                 ival = IOCPARM_IVAL(arg);
980                 arg = (caddr_t)&ival;
981                 /* FALLTHROUGH */
982 #endif
983         case KDSETRAD:          /* set keyboard repeat rate (old interface) */
984                 splx(s);
985                 if (!KBD_HAS_DEVICE(kbd))
986                         return 0;
987                 error = write_kbd(state->kbdc, KBDC_SET_TYPEMATIC, *(int *)arg);
988                 if (error == 0) {
989                         kbd->kb_delay1 = typematic_delay(*(int *)arg);
990                         kbd->kb_delay2 = typematic_rate(*(int *)arg);
991                 }
992                 return error;
993
994         case PIO_KEYMAP:        /* set keyboard translation table */
995         case OPIO_KEYMAP:       /* set keyboard translation table (compat) */
996         case PIO_KEYMAPENT:     /* set keyboard translation table entry */
997         case PIO_DEADKEYMAP:    /* set accent key translation table */
998                 state->ks_accents = 0;
999                 /* FALLTHROUGH */
1000         default:
1001                 splx(s);
1002                 return genkbd_commonioctl(kbd, cmd, arg);
1003         }
1004
1005         splx(s);
1006         return 0;
1007 }
1008
1009 /* lock the access to the keyboard */
1010 static int
1011 atkbd_lock(keyboard_t *kbd, int lock)
1012 {
1013         return kbdc_lock(((atkbd_state_t *)kbd->kb_data)->kbdc, lock);
1014 }
1015
1016 /* clear the internal state of the keyboard */
1017 static void
1018 atkbd_clear_state(keyboard_t *kbd)
1019 {
1020         atkbd_state_t *state;
1021
1022         state = (atkbd_state_t *)kbd->kb_data;
1023         state->ks_flags = 0;
1024         state->ks_polling = 0;
1025         state->ks_state &= LOCK_MASK;   /* preserve locking key state */
1026         state->ks_accents = 0;
1027         state->ks_composed_char = 0;
1028 #if 0
1029         state->ks_prefix = 0; /* XXX */
1030 #endif
1031 }
1032
1033 /* save the internal state */
1034 static int
1035 atkbd_get_state(keyboard_t *kbd, void *buf, size_t len)
1036 {
1037         if (len == 0)
1038                 return sizeof(atkbd_state_t);
1039         if (len < sizeof(atkbd_state_t))
1040                 return -1;
1041         bcopy(kbd->kb_data, buf, sizeof(atkbd_state_t));
1042         return 0;
1043 }
1044
1045 /* set the internal state */
1046 static int
1047 atkbd_set_state(keyboard_t *kbd, void *buf, size_t len)
1048 {
1049         if (len < sizeof(atkbd_state_t))
1050                 return ENOMEM;
1051         if (((atkbd_state_t *)kbd->kb_data)->kbdc
1052                 != ((atkbd_state_t *)buf)->kbdc)
1053                 return ENOMEM;
1054         bcopy(buf, kbd->kb_data, sizeof(atkbd_state_t));
1055         return 0;
1056 }
1057
1058 static int
1059 atkbd_poll(keyboard_t *kbd, int on)
1060 {
1061         atkbd_state_t *state;
1062         int s;
1063
1064         state = (atkbd_state_t *)kbd->kb_data;
1065         s = spltty();
1066         if (on)
1067                 ++state->ks_polling;
1068         else
1069                 --state->ks_polling;
1070         splx(s);
1071         return 0;
1072 }
1073
1074 static void
1075 atkbd_shutdown_final(void *v)
1076 {
1077 #ifdef __sparc64__
1078         keyboard_t *kbd = v;
1079         KBDC kbdc = ((atkbd_state_t *)kbd->kb_data)->kbdc;
1080
1081         /*
1082          * Turn off the translation in preparation for handing the keyboard
1083          * over to the OFW as the OBP driver doesn't use translation and
1084          * also doesn't disable it itself resulting in a broken keymap at
1085          * the boot prompt. Also disable the aux port and the interrupts as
1086          * the OBP driver doesn't use them, i.e. polls the keyboard. Not
1087          * disabling the interrupts doesn't cause real problems but the
1088          * responsiveness is a bit better when they are turned off.
1089          */
1090         send_kbd_command(kbdc, KBDC_DISABLE_KBD);
1091         set_controller_command_byte(kbdc,
1092             KBD_AUX_CONTROL_BITS | KBD_KBD_CONTROL_BITS | KBD_TRANSLATION,
1093             KBD_DISABLE_AUX_PORT | KBD_DISABLE_KBD_INT | KBD_ENABLE_KBD_PORT);
1094         send_kbd_command(kbdc, KBDC_ENABLE_KBD);
1095 #endif
1096 }
1097
1098 /* local functions */
1099
1100 static int
1101 get_typematic(keyboard_t *kbd)
1102 {
1103 #if defined(__i386__) || defined(__amd64__)
1104         /*
1105          * Only some systems allow us to retrieve the keyboard repeat
1106          * rate previously set via the BIOS...
1107          */
1108         x86regs_t regs;
1109         uint8_t *p;
1110
1111         /*
1112          * Traditional entry points of int 0x15 and 0x16 are fixed
1113          * and later BIOSes follow them.  (U)EFI CSM specification
1114          * also mandates these fixed entry points.
1115          *
1116          * Validate the entry points here before we proceed further.
1117          * It's known that some recent laptops does not have the
1118          * same entry point and hang on boot if we call it.
1119          */
1120         if (x86bios_get_intr(0x15) != 0xf000f859 ||
1121             x86bios_get_intr(0x16) != 0xf000e82e)
1122                 return (ENODEV);
1123
1124         /* Is BIOS system configuration table supported? */
1125         x86bios_init_regs(&regs);
1126         regs.R_AH = 0xc0;
1127         x86bios_intr(&regs, 0x15);
1128         if ((regs.R_FLG & PSL_C) != 0 || regs.R_AH != 0)
1129                 return (ENODEV);
1130
1131         /* Is int 0x16, function 0x09 supported? */
1132         p = x86bios_offset((regs.R_ES << 4) + regs.R_BX);
1133         if (readw(p) < 5 || (readb(p + 6) & 0x40) == 0)
1134                 return (ENODEV);
1135
1136         /* Is int 0x16, function 0x0306 supported? */
1137         x86bios_init_regs(&regs);
1138         regs.R_AH = 0x09;
1139         x86bios_intr(&regs, 0x16);
1140         if ((regs.R_AL & 0x08) == 0)
1141                 return (ENODEV);
1142
1143         x86bios_init_regs(&regs);
1144         regs.R_AX = 0x0306;
1145         x86bios_intr(&regs, 0x16);
1146         kbd->kb_delay1 = typematic_delay(regs.R_BH << 5);
1147         kbd->kb_delay2 = typematic_rate(regs.R_BL);
1148         return (0);
1149 #else
1150         return (ENODEV);
1151 #endif /* __i386__ || __amd64__ */
1152 }
1153
1154 static int
1155 setup_kbd_port(KBDC kbdc, int port, int intr)
1156 {
1157         if (!set_controller_command_byte(kbdc,
1158                 KBD_KBD_CONTROL_BITS,
1159                 ((port) ? KBD_ENABLE_KBD_PORT : KBD_DISABLE_KBD_PORT)
1160                     | ((intr) ? KBD_ENABLE_KBD_INT : KBD_DISABLE_KBD_INT)))
1161                 return 1;
1162         return 0;
1163 }
1164
1165 static int
1166 get_kbd_echo(KBDC kbdc)
1167 {
1168         /* enable the keyboard port, but disable the keyboard intr. */
1169         if (setup_kbd_port(kbdc, TRUE, FALSE))
1170                 /* CONTROLLER ERROR: there is very little we can do... */
1171                 return ENXIO;
1172
1173         /* see if something is present */
1174         write_kbd_command(kbdc, KBDC_ECHO);
1175         if (read_kbd_data(kbdc) != KBD_ECHO) {
1176                 empty_both_buffers(kbdc, 10);
1177                 test_controller(kbdc);
1178                 test_kbd_port(kbdc);
1179                 return ENXIO;
1180         }
1181
1182         /* enable the keyboard port and intr. */
1183         if (setup_kbd_port(kbdc, TRUE, TRUE)) {
1184                 /*
1185                  * CONTROLLER ERROR 
1186                  * This is serious; the keyboard intr is left disabled! 
1187                  */
1188                 return ENXIO;
1189         }
1190
1191         return 0;
1192 }
1193
1194 static int
1195 probe_keyboard(KBDC kbdc, int flags)
1196 {
1197         /*
1198          * Don't try to print anything in this function.  The low-level 
1199          * console may not have been initialized yet...
1200          */
1201         int err;
1202         int c;
1203         int m;
1204
1205         if (!kbdc_lock(kbdc, TRUE)) {
1206                 /* driver error? */
1207                 return ENXIO;
1208         }
1209
1210         /* temporarily block data transmission from the keyboard */
1211         write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
1212
1213         /* flush any noise in the buffer */
1214         empty_both_buffers(kbdc, 100);
1215
1216         /* save the current keyboard controller command byte */
1217         m = kbdc_get_device_mask(kbdc) & ~KBD_KBD_CONTROL_BITS;
1218         c = get_controller_command_byte(kbdc);
1219         if (c == -1) {
1220                 /* CONTROLLER ERROR */
1221                 kbdc_set_device_mask(kbdc, m);
1222                 kbdc_lock(kbdc, FALSE);
1223                 return ENXIO;
1224         }
1225
1226         /* 
1227          * The keyboard may have been screwed up by the boot block.
1228          * We may just be able to recover from error by testing the controller
1229          * and the keyboard port. The controller command byte needs to be
1230          * saved before this recovery operation, as some controllers seem 
1231          * to set the command byte to particular values.
1232          */
1233         test_controller(kbdc);
1234         if (!(flags & KB_CONF_NO_PROBE_TEST))
1235                 test_kbd_port(kbdc);
1236
1237         err = get_kbd_echo(kbdc);
1238
1239         /*
1240          * Even if the keyboard doesn't seem to be present (err != 0),
1241          * we shall enable the keyboard port and interrupt so that
1242          * the driver will be operable when the keyboard is attached
1243          * to the system later.  It is NOT recommended to hot-plug
1244          * the AT keyboard, but many people do so...
1245          */
1246         kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
1247         setup_kbd_port(kbdc, TRUE, TRUE);
1248 #if 0
1249         if (err == 0) {
1250                 kbdc_set_device_mask(kbdc, m | KBD_KBD_CONTROL_BITS);
1251         } else {
1252                 /* try to restore the command byte as before */
1253                 set_controller_command_byte(kbdc, 0xff, c);
1254                 kbdc_set_device_mask(kbdc, m);
1255         }
1256 #endif
1257
1258         kbdc_lock(kbdc, FALSE);
1259         return err;
1260 }
1261
1262 static int
1263 init_keyboard(KBDC kbdc, int *type, int flags)
1264 {
1265         int codeset;
1266         int id;
1267         int c;
1268
1269         if (!kbdc_lock(kbdc, TRUE)) {
1270                 /* driver error? */
1271                 return EIO;
1272         }
1273
1274         /* temporarily block data transmission from the keyboard */
1275         write_controller_command(kbdc, KBDC_DISABLE_KBD_PORT);
1276
1277         /* save the current controller command byte */
1278         empty_both_buffers(kbdc, 200);
1279         c = get_controller_command_byte(kbdc);
1280         if (c == -1) {
1281                 /* CONTROLLER ERROR */
1282                 kbdc_lock(kbdc, FALSE);
1283                 printf("atkbd: unable to get the current command byte value.\n");
1284                 return EIO;
1285         }
1286         if (bootverbose)
1287                 printf("atkbd: the current kbd controller command byte %04x\n",
1288                    c);
1289 #if 0
1290         /* override the keyboard lock switch */
1291         c |= KBD_OVERRIDE_KBD_LOCK;
1292 #endif
1293
1294         /* enable the keyboard port, but disable the keyboard intr. */
1295         if (setup_kbd_port(kbdc, TRUE, FALSE)) {
1296                 /* CONTROLLER ERROR: there is very little we can do... */
1297                 printf("atkbd: unable to set the command byte.\n");
1298                 kbdc_lock(kbdc, FALSE);
1299                 return EIO;
1300         }
1301
1302         /* 
1303          * Check if we have an XT keyboard before we attempt to reset it. 
1304          * The procedure assumes that the keyboard and the controller have 
1305          * been set up properly by BIOS and have not been messed up 
1306          * during the boot process.
1307          */
1308         codeset = -1;
1309         if (flags & KB_CONF_ALT_SCANCODESET)
1310                 /* the user says there is a XT keyboard */
1311                 codeset = 1;
1312 #ifdef KBD_DETECT_XT_KEYBOARD
1313         else if ((c & KBD_TRANSLATION) == 0) {
1314                 /* SET_SCANCODE_SET is not always supported; ignore error */
1315                 if (send_kbd_command_and_data(kbdc, KBDC_SET_SCANCODE_SET, 0)
1316                         == KBD_ACK) 
1317                         codeset = read_kbd_data(kbdc);
1318         }
1319         if (bootverbose)
1320                 printf("atkbd: scancode set %d\n", codeset);
1321 #endif /* KBD_DETECT_XT_KEYBOARD */
1322  
1323         *type = KB_OTHER;
1324         id = get_kbd_id(kbdc);
1325         switch(id) {
1326         case 0x41ab:    /* 101/102/... Enhanced */
1327         case 0x83ab:    /* ditto */
1328         case 0x54ab:    /* SpaceSaver */
1329         case 0x84ab:    /* ditto */
1330 #if 0
1331         case 0x90ab:    /* 'G' */
1332         case 0x91ab:    /* 'P' */
1333         case 0x92ab:    /* 'A' */
1334 #endif
1335                 *type = KB_101;
1336                 break;
1337         case -1:        /* AT 84 keyboard doesn't return ID */
1338                 *type = KB_84;
1339                 break;
1340         default:
1341                 break;
1342         }
1343         if (bootverbose)
1344                 printf("atkbd: keyboard ID 0x%x (%d)\n", id, *type);
1345
1346         /* reset keyboard hardware */
1347         if (!(flags & KB_CONF_NO_RESET) && !reset_kbd(kbdc)) {
1348                 /*
1349                  * KEYBOARD ERROR
1350                  * Keyboard reset may fail either because the keyboard
1351                  * doen't exist, or because the keyboard doesn't pass
1352                  * the self-test, or the keyboard controller on the
1353                  * motherboard and the keyboard somehow fail to shake hands.
1354                  * It is just possible, particularly in the last case,
1355                  * that the keyboard controller may be left in a hung state.
1356                  * test_controller() and test_kbd_port() appear to bring
1357                  * the keyboard controller back (I don't know why and how,
1358                  * though.)
1359                  */
1360                 empty_both_buffers(kbdc, 10);
1361                 test_controller(kbdc);
1362                 test_kbd_port(kbdc);
1363                 /*
1364                  * We could disable the keyboard port and interrupt... but, 
1365                  * the keyboard may still exist (see above). 
1366                  */
1367                 set_controller_command_byte(kbdc, 0xff, c);
1368                 kbdc_lock(kbdc, FALSE);
1369                 if (bootverbose)
1370                         printf("atkbd: failed to reset the keyboard.\n");
1371                 return EIO;
1372         }
1373
1374         /*
1375          * Allow us to set the XT_KEYBD flag so that keyboards
1376          * such as those on the IBM ThinkPad laptop computers can be used
1377          * with the standard console driver.
1378          */
1379         if (codeset == 1) {
1380                 if (send_kbd_command_and_data(kbdc,
1381                         KBDC_SET_SCANCODE_SET, codeset) == KBD_ACK) {
1382                         /* XT kbd doesn't need scan code translation */
1383                         c &= ~KBD_TRANSLATION;
1384                 } else {
1385                         /*
1386                          * KEYBOARD ERROR 
1387                          * The XT kbd isn't usable unless the proper scan
1388                          * code set is selected. 
1389                          */
1390                         set_controller_command_byte(kbdc, 0xff, c);
1391                         kbdc_lock(kbdc, FALSE);
1392                         printf("atkbd: unable to set the XT keyboard mode.\n");
1393                         return EIO;
1394                 }
1395         }
1396
1397 #if defined(__sparc64__)
1398         if (send_kbd_command_and_data(
1399                 kbdc, KBDC_SET_SCANCODE_SET, 2) != KBD_ACK) {
1400                 printf("atkbd: can't set translation.\n");
1401         }
1402         c |= KBD_TRANSLATION;
1403 #endif
1404
1405         /* enable the keyboard port and intr. */
1406         if (!set_controller_command_byte(kbdc, 
1407                 KBD_KBD_CONTROL_BITS | KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK,
1408                 (c & (KBD_TRANSLATION | KBD_OVERRIDE_KBD_LOCK))
1409                     | KBD_ENABLE_KBD_PORT | KBD_ENABLE_KBD_INT)) {
1410                 /*
1411                  * CONTROLLER ERROR 
1412                  * This is serious; we are left with the disabled
1413                  * keyboard intr. 
1414                  */
1415                 set_controller_command_byte(kbdc, 0xff, c);
1416                 kbdc_lock(kbdc, FALSE);
1417                 printf("atkbd: unable to enable the keyboard port and intr.\n");
1418                 return EIO;
1419         }
1420
1421         kbdc_lock(kbdc, FALSE);
1422         return 0;
1423 }
1424
1425 static int
1426 write_kbd(KBDC kbdc, int command, int data)
1427 {
1428         int s;
1429
1430         /* prevent the timeout routine from polling the keyboard */
1431         if (!kbdc_lock(kbdc, TRUE)) 
1432                 return EBUSY;
1433
1434         /* disable the keyboard and mouse interrupt */
1435         s = spltty();
1436 #if 0
1437         c = get_controller_command_byte(kbdc);
1438         if ((c == -1) 
1439             || !set_controller_command_byte(kbdc, 
1440                 kbdc_get_device_mask(kbdc),
1441                 KBD_DISABLE_KBD_PORT | KBD_DISABLE_KBD_INT
1442                 | KBD_DISABLE_AUX_PORT | KBD_DISABLE_AUX_INT)) {
1443                 /* CONTROLLER ERROR */
1444                 kbdc_lock(kbdc, FALSE);
1445                 splx(s);
1446                 return EIO;
1447         }
1448         /* 
1449          * Now that the keyboard controller is told not to generate 
1450          * the keyboard and mouse interrupts, call `splx()' to allow 
1451          * the other tty interrupts. The clock interrupt may also occur, 
1452          * but the timeout routine (`scrn_timer()') will be blocked 
1453          * by the lock flag set via `kbdc_lock()'
1454          */
1455         splx(s);
1456 #endif
1457         if (send_kbd_command_and_data(kbdc, command, data) != KBD_ACK)
1458                 send_kbd_command(kbdc, KBDC_ENABLE_KBD);
1459 #if 0
1460         /* restore the interrupts */
1461         if (!set_controller_command_byte(kbdc, kbdc_get_device_mask(kbdc),
1462             c & (KBD_KBD_CONTROL_BITS | KBD_AUX_CONTROL_BITS))) { 
1463                 /* CONTROLLER ERROR */
1464         }
1465 #else
1466         splx(s);
1467 #endif
1468         kbdc_lock(kbdc, FALSE);
1469
1470         return 0;
1471 }
1472
1473 static int
1474 get_kbd_id(KBDC kbdc)
1475 {
1476         int id1, id2;
1477
1478         empty_both_buffers(kbdc, 10);
1479         id1 = id2 = -1;
1480         if (send_kbd_command(kbdc, KBDC_SEND_DEV_ID) != KBD_ACK)
1481                 return -1;
1482
1483         DELAY(10000);   /* 10 msec delay */
1484         id1 = read_kbd_data(kbdc);
1485         if (id1 != -1)
1486                 id2 = read_kbd_data(kbdc);
1487
1488         if ((id1 == -1) || (id2 == -1)) {
1489                 empty_both_buffers(kbdc, 10);
1490                 test_controller(kbdc);
1491                 test_kbd_port(kbdc);
1492                 return -1;
1493         }
1494         return ((id2 << 8) | id1);
1495 }
1496
1497 static int delays[] = { 250, 500, 750, 1000 };
1498 static int rates[] = {  34,  38,  42,  46,  50,  55,  59,  63,
1499                         68,  76,  84,  92, 100, 110, 118, 126,
1500                        136, 152, 168, 184, 200, 220, 236, 252,
1501                        272, 304, 336, 368, 400, 440, 472, 504 };
1502
1503 static int
1504 typematic_delay(int i)
1505 {
1506         return delays[(i >> 5) & 3];
1507 }
1508
1509 static int
1510 typematic_rate(int i)
1511 {
1512         return rates[i & 0x1f];
1513 }
1514
1515 static int
1516 typematic(int delay, int rate)
1517 {
1518         int value;
1519         int i;
1520
1521         for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; --i) {
1522                 if (delay >= delays[i])
1523                         break;
1524         }
1525         value = i << 5;
1526         for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; --i) {
1527                 if (rate >= rates[i])
1528                         break;
1529         }
1530         value |= i;
1531         return value;
1532 }