4 * Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * $Id: kbdmux.c,v 1.4 2005/07/14 17:38:35 max Exp $
32 #include "opt_evdev.h"
35 #include <sys/param.h>
38 #include <sys/consio.h>
39 #include <sys/fcntl.h>
41 #include <sys/kernel.h>
42 #include <sys/limits.h>
44 #include <sys/malloc.h>
45 #include <sys/module.h>
48 #include <sys/queue.h>
49 #include <sys/event.h>
50 #include <sys/systm.h>
51 #include <sys/taskqueue.h>
53 #include <dev/misc/kbd/kbdreg.h>
54 #include <dev/misc/kbd/kbdtables.h>
57 #include <dev/misc/evdev/evdev.h>
58 #include <dev/misc/evdev/input.h>
61 #define KEYBOARD_NAME "kbdmux"
63 MALLOC_DECLARE(M_KBDMUX
);
64 MALLOC_DEFINE(M_KBDMUX
, KEYBOARD_NAME
, "Keyboard multiplexor");
66 /*****************************************************************************
67 *****************************************************************************
69 *****************************************************************************
70 *****************************************************************************/
72 #define KBDMUX_Q_SIZE 512 /* input queue size */
79 keyboard_t
*kbd
; /* keyboard */
80 SLIST_ENTRY(kbdmux_kbd
) next
; /* link to next */
83 typedef struct kbdmux_kbd kbdmux_kbd_t
;
90 char ks_inq
[KBDMUX_Q_SIZE
]; /* input chars queue */
91 unsigned int ks_inq_start
;
92 unsigned int ks_inq_length
;
93 struct task ks_task
; /* interrupt task */
95 int ks_flags
; /* flags */
96 #define COMPOSE (1 << 0) /* compose char flag */
97 #define POLLING (1 << 1) /* polling */
99 int ks_mode
; /* K_XLATE, K_RAW, K_CODE */
100 int ks_state
; /* state */
101 int ks_accents
; /* accent key index (> 0) */
102 u_int ks_composed_char
; /* composed char code */
103 u_char ks_prefix
; /* AT scan code prefix */
106 struct evdev_dev
* ks_evdev
;
110 SLIST_HEAD(, kbdmux_kbd
) ks_kbds
; /* keyboards */
113 typedef struct kbdmux_state kbdmux_state_t
;
115 /*****************************************************************************
116 *****************************************************************************
118 *****************************************************************************
119 *****************************************************************************/
121 static task_fn_t kbdmux_kbd_intr
;
122 static kbd_callback_func_t kbdmux_kbd_event
;
125 kbdmux_kbd_putc(kbdmux_state_t
*state
, char c
)
129 if (state
->ks_inq_length
== KBDMUX_Q_SIZE
)
132 p
= (state
->ks_inq_start
+ state
->ks_inq_length
) % KBDMUX_Q_SIZE
;
133 state
->ks_inq
[p
] = c
;
134 state
->ks_inq_length
++;
138 kbdmux_kbd_getc(kbdmux_state_t
*state
)
142 if (state
->ks_inq_length
== 0)
145 c
= state
->ks_inq
[state
->ks_inq_start
];
146 state
->ks_inq_start
= (state
->ks_inq_start
+ 1) % KBDMUX_Q_SIZE
;
147 state
->ks_inq_length
--;
153 * Interrupt handler task
156 kbdmux_kbd_intr(void *xkbd
, int pending
)
158 keyboard_t
*kbd
= (keyboard_t
*) xkbd
;
161 KBD_LOCK(kbd
); /* recursive so ok */
167 * Process event from one of our keyboards
170 kbdmux_kbd_event(keyboard_t
*kbd
, int event
, void *arg
)
172 kbdmux_state_t
*state
= (kbdmux_state_t
*) arg
;
175 case KBDIO_KEYINPUT
: {
179 * Read all chars from the keyboard
181 * Turns out that atkbd(4) check_char() method may return
182 * "true" while read_char() method returns NOKEY. If this
183 * happens we could stuck in the loop below. Avoid this
184 * by breaking out of the loop if read_char() method returns
188 while (kbd_check_char(kbd
)) {
189 c
= kbd_read_char(kbd
, 0);
193 continue; /* XXX ring bell */
194 if (!KBD_IS_BUSY(kbd
))
195 continue; /* not open - discard the input */
197 kbdmux_kbd_putc(state
, c
);
200 /* queue interrupt task if needed */
201 if (state
->ks_inq_length
> 0)
202 taskqueue_enqueue(taskqueue_swi
, &state
->ks_task
);
206 case KBDIO_UNLOADING
: {
209 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
214 kbd_release(k
->kbd
, &k
->kbd
);
215 SLIST_REMOVE(&state
->ks_kbds
, k
, kbdmux_kbd
, next
);
231 /****************************************************************************
232 ****************************************************************************
234 ****************************************************************************
235 ****************************************************************************/
237 static int kbdmux_configure(int flags
);
238 static kbd_probe_t kbdmux_probe
;
239 static kbd_init_t kbdmux_init
;
240 static kbd_term_t kbdmux_term
;
241 static kbd_intr_t kbdmux_intr
;
242 static kbd_test_if_t kbdmux_test_if
;
243 static kbd_enable_t kbdmux_enable
;
244 static kbd_disable_t kbdmux_disable
;
245 static kbd_read_t kbdmux_read
;
246 static kbd_check_t kbdmux_check
;
247 static kbd_read_char_t kbdmux_read_char
;
248 static kbd_check_char_t kbdmux_check_char
;
249 static kbd_ioctl_t kbdmux_ioctl
;
250 static kbd_lock_t kbdmux_lock
;
251 static kbd_clear_state_t kbdmux_clear_state
;
252 static kbd_get_state_t kbdmux_get_state
;
253 static kbd_set_state_t kbdmux_set_state
;
254 static kbd_poll_mode_t kbdmux_poll
;
256 static keyboard_switch_t kbdmuxsw
= {
257 .probe
= kbdmux_probe
,
261 .test_if
= kbdmux_test_if
,
262 .enable
= kbdmux_enable
,
263 .disable
= kbdmux_disable
,
265 .check
= kbdmux_check
,
266 .read_char
= kbdmux_read_char
,
267 .check_char
= kbdmux_check_char
,
268 .ioctl
= kbdmux_ioctl
,
270 .clear_state
= kbdmux_clear_state
,
271 .get_state
= kbdmux_get_state
,
272 .set_state
= kbdmux_set_state
,
273 .get_fkeystr
= genkbd_get_fkeystr
,
279 static const struct evdev_methods kbdmux_evdev_methods
= {
280 .ev_event
= evdev_ev_kbd_event
,
285 * Return the number of found keyboards
288 kbdmux_configure(int flags
)
297 kbdmux_probe(int unit
, void *arg
, int flags
)
299 if (resource_disabled(KEYBOARD_NAME
, unit
))
306 * Reset and initialize the keyboard (stolen from atkbd.c)
308 * Called without kbd lock held.
311 kbdmux_init(int unit
, keyboard_t
**kbdp
, void *arg
, int flags
)
313 kbdmux_state_t
*state
= NULL
;
314 keymap_t
*keymap
= NULL
;
315 accentmap_t
*accmap
= NULL
;
316 fkeytab_t
*fkeymap
= NULL
;
317 keyboard_t
*kbd
= NULL
;
318 int error
, needfree
, fkeymap_size
, delay
[2];
320 struct evdev_dev
*evdev
;
321 char phys_loc
[NAMELEN
];
325 *kbdp
= kbd
= kmalloc(sizeof(*kbd
), M_KBDMUX
, M_NOWAIT
| M_ZERO
);
326 state
= kmalloc(sizeof(*state
), M_KBDMUX
, M_NOWAIT
| M_ZERO
);
327 keymap
= kmalloc(sizeof(key_map
), M_KBDMUX
, M_NOWAIT
);
328 accmap
= kmalloc(sizeof(accent_map
), M_KBDMUX
, M_NOWAIT
);
329 fkeymap
= kmalloc(sizeof(fkey_tab
), M_KBDMUX
, M_NOWAIT
);
330 fkeymap_size
= NELEM(fkey_tab
);
333 if ((kbd
== NULL
) || (state
== NULL
) || (keymap
== NULL
) ||
334 (accmap
== NULL
) || (fkeymap
== NULL
)) {
339 TASK_INIT(&state
->ks_task
, 0, kbdmux_kbd_intr
, (void *) kbd
);
340 SLIST_INIT(&state
->ks_kbds
);
341 } else if (KBD_IS_INITIALIZED(*kbdp
) && KBD_IS_CONFIGURED(*kbdp
)) {
345 state
= (kbdmux_state_t
*) kbd
->kb_data
;
346 keymap
= kbd
->kb_keymap
;
347 accmap
= kbd
->kb_accentmap
;
348 fkeymap
= kbd
->kb_fkeytab
;
349 fkeymap_size
= kbd
->kb_fkeytab_size
;
353 if (!KBD_IS_PROBED(kbd
)) {
354 /* XXX assume 101/102 keys keyboard */
355 kbd_init_struct(kbd
, KEYBOARD_NAME
, KB_101
, unit
, flags
,
357 bcopy(&key_map
, keymap
, sizeof(key_map
));
358 bcopy(&accent_map
, accmap
, sizeof(accent_map
));
359 bcopy(fkey_tab
, fkeymap
,
360 imin(fkeymap_size
*sizeof(fkeymap
[0]), sizeof(fkey_tab
)));
361 kbd_set_maps(kbd
, keymap
, accmap
, fkeymap
, fkeymap_size
);
362 kbd
->kb_data
= (void *)state
;
364 KBD_FOUND_DEVICE(kbd
);
367 kbdmux_clear_state(kbd
);
368 state
->ks_mode
= K_XLATE
;
371 if (!KBD_IS_INITIALIZED(kbd
) && !(flags
& KB_CONF_PROBE_ONLY
)) {
372 kbd
->kb_config
= flags
& ~KB_CONF_PROBE_ONLY
;
374 kbdmux_ioctl(kbd
, KDSETLED
, (caddr_t
)&state
->ks_state
);
376 delay
[0] = kbd
->kb_delay1
;
377 delay
[1] = kbd
->kb_delay2
;
378 kbdmux_ioctl(kbd
, KDSETREPEAT
, (caddr_t
)delay
);
381 /* register as evdev provider */
382 evdev
= evdev_alloc();
383 evdev_set_name(evdev
, "System keyboard multiplexer");
384 ksnprintf(phys_loc
, NAMELEN
, KEYBOARD_NAME
"%d", unit
);
385 evdev_set_phys(evdev
, phys_loc
);
386 evdev_set_id(evdev
, BUS_VIRTUAL
, 0, 0, 0);
387 evdev_set_methods(evdev
, kbd
, &kbdmux_evdev_methods
);
388 evdev_support_event(evdev
, EV_SYN
);
389 evdev_support_event(evdev
, EV_KEY
);
390 evdev_support_event(evdev
, EV_LED
);
391 evdev_support_event(evdev
, EV_REP
);
392 evdev_support_all_known_keys(evdev
);
393 evdev_support_led(evdev
, LED_NUML
);
394 evdev_support_led(evdev
, LED_CAPSL
);
395 evdev_support_led(evdev
, LED_SCROLLL
);
397 if (evdev_register(evdev
))
400 state
->ks_evdev
= evdev
;
401 state
->ks_evdev_state
= 0;
407 if (!KBD_IS_CONFIGURED(kbd
)) {
408 if (kbd_register(kbd
) < 0) {
413 KBD_CONFIG_DONE(kbd
);
420 kfree(state
, M_KBDMUX
);
422 kfree(keymap
, M_KBDMUX
);
424 kfree(accmap
, M_KBDMUX
);
426 kfree(fkeymap
, M_KBDMUX
);
428 kfree(kbd
, M_KBDMUX
);
429 *kbdp
= NULL
; /* insure ref doesn't leak to caller */
437 * Finish using this keyboard
439 * NOTE: deregistration automatically unlocks lock.
442 kbdmux_term(keyboard_t
*kbd
)
444 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
447 /* wait for interrupt task */
448 while (taskqueue_cancel(taskqueue_swi
, &state
->ks_task
, NULL
) != 0)
449 taskqueue_drain(taskqueue_swi
, &state
->ks_task
);
451 /* release all keyboards from the mux */
452 while ((k
= SLIST_FIRST(&state
->ks_kbds
)) != NULL
) {
453 kbd_release(k
->kbd
, &k
->kbd
);
454 SLIST_REMOVE_HEAD(&state
->ks_kbds
, next
);
464 evdev_free(state
->ks_evdev
);
467 bzero(state
, sizeof(*state
));
468 kfree(state
, M_KBDMUX
);
470 kfree(kbd
->kb_keymap
, M_KBDMUX
);
471 kfree(kbd
->kb_accentmap
, M_KBDMUX
);
472 kfree(kbd
->kb_fkeytab
, M_KBDMUX
);
473 kfree(kbd
, M_KBDMUX
);
479 * Keyboard interrupt routine
482 kbdmux_intr(keyboard_t
*kbd
, void *arg
)
486 if (KBD_IS_ACTIVE(kbd
) && KBD_IS_BUSY(kbd
)) {
487 /* let the callback function to process the input */
488 (*kbd
->kb_callback
.kc_func
)(kbd
, KBDIO_KEYINPUT
,
489 kbd
->kb_callback
.kc_arg
);
491 /* read and discard the input; no one is waiting for input */
493 c
= kbdmux_read_char(kbd
, FALSE
);
494 } while (c
!= NOKEY
);
501 * Test the interface to the device
504 kbdmux_test_if(keyboard_t
*kbd
)
510 * Enable the access to the device; until this function is called,
511 * the client cannot read from the keyboard.
514 kbdmux_enable(keyboard_t
*kbd
)
521 * Disallow the access to the device
524 kbdmux_disable(keyboard_t
*kbd
)
531 * Read one byte from the keyboard if it's allowed
534 kbdmux_read(keyboard_t
*kbd
, int wait
)
536 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
540 c
= kbdmux_kbd_getc(state
);
541 } while (c
== -1 && wait
);
546 ret
= (KBD_IS_ACTIVE(kbd
)? c
: -1);
552 * Check if data is waiting
555 kbdmux_check(keyboard_t
*kbd
)
557 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
560 if (!KBD_IS_ACTIVE(kbd
))
563 ready
= (state
->ks_inq_length
> 0) ? TRUE
: FALSE
;
569 * Read char from the keyboard (stolen from atkbd.c)
571 * Note: We do not attempt to detect the case where no keyboards are
572 * present in the wait case. If the kernel is sitting at the
573 * debugger prompt we want someone to be able to plug in a keyboard
574 * and have it work, and not just panic or fall through or do
575 * something equally nasty.
578 kbdmux_read_char(keyboard_t
*kbd
, int wait
)
580 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
582 int scancode
, keycode
;
586 /* do we have a composed char to return? */
587 if (!(state
->ks_flags
& COMPOSE
) && (state
->ks_composed_char
> 0)) {
588 action
= state
->ks_composed_char
;
589 state
->ks_composed_char
= 0;
590 if (action
> UCHAR_MAX
) {
597 * See if there is something in the keyboard queue
599 scancode
= kbdmux_kbd_getc(state
);
601 if (scancode
== -1) {
602 if (state
->ks_flags
& POLLING
) {
605 SLIST_FOREACH(k
, &state
->ks_kbds
, next
) {
606 while (kbd_check_char(k
->kbd
)) {
607 scancode
= kbd_read_char(k
->kbd
, 0);
608 if (scancode
== ERRKEY
)
610 if (scancode
== NOKEY
)
612 if (!KBD_IS_BUSY(k
->kbd
))
614 kbdmux_kbd_putc(state
, scancode
);
618 if (state
->ks_inq_length
> 0)
624 if (kbd
->kb_flags
& KB_POLLED
) {
625 tsleep(&state
->ks_task
, PCATCH
,
628 lksleep(&state
->ks_task
,
629 &kbd
->kb_lock
, PCATCH
,
641 /* push evdev event */
642 if (evdev_rcpt_mask
& EVDEV_RCPT_KBDMUX
&& state
->ks_evdev
!= NULL
) {
643 uint16_t key
= evdev_scancode2key(&state
->ks_evdev_state
,
646 if (key
!= KEY_RESERVED
) {
647 evdev_push_event(state
->ks_evdev
, EV_KEY
,
648 key
, scancode
& 0x80 ? 0 : 1);
649 evdev_sync(state
->ks_evdev
);
654 /* return the byte as is for the K_RAW mode */
655 if (state
->ks_mode
== K_RAW
)
658 /* translate the scan code into a keycode */
659 keycode
= scancode
& 0x7F;
660 switch (state
->ks_prefix
) {
661 case 0x00: /* normal scancode */
663 case 0xB8: /* left alt (compose key) released */
664 if (state
->ks_flags
& COMPOSE
) {
665 state
->ks_flags
&= ~COMPOSE
;
666 if (state
->ks_composed_char
> UCHAR_MAX
)
667 state
->ks_composed_char
= 0;
670 case 0x38: /* left alt (compose key) pressed */
671 if (!(state
->ks_flags
& COMPOSE
)) {
672 state
->ks_flags
|= COMPOSE
;
673 state
->ks_composed_char
= 0;
678 state
->ks_prefix
= scancode
;
682 case 0xE0: /* 0xE0 prefix */
683 state
->ks_prefix
= 0;
685 case 0x1C: /* right enter key */
688 case 0x1D: /* right ctrl key */
691 case 0x35: /* keypad divide key */
694 case 0x37: /* print scrn key */
697 case 0x38: /* right alt key (alt gr) */
700 case 0x46: /* ctrl-pause/break on AT 101 (see below) */
703 case 0x47: /* grey home key */
706 case 0x48: /* grey up arrow key */
709 case 0x49: /* grey page up key */
712 case 0x4B: /* grey left arrow key */
715 case 0x4D: /* grey right arrow key */
718 case 0x4F: /* grey end key */
721 case 0x50: /* grey down arrow key */
724 case 0x51: /* grey page down key */
727 case 0x52: /* grey insert key */
730 case 0x53: /* grey delete key */
733 /* the following 3 are only used on the MS "Natural" keyboard */
734 case 0x5b: /* left Window key */
737 case 0x5c: /* right Window key */
740 case 0x5d: /* menu key */
743 case 0x5e: /* power key */
746 case 0x5f: /* sleep key */
749 case 0x63: /* wake key */
752 case 0x64: /* [JP106USB] backslash, underscore */
755 default: /* ignore everything else */
759 case 0xE1: /* 0xE1 prefix */
761 * The pause/break key on the 101 keyboard produces:
763 * Ctrl-pause/break produces:
764 * E0-46 E0-C6 (See above.)
766 state
->ks_prefix
= 0;
768 state
->ks_prefix
= 0x1D;
771 case 0x1D: /* pause / break */
772 state
->ks_prefix
= 0;
779 /* XXX assume 101/102 keys AT keyboard */
781 case 0x5c: /* print screen */
782 if (state
->ks_flags
& ALTS
)
783 keycode
= 0x54; /* sysrq */
785 case 0x68: /* pause/break */
786 if (state
->ks_flags
& CTLS
)
787 keycode
= 0x6c; /* break */
791 /* return the key code in the K_CODE mode */
792 if (state
->ks_mode
== K_CODE
)
793 return (keycode
| (scancode
& 0x80));
795 /* compose a character code */
796 if (state
->ks_flags
& COMPOSE
) {
797 switch (keycode
| (scancode
& 0x80)) {
798 /* key pressed, process it */
799 case 0x47: case 0x48: case 0x49: /* keypad 7,8,9 */
800 state
->ks_composed_char
*= 10;
801 state
->ks_composed_char
+= keycode
- 0x40;
802 if (state
->ks_composed_char
> UCHAR_MAX
)
805 case 0x4B: case 0x4C: case 0x4D: /* keypad 4,5,6 */
806 state
->ks_composed_char
*= 10;
807 state
->ks_composed_char
+= keycode
- 0x47;
808 if (state
->ks_composed_char
> UCHAR_MAX
)
811 case 0x4F: case 0x50: case 0x51: /* keypad 1,2,3 */
812 state
->ks_composed_char
*= 10;
813 state
->ks_composed_char
+= keycode
- 0x4E;
814 if (state
->ks_composed_char
> UCHAR_MAX
)
817 case 0x52: /* keypad 0 */
818 state
->ks_composed_char
*= 10;
819 if (state
->ks_composed_char
> UCHAR_MAX
)
823 /* key released, no interest here */
824 case 0xC7: case 0xC8: case 0xC9: /* keypad 7,8,9 */
825 case 0xCB: case 0xCC: case 0xCD: /* keypad 4,5,6 */
826 case 0xCF: case 0xD0: case 0xD1: /* keypad 1,2,3 */
827 case 0xD2: /* keypad 0 */
830 case 0x38: /* left alt key */
834 if (state
->ks_composed_char
> 0) {
835 state
->ks_flags
&= ~COMPOSE
;
836 state
->ks_composed_char
= 0;
843 /* keycode to key action */
844 action
= genkbd_keyaction(kbd
, keycode
, scancode
& 0x80,
845 &state
->ks_state
, &state
->ks_accents
);
853 * Check if char is waiting
856 kbdmux_check_char(keyboard_t
*kbd
)
858 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
861 if (!KBD_IS_ACTIVE(kbd
))
864 if (!(state
->ks_flags
& COMPOSE
) && (state
->ks_composed_char
!= 0))
867 ready
= (state
->ks_inq_length
> 0) ? TRUE
: FALSE
;
876 kbdmux_ioctl(keyboard_t
*kbd
, u_long cmd
, caddr_t arg
)
878 static int delays
[] = {
882 static int rates
[] = {
883 34, 38, 42, 46, 50, 55, 59, 63,
884 68, 76, 84, 92, 100, 110, 118, 126,
885 136, 152, 168, 184, 200, 220, 236, 252,
886 272, 304, 336, 368, 400, 440, 472, 504
889 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
892 int error
= 0, mode
, i
;
898 case KBADDKBD
: /* add keyboard to the mux */
899 ki
= (keyboard_info_t
*) arg
;
901 if (ki
== NULL
|| ki
->kb_unit
< 0 || ki
->kb_name
[0] == '\0' ||
902 strcmp(ki
->kb_name
, "*") == 0) {
903 return (EINVAL
); /* bad input */
906 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
907 if (k
->kbd
->kb_unit
== ki
->kb_unit
&&
908 strcmp(k
->kbd
->kb_name
, ki
->kb_name
) == 0)
912 return (0); /* keyboard already in the mux */
914 k
= kmalloc(sizeof(*k
), M_KBDMUX
, M_NOWAIT
| M_ZERO
);
916 return (ENOMEM
); /* out of memory */
918 k
->kbd
= kbd_get_keyboard(
923 kbdmux_kbd_event
, (void *) state
));
924 if (k
->kbd
== NULL
) {
926 return (EINVAL
); /* bad keyboard */
930 kbd_clear_state(k
->kbd
);
932 /* set K_RAW mode on slave keyboard */
934 error
= kbd_ioctl(k
->kbd
, KDSKBMODE
, (caddr_t
)&mode
);
936 /* set lock keys state on slave keyboard */
937 mode
= state
->ks_state
& LOCK_MASK
;
938 error
= kbd_ioctl(k
->kbd
, KDSKBSTATE
, (caddr_t
)&mode
);
942 kbd_release(k
->kbd
, &k
->kbd
);
945 return (error
); /* could not set mode */
948 SLIST_INSERT_HEAD(&state
->ks_kbds
, k
, next
);
951 case KBRELKBD
: /* release keyboard from the mux */
952 ki
= (keyboard_info_t
*) arg
;
954 if (ki
== NULL
|| ki
->kb_unit
< 0 || ki
->kb_name
[0] == '\0' ||
955 strcmp(ki
->kb_name
, "*") == 0) {
956 return (EINVAL
); /* bad input */
959 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
960 if (k
->kbd
->kb_unit
== ki
->kb_unit
&&
961 strcmp(k
->kbd
->kb_name
, ki
->kb_name
) == 0)
965 error
= kbd_release(k
->kbd
, &k
->kbd
);
967 SLIST_REMOVE(&state
->ks_kbds
, k
, kbdmux_kbd
, next
);
974 error
= ENXIO
; /* keyboard is not in the mux */
978 case KDGKBMODE
: /* get kyboard mode */
979 *(int *)arg
= state
->ks_mode
;
982 case KDSKBMODE
: /* set keyboard mode */
983 switch (*(int *)arg
) {
985 if (state
->ks_mode
!= K_XLATE
) {
986 /* make lock key state and LED state match */
987 state
->ks_state
&= ~LOCK_MASK
;
988 state
->ks_state
|= KBD_LED_VAL(kbd
);
994 if (state
->ks_mode
!= *(int *)arg
) {
995 kbdmux_clear_state(kbd
);
996 state
->ks_mode
= *(int *)arg
;
1006 case KDGETLED
: /* get keyboard LED */
1007 *(int *)arg
= KBD_LED_VAL(kbd
);
1010 case KDSETLED
: /* set keyboard LED */
1011 /* NOTE: lock key state in ks_state won't be changed */
1012 if (*(int *)arg
& ~LOCK_MASK
)
1015 KBD_LED_VAL(kbd
) = *(int *)arg
;
1016 #ifdef EVDEV_SUPPORT
1017 if (state
->ks_evdev
!= NULL
&&
1018 evdev_rcpt_mask
& EVDEV_RCPT_KBDMUX
)
1019 evdev_push_leds(state
->ks_evdev
, *(int *)arg
);
1021 /* KDSETLED on all slave keyboards */
1022 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
1023 kbd_ioctl(k
->kbd
, KDSETLED
, arg
);
1026 case KDGKBSTATE
: /* get lock key state */
1027 *(int *)arg
= state
->ks_state
& LOCK_MASK
;
1030 case KDSKBSTATE
: /* set lock key state */
1031 if (*(int *)arg
& ~LOCK_MASK
)
1034 state
->ks_state
&= ~LOCK_MASK
;
1035 state
->ks_state
|= *(int *)arg
;
1037 /* KDSKBSTATE on all slave keyboards */
1038 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
1039 kbd_ioctl(k
->kbd
, KDSKBSTATE
, arg
);
1041 return (kbdmux_ioctl(kbd
, KDSETLED
, arg
));
1044 case KDSETREPEAT
: /* set keyboard repeat rate (new interface) */
1046 for (i
= NELEM(delays
) - 1; i
> 0; i
--)
1047 if (((int *)arg
)[0] >= delays
[i
])
1052 for (i
= NELEM(rates
) - 1; i
> 0; i
--)
1053 if (((int *)arg
)[1] >= rates
[i
])
1060 kbd
->kb_delay1
= delays
[(mode
>> 5) & 3];
1061 kbd
->kb_delay2
= rates
[mode
& 0x1f];
1062 #ifdef EVDEV_SUPPORT
1063 if (state
->ks_evdev
!= NULL
&&
1064 evdev_rcpt_mask
& EVDEV_RCPT_KBDMUX
)
1065 evdev_push_repeats(state
->ks_evdev
, kbd
);
1067 /* perform command on all slave keyboards */
1068 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
1069 kbd_ioctl(k
->kbd
, cmd
, arg
);
1072 case PIO_KEYMAP
: /* set keyboard translation table */
1073 case PIO_KEYMAPENT
: /* set keyboard translation table entry */
1074 case PIO_DEADKEYMAP
: /* set accent key translation table */
1075 state
->ks_accents
= 0;
1077 /* perform command on all slave keyboards */
1078 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
1079 kbd_ioctl(k
->kbd
, cmd
, arg
);
1083 error
= genkbd_commonioctl(kbd
, cmd
, arg
);
1090 * Lock the access to the keyboard
1093 kbdmux_lock(keyboard_t
*kbd
, int lock
)
1095 return (1); /* XXX */
1099 * Clear the internal state of the keyboard
1101 * NOTE: May be called unlocked from init
1104 kbdmux_clear_state(keyboard_t
*kbd
)
1106 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
1108 state
->ks_flags
&= ~(COMPOSE
|POLLING
);
1109 state
->ks_state
&= LOCK_MASK
; /* preserve locking key state */
1110 state
->ks_accents
= 0;
1111 state
->ks_composed_char
= 0;
1112 /* state->ks_prefix = 0; XXX */
1113 state
->ks_inq_length
= 0;
1117 * Save the internal state
1120 kbdmux_get_state(keyboard_t
*kbd
, void *buf
, size_t len
)
1123 return (sizeof(kbdmux_state_t
));
1124 if (len
< sizeof(kbdmux_state_t
))
1127 bcopy(kbd
->kb_data
, buf
, sizeof(kbdmux_state_t
)); /* XXX locking? */
1133 * Set the internal state
1136 kbdmux_set_state(keyboard_t
*kbd
, void *buf
, size_t len
)
1138 if (len
< sizeof(kbdmux_state_t
))
1141 bcopy(buf
, kbd
->kb_data
, sizeof(kbdmux_state_t
)); /* XXX locking? */
1149 * Caller interlocks all keyboard calls. We must not lock here.
1152 kbdmux_poll(keyboard_t
*kbd
, int on
)
1154 kbdmux_state_t
*state
= (kbdmux_state_t
*) kbd
->kb_data
;
1158 state
->ks_flags
|= POLLING
;
1160 state
->ks_flags
&= ~POLLING
;
1162 /* set poll on slave keyboards */
1163 SLIST_FOREACH(k
, &state
->ks_kbds
, next
)
1164 kbd_poll(k
->kbd
, on
);
1169 /*****************************************************************************
1170 *****************************************************************************
1172 *****************************************************************************
1173 *****************************************************************************/
1175 KEYBOARD_DRIVER(kbdmux
, kbdmuxsw
, kbdmux_configure
);
1178 kbdmux_modevent(module_t mod
, int type
, void *data
)
1180 keyboard_switch_t
*sw
;
1186 if ((error
= kbd_add_driver(&kbdmux_kbd_driver
)) != 0)
1189 if ((sw
= kbd_get_switch(KEYBOARD_NAME
)) == NULL
) {
1190 kbd_delete_driver(&kbdmux_kbd_driver
);
1197 if ((error
= (*sw
->probe
)(0, NULL
, 0)) != 0 ||
1198 (error
= (*sw
->init
)(0, &kbd
, NULL
, 0)) != 0) {
1199 kbd_delete_driver(&kbdmux_kbd_driver
);
1203 #ifdef KBD_INSTALL_CDEV
1204 if ((error
= kbd_attach(kbd
)) != 0) {
1206 kbd_delete_driver(&kbdmux_kbd_driver
);
1211 if ((error
= (*sw
->enable
)(kbd
)) != 0) {
1212 (*sw
->disable
)(kbd
);
1213 #ifdef KBD_INSTALL_CDEV
1217 kbd_delete_driver(&kbdmux_kbd_driver
);
1223 if ((sw
= kbd_get_switch(KEYBOARD_NAME
)) == NULL
)
1224 panic("kbd_get_switch(" KEYBOARD_NAME
") == NULL");
1226 kbd
= kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME
, 0));
1228 (*sw
->disable
)(kbd
);
1229 #ifdef KBD_INSTALL_CDEV
1233 kbd_delete_driver(&kbdmux_kbd_driver
);
1245 DEV_MODULE(kbdmux
, kbdmux_modevent
, NULL
);
1246 #ifdef EVDEV_SUPPORT
1247 MODULE_DEPEND(kbdmux
, evdev
, 1, 1, 1);