xref: /dragonfly/sys/dev/misc/kbdmux/kbdmux.c (revision e6e77800)
1 /*-
2  * (MPSAFE)
3  *
4  * Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  *
28  * $Id: kbdmux.c,v 1.4 2005/07/14 17:38:35 max Exp $
29  * $FreeBSD$
30  */
31 
32 #include "opt_kbd.h"
33 
34 #include <sys/param.h>
35 #include <sys/bus.h>
36 #include <sys/conf.h>
37 #include <sys/consio.h>
38 #include <sys/fcntl.h>
39 #include <sys/kbio.h>
40 #include <sys/kernel.h>
41 #include <sys/limits.h>
42 #include <sys/lock.h>
43 #include <sys/malloc.h>
44 #include <sys/module.h>
45 #include <sys/mutex.h>
46 #include <sys/poll.h>
47 #include <sys/proc.h>
48 #include <sys/queue.h>
49 #include <sys/event.h>
50 #include <sys/systm.h>
51 #include <sys/taskqueue.h>
52 #include <sys/uio.h>
53 #include <dev/misc/kbd/kbdreg.h>
54 #include <dev/misc/kbd/kbdtables.h>
55 
56 #define KEYBOARD_NAME	"kbdmux"
57 
58 MALLOC_DECLARE(M_KBDMUX);
59 MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
60 
61 /*****************************************************************************
62  *****************************************************************************
63  **                             Keyboard state
64  *****************************************************************************
65  *****************************************************************************/
66 
67 #define	KBDMUX_Q_SIZE	512	/* input queue size */
68 
69 #define KBDMUX_CALLOUT_INIT(s) \
70 	callout_init_mp(&(s)->ks_timo)
71 
72 #define KBDMUX_QUEUE_INTR(s) \
73 	taskqueue_enqueue(taskqueue_swi, &(s)->ks_task)
74 
75 /*
76  * kbdmux keyboard
77  */
78 struct kbdmux_kbd
79 {
80 	keyboard_t		*kbd;	/* keyboard */
81 	SLIST_ENTRY(kbdmux_kbd)	 next;	/* link to next */
82 };
83 
84 typedef struct kbdmux_kbd	kbdmux_kbd_t;
85 
86 /*
87  * kbdmux state
88  */
89 struct kbdmux_state
90 {
91 	char			 ks_inq[KBDMUX_Q_SIZE]; /* input chars queue */
92 	unsigned int		 ks_inq_start;
93 	unsigned int		 ks_inq_length;
94 	struct task		 ks_task;	/* interrupt task */
95 	struct callout		 ks_timo;	/* timeout handler */
96 #define TICKS			(hz)		/* rate */
97 
98 	int			 ks_flags;	/* flags */
99 #define COMPOSE			(1 << 0)	/* compose char flag */
100 #define POLLING			(1 << 1)	/* polling */
101 #define TASK			(1 << 2)	/* interrupt task queued */
102 
103 	int			 ks_mode;	/* K_XLATE, K_RAW, K_CODE */
104 	int			 ks_state;	/* state */
105 	int			 ks_accents;	/* accent key index (> 0) */
106 	u_int			 ks_composed_char; /* composed char code */
107 	u_char			 ks_prefix;	/* AT scan code prefix */
108 
109 	SLIST_HEAD(, kbdmux_kbd) ks_kbds;	/* keyboards */
110 };
111 
112 typedef struct kbdmux_state	kbdmux_state_t;
113 
114 /*****************************************************************************
115  *****************************************************************************
116  **                             Helper functions
117  *****************************************************************************
118  *****************************************************************************/
119 
120 static task_fn_t		kbdmux_kbd_intr;
121 static timeout_t		kbdmux_kbd_intr_timo;
122 static kbd_callback_func_t	kbdmux_kbd_event;
123 
124 static void
125 kbdmux_kbd_putc(kbdmux_state_t *state, char c)
126 {
127 	unsigned int p;
128 
129 	if (state->ks_inq_length == KBDMUX_Q_SIZE)
130 		return;
131 
132 	p = (state->ks_inq_start + state->ks_inq_length) % KBDMUX_Q_SIZE;
133 	state->ks_inq[p] = c;
134 	state->ks_inq_length++;
135 }
136 
137 static int
138 kbdmux_kbd_getc(kbdmux_state_t *state)
139 {
140 	unsigned char c;
141 
142 	if (state->ks_inq_length == 0)
143 		return (-1);
144 
145 	c = state->ks_inq[state->ks_inq_start];
146 	state->ks_inq_start = (state->ks_inq_start + 1) % KBDMUX_Q_SIZE;
147 	state->ks_inq_length--;
148 
149 	return (c);
150 }
151 
152 /*
153  * Interrupt handler task
154  */
155 static void
156 kbdmux_kbd_intr(void *xkbd, int pending)
157 {
158 	keyboard_t	*kbd = (keyboard_t *) xkbd;
159 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
160 	KBD_LOCK_DECLARE;
161 
162 	KBD_LOCK(kbd);		/* recursive so ok */
163 	kbd_intr(kbd, NULL);
164 	state->ks_flags &= ~TASK;
165 	wakeup(&state->ks_task);
166 	KBD_UNLOCK(kbd);
167 }
168 
169 /*
170  * Schedule interrupt handler on timeout. Called with locked state.
171  */
172 static void
173 kbdmux_kbd_intr_timo(void *xkbd)
174 {
175 	keyboard_t	*kbd = (keyboard_t *) xkbd;
176 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
177 	KBD_LOCK_DECLARE;
178 
179 	KBD_LOCK(kbd);
180 
181 	if (callout_pending(&state->ks_timo)) {
182 		KBD_UNLOCK(kbd);
183 		return; /* callout was reset */
184 	}
185 
186 	if (!callout_active(&state->ks_timo)) {
187 		KBD_UNLOCK(kbd);
188 		return; /* callout was stopped */
189 	}
190 
191 	callout_deactivate(&state->ks_timo);
192 
193 	/* queue interrupt task if needed */
194 	if (state->ks_inq_length > 0 && !(state->ks_flags & TASK) &&
195 	    KBDMUX_QUEUE_INTR(state) == 0)
196 		state->ks_flags |= TASK;
197 
198 	/* re-schedule timeout */
199 	callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, kbd);
200 	KBD_UNLOCK(kbd);
201 }
202 
203 /*
204  * Process event from one of our keyboards
205  */
206 static int
207 kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg)
208 {
209 	kbdmux_state_t	*state = (kbdmux_state_t *) arg;
210 
211 	switch (event) {
212 	case KBDIO_KEYINPUT: {
213 		int	c;
214 
215 		/*
216 		 * Read all chars from the keyboard
217 		 *
218 		 * Turns out that atkbd(4) check_char() method may return
219 		 * "true" while read_char() method returns NOKEY. If this
220 		 * happens we could stuck in the loop below. Avoid this
221 		 * by breaking out of the loop if read_char() method returns
222 		 * NOKEY.
223 		 */
224 
225 		while (kbd_check_char(kbd)) {
226 			c = kbd_read_char(kbd, 0);
227 			if (c == NOKEY)
228 				break;
229 			if (c == ERRKEY)
230 				continue; /* XXX ring bell */
231 			if (!KBD_IS_BUSY(kbd))
232 				continue; /* not open - discard the input */
233 
234 			kbdmux_kbd_putc(state, c);
235 		}
236 
237 		/* queue interrupt task if needed */
238 		if (state->ks_inq_length > 0 && !(state->ks_flags & TASK) &&
239 		    KBDMUX_QUEUE_INTR(state) == 0)
240 			state->ks_flags |= TASK;
241 
242 		} break;
243 
244 	case KBDIO_UNLOADING: {
245 		kbdmux_kbd_t	*k;
246 
247 		SLIST_FOREACH(k, &state->ks_kbds, next)
248 			if (k->kbd == kbd)
249 				break;
250 
251 		if (k != NULL) {
252 			kbd_release(k->kbd, &k->kbd);
253 			SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
254 
255 			k->kbd = NULL;
256 
257 			kfree(k, M_KBDMUX);
258 		}
259 
260 		} break;
261 
262 	default:
263 		return (EINVAL);
264 		/* NOT REACHED */
265 	}
266 	return (0);
267 }
268 
269 /****************************************************************************
270  ****************************************************************************
271  **                              Keyboard driver
272  ****************************************************************************
273  ****************************************************************************/
274 
275 static int		kbdmux_configure(int flags);
276 static kbd_probe_t	kbdmux_probe;
277 static kbd_init_t	kbdmux_init;
278 static kbd_term_t	kbdmux_term;
279 static kbd_intr_t	kbdmux_intr;
280 static kbd_test_if_t	kbdmux_test_if;
281 static kbd_enable_t	kbdmux_enable;
282 static kbd_disable_t	kbdmux_disable;
283 static kbd_read_t	kbdmux_read;
284 static kbd_check_t	kbdmux_check;
285 static kbd_read_char_t	kbdmux_read_char;
286 static kbd_check_char_t	kbdmux_check_char;
287 static kbd_ioctl_t	kbdmux_ioctl;
288 static kbd_lock_t	kbdmux_lock;
289 static kbd_clear_state_t kbdmux_clear_state;
290 static kbd_get_state_t	kbdmux_get_state;
291 static kbd_set_state_t	kbdmux_set_state;
292 static kbd_poll_mode_t	kbdmux_poll;
293 
294 static keyboard_switch_t kbdmuxsw = {
295 	.probe =	kbdmux_probe,
296 	.init =		kbdmux_init,
297 	.term =		kbdmux_term,
298 	.intr =		kbdmux_intr,
299 	.test_if =	kbdmux_test_if,
300 	.enable =	kbdmux_enable,
301 	.disable =	kbdmux_disable,
302 	.read =		kbdmux_read,
303 	.check =	kbdmux_check,
304 	.read_char =	kbdmux_read_char,
305 	.check_char =	kbdmux_check_char,
306 	.ioctl =	kbdmux_ioctl,
307 	.lock =		kbdmux_lock,
308 	.clear_state =	kbdmux_clear_state,
309 	.get_state =	kbdmux_get_state,
310 	.set_state =	kbdmux_set_state,
311 	.get_fkeystr =	genkbd_get_fkeystr,
312 	.poll =		kbdmux_poll,
313 	.diag =		genkbd_diag,
314 };
315 
316 /*
317  * Return the number of found keyboards
318  */
319 static int
320 kbdmux_configure(int flags)
321 {
322 	return (1);
323 }
324 
325 /*
326  * Detect a keyboard
327  */
328 static int
329 kbdmux_probe(int unit, void *arg, int flags)
330 {
331 	if (resource_disabled(KEYBOARD_NAME, unit))
332 		return (ENXIO);
333 
334 	return (0);
335 }
336 
337 /*
338  * Reset and initialize the keyboard (stolen from atkbd.c)
339  *
340  * Called without kbd lock held.
341  */
342 static int
343 kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
344 {
345 	kbdmux_state_t	*state = NULL;
346 	keymap_t	*keymap = NULL;
347         accentmap_t	*accmap = NULL;
348         fkeytab_t	*fkeymap = NULL;
349 	keyboard_t	*kbd = NULL;
350 	int		 error, needfree, fkeymap_size, delay[2];
351 
352 	if (*kbdp == NULL) {
353 		*kbdp = kbd = kmalloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
354 		state = kmalloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO);
355 		keymap = kmalloc(sizeof(key_map), M_KBDMUX, M_NOWAIT);
356 		accmap = kmalloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT);
357 		fkeymap = kmalloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT);
358 		fkeymap_size = NELEM(fkey_tab);
359 		needfree = 1;
360 
361 		if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
362 		    (accmap == NULL) || (fkeymap == NULL)) {
363 			error = ENOMEM;
364 			goto bad;
365 		}
366 
367 		TASK_INIT(&state->ks_task, 0, kbdmux_kbd_intr, (void *) kbd);
368 		KBDMUX_CALLOUT_INIT(state);
369 		SLIST_INIT(&state->ks_kbds);
370 	} else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
371 		return (0);
372 	} else {
373 		kbd = *kbdp;
374 		state = (kbdmux_state_t *) kbd->kb_data;
375 		keymap = kbd->kb_keymap;
376 		accmap = kbd->kb_accentmap;
377 		fkeymap = kbd->kb_fkeytab;
378 		fkeymap_size = kbd->kb_fkeytab_size;
379 		needfree = 0;
380 	}
381 
382 	if (!KBD_IS_PROBED(kbd)) {
383 		/* XXX assume 101/102 keys keyboard */
384 		kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags,
385 			    KB_PRI_MUX, 0, 0);
386 		bcopy(&key_map, keymap, sizeof(key_map));
387 		bcopy(&accent_map, accmap, sizeof(accent_map));
388 		bcopy(fkey_tab, fkeymap,
389 			imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
390 		kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
391 		kbd->kb_data = (void *)state;
392 
393 		KBD_FOUND_DEVICE(kbd);
394 		KBD_PROBE_DONE(kbd);
395 
396 		kbdmux_clear_state(kbd);
397 		state->ks_mode = K_XLATE;
398 	}
399 
400 	if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
401 		kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
402 
403 		kbdmux_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
404 
405 		delay[0] = kbd->kb_delay1;
406 		delay[1] = kbd->kb_delay2;
407 		kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
408 
409 		KBD_INIT_DONE(kbd);
410 	}
411 
412 	if (!KBD_IS_CONFIGURED(kbd)) {
413 		if (kbd_register(kbd) < 0) {
414 			error = ENXIO;
415 			goto bad;
416 		}
417 
418 		KBD_CONFIG_DONE(kbd);
419 
420 		callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, kbd);
421 	}
422 
423 	return (0);
424 bad:
425 	if (needfree) {
426 		if (state != NULL)
427 			kfree(state, M_KBDMUX);
428 		if (keymap != NULL)
429 			kfree(keymap, M_KBDMUX);
430 		if (accmap != NULL)
431 			kfree(accmap, M_KBDMUX);
432 		if (fkeymap != NULL)
433 			kfree(fkeymap, M_KBDMUX);
434 		if (kbd != NULL) {
435 			kfree(kbd, M_KBDMUX);
436 			*kbdp = NULL;	/* insure ref doesn't leak to caller */
437 		}
438 	}
439 
440 	return (error);
441 }
442 
443 /*
444  * Finish using this keyboard
445  *
446  * NOTE: deregistration automatically unlocks lock.
447  */
448 static int
449 kbdmux_term(keyboard_t *kbd)
450 {
451 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
452 	kbdmux_kbd_t	*k;
453 
454 	/* kill callout */
455 	callout_stop(&state->ks_timo);
456 
457 	/* wait for interrupt task */
458 	while (state->ks_flags & TASK)
459 		lksleep(&state->ks_task, &kbd->kb_lock, PCATCH, "kbdmuxc", 0);
460 
461 	/* release all keyboards from the mux */
462 	while ((k = SLIST_FIRST(&state->ks_kbds)) != NULL) {
463 		kbd_release(k->kbd, &k->kbd);
464 		SLIST_REMOVE_HEAD(&state->ks_kbds, next);
465 
466 		k->kbd = NULL;
467 
468 		kfree(k, M_KBDMUX);
469 	}
470 
471 	kbd_unregister(kbd);
472 
473 	bzero(state, sizeof(*state));
474 	kfree(state, M_KBDMUX);
475 
476 	kfree(kbd->kb_keymap, M_KBDMUX);
477 	kfree(kbd->kb_accentmap, M_KBDMUX);
478 	kfree(kbd->kb_fkeytab, M_KBDMUX);
479 	kfree(kbd, M_KBDMUX);
480 
481 	return (0);
482 }
483 
484 /*
485  * Keyboard interrupt routine
486  */
487 static int
488 kbdmux_intr(keyboard_t *kbd, void *arg)
489 {
490 	int	c;
491 
492 	if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
493 		/* let the callback function to process the input */
494 		(*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
495 					    kbd->kb_callback.kc_arg);
496 	} else {
497 		/* read and discard the input; no one is waiting for input */
498 		do {
499 			c = kbdmux_read_char(kbd, FALSE);
500 		} while (c != NOKEY);
501 	}
502 
503 	return (0);
504 }
505 
506 /*
507  * Test the interface to the device
508  */
509 static int
510 kbdmux_test_if(keyboard_t *kbd)
511 {
512 	return (0);
513 }
514 
515 /*
516  * Enable the access to the device; until this function is called,
517  * the client cannot read from the keyboard.
518  */
519 static int
520 kbdmux_enable(keyboard_t *kbd)
521 {
522 	KBD_ACTIVATE(kbd);
523 	return (0);
524 }
525 
526 /*
527  * Disallow the access to the device
528  */
529 static int
530 kbdmux_disable(keyboard_t *kbd)
531 {
532 	KBD_DEACTIVATE(kbd);
533 	return (0);
534 }
535 
536 /*
537  * Read one byte from the keyboard if it's allowed
538  */
539 static int
540 kbdmux_read(keyboard_t *kbd, int wait)
541 {
542 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
543 	int		 c, ret;
544 
545 	do {
546 		c = kbdmux_kbd_getc(state);
547 	} while (c == -1 && wait);
548 
549 	if (c != -1)
550 		kbd->kb_count++;
551 
552 	ret = (KBD_IS_ACTIVE(kbd)? c : -1);
553 
554 	return ret;
555 }
556 
557 /*
558  * Check if data is waiting
559  */
560 static int
561 kbdmux_check(keyboard_t *kbd)
562 {
563 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
564 	int		 ready;
565 
566 	if (!KBD_IS_ACTIVE(kbd))
567 		return (FALSE);
568 
569 	ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
570 
571 	return (ready);
572 }
573 
574 /*
575  * Read char from the keyboard (stolen from atkbd.c)
576  *
577  * Note: We do not attempt to detect the case where no keyboards are
578  *	 present in the wait case.  If the kernel is sitting at the
579  *	 debugger prompt we want someone to be able to plug in a keyboard
580  *	 and have it work, and not just panic or fall through or do
581  *	 something equally nasty.
582  */
583 static u_int
584 kbdmux_read_char(keyboard_t *kbd, int wait)
585 {
586 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
587 	u_int		 action;
588 	int		 scancode, keycode;
589 
590 next_code:
591 
592 	/* do we have a composed char to return? */
593 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
594 		action = state->ks_composed_char;
595 		state->ks_composed_char = 0;
596 		if (action > UCHAR_MAX) {
597 			return (ERRKEY);
598 		}
599 		return (action);
600 	}
601 
602 	/*
603 	 * See if there is something in the keyboard queue
604 	 */
605 	scancode = kbdmux_kbd_getc(state);
606 
607 	if (scancode == -1) {
608 		if (state->ks_flags & POLLING) {
609 			kbdmux_kbd_t	*k;
610 
611 			SLIST_FOREACH(k, &state->ks_kbds, next) {
612 				while (kbd_check_char(k->kbd)) {
613 					scancode = kbd_read_char(k->kbd, 0);
614 					if (scancode == ERRKEY)
615 						continue;
616 					if (scancode == NOKEY)
617 						break;
618 					if (!KBD_IS_BUSY(k->kbd))
619 						continue;
620 					kbdmux_kbd_putc(state, scancode);
621 				}
622 			}
623 
624 			if (state->ks_inq_length > 0)
625 				goto next_code;
626 			if (wait)
627 				goto next_code;
628 		} else {
629 			if (wait) {
630 				lksleep(&state->ks_task, &kbd->kb_lock, PCATCH,
631 				    "kbdwai", hz/10);
632 				goto next_code;
633 			}
634 		}
635 		return (NOKEY);
636 	}
637 
638 	kbd->kb_count++;
639 
640 	/* return the byte as is for the K_RAW mode */
641 	if (state->ks_mode == K_RAW)
642 		return (scancode);
643 
644 	/* translate the scan code into a keycode */
645 	keycode = scancode & 0x7F;
646 	switch (state->ks_prefix) {
647 	case 0x00:	/* normal scancode */
648 		switch(scancode) {
649 		case 0xB8:	/* left alt (compose key) released */
650 			if (state->ks_flags & COMPOSE) {
651 				state->ks_flags &= ~COMPOSE;
652 				if (state->ks_composed_char > UCHAR_MAX)
653 					state->ks_composed_char = 0;
654 			}
655 			break;
656 		case 0x38:	/* left alt (compose key) pressed */
657 			if (!(state->ks_flags & COMPOSE)) {
658 				state->ks_flags |= COMPOSE;
659 				state->ks_composed_char = 0;
660 			}
661 			break;
662 		case 0xE0:
663 		case 0xE1:
664 			state->ks_prefix = scancode;
665 			goto next_code;
666 		}
667 		break;
668 	case 0xE0:      /* 0xE0 prefix */
669 		state->ks_prefix = 0;
670 		switch (keycode) {
671 		case 0x1C:	/* right enter key */
672 			keycode = 0x59;
673 			break;
674 		case 0x1D:	/* right ctrl key */
675 			keycode = 0x5A;
676 			break;
677 		case 0x35:	/* keypad divide key */
678 			keycode = 0x5B;
679 			break;
680 		case 0x37:	/* print scrn key */
681 			keycode = 0x5C;
682 			break;
683 		case 0x38:	/* right alt key (alt gr) */
684 			keycode = 0x5D;
685 			break;
686 		case 0x46:	/* ctrl-pause/break on AT 101 (see below) */
687 			keycode = 0x68;
688 			break;
689 		case 0x47:	/* grey home key */
690 			keycode = 0x5E;
691 			break;
692 		case 0x48:	/* grey up arrow key */
693 			keycode = 0x5F;
694 			break;
695 		case 0x49:	/* grey page up key */
696 			keycode = 0x60;
697 			break;
698 		case 0x4B:	/* grey left arrow key */
699 			keycode = 0x61;
700 			break;
701 		case 0x4D:	/* grey right arrow key */
702 			keycode = 0x62;
703 			break;
704 		case 0x4F:	/* grey end key */
705 			keycode = 0x63;
706 			break;
707 		case 0x50:	/* grey down arrow key */
708 			keycode = 0x64;
709 			break;
710 		case 0x51:	/* grey page down key */
711 			keycode = 0x65;
712 			break;
713 		case 0x52:	/* grey insert key */
714 			keycode = 0x66;
715 			break;
716 		case 0x53:	/* grey delete key */
717 			keycode = 0x67;
718 			break;
719 		/* the following 3 are only used on the MS "Natural" keyboard */
720 		case 0x5b:	/* left Window key */
721 			keycode = 0x69;
722 			break;
723 		case 0x5c:	/* right Window key */
724 			keycode = 0x6a;
725 			break;
726 		case 0x5d:	/* menu key */
727 			keycode = 0x6b;
728 			break;
729 		case 0x5e:	/* power key */
730 			keycode = 0x6d;
731 			break;
732 		case 0x5f:	/* sleep key */
733 			keycode = 0x6e;
734 			break;
735 		case 0x63:	/* wake key */
736 			keycode = 0x6f;
737 			break;
738 		case 0x64:	/* [JP106USB] backslash, underscore */
739 			keycode = 0x73;
740 			break;
741 		default:	/* ignore everything else */
742 			goto next_code;
743 		}
744 		break;
745 	case 0xE1:	/* 0xE1 prefix */
746 		/*
747 		 * The pause/break key on the 101 keyboard produces:
748 		 * E1-1D-45 E1-9D-C5
749 		 * Ctrl-pause/break produces:
750 		 * E0-46 E0-C6 (See above.)
751 		 */
752 		state->ks_prefix = 0;
753 		if (keycode == 0x1D)
754 			state->ks_prefix = 0x1D;
755 		goto next_code;
756 		/* NOT REACHED */
757 	case 0x1D:	/* pause / break */
758 		state->ks_prefix = 0;
759 		if (keycode != 0x45)
760 			goto next_code;
761 		keycode = 0x68;
762 		break;
763 	}
764 
765 	/* XXX assume 101/102 keys AT keyboard */
766 	switch (keycode) {
767 	case 0x5c:	/* print screen */
768 		if (state->ks_flags & ALTS)
769 			keycode = 0x54;	/* sysrq */
770 		break;
771 	case 0x68:	/* pause/break */
772 		if (state->ks_flags & CTLS)
773 			keycode = 0x6c;	/* break */
774 		break;
775 	}
776 
777 	/* return the key code in the K_CODE mode */
778 	if (state->ks_mode == K_CODE)
779 		return (keycode | (scancode & 0x80));
780 
781 	/* compose a character code */
782 	if (state->ks_flags & COMPOSE) {
783 		switch (keycode | (scancode & 0x80)) {
784 		/* key pressed, process it */
785 		case 0x47: case 0x48: case 0x49:	/* keypad 7,8,9 */
786 			state->ks_composed_char *= 10;
787 			state->ks_composed_char += keycode - 0x40;
788 			if (state->ks_composed_char > UCHAR_MAX)
789 				return (ERRKEY);
790 			goto next_code;
791 		case 0x4B: case 0x4C: case 0x4D:	/* keypad 4,5,6 */
792 			state->ks_composed_char *= 10;
793 			state->ks_composed_char += keycode - 0x47;
794 			if (state->ks_composed_char > UCHAR_MAX)
795 				return (ERRKEY);
796 			goto next_code;
797 		case 0x4F: case 0x50: case 0x51:	/* keypad 1,2,3 */
798 			state->ks_composed_char *= 10;
799 			state->ks_composed_char += keycode - 0x4E;
800 			if (state->ks_composed_char > UCHAR_MAX)
801 				return (ERRKEY);
802 			goto next_code;
803 		case 0x52:	/* keypad 0 */
804 			state->ks_composed_char *= 10;
805 			if (state->ks_composed_char > UCHAR_MAX)
806 				return (ERRKEY);
807 			goto next_code;
808 
809 		/* key released, no interest here */
810 		case 0xC7: case 0xC8: case 0xC9:	/* keypad 7,8,9 */
811 		case 0xCB: case 0xCC: case 0xCD:	/* keypad 4,5,6 */
812 		case 0xCF: case 0xD0: case 0xD1:	/* keypad 1,2,3 */
813 		case 0xD2:				/* keypad 0 */
814 			goto next_code;
815 
816 		case 0x38:				/* left alt key */
817 			break;
818 
819 		default:
820 			if (state->ks_composed_char > 0) {
821 				state->ks_flags &= ~COMPOSE;
822 				state->ks_composed_char = 0;
823 				return (ERRKEY);
824 			}
825 			break;
826 		}
827 	}
828 
829 	/* keycode to key action */
830 	action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
831 			&state->ks_state, &state->ks_accents);
832 	if (action == NOKEY)
833 		goto next_code;
834 
835 	return (action);
836 }
837 
838 /*
839  * Check if char is waiting
840  */
841 static int
842 kbdmux_check_char(keyboard_t *kbd)
843 {
844 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
845 	int		 ready;
846 
847 	if (!KBD_IS_ACTIVE(kbd))
848 		return (FALSE);
849 
850 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0))
851 		ready = TRUE;
852 	else
853 		ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
854 
855 	return (ready);
856 }
857 
858 /*
859  * Keyboard ioctl's
860  */
861 static int
862 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
863 {
864 	static int	 delays[] = {
865 		250, 500, 750, 1000
866 	};
867 
868 	static int	 rates[]  =  {
869 		34,  38,  42,  46,  50,   55,  59,  63,
870 		68,  76,  84,  92,  100, 110, 118, 126,
871 		136, 152, 168, 184, 200, 220, 236, 252,
872 		272, 304, 336, 368, 400, 440, 472, 504
873 	};
874 
875 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
876 	kbdmux_kbd_t	*k;
877 	keyboard_info_t	*ki;
878 	int		 error = 0, mode;
879 
880 	if (state == NULL)
881 		return (ENXIO);
882 
883 	switch (cmd) {
884 	case KBADDKBD: /* add keyboard to the mux */
885 		ki = (keyboard_info_t *) arg;
886 
887 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
888 		    strcmp(ki->kb_name, "*") == 0) {
889 			return (EINVAL); /* bad input */
890 		}
891 
892 		SLIST_FOREACH(k, &state->ks_kbds, next)
893 			if (k->kbd->kb_unit == ki->kb_unit &&
894 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
895 				break;
896 
897 		if (k != NULL)
898 			return (0); /* keyboard already in the mux */
899 
900 		k = kmalloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
901 		if (k == NULL)
902 			return (ENOMEM); /* out of memory */
903 
904 		k->kbd = kbd_get_keyboard(
905 				kbd_allocate(
906 					ki->kb_name,
907 					ki->kb_unit,
908 					(void *) &k->kbd,
909 					kbdmux_kbd_event, (void *) state));
910 		if (k->kbd == NULL) {
911 			kfree(k, M_KBDMUX);
912 			return (EINVAL); /* bad keyboard */
913 		}
914 
915 		kbd_enable(k->kbd);
916 		kbd_clear_state(k->kbd);
917 
918 		/* set K_RAW mode on slave keyboard */
919 		mode = K_RAW;
920 		error = kbd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
921 		if (error == 0) {
922 			/* set lock keys state on slave keyboard */
923 			mode = state->ks_state & LOCK_MASK;
924 			error = kbd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
925 		}
926 
927 		if (error != 0) {
928 			kbd_release(k->kbd, &k->kbd);
929 			k->kbd = NULL;
930 			kfree(k, M_KBDMUX);
931 			return (error); /* could not set mode */
932 		}
933 
934 		SLIST_INSERT_HEAD(&state->ks_kbds, k, next);
935 		break;
936 
937 	case KBRELKBD: /* release keyboard from the mux */
938 		ki = (keyboard_info_t *) arg;
939 
940 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
941 		    strcmp(ki->kb_name, "*") == 0) {
942 			return (EINVAL); /* bad input */
943 		}
944 
945 		SLIST_FOREACH(k, &state->ks_kbds, next)
946 			if (k->kbd->kb_unit == ki->kb_unit &&
947 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
948 				break;
949 
950 		if (k != NULL) {
951 			error = kbd_release(k->kbd, &k->kbd);
952 			if (error == 0) {
953 				SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
954 
955 				k->kbd = NULL;
956 
957 				kfree(k, M_KBDMUX);
958 			}
959 		} else
960 			error = ENXIO; /* keyboard is not in the mux */
961 
962 		break;
963 
964 	case KDGKBMODE: /* get kyboard mode */
965 		*(int *)arg = state->ks_mode;
966 		break;
967 
968 	case KDSKBMODE: /* set keyboard mode */
969 		switch (*(int *)arg) {
970 		case K_XLATE:
971 			if (state->ks_mode != K_XLATE) {
972 				/* make lock key state and LED state match */
973 				state->ks_state &= ~LOCK_MASK;
974 				state->ks_state |= KBD_LED_VAL(kbd);
975                         }
976                         /* FALLTHROUGH */
977 
978 		case K_RAW:
979 		case K_CODE:
980 			if (state->ks_mode != *(int *)arg) {
981 				kbdmux_clear_state(kbd);
982 				state->ks_mode = *(int *)arg;
983 			}
984 			break;
985 
986                 default:
987 			error = EINVAL;
988 			break;
989 		}
990 		break;
991 
992 	case KDGETLED: /* get keyboard LED */
993 		*(int *)arg = KBD_LED_VAL(kbd);
994 		break;
995 
996 	case KDSETLED: /* set keyboard LED */
997 		/* NOTE: lock key state in ks_state won't be changed */
998 		if (*(int *)arg & ~LOCK_MASK)
999 			return (EINVAL);
1000 
1001 		KBD_LED_VAL(kbd) = *(int *)arg;
1002 
1003 		/* KDSETLED on all slave keyboards */
1004 		SLIST_FOREACH(k, &state->ks_kbds, next)
1005 			kbd_ioctl(k->kbd, KDSETLED, arg);
1006 		break;
1007 
1008 	case KDGKBSTATE: /* get lock key state */
1009 		*(int *)arg = state->ks_state & LOCK_MASK;
1010 		break;
1011 
1012 	case KDSKBSTATE: /* set lock key state */
1013 		if (*(int *)arg & ~LOCK_MASK)
1014 			return (EINVAL);
1015 
1016 		state->ks_state &= ~LOCK_MASK;
1017 		state->ks_state |= *(int *)arg;
1018 
1019 		/* KDSKBSTATE on all slave keyboards */
1020 		SLIST_FOREACH(k, &state->ks_kbds, next)
1021 			kbd_ioctl(k->kbd, KDSKBSTATE, arg);
1022 
1023 		return (kbdmux_ioctl(kbd, KDSETLED, arg));
1024 		/* NOT REACHED */
1025 
1026 	case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
1027 	case KDSETRAD: /* set keyboard repeat rate (old interface) */
1028 		if (cmd == KDSETREPEAT) {
1029 			int	i;
1030 
1031 			/* lookup delay */
1032 			for (i = NELEM(delays) - 1; i > 0; i --)
1033 				if (((int *)arg)[0] >= delays[i])
1034 					break;
1035 			mode = i << 5;
1036 
1037 			/* lookup rate */
1038 			for (i = NELEM(rates) - 1; i > 0; i --)
1039 				if (((int *)arg)[1] >= rates[i])
1040 					break;
1041 			mode |= i;
1042 		} else
1043 			mode = *(int *)arg;
1044 
1045 		if (mode & ~0x7f)
1046 			return (EINVAL);
1047 
1048 		kbd->kb_delay1 = delays[(mode >> 5) & 3];
1049 		kbd->kb_delay2 = rates[mode & 0x1f];
1050 
1051 		/* perform command on all slave keyboards */
1052 		SLIST_FOREACH(k, &state->ks_kbds, next)
1053 			kbd_ioctl(k->kbd, cmd, arg);
1054 		break;
1055 
1056 	case PIO_KEYMAP:	/* set keyboard translation table */
1057 	case PIO_KEYMAPENT:	/* set keyboard translation table entry */
1058 	case PIO_DEADKEYMAP:	/* set accent key translation table */
1059                 state->ks_accents = 0;
1060 
1061 		/* perform command on all slave keyboards */
1062 		SLIST_FOREACH(k, &state->ks_kbds, next)
1063 			kbd_ioctl(k->kbd, cmd, arg);
1064                 /* FALLTHROUGH */
1065 
1066 	default:
1067 		error = genkbd_commonioctl(kbd, cmd, arg);
1068 		break;
1069 	}
1070 	return (error);
1071 }
1072 
1073 /*
1074  * Lock the access to the keyboard
1075  */
1076 static int
1077 kbdmux_lock(keyboard_t *kbd, int lock)
1078 {
1079 	return (1); /* XXX */
1080 }
1081 
1082 /*
1083  * Clear the internal state of the keyboard
1084  *
1085  * NOTE: May be called unlocked from init
1086  */
1087 static void
1088 kbdmux_clear_state(keyboard_t *kbd)
1089 {
1090 	kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
1091 
1092 	state->ks_flags &= ~(COMPOSE|POLLING);
1093 	state->ks_state &= LOCK_MASK;	/* preserve locking key state */
1094 	state->ks_accents = 0;
1095 	state->ks_composed_char = 0;
1096 /*	state->ks_prefix = 0;		XXX */
1097 	state->ks_inq_length = 0;
1098 }
1099 
1100 /*
1101  * Save the internal state
1102  */
1103 static int
1104 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len)
1105 {
1106 	if (len == 0)
1107 		return (sizeof(kbdmux_state_t));
1108 	if (len < sizeof(kbdmux_state_t))
1109 		return (-1);
1110 
1111 	bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */
1112 
1113 	return (0);
1114 }
1115 
1116 /*
1117  * Set the internal state
1118  */
1119 static int
1120 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len)
1121 {
1122 	if (len < sizeof(kbdmux_state_t))
1123 		return (ENOMEM);
1124 
1125 	bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */
1126 
1127 	return (0);
1128 }
1129 
1130 /*
1131  * Set polling
1132  *
1133  * Caller interlocks all keyboard calls.  We must not lock here.
1134  */
1135 static int
1136 kbdmux_poll(keyboard_t *kbd, int on)
1137 {
1138 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1139 	kbdmux_kbd_t	*k;
1140 
1141 	if (on)
1142 		state->ks_flags |= POLLING;
1143 	else
1144 		state->ks_flags &= ~POLLING;
1145 
1146 	/* set poll on slave keyboards */
1147 	SLIST_FOREACH(k, &state->ks_kbds, next)
1148 		kbd_poll(k->kbd, on);
1149 
1150 	return (0);
1151 }
1152 
1153 /*****************************************************************************
1154  *****************************************************************************
1155  **                                    Module
1156  *****************************************************************************
1157  *****************************************************************************/
1158 
1159 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure);
1160 
1161 static int
1162 kbdmux_modevent(module_t mod, int type, void *data)
1163 {
1164 	keyboard_switch_t	*sw;
1165 	keyboard_t		*kbd;
1166 	int			 error;
1167 
1168 	switch (type) {
1169 	case MOD_LOAD:
1170 		if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0)
1171 			break;
1172 
1173 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) {
1174 			kbd_delete_driver(&kbdmux_kbd_driver);
1175 			error = ENXIO;
1176 			break;
1177 		}
1178 
1179 		kbd = NULL;
1180 
1181 		if ((error = (*sw->probe)(0, NULL, 0)) != 0 ||
1182 		    (error = (*sw->init)(0, &kbd, NULL, 0)) != 0) {
1183 			kbd_delete_driver(&kbdmux_kbd_driver);
1184 			break;
1185 		}
1186 
1187 #ifdef KBD_INSTALL_CDEV
1188 		if ((error = kbd_attach(kbd)) != 0) {
1189 			(*sw->term)(kbd);
1190 			kbd_delete_driver(&kbdmux_kbd_driver);
1191 			break;
1192 		}
1193 #endif
1194 
1195 		if ((error = (*sw->enable)(kbd)) != 0) {
1196 			(*sw->disable)(kbd);
1197 #ifdef KBD_INSTALL_CDEV
1198 			kbd_detach(kbd);
1199 #endif
1200 			(*sw->term)(kbd);
1201 			kbd_delete_driver(&kbdmux_kbd_driver);
1202 			break;
1203 		}
1204 		break;
1205 
1206 	case MOD_UNLOAD:
1207 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
1208 			panic("kbd_get_switch(" KEYBOARD_NAME ") == NULL");
1209 
1210 		kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0));
1211 		if (kbd != NULL) {
1212 			(*sw->disable)(kbd);
1213 #ifdef KBD_INSTALL_CDEV
1214 			kbd_detach(kbd);
1215 #endif
1216 			(*sw->term)(kbd);
1217 			kbd_delete_driver(&kbdmux_kbd_driver);
1218 		}
1219 		error = 0;
1220 		break;
1221 
1222 	default:
1223 		error = EOPNOTSUPP;
1224 		break;
1225 	}
1226 	return (error);
1227 }
1228 
1229 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
1230