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