xref: /dragonfly/sys/dev/misc/kbdmux/kbdmux.c (revision 235099c3)
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 	c = kbdmux_kbd_getc(state);
605 	KBDMUX_UNLOCK(state);
606 
607 	if (c != -1)
608 		kbd->kb_count ++;
609 
610 	return (KBD_IS_ACTIVE(kbd)? c : -1);
611 }
612 
613 /*
614  * Check if data is waiting
615  */
616 static int
617 kbdmux_check(keyboard_t *kbd)
618 {
619 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
620 	int		 ready;
621 
622 	if (!KBD_IS_ACTIVE(kbd))
623 		return (FALSE);
624 
625 	KBDMUX_LOCK(state);
626 	ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
627 	KBDMUX_UNLOCK(state);
628 
629 	return (ready);
630 }
631 
632 /*
633  * Read char from the keyboard (stolen from atkbd.c)
634  */
635 static u_int
636 kbdmux_read_char(keyboard_t *kbd, int wait)
637 {
638 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
639 	u_int		 action;
640 	int		 scancode, keycode;
641 
642 	KBDMUX_LOCK(state);
643 
644 next_code:
645 
646 	/* do we have a composed char to return? */
647 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
648 		action = state->ks_composed_char;
649 		state->ks_composed_char = 0;
650 		if (action > UCHAR_MAX) {
651 			KBDMUX_UNLOCK(state);
652 
653 			return (ERRKEY);
654 		}
655 
656 		KBDMUX_UNLOCK(state);
657 
658 		return (action);
659 	}
660 
661 	/* see if there is something in the keyboard queue */
662 	scancode = kbdmux_kbd_getc(state);
663 	if (scancode == -1) {
664 		if (state->ks_flags & POLLING) {
665 			kbdmux_kbd_t	*k;
666 
667 			SLIST_FOREACH(k, &state->ks_kbds, next) {
668 				while (kbd_check_char(k->kbd)) {
669 					scancode = kbd_read_char(k->kbd, 0);
670 					if (scancode == NOKEY)
671 						break;
672 					if (scancode == ERRKEY)
673 						continue;
674 					if (!KBD_IS_BUSY(k->kbd))
675 						continue;
676 
677 					kbdmux_kbd_putc(state, scancode);
678 				}
679 			}
680 
681 			if (state->ks_inq_length > 0)
682 				goto next_code;
683 		}
684 
685 		KBDMUX_UNLOCK(state);
686 		return (NOKEY);
687 	}
688 	/* XXX FIXME: check for -1 if wait == 1! */
689 
690 	kbd->kb_count ++;
691 
692 	/* return the byte as is for the K_RAW mode */
693 	if (state->ks_mode == K_RAW) {
694 		KBDMUX_UNLOCK(state);
695 		return (scancode);
696 	}
697 
698 	/* translate the scan code into a keycode */
699 	keycode = scancode & 0x7F;
700 	switch (state->ks_prefix) {
701 	case 0x00:	/* normal scancode */
702 		switch(scancode) {
703 		case 0xB8:	/* left alt (compose key) released */
704 			if (state->ks_flags & COMPOSE) {
705 				state->ks_flags &= ~COMPOSE;
706 				if (state->ks_composed_char > UCHAR_MAX)
707 					state->ks_composed_char = 0;
708 			}
709 			break;
710 		case 0x38:	/* left alt (compose key) pressed */
711 			if (!(state->ks_flags & COMPOSE)) {
712 				state->ks_flags |= COMPOSE;
713 				state->ks_composed_char = 0;
714 			}
715 			break;
716 		case 0xE0:
717 		case 0xE1:
718 			state->ks_prefix = scancode;
719 			goto next_code;
720 		}
721 		break;
722 	case 0xE0:      /* 0xE0 prefix */
723 		state->ks_prefix = 0;
724 		switch (keycode) {
725 		case 0x1C:	/* right enter key */
726 			keycode = 0x59;
727 			break;
728 		case 0x1D:	/* right ctrl key */
729 			keycode = 0x5A;
730 			break;
731 		case 0x35:	/* keypad divide key */
732 			keycode = 0x5B;
733 			break;
734 		case 0x37:	/* print scrn key */
735 			keycode = 0x5C;
736 			break;
737 		case 0x38:	/* right alt key (alt gr) */
738 			keycode = 0x5D;
739 			break;
740 		case 0x46:	/* ctrl-pause/break on AT 101 (see below) */
741 			keycode = 0x68;
742 			break;
743 		case 0x47:	/* grey home key */
744 			keycode = 0x5E;
745 			break;
746 		case 0x48:	/* grey up arrow key */
747 			keycode = 0x5F;
748 			break;
749 		case 0x49:	/* grey page up key */
750 			keycode = 0x60;
751 			break;
752 		case 0x4B:	/* grey left arrow key */
753 			keycode = 0x61;
754 			break;
755 		case 0x4D:	/* grey right arrow key */
756 			keycode = 0x62;
757 			break;
758 		case 0x4F:	/* grey end key */
759 			keycode = 0x63;
760 			break;
761 		case 0x50:	/* grey down arrow key */
762 			keycode = 0x64;
763 			break;
764 		case 0x51:	/* grey page down key */
765 			keycode = 0x65;
766 			break;
767 		case 0x52:	/* grey insert key */
768 			keycode = 0x66;
769 			break;
770 		case 0x53:	/* grey delete key */
771 			keycode = 0x67;
772 			break;
773 		/* the following 3 are only used on the MS "Natural" keyboard */
774 		case 0x5b:	/* left Window key */
775 			keycode = 0x69;
776 			break;
777 		case 0x5c:	/* right Window key */
778 			keycode = 0x6a;
779 			break;
780 		case 0x5d:	/* menu key */
781 			keycode = 0x6b;
782 			break;
783 		case 0x5e:	/* power key */
784 			keycode = 0x6d;
785 			break;
786 		case 0x5f:	/* sleep key */
787 			keycode = 0x6e;
788 			break;
789 		case 0x63:	/* wake key */
790 			keycode = 0x6f;
791 			break;
792 		case 0x64:	/* [JP106USB] backslash, underscore */
793 			keycode = 0x73;
794 			break;
795 		default:	/* ignore everything else */
796 			goto next_code;
797 		}
798 		break;
799 	case 0xE1:	/* 0xE1 prefix */
800 		/*
801 		 * The pause/break key on the 101 keyboard produces:
802 		 * E1-1D-45 E1-9D-C5
803 		 * Ctrl-pause/break produces:
804 		 * E0-46 E0-C6 (See above.)
805 		 */
806 		state->ks_prefix = 0;
807 		if (keycode == 0x1D)
808 			state->ks_prefix = 0x1D;
809 		goto next_code;
810 		/* NOT REACHED */
811 	case 0x1D:	/* pause / break */
812 		state->ks_prefix = 0;
813 		if (keycode != 0x45)
814 			goto next_code;
815 		keycode = 0x68;
816 		break;
817 	}
818 
819 	/* XXX assume 101/102 keys AT keyboard */
820 	switch (keycode) {
821 	case 0x5c:	/* print screen */
822 		if (state->ks_flags & ALTS)
823 			keycode = 0x54;	/* sysrq */
824 		break;
825 	case 0x68:	/* pause/break */
826 		if (state->ks_flags & CTLS)
827 			keycode = 0x6c;	/* break */
828 		break;
829 	}
830 
831 	/* return the key code in the K_CODE mode */
832 	if (state->ks_mode == K_CODE) {
833 		KBDMUX_UNLOCK(state);
834 		return (keycode | (scancode & 0x80));
835 	}
836 
837 	/* compose a character code */
838 	if (state->ks_flags & COMPOSE) {
839 		switch (keycode | (scancode & 0x80)) {
840 		/* key pressed, process it */
841 		case 0x47: case 0x48: case 0x49:	/* keypad 7,8,9 */
842 			state->ks_composed_char *= 10;
843 			state->ks_composed_char += keycode - 0x40;
844 			if (state->ks_composed_char > UCHAR_MAX) {
845 				KBDMUX_UNLOCK(state);
846 				return (ERRKEY);
847 			}
848 			goto next_code;
849 		case 0x4B: case 0x4C: case 0x4D:	/* keypad 4,5,6 */
850 			state->ks_composed_char *= 10;
851 			state->ks_composed_char += keycode - 0x47;
852 			if (state->ks_composed_char > UCHAR_MAX) {
853 				KBDMUX_UNLOCK(state);
854 				return (ERRKEY);
855 			}
856 			goto next_code;
857 		case 0x4F: case 0x50: case 0x51:	/* keypad 1,2,3 */
858 			state->ks_composed_char *= 10;
859 			state->ks_composed_char += keycode - 0x4E;
860 			if (state->ks_composed_char > UCHAR_MAX) {
861 				KBDMUX_UNLOCK(state);
862 				return (ERRKEY);
863 			}
864 			goto next_code;
865 		case 0x52:	/* keypad 0 */
866 			state->ks_composed_char *= 10;
867 			if (state->ks_composed_char > UCHAR_MAX) {
868 				KBDMUX_UNLOCK(state);
869 				return (ERRKEY);
870 			}
871 			goto next_code;
872 
873 		/* key released, no interest here */
874 		case 0xC7: case 0xC8: case 0xC9:	/* keypad 7,8,9 */
875 		case 0xCB: case 0xCC: case 0xCD:	/* keypad 4,5,6 */
876 		case 0xCF: case 0xD0: case 0xD1:	/* keypad 1,2,3 */
877 		case 0xD2:				/* keypad 0 */
878 			goto next_code;
879 
880 		case 0x38:				/* left alt key */
881 			break;
882 
883 		default:
884 			if (state->ks_composed_char > 0) {
885 				state->ks_flags &= ~COMPOSE;
886 				state->ks_composed_char = 0;
887 				KBDMUX_UNLOCK(state);
888 				return (ERRKEY);
889 			}
890 			break;
891 		}
892 	}
893 
894 	/* keycode to key action */
895 	action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
896 			&state->ks_state, &state->ks_accents);
897 	if (action == NOKEY)
898 		goto next_code;
899 
900 	KBDMUX_UNLOCK(state);
901 
902 	return (action);
903 }
904 
905 /*
906  * Check if char is waiting
907  */
908 static int
909 kbdmux_check_char(keyboard_t *kbd)
910 {
911 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
912 	int		 ready;
913 
914 	if (!KBD_IS_ACTIVE(kbd))
915 		return (FALSE);
916 
917 	KBDMUX_LOCK(state);
918 
919 	if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0))
920 		ready = TRUE;
921 	else
922 		ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
923 
924 	KBDMUX_UNLOCK(state);
925 
926 	return (ready);
927 }
928 
929 /*
930  * Keyboard ioctl's
931  */
932 static int
933 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
934 {
935 	static int	 delays[] = {
936 		250, 500, 750, 1000
937 	};
938 
939 	static int	 rates[]  =  {
940 		34,  38,  42,  46,  50,   55,  59,  63,
941 		68,  76,  84,  92,  100, 110, 118, 126,
942 		136, 152, 168, 184, 200, 220, 236, 252,
943 		272, 304, 336, 368, 400, 440, 472, 504
944 	};
945 
946 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
947 	kbdmux_kbd_t	*k;
948 	keyboard_info_t	*ki;
949 	int		 error = 0, mode;
950 
951 	if (state == NULL)
952 		return (ENXIO);
953 
954 	switch (cmd) {
955 	case KBADDKBD: /* add keyboard to the mux */
956 		ki = (keyboard_info_t *) arg;
957 
958 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
959 		    strcmp(ki->kb_name, "*") == 0)
960 			return (EINVAL); /* bad input */
961 
962 		KBDMUX_LOCK(state);
963 
964 		SLIST_FOREACH(k, &state->ks_kbds, next)
965 			if (k->kbd->kb_unit == ki->kb_unit &&
966 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
967 				break;
968 
969 		if (k != NULL) {
970 			KBDMUX_UNLOCK(state);
971 
972 			return (0); /* keyboard already in the mux */
973 		}
974 
975 		k = kmalloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
976 		if (k == NULL) {
977 			KBDMUX_UNLOCK(state);
978 
979 			return (ENOMEM); /* out of memory */
980 		}
981 
982 		k->kbd = kbd_get_keyboard(
983 				kbd_allocate(
984 					ki->kb_name,
985 					ki->kb_unit,
986 					(void *) &k->kbd,
987 					kbdmux_kbd_event, (void *) state));
988 		if (k->kbd == NULL) {
989 			KBDMUX_UNLOCK(state);
990 			kfree(k, M_KBDMUX);
991 
992 			return (EINVAL); /* bad keyboard */
993 		}
994 
995 		kbd_enable(k->kbd);
996 		kbd_clear_state(k->kbd);
997 
998 		/* set K_RAW mode on slave keyboard */
999 		mode = K_RAW;
1000 		error = kbd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
1001 		if (error == 0) {
1002 			/* set lock keys state on slave keyboard */
1003 			mode = state->ks_state & LOCK_MASK;
1004 			error = kbd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
1005 		}
1006 
1007 		if (error != 0) {
1008 			KBDMUX_UNLOCK(state);
1009 
1010 			kbd_release(k->kbd, &k->kbd);
1011 			k->kbd = NULL;
1012 
1013 			kfree(k, M_KBDMUX);
1014 
1015 			return (error); /* could not set mode */
1016 		}
1017 
1018 		SLIST_INSERT_HEAD(&state->ks_kbds, k, next);
1019 
1020 		KBDMUX_UNLOCK(state);
1021 		break;
1022 
1023 	case KBRELKBD: /* release keyboard from the mux */
1024 		ki = (keyboard_info_t *) arg;
1025 
1026 		if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
1027 		    strcmp(ki->kb_name, "*") == 0)
1028 			return (EINVAL); /* bad input */
1029 
1030 		KBDMUX_LOCK(state);
1031 
1032 		SLIST_FOREACH(k, &state->ks_kbds, next)
1033 			if (k->kbd->kb_unit == ki->kb_unit &&
1034 			    strcmp(k->kbd->kb_name, ki->kb_name) == 0)
1035 				break;
1036 
1037 		if (k != NULL) {
1038 			error = kbd_release(k->kbd, &k->kbd);
1039 			if (error == 0) {
1040 				SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
1041 
1042 				k->kbd = NULL;
1043 
1044 				kfree(k, M_KBDMUX);
1045 			}
1046 		} else
1047 			error = ENXIO; /* keyboard is not in the mux */
1048 
1049 		KBDMUX_UNLOCK(state);
1050 		break;
1051 
1052 	case KDGKBMODE: /* get kyboard mode */
1053 		KBDMUX_LOCK(state);
1054 		*(int *)arg = state->ks_mode;
1055 		KBDMUX_UNLOCK(state);
1056 		break;
1057 
1058 	case KDSKBMODE: /* set keyboard mode */
1059 		KBDMUX_LOCK(state);
1060 
1061 		switch (*(int *)arg) {
1062 		case K_XLATE:
1063 			if (state->ks_mode != K_XLATE) {
1064 				/* make lock key state and LED state match */
1065 				state->ks_state &= ~LOCK_MASK;
1066 				state->ks_state |= KBD_LED_VAL(kbd);
1067                         }
1068                         /* FALLTHROUGH */
1069 
1070 		case K_RAW:
1071 		case K_CODE:
1072 			if (state->ks_mode != *(int *)arg) {
1073 				kbdmux_clear_state_locked(state);
1074 				state->ks_mode = *(int *)arg;
1075 			}
1076 			break;
1077 
1078                 default:
1079 			error = EINVAL;
1080 			break;
1081 		}
1082 
1083 		KBDMUX_UNLOCK(state);
1084 		break;
1085 
1086 	case KDGETLED: /* get keyboard LED */
1087 		KBDMUX_LOCK(state);
1088 		*(int *)arg = KBD_LED_VAL(kbd);
1089 		KBDMUX_UNLOCK(state);
1090 		break;
1091 
1092 	case KDSETLED: /* set keyboard LED */
1093 		KBDMUX_LOCK(state);
1094 
1095 		/* NOTE: lock key state in ks_state won't be changed */
1096 		if (*(int *)arg & ~LOCK_MASK) {
1097 			KBDMUX_UNLOCK(state);
1098 
1099 			return (EINVAL);
1100 		}
1101 
1102 		KBD_LED_VAL(kbd) = *(int *)arg;
1103 
1104 		/* KDSETLED on all slave keyboards */
1105 		SLIST_FOREACH(k, &state->ks_kbds, next)
1106 			kbd_ioctl(k->kbd, KDSETLED, arg);
1107 
1108 		KBDMUX_UNLOCK(state);
1109 		break;
1110 
1111 	case KDGKBSTATE: /* get lock key state */
1112 		KBDMUX_LOCK(state);
1113 		*(int *)arg = state->ks_state & LOCK_MASK;
1114 		KBDMUX_UNLOCK(state);
1115 		break;
1116 
1117 	case KDSKBSTATE: /* set lock key state */
1118 		KBDMUX_LOCK(state);
1119 
1120 		if (*(int *)arg & ~LOCK_MASK) {
1121 			KBDMUX_UNLOCK(state);
1122 
1123 			return (EINVAL);
1124 		}
1125 
1126 		state->ks_state &= ~LOCK_MASK;
1127 		state->ks_state |= *(int *)arg;
1128 
1129 		/* KDSKBSTATE on all slave keyboards */
1130 		SLIST_FOREACH(k, &state->ks_kbds, next)
1131 			kbd_ioctl(k->kbd, KDSKBSTATE, arg);
1132 
1133 		KBDMUX_UNLOCK(state);
1134 
1135 		return (kbdmux_ioctl(kbd, KDSETLED, arg));
1136 		/* NOT REACHED */
1137 
1138 	case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
1139 	case KDSETRAD: /* set keyboard repeat rate (old interface) */
1140 		KBDMUX_LOCK(state);
1141 
1142 		if (cmd == KDSETREPEAT) {
1143 			int	i;
1144 
1145 			/* lookup delay */
1146 			for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --)
1147 				if (((int *)arg)[0] >= delays[i])
1148 					break;
1149 			mode = i << 5;
1150 
1151 			/* lookup rate */
1152 			for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --)
1153 				if (((int *)arg)[1] >= rates[i])
1154 					break;
1155 			mode |= i;
1156 		} else
1157 			mode = *(int *)arg;
1158 
1159 		if (mode & ~0x7f) {
1160 			KBDMUX_UNLOCK(state);
1161 
1162 			return (EINVAL);
1163 		}
1164 
1165 		kbd->kb_delay1 = delays[(mode >> 5) & 3];
1166 		kbd->kb_delay2 = rates[mode & 0x1f];
1167 
1168 		/* perform command on all slave keyboards */
1169 		SLIST_FOREACH(k, &state->ks_kbds, next)
1170 			kbd_ioctl(k->kbd, cmd, arg);
1171 
1172 		KBDMUX_UNLOCK(state);
1173 		break;
1174 
1175 	case PIO_KEYMAP:	/* set keyboard translation table */
1176 	case PIO_KEYMAPENT:	/* set keyboard translation table entry */
1177 	case PIO_DEADKEYMAP:	/* set accent key translation table */
1178 		KBDMUX_LOCK(state);
1179                 state->ks_accents = 0;
1180 
1181 		/* perform command on all slave keyboards */
1182 		SLIST_FOREACH(k, &state->ks_kbds, next)
1183 			kbd_ioctl(k->kbd, cmd, arg);
1184 
1185 		KBDMUX_UNLOCK(state);
1186                 /* FALLTHROUGH */
1187 
1188 	default:
1189 		error = genkbd_commonioctl(kbd, cmd, arg);
1190 		break;
1191 	}
1192 
1193 	return (error);
1194 }
1195 
1196 /*
1197  * Lock the access to the keyboard
1198  */
1199 static int
1200 kbdmux_lock(keyboard_t *kbd, int lock)
1201 {
1202 	return (1); /* XXX */
1203 }
1204 
1205 /*
1206  * Clear the internal state of the keyboard
1207  */
1208 static void
1209 kbdmux_clear_state_locked(kbdmux_state_t *state)
1210 {
1211 	KBDMUX_LOCK_ASSERT(state, MA_OWNED);
1212 
1213 	state->ks_flags &= ~(COMPOSE|POLLING);
1214 	state->ks_state &= LOCK_MASK;	/* preserve locking key state */
1215 	state->ks_accents = 0;
1216 	state->ks_composed_char = 0;
1217 /*	state->ks_prefix = 0;		XXX */
1218 	state->ks_inq_length = 0;
1219 }
1220 
1221 static void
1222 kbdmux_clear_state(keyboard_t *kbd)
1223 {
1224 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1225 
1226 	KBDMUX_LOCK(state);
1227 	kbdmux_clear_state_locked(state);
1228 	KBDMUX_UNLOCK(state);
1229 }
1230 
1231 /*
1232  * Save the internal state
1233  */
1234 static int
1235 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len)
1236 {
1237 	if (len == 0)
1238 		return (sizeof(kbdmux_state_t));
1239 	if (len < sizeof(kbdmux_state_t))
1240 		return (-1);
1241 
1242 	bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */
1243 
1244 	return (0);
1245 }
1246 
1247 /*
1248  * Set the internal state
1249  */
1250 static int
1251 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len)
1252 {
1253 	if (len < sizeof(kbdmux_state_t))
1254 		return (ENOMEM);
1255 
1256 	bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */
1257 
1258 	return (0);
1259 }
1260 
1261 /*
1262  * Set polling
1263  */
1264 static int
1265 kbdmux_poll(keyboard_t *kbd, int on)
1266 {
1267 	kbdmux_state_t	*state = (kbdmux_state_t *) kbd->kb_data;
1268 	kbdmux_kbd_t	*k;
1269 
1270 	KBDMUX_LOCK(state);
1271 
1272 	if (on)
1273 		state->ks_flags |= POLLING;
1274 	else
1275 		state->ks_flags &= ~POLLING;
1276 
1277 	/* set poll on slave keyboards */
1278 	SLIST_FOREACH(k, &state->ks_kbds, next)
1279 		kbd_poll(k->kbd, on);
1280 
1281 	KBDMUX_UNLOCK(state);
1282 
1283 	return (0);
1284 }
1285 
1286 /*****************************************************************************
1287  *****************************************************************************
1288  **                                    Module
1289  *****************************************************************************
1290  *****************************************************************************/
1291 
1292 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure);
1293 
1294 static int
1295 kbdmux_modevent(module_t mod, int type, void *data)
1296 {
1297 	keyboard_switch_t	*sw;
1298 	keyboard_t		*kbd;
1299 	int			 error;
1300 
1301 	switch (type) {
1302 	case MOD_LOAD:
1303 		if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0)
1304 			break;
1305 
1306 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) {
1307 			kbd_delete_driver(&kbdmux_kbd_driver);
1308 			error = ENXIO;
1309 			break;
1310 		}
1311 
1312 		kbd = NULL;
1313 
1314 		if ((error = (*sw->probe)(0, NULL, 0)) != 0 ||
1315 		    (error = (*sw->init)(0, &kbd, NULL, 0)) != 0) {
1316 			kbd_delete_driver(&kbdmux_kbd_driver);
1317 			break;
1318 		}
1319 
1320 #ifdef KBD_INSTALL_CDEV
1321 		if ((error = kbd_attach(kbd)) != 0) {
1322 			(*sw->term)(kbd);
1323 			kbd_delete_driver(&kbdmux_kbd_driver);
1324 			break;
1325 		}
1326 #endif
1327 
1328 		if ((error = (*sw->enable)(kbd)) != 0) {
1329 			(*sw->disable)(kbd);
1330 #ifdef KBD_INSTALL_CDEV
1331 			kbd_detach(kbd);
1332 #endif
1333 			(*sw->term)(kbd);
1334 			kbd_delete_driver(&kbdmux_kbd_driver);
1335 			break;
1336 		}
1337 		break;
1338 
1339 	case MOD_UNLOAD:
1340 		if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
1341 			panic("kbd_get_switch(" KEYBOARD_NAME ") == NULL");
1342 
1343 		kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0));
1344 		if (kbd != NULL) {
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 		}
1352 		error = 0;
1353 		break;
1354 
1355 	default:
1356 		error = EOPNOTSUPP;
1357 		break;
1358 	}
1359 
1360 	return (error);
1361 }
1362 
1363 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
1364