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