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