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