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