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