]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/kbdmux/kbdmux.c
Upgrade Unbound to 1.6.1. More to follow.
[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 const struct evdev_methods kbdmux_evdev_methods = {
388         .ev_event = evdev_ev_kbd_event,
389 };
390 #endif
391
392 /*
393  * Return the number of found keyboards
394  */
395 static int
396 kbdmux_configure(int flags)
397 {
398         return (1);
399 }
400
401 /*
402  * Detect a keyboard
403  */
404 static int
405 kbdmux_probe(int unit, void *arg, int flags)
406 {
407         if (resource_disabled(KEYBOARD_NAME, unit))
408                 return (ENXIO);
409
410         return (0);
411 }
412
413 /*
414  * Reset and initialize the keyboard (stolen from atkbd.c)
415  */
416 static int
417 kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
418 {
419         keyboard_t      *kbd = NULL;
420         kbdmux_state_t  *state = NULL;
421         keymap_t        *keymap = NULL;
422         accentmap_t     *accmap = NULL;
423         fkeytab_t       *fkeymap = NULL;
424         int              error, needfree, fkeymap_size, delay[2];
425 #ifdef EVDEV_SUPPORT
426         struct evdev_dev *evdev;
427         char             phys_loc[NAMELEN];
428 #endif
429
430         if (*kbdp == NULL) {
431                 *kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO);
432                 state = malloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO);
433                 keymap = malloc(sizeof(key_map), M_KBDMUX, M_NOWAIT);
434                 accmap = malloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT);
435                 fkeymap = malloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT);
436                 fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]);
437                 needfree = 1;
438
439                 if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
440                     (accmap == NULL) || (fkeymap == NULL)) {
441                         error = ENOMEM;
442                         goto bad;
443                 }
444
445                 KBDMUX_LOCK_INIT(state);
446                 TASK_INIT(&state->ks_task, 0, kbdmux_kbd_intr, (void *) kbd);
447                 KBDMUX_CALLOUT_INIT(state);
448                 SLIST_INIT(&state->ks_kbds);
449         } else if (KBD_IS_INITIALIZED(*kbdp) && KBD_IS_CONFIGURED(*kbdp)) {
450                 return (0);
451         } else {
452                 kbd = *kbdp;
453                 state = (kbdmux_state_t *) kbd->kb_data;
454                 keymap = kbd->kb_keymap;
455                 accmap = kbd->kb_accentmap;
456                 fkeymap = kbd->kb_fkeytab;
457                 fkeymap_size = kbd->kb_fkeytab_size;
458                 needfree = 0;
459         }
460
461         if (!KBD_IS_PROBED(kbd)) {
462                 /* XXX assume 101/102 keys keyboard */
463                 kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, 0, 0);
464                 bcopy(&key_map, keymap, sizeof(key_map));
465                 bcopy(&accent_map, accmap, sizeof(accent_map));
466                 bcopy(fkey_tab, fkeymap,
467                         imin(fkeymap_size*sizeof(fkeymap[0]), sizeof(fkey_tab)));
468                 kbd_set_maps(kbd, keymap, accmap, fkeymap, fkeymap_size);
469                 kbd->kb_data = (void *)state;
470         
471                 KBD_FOUND_DEVICE(kbd);
472                 KBD_PROBE_DONE(kbd);
473
474                 KBDMUX_LOCK(state);
475                 kbdmux_clear_state_locked(state);
476                 state->ks_mode = K_XLATE;
477                 KBDMUX_UNLOCK(state);
478         }
479
480         if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
481                 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
482
483                 kbdmux_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
484
485                 delay[0] = kbd->kb_delay1;
486                 delay[1] = kbd->kb_delay2;
487                 kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
488
489 #ifdef EVDEV_SUPPORT
490                 /* register as evdev provider */
491                 evdev = evdev_alloc();
492                 evdev_set_name(evdev, "System keyboard multiplexer");
493                 snprintf(phys_loc, NAMELEN, KEYBOARD_NAME"%d", unit);
494                 evdev_set_phys(evdev, phys_loc);
495                 evdev_set_id(evdev, BUS_VIRTUAL, 0, 0, 0);
496                 evdev_set_methods(evdev, kbd, &kbdmux_evdev_methods);
497                 evdev_support_event(evdev, EV_SYN);
498                 evdev_support_event(evdev, EV_KEY);
499                 evdev_support_event(evdev, EV_LED);
500                 evdev_support_event(evdev, EV_REP);
501                 evdev_support_all_known_keys(evdev);
502                 evdev_support_led(evdev, LED_NUML);
503                 evdev_support_led(evdev, LED_CAPSL);
504                 evdev_support_led(evdev, LED_SCROLLL);
505
506                 if (evdev_register(evdev))
507                         evdev_free(evdev);
508                 else
509                         state->ks_evdev = evdev;
510                 state->ks_evdev_state = 0;
511 #endif
512
513                 KBD_INIT_DONE(kbd);
514         }
515
516         if (!KBD_IS_CONFIGURED(kbd)) {
517                 if (kbd_register(kbd) < 0) {
518                         error = ENXIO;
519                         goto bad;
520                 }
521
522                 KBD_CONFIG_DONE(kbd);
523
524                 KBDMUX_LOCK(state);
525                 callout_reset(&state->ks_timo, TICKS, kbdmux_kbd_intr_timo, state);
526                 KBDMUX_UNLOCK(state);
527         }
528
529         return (0);
530 bad:
531         if (needfree) {
532                 if (state != NULL)
533                         free(state, M_KBDMUX);
534                 if (keymap != NULL)
535                         free(keymap, M_KBDMUX);
536                 if (accmap != NULL)
537                         free(accmap, M_KBDMUX);
538                 if (fkeymap != NULL)
539                         free(fkeymap, M_KBDMUX);
540                 if (kbd != NULL) {
541                         free(kbd, M_KBDMUX);
542                         *kbdp = NULL;   /* insure ref doesn't leak to caller */
543                 }
544         }
545
546         return (error);
547 }
548
549 /*
550  * Finish using this keyboard
551  */
552 static int
553 kbdmux_term(keyboard_t *kbd)
554 {
555         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
556         kbdmux_kbd_t    *k;
557
558         KBDMUX_LOCK(state);
559
560         /* kill callout */
561         callout_stop(&state->ks_timo);
562
563         /* wait for interrupt task */
564         while (state->ks_flags & TASK)
565                 KBDMUX_SLEEP(state, ks_task, "kbdmuxc", 0);
566
567         /* release all keyboards from the mux */
568         while ((k = SLIST_FIRST(&state->ks_kbds)) != NULL) {
569                 kbd_release(k->kbd, &k->kbd);
570                 SLIST_REMOVE_HEAD(&state->ks_kbds, next);
571
572                 k->kbd = NULL;
573
574                 free(k, M_KBDMUX);
575         }
576
577         KBDMUX_UNLOCK(state);
578
579         kbd_unregister(kbd);
580
581 #ifdef EVDEV_SUPPORT
582         evdev_free(state->ks_evdev);
583 #endif
584
585         KBDMUX_LOCK_DESTROY(state);
586         bzero(state, sizeof(*state));
587         free(state, M_KBDMUX);
588
589         free(kbd->kb_keymap, M_KBDMUX);
590         free(kbd->kb_accentmap, M_KBDMUX);
591         free(kbd->kb_fkeytab, M_KBDMUX);
592         free(kbd, M_KBDMUX);
593
594         return (0);
595 }
596
597 /*
598  * Keyboard interrupt routine
599  */
600 static int
601 kbdmux_intr(keyboard_t *kbd, void *arg)
602 {
603         int     c;
604
605         if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) {
606                 /* let the callback function to process the input */
607                 (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT,
608                                             kbd->kb_callback.kc_arg);
609         } else {
610                 /* read and discard the input; no one is waiting for input */
611                 do {
612                         c = kbdmux_read_char(kbd, FALSE);
613                 } while (c != NOKEY);
614         }
615
616         return (0);
617 }
618
619 /*
620  * Test the interface to the device
621  */
622 static int
623 kbdmux_test_if(keyboard_t *kbd)
624 {
625         return (0);
626 }
627
628 /* 
629  * Enable the access to the device; until this function is called,
630  * the client cannot read from the keyboard.
631  */
632 static int
633 kbdmux_enable(keyboard_t *kbd)
634 {
635         KBD_ACTIVATE(kbd);
636         return (0);
637 }
638
639 /*
640  * Disallow the access to the device
641  */
642 static int
643 kbdmux_disable(keyboard_t *kbd)
644 {
645         KBD_DEACTIVATE(kbd);
646         return (0);
647 }
648
649 /*
650  * Read one byte from the keyboard if it's allowed
651  */
652 static int
653 kbdmux_read(keyboard_t *kbd, int wait)
654 {
655         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
656         int              c;
657
658         KBDMUX_LOCK(state);
659         c = kbdmux_kbd_getc(state);
660         KBDMUX_UNLOCK(state);
661
662         if (c != -1)
663                 kbd->kb_count ++;
664
665         return (KBD_IS_ACTIVE(kbd)? c : -1);
666 }
667
668 /*
669  * Check if data is waiting
670  */
671 static int
672 kbdmux_check(keyboard_t *kbd)
673 {
674         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
675         int              ready;
676
677         if (!KBD_IS_ACTIVE(kbd))
678                 return (FALSE);
679
680         KBDMUX_LOCK(state);
681         ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
682         KBDMUX_UNLOCK(state);
683
684         return (ready);
685 }
686
687 /*
688  * Read char from the keyboard (stolen from atkbd.c)
689  */
690 static u_int
691 kbdmux_read_char(keyboard_t *kbd, int wait)
692 {
693         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
694         u_int            action;
695         int              scancode, keycode;
696
697         KBDMUX_LOCK(state);
698
699 next_code:
700
701         /* do we have a composed char to return? */
702         if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) {
703                 action = state->ks_composed_char;
704                 state->ks_composed_char = 0;
705                 if (action > UCHAR_MAX) {
706                         KBDMUX_UNLOCK(state);
707
708                         return (ERRKEY);
709                 }
710
711                 KBDMUX_UNLOCK(state);
712
713                 return (action);
714         }
715
716         /* see if there is something in the keyboard queue */
717         scancode = kbdmux_kbd_getc(state);
718         if (scancode == -1) {
719                 if (state->ks_polling != 0) {
720                         kbdmux_kbd_t    *k;
721
722                         SLIST_FOREACH(k, &state->ks_kbds, next) {
723                                 while (kbdd_check_char(k->kbd)) {
724                                         scancode = kbdd_read_char(k->kbd, 0);
725                                         if (scancode == NOKEY)
726                                                 break;
727                                         if (scancode == ERRKEY)
728                                                 continue;
729                                         if (!KBD_IS_BUSY(k->kbd))
730                                                 continue; 
731
732                                         kbdmux_kbd_putc(state, scancode);
733                                 }
734                         }
735
736                         if (state->ks_inq_length > 0)
737                                 goto next_code;
738                 }
739
740                 KBDMUX_UNLOCK(state);
741                 return (NOKEY);
742         }
743         /* XXX FIXME: check for -1 if wait == 1! */
744
745         kbd->kb_count ++;
746
747 #ifdef EVDEV_SUPPORT
748         /* push evdev event */
749         if (evdev_rcpt_mask & EVDEV_RCPT_KBDMUX && state->ks_evdev != NULL) {
750                 uint16_t key = evdev_scancode2key(&state->ks_evdev_state,
751                     scancode);
752
753                 if (key != KEY_RESERVED) {
754                         evdev_push_event(state->ks_evdev, EV_KEY,
755                             key, scancode & 0x80 ? 0 : 1);
756                         evdev_sync(state->ks_evdev);
757                 }
758         }
759 #endif
760
761         /* return the byte as is for the K_RAW mode */
762         if (state->ks_mode == K_RAW) {
763                 KBDMUX_UNLOCK(state);
764                 return (scancode);
765         }
766
767         /* translate the scan code into a keycode */
768         keycode = scancode & 0x7F;
769         switch (state->ks_prefix) {
770         case 0x00:      /* normal scancode */
771                 switch(scancode) {
772                 case 0xB8:      /* left alt (compose key) released */
773                         if (state->ks_flags & COMPOSE) {
774                                 state->ks_flags &= ~COMPOSE;
775                                 if (state->ks_composed_char > UCHAR_MAX)
776                                         state->ks_composed_char = 0;
777                         }
778                         break;
779                 case 0x38:      /* left alt (compose key) pressed */
780                         if (!(state->ks_flags & COMPOSE)) {
781                                 state->ks_flags |= COMPOSE;
782                                 state->ks_composed_char = 0;
783                         }
784                         break;
785                 case 0xE0:
786                 case 0xE1:
787                         state->ks_prefix = scancode;
788                         goto next_code;
789                 }
790                 break;
791         case 0xE0:      /* 0xE0 prefix */
792                 state->ks_prefix = 0;
793                 switch (keycode) {
794                 case 0x1C:      /* right enter key */
795                         keycode = 0x59;
796                         break;
797                 case 0x1D:      /* right ctrl key */
798                         keycode = 0x5A;
799                         break;
800                 case 0x35:      /* keypad divide key */
801                         keycode = 0x5B;
802                         break;
803                 case 0x37:      /* print scrn key */
804                         keycode = 0x5C;
805                         break;
806                 case 0x38:      /* right alt key (alt gr) */
807                         keycode = 0x5D;
808                         break;
809                 case 0x46:      /* ctrl-pause/break on AT 101 (see below) */
810                         keycode = 0x68;
811                         break;
812                 case 0x47:      /* grey home key */
813                         keycode = 0x5E;
814                         break;
815                 case 0x48:      /* grey up arrow key */
816                         keycode = 0x5F;
817                         break;
818                 case 0x49:      /* grey page up key */
819                         keycode = 0x60;
820                         break;
821                 case 0x4B:      /* grey left arrow key */
822                         keycode = 0x61;
823                         break;
824                 case 0x4D:      /* grey right arrow key */
825                         keycode = 0x62;
826                         break;
827                 case 0x4F:      /* grey end key */
828                         keycode = 0x63;
829                         break;
830                 case 0x50:      /* grey down arrow key */
831                         keycode = 0x64;
832                         break;
833                 case 0x51:      /* grey page down key */
834                         keycode = 0x65;
835                         break;
836                 case 0x52:      /* grey insert key */
837                         keycode = 0x66;
838                         break;
839                 case 0x53:      /* grey delete key */
840                         keycode = 0x67;
841                         break;
842                 /* the following 3 are only used on the MS "Natural" keyboard */
843                 case 0x5b:      /* left Window key */
844                         keycode = 0x69;
845                         break;
846                 case 0x5c:      /* right Window key */
847                         keycode = 0x6a;
848                         break;
849                 case 0x5d:      /* menu key */
850                         keycode = 0x6b;
851                         break;
852                 case 0x5e:      /* power key */
853                         keycode = 0x6d;
854                         break;
855                 case 0x5f:      /* sleep key */
856                         keycode = 0x6e;
857                         break;
858                 case 0x63:      /* wake key */
859                         keycode = 0x6f;
860                         break;
861                 case 0x64:      /* [JP106USB] backslash, underscore */
862                         keycode = 0x73;
863                         break;
864                 default:        /* ignore everything else */
865                         goto next_code;
866                 }
867                 break;
868         case 0xE1:      /* 0xE1 prefix */
869                 /* 
870                  * The pause/break key on the 101 keyboard produces:
871                  * E1-1D-45 E1-9D-C5
872                  * Ctrl-pause/break produces:
873                  * E0-46 E0-C6 (See above.)
874                  */
875                 state->ks_prefix = 0;
876                 if (keycode == 0x1D)
877                         state->ks_prefix = 0x1D;
878                 goto next_code;
879                 /* NOT REACHED */
880         case 0x1D:      /* pause / break */
881                 state->ks_prefix = 0;
882                 if (keycode != 0x45)
883                         goto next_code;
884                 keycode = 0x68;
885                 break;
886         }
887
888         /* XXX assume 101/102 keys AT keyboard */
889         switch (keycode) {
890         case 0x5c:      /* print screen */
891                 if (state->ks_flags & ALTS)
892                         keycode = 0x54; /* sysrq */
893                 break;
894         case 0x68:      /* pause/break */
895                 if (state->ks_flags & CTLS)
896                         keycode = 0x6c; /* break */
897                 break;
898         }
899
900         /* return the key code in the K_CODE mode */
901         if (state->ks_mode == K_CODE) {
902                 KBDMUX_UNLOCK(state);
903                 return (keycode | (scancode & 0x80));
904         }
905
906         /* compose a character code */
907         if (state->ks_flags & COMPOSE) {
908                 switch (keycode | (scancode & 0x80)) {
909                 /* key pressed, process it */
910                 case 0x47: case 0x48: case 0x49:        /* keypad 7,8,9 */
911                         state->ks_composed_char *= 10;
912                         state->ks_composed_char += keycode - 0x40;
913                         if (state->ks_composed_char > UCHAR_MAX) {
914                                 KBDMUX_UNLOCK(state);
915                                 return (ERRKEY);
916                         }
917                         goto next_code;
918                 case 0x4B: case 0x4C: case 0x4D:        /* keypad 4,5,6 */
919                         state->ks_composed_char *= 10;
920                         state->ks_composed_char += keycode - 0x47;
921                         if (state->ks_composed_char > UCHAR_MAX) {
922                                 KBDMUX_UNLOCK(state);
923                                 return (ERRKEY);
924                         }
925                         goto next_code;
926                 case 0x4F: case 0x50: case 0x51:        /* keypad 1,2,3 */
927                         state->ks_composed_char *= 10;
928                         state->ks_composed_char += keycode - 0x4E;
929                         if (state->ks_composed_char > UCHAR_MAX) {
930                                 KBDMUX_UNLOCK(state);
931                                 return (ERRKEY);
932                         }
933                         goto next_code;
934                 case 0x52:      /* keypad 0 */
935                         state->ks_composed_char *= 10;
936                         if (state->ks_composed_char > UCHAR_MAX) {
937                                 KBDMUX_UNLOCK(state);
938                                 return (ERRKEY);
939                         }
940                         goto next_code;
941
942                 /* key released, no interest here */
943                 case 0xC7: case 0xC8: case 0xC9:        /* keypad 7,8,9 */
944                 case 0xCB: case 0xCC: case 0xCD:        /* keypad 4,5,6 */
945                 case 0xCF: case 0xD0: case 0xD1:        /* keypad 1,2,3 */
946                 case 0xD2:                              /* keypad 0 */
947                         goto next_code;
948
949                 case 0x38:                              /* left alt key */
950                         break;
951
952                 default:
953                         if (state->ks_composed_char > 0) {
954                                 state->ks_flags &= ~COMPOSE;
955                                 state->ks_composed_char = 0;
956                                 KBDMUX_UNLOCK(state);
957                                 return (ERRKEY);
958                         }
959                         break;
960                 }
961         }
962
963         /* keycode to key action */
964         action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
965                         &state->ks_state, &state->ks_accents);
966         if (action == NOKEY)
967                 goto next_code;
968
969         KBDMUX_UNLOCK(state);
970
971         return (action);
972 }
973
974 /*
975  * Check if char is waiting
976  */
977 static int
978 kbdmux_check_char(keyboard_t *kbd)
979 {
980         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
981         int              ready;
982
983         if (!KBD_IS_ACTIVE(kbd))
984                 return (FALSE);
985
986         KBDMUX_LOCK(state);
987
988         if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0))
989                 ready = TRUE;
990         else
991                 ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
992
993         KBDMUX_UNLOCK(state);
994
995         return (ready);
996 }
997
998 /*
999  * Keyboard ioctl's
1000  */
1001 static int
1002 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
1003 {
1004         static int       delays[] = {
1005                 250, 500, 750, 1000
1006         };
1007
1008         static int       rates[]  =  {
1009                 34,  38,  42,  46,  50,   55,  59,  63,
1010                 68,  76,  84,  92,  100, 110, 118, 126,
1011                 136, 152, 168, 184, 200, 220, 236, 252,
1012                 272, 304, 336, 368, 400, 440, 472, 504
1013         };
1014
1015         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
1016         kbdmux_kbd_t    *k;
1017         keyboard_info_t *ki;
1018         int              error = 0, mode;
1019 #ifdef COMPAT_FREEBSD6
1020         int              ival;
1021 #endif
1022
1023         if (state == NULL)
1024                 return (ENXIO);
1025
1026         switch (cmd) {
1027         case KBADDKBD: /* add keyboard to the mux */
1028                 ki = (keyboard_info_t *) arg;
1029
1030                 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
1031                     strcmp(ki->kb_name, "*") == 0)
1032                         return (EINVAL); /* bad input */
1033
1034                 KBDMUX_LOCK(state);
1035
1036                 SLIST_FOREACH(k, &state->ks_kbds, next)
1037                         if (k->kbd->kb_unit == ki->kb_unit &&
1038                             strcmp(k->kbd->kb_name, ki->kb_name) == 0)
1039                                 break;
1040
1041                 if (k != NULL) {
1042                         KBDMUX_UNLOCK(state);
1043
1044                         return (0); /* keyboard already in the mux */
1045                 }
1046
1047                 k = malloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
1048                 if (k == NULL) {
1049                         KBDMUX_UNLOCK(state);
1050
1051                         return (ENOMEM); /* out of memory */
1052                 }
1053
1054                 k->kbd = kbd_get_keyboard(
1055                                 kbd_allocate(
1056                                         ki->kb_name,
1057                                         ki->kb_unit,
1058                                         (void *) &k->kbd,
1059                                         kbdmux_kbd_event, (void *) state));
1060                 if (k->kbd == NULL) {
1061                         KBDMUX_UNLOCK(state);
1062                         free(k, M_KBDMUX);
1063
1064                         return (EINVAL); /* bad keyboard */
1065                 }
1066
1067                 kbdd_enable(k->kbd);
1068                 kbdd_clear_state(k->kbd);
1069
1070                 /* set K_RAW mode on slave keyboard */
1071                 mode = K_RAW;
1072                 error = kbdd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
1073                 if (error == 0) {
1074                         /* set lock keys state on slave keyboard */
1075                         mode = state->ks_state & LOCK_MASK;
1076                         error = kbdd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode);
1077                 }
1078
1079                 if (error != 0) {
1080                         KBDMUX_UNLOCK(state);
1081
1082                         kbd_release(k->kbd, &k->kbd);
1083                         k->kbd = NULL;
1084
1085                         free(k, M_KBDMUX);
1086
1087                         return (error); /* could not set mode */
1088                 }
1089
1090                 SLIST_INSERT_HEAD(&state->ks_kbds, k, next);
1091
1092                 KBDMUX_UNLOCK(state);
1093                 break;
1094
1095         case KBRELKBD: /* release keyboard from the mux */
1096                 ki = (keyboard_info_t *) arg;
1097
1098                 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
1099                     strcmp(ki->kb_name, "*") == 0)
1100                         return (EINVAL); /* bad input */
1101
1102                 KBDMUX_LOCK(state);
1103
1104                 SLIST_FOREACH(k, &state->ks_kbds, next)
1105                         if (k->kbd->kb_unit == ki->kb_unit &&
1106                             strcmp(k->kbd->kb_name, ki->kb_name) == 0)
1107                                 break;
1108
1109                 if (k != NULL) {
1110                         error = kbd_release(k->kbd, &k->kbd);
1111                         if (error == 0) {
1112                                 SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
1113
1114                                 k->kbd = NULL;
1115
1116                                 free(k, M_KBDMUX);
1117                         }
1118                 } else
1119                         error = ENXIO; /* keyboard is not in the mux */
1120
1121                 KBDMUX_UNLOCK(state);
1122                 break;
1123
1124         case KDGKBMODE: /* get kyboard mode */
1125                 KBDMUX_LOCK(state);
1126                 *(int *)arg = state->ks_mode;
1127                 KBDMUX_UNLOCK(state);
1128                 break;
1129
1130 #ifdef COMPAT_FREEBSD6
1131         case _IO('K', 7):
1132                 ival = IOCPARM_IVAL(arg);
1133                 arg = (caddr_t)&ival;
1134                 /* FALLTHROUGH */
1135 #endif
1136         case KDSKBMODE: /* set keyboard mode */
1137                 KBDMUX_LOCK(state);
1138
1139                 switch (*(int *)arg) {
1140                 case K_XLATE:
1141                         if (state->ks_mode != K_XLATE) {
1142                                 /* make lock key state and LED state match */
1143                                 state->ks_state &= ~LOCK_MASK;
1144                                 state->ks_state |= KBD_LED_VAL(kbd);
1145                         }
1146                         /* FALLTHROUGH */
1147
1148                 case K_RAW:
1149                 case K_CODE:
1150                         if (state->ks_mode != *(int *)arg) {
1151                                 kbdmux_clear_state_locked(state);
1152                                 state->ks_mode = *(int *)arg;
1153                         }
1154                         break;
1155
1156                 default:
1157                         error = EINVAL;
1158                         break;
1159                 }
1160
1161                 KBDMUX_UNLOCK(state);
1162                 break;
1163
1164         case KDGETLED: /* get keyboard LED */
1165                 KBDMUX_LOCK(state);
1166                 *(int *)arg = KBD_LED_VAL(kbd);
1167                 KBDMUX_UNLOCK(state);
1168                 break;
1169
1170 #ifdef COMPAT_FREEBSD6
1171         case _IO('K', 66):
1172                 ival = IOCPARM_IVAL(arg);
1173                 arg = (caddr_t)&ival;
1174                 /* FALLTHROUGH */
1175 #endif
1176         case KDSETLED: /* set keyboard LED */
1177                 KBDMUX_LOCK(state);
1178
1179                 /* NOTE: lock key state in ks_state won't be changed */
1180                 if (*(int *)arg & ~LOCK_MASK) {
1181                         KBDMUX_UNLOCK(state);
1182
1183                         return (EINVAL);
1184                 }
1185
1186                 KBD_LED_VAL(kbd) = *(int *)arg;
1187 #ifdef EVDEV_SUPPORT
1188                 if (state->ks_evdev != NULL &&
1189                     evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
1190                         evdev_push_leds(state->ks_evdev, *(int *)arg);
1191 #endif
1192                 /* KDSETLED on all slave keyboards */
1193                 SLIST_FOREACH(k, &state->ks_kbds, next)
1194                         (void)kbdd_ioctl(k->kbd, KDSETLED, arg);
1195
1196                 KBDMUX_UNLOCK(state);
1197                 break;
1198
1199         case KDGKBSTATE: /* get lock key state */
1200                 KBDMUX_LOCK(state);
1201                 *(int *)arg = state->ks_state & LOCK_MASK;
1202                 KBDMUX_UNLOCK(state);
1203                 break;
1204
1205 #ifdef COMPAT_FREEBSD6
1206         case _IO('K', 20):
1207                 ival = IOCPARM_IVAL(arg);
1208                 arg = (caddr_t)&ival;
1209                 /* FALLTHROUGH */
1210 #endif
1211         case KDSKBSTATE: /* set lock key state */
1212                 KBDMUX_LOCK(state);
1213
1214                 if (*(int *)arg & ~LOCK_MASK) {
1215                         KBDMUX_UNLOCK(state);
1216
1217                         return (EINVAL);
1218                 }
1219
1220                 state->ks_state &= ~LOCK_MASK;
1221                 state->ks_state |= *(int *)arg;
1222
1223                 /* KDSKBSTATE on all slave keyboards */
1224                 SLIST_FOREACH(k, &state->ks_kbds, next)
1225                         (void)kbdd_ioctl(k->kbd, KDSKBSTATE, arg);
1226
1227                 KBDMUX_UNLOCK(state);
1228
1229                 return (kbdmux_ioctl(kbd, KDSETLED, arg));
1230                 /* NOT REACHED */
1231
1232 #ifdef COMPAT_FREEBSD6
1233         case _IO('K', 67):
1234                 cmd = KDSETRAD;
1235                 ival = IOCPARM_IVAL(arg);
1236                 arg = (caddr_t)&ival;
1237                 /* FALLTHROUGH */
1238 #endif
1239         case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
1240         case KDSETRAD: /* set keyboard repeat rate (old interface) */
1241                 KBDMUX_LOCK(state);
1242
1243                 if (cmd == KDSETREPEAT) {
1244                         int     i;
1245
1246                         /* lookup delay */
1247                         for (i = sizeof(delays)/sizeof(delays[0]) - 1; i > 0; i --)
1248                                 if (((int *)arg)[0] >= delays[i])
1249                                         break;
1250                         mode = i << 5;
1251
1252                         /* lookup rate */
1253                         for (i = sizeof(rates)/sizeof(rates[0]) - 1; i > 0; i --)
1254                                 if (((int *)arg)[1] >= rates[i])
1255                                         break;
1256                         mode |= i;
1257                 } else
1258                         mode = *(int *)arg;
1259
1260                 if (mode & ~0x7f) {
1261                         KBDMUX_UNLOCK(state);
1262
1263                         return (EINVAL);
1264                 }
1265
1266                 kbd->kb_delay1 = delays[(mode >> 5) & 3];
1267                 kbd->kb_delay2 = rates[mode & 0x1f];
1268 #ifdef EVDEV_SUPPORT
1269                 if (state->ks_evdev != NULL &&
1270                     evdev_rcpt_mask & EVDEV_RCPT_KBDMUX)
1271                         evdev_push_repeats(state->ks_evdev, kbd);
1272 #endif
1273                 /* perform command on all slave keyboards */
1274                 SLIST_FOREACH(k, &state->ks_kbds, next)
1275                         (void)kbdd_ioctl(k->kbd, cmd, arg);
1276
1277                 KBDMUX_UNLOCK(state);
1278                 break;
1279
1280         case PIO_KEYMAP:        /* set keyboard translation table */
1281         case OPIO_KEYMAP:       /* set keyboard translation table (compat) */
1282         case PIO_KEYMAPENT:     /* set keyboard translation table entry */
1283         case PIO_DEADKEYMAP:    /* set accent key translation table */
1284                 KBDMUX_LOCK(state);
1285                 state->ks_accents = 0;
1286
1287                 /* perform command on all slave keyboards */
1288                 SLIST_FOREACH(k, &state->ks_kbds, next)
1289                         (void)kbdd_ioctl(k->kbd, cmd, arg);
1290
1291                 KBDMUX_UNLOCK(state);
1292                 /* FALLTHROUGH */
1293
1294         default:
1295                 error = genkbd_commonioctl(kbd, cmd, arg);
1296                 break;
1297         }
1298
1299         return (error);
1300 }
1301
1302 /*
1303  * Lock the access to the keyboard
1304  */
1305 static int
1306 kbdmux_lock(keyboard_t *kbd, int lock)
1307 {
1308         return (1); /* XXX */
1309 }
1310
1311 /*
1312  * Clear the internal state of the keyboard
1313  */
1314 static void
1315 kbdmux_clear_state_locked(kbdmux_state_t *state)
1316 {
1317         KBDMUX_LOCK_ASSERT(state, MA_OWNED);
1318
1319         state->ks_flags &= ~COMPOSE;
1320         state->ks_polling = 0;
1321         state->ks_state &= LOCK_MASK;   /* preserve locking key state */
1322         state->ks_accents = 0;
1323         state->ks_composed_char = 0;
1324 /*      state->ks_prefix = 0;           XXX */
1325         state->ks_inq_length = 0;
1326 }
1327
1328 static void
1329 kbdmux_clear_state(keyboard_t *kbd)
1330 {
1331         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
1332
1333         KBDMUX_LOCK(state);
1334         kbdmux_clear_state_locked(state);
1335         KBDMUX_UNLOCK(state);
1336 }
1337
1338 /*
1339  * Save the internal state
1340  */
1341 static int
1342 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len)
1343 {
1344         if (len == 0)
1345                 return (sizeof(kbdmux_state_t));
1346         if (len < sizeof(kbdmux_state_t))
1347                 return (-1);
1348
1349         bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */
1350
1351         return (0);
1352 }
1353
1354 /*
1355  * Set the internal state
1356  */
1357 static int
1358 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len)
1359 {
1360         if (len < sizeof(kbdmux_state_t))
1361                 return (ENOMEM);
1362
1363         bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */
1364
1365         return (0);
1366 }
1367
1368 /*
1369  * Set polling
1370  */
1371 static int
1372 kbdmux_poll(keyboard_t *kbd, int on)
1373 {
1374         kbdmux_state_t  *state = (kbdmux_state_t *) kbd->kb_data;
1375         kbdmux_kbd_t    *k;
1376
1377         KBDMUX_LOCK(state);
1378
1379         if (on)
1380                 state->ks_polling++;
1381         else
1382                 state->ks_polling--;
1383
1384         /* set poll on slave keyboards */
1385         SLIST_FOREACH(k, &state->ks_kbds, next)
1386                 kbdd_poll(k->kbd, on);
1387
1388         KBDMUX_UNLOCK(state);
1389
1390         return (0);
1391 }
1392
1393 /*****************************************************************************
1394  *****************************************************************************
1395  **                                    Module 
1396  *****************************************************************************
1397  *****************************************************************************/
1398
1399 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure);
1400
1401 static int
1402 kbdmux_modevent(module_t mod, int type, void *data)
1403 {
1404         keyboard_switch_t       *sw;
1405         keyboard_t              *kbd;
1406         int                      error;
1407
1408         switch (type) {
1409         case MOD_LOAD:
1410                 if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0)
1411                         break;
1412
1413                 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) {
1414                         kbd_delete_driver(&kbdmux_kbd_driver);
1415                         error = ENXIO;
1416                         break;
1417                 }
1418
1419                 kbd = NULL;
1420
1421                 if ((error = (*sw->probe)(0, NULL, 0)) != 0 ||
1422                     (error = (*sw->init)(0, &kbd, NULL, 0)) != 0) {
1423                         kbd_delete_driver(&kbdmux_kbd_driver);
1424                         break;
1425                 }
1426
1427 #ifdef KBD_INSTALL_CDEV
1428                 if ((error = kbd_attach(kbd)) != 0) {
1429                         (*sw->term)(kbd);
1430                         kbd_delete_driver(&kbdmux_kbd_driver);
1431                         break;
1432                 }
1433 #endif
1434
1435                 if ((error = (*sw->enable)(kbd)) != 0) {
1436                         (*sw->disable)(kbd);
1437 #ifdef KBD_INSTALL_CDEV
1438                         kbd_detach(kbd);
1439 #endif
1440                         (*sw->term)(kbd);
1441                         kbd_delete_driver(&kbdmux_kbd_driver);
1442                         break;
1443                 }
1444                 break;
1445
1446         case MOD_UNLOAD:
1447                 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
1448                         panic("kbd_get_switch(" KEYBOARD_NAME ") == NULL");
1449
1450                 kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0));
1451                 if (kbd != NULL) {
1452                         (*sw->disable)(kbd);
1453 #ifdef KBD_INSTALL_CDEV
1454                         kbd_detach(kbd);
1455 #endif
1456                         (*sw->term)(kbd);
1457                         kbd_delete_driver(&kbdmux_kbd_driver);
1458                 }
1459                 error = 0;
1460                 break;
1461
1462         default:
1463                 error = EOPNOTSUPP;
1464                 break;
1465         }
1466
1467         return (error);
1468 }
1469
1470 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
1471 #ifdef EVDEV_SUPPORT
1472 MODULE_DEPEND(kbdmux, evdev, 1, 1, 1);
1473 #endif