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