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