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