1 /*-
2 * (MPSAFE)
3 *
4 * Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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.
15 *
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
26 * SUCH DAMAGE.
27 *
28 * $Id: kbdmux.c,v 1.4 2005/07/14 17:38:35 max Exp $
29 * $FreeBSD$
30 */
31
32 #include "opt_evdev.h"
33 #include "opt_kbd.h"
34
35 #include <sys/param.h>
36 #include <sys/bus.h>
37 #include <sys/conf.h>
38 #include <sys/consio.h>
39 #include <sys/fcntl.h>
40 #include <sys/kbio.h>
41 #include <sys/kernel.h>
42 #include <sys/limits.h>
43 #include <sys/lock.h>
44 #include <sys/malloc.h>
45 #include <sys/module.h>
46 #include <sys/poll.h>
47 #include <sys/proc.h>
48 #include <sys/queue.h>
49 #include <sys/event.h>
50 #include <sys/systm.h>
51 #include <sys/taskqueue.h>
52 #include <sys/uio.h>
53 #include <dev/misc/kbd/kbdreg.h>
54 #include <dev/misc/kbd/kbdtables.h>
55
56 #ifdef EVDEV_SUPPORT
57 #include <dev/misc/evdev/evdev.h>
58 #include <dev/misc/evdev/input.h>
59 #endif
60
61 #define KEYBOARD_NAME "kbdmux"
62
63 MALLOC_DECLARE(M_KBDMUX);
64 MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor");
65
66 /*****************************************************************************
67 *****************************************************************************
68 ** Keyboard state
69 *****************************************************************************
70 *****************************************************************************/
71
72 #define KBDMUX_Q_SIZE 512 /* input queue size */
73
74 /*
75 * kbdmux keyboard
76 */
77 struct kbdmux_kbd
78 {
79 keyboard_t *kbd; /* keyboard */
80 SLIST_ENTRY(kbdmux_kbd) next; /* link to next */
81 };
82
83 typedef struct kbdmux_kbd kbdmux_kbd_t;
84
85 /*
86 * kbdmux state
87 */
88 struct kbdmux_state
89 {
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 */
94
95 int ks_flags; /* flags */
96 #define COMPOSE (1 << 0) /* compose char flag */
97 #define POLLING (1 << 1) /* polling */
98
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 */
104
105 #ifdef EVDEV_SUPPORT
106 struct evdev_dev * ks_evdev;
107 int ks_evdev_state;
108 #endif
109
110 SLIST_HEAD(, kbdmux_kbd) ks_kbds; /* keyboards */
111 };
112
113 typedef struct kbdmux_state kbdmux_state_t;
114
115 /*****************************************************************************
116 *****************************************************************************
117 ** Helper functions
118 *****************************************************************************
119 *****************************************************************************/
120
121 static task_fn_t kbdmux_kbd_intr;
122 static kbd_callback_func_t kbdmux_kbd_event;
123
124 static void
kbdmux_kbd_putc(kbdmux_state_t * state,char c)125 kbdmux_kbd_putc(kbdmux_state_t *state, char c)
126 {
127 unsigned int p;
128
129 if (state->ks_inq_length == KBDMUX_Q_SIZE)
130 return;
131
132 p = (state->ks_inq_start + state->ks_inq_length) % KBDMUX_Q_SIZE;
133 state->ks_inq[p] = c;
134 state->ks_inq_length++;
135 }
136
137 static int
kbdmux_kbd_getc(kbdmux_state_t * state)138 kbdmux_kbd_getc(kbdmux_state_t *state)
139 {
140 unsigned char c;
141
142 if (state->ks_inq_length == 0)
143 return (-1);
144
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--;
148
149 return (c);
150 }
151
152 /*
153 * Interrupt handler task
154 */
155 static void
kbdmux_kbd_intr(void * xkbd,int pending)156 kbdmux_kbd_intr(void *xkbd, int pending)
157 {
158 keyboard_t *kbd = (keyboard_t *) xkbd;
159 KBD_LOCK_DECLARE;
160
161 KBD_LOCK(kbd); /* recursive so ok */
162 kbd_intr(kbd, NULL);
163 KBD_UNLOCK(kbd);
164 }
165
166 /*
167 * Process event from one of our keyboards
168 */
169 static int
kbdmux_kbd_event(keyboard_t * kbd,int event,void * arg)170 kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg)
171 {
172 kbdmux_state_t *state = (kbdmux_state_t *) arg;
173
174 switch (event) {
175 case KBDIO_KEYINPUT: {
176 int c;
177
178 /*
179 * Read all chars from the keyboard
180 *
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
185 * NOKEY.
186 */
187
188 while (kbd_check_char(kbd)) {
189 c = kbd_read_char(kbd, 0);
190 if (c == NOKEY)
191 break;
192 if (c == ERRKEY)
193 continue; /* XXX ring bell */
194 if (!KBD_IS_BUSY(kbd))
195 continue; /* not open - discard the input */
196
197 kbdmux_kbd_putc(state, c);
198 }
199
200 /* queue interrupt task if needed */
201 if (state->ks_inq_length > 0)
202 taskqueue_enqueue(taskqueue_swi, &state->ks_task);
203
204 } break;
205
206 case KBDIO_UNLOADING: {
207 kbdmux_kbd_t *k;
208
209 SLIST_FOREACH(k, &state->ks_kbds, next)
210 if (k->kbd == kbd)
211 break;
212
213 if (k != NULL) {
214 kbd_release(k->kbd, &k->kbd);
215 SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
216
217 k->kbd = NULL;
218
219 kfree(k, M_KBDMUX);
220 }
221
222 } break;
223
224 default:
225 return (EINVAL);
226 /* NOT REACHED */
227 }
228 return (0);
229 }
230
231 /****************************************************************************
232 ****************************************************************************
233 ** Keyboard driver
234 ****************************************************************************
235 ****************************************************************************/
236
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;
255
256 static keyboard_switch_t kbdmuxsw = {
257 .probe = kbdmux_probe,
258 .init = kbdmux_init,
259 .term = kbdmux_term,
260 .intr = kbdmux_intr,
261 .test_if = kbdmux_test_if,
262 .enable = kbdmux_enable,
263 .disable = kbdmux_disable,
264 .read = kbdmux_read,
265 .check = kbdmux_check,
266 .read_char = kbdmux_read_char,
267 .check_char = kbdmux_check_char,
268 .ioctl = kbdmux_ioctl,
269 .lock = kbdmux_lock,
270 .clear_state = kbdmux_clear_state,
271 .get_state = kbdmux_get_state,
272 .set_state = kbdmux_set_state,
273 .get_fkeystr = genkbd_get_fkeystr,
274 .poll = kbdmux_poll,
275 .diag = genkbd_diag,
276 };
277
278 #ifdef EVDEV_SUPPORT
279 static const struct evdev_methods kbdmux_evdev_methods = {
280 .ev_event = evdev_ev_kbd_event,
281 };
282 #endif
283
284 /*
285 * Return the number of found keyboards
286 */
287 static int
kbdmux_configure(int flags)288 kbdmux_configure(int flags)
289 {
290 return (1);
291 }
292
293 /*
294 * Detect a keyboard
295 */
296 static int
kbdmux_probe(int unit,void * arg,int flags)297 kbdmux_probe(int unit, void *arg, int flags)
298 {
299 if (resource_disabled(KEYBOARD_NAME, unit))
300 return (ENXIO);
301
302 return (0);
303 }
304
305 /*
306 * Reset and initialize the keyboard (stolen from atkbd.c)
307 *
308 * Called without kbd lock held.
309 */
310 static int
kbdmux_init(int unit,keyboard_t ** kbdp,void * arg,int flags)311 kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags)
312 {
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];
319 #ifdef EVDEV_SUPPORT
320 struct evdev_dev *evdev;
321 char phys_loc[NAMELEN];
322 #endif
323
324 if (*kbdp == NULL) {
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);
331 needfree = 1;
332
333 if ((kbd == NULL) || (state == NULL) || (keymap == NULL) ||
334 (accmap == NULL) || (fkeymap == NULL)) {
335 error = ENOMEM;
336 goto bad;
337 }
338
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)) {
342 return (0);
343 } else {
344 kbd = *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;
350 needfree = 0;
351 }
352
353 if (!KBD_IS_PROBED(kbd)) {
354 /* XXX assume 101/102 keys keyboard */
355 kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags,
356 KB_PRI_MUX, 0, 0);
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;
363
364 KBD_FOUND_DEVICE(kbd);
365 KBD_PROBE_DONE(kbd);
366
367 kbdmux_clear_state(kbd);
368 state->ks_mode = K_XLATE;
369 }
370
371 if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) {
372 kbd->kb_config = flags & ~KB_CONF_PROBE_ONLY;
373
374 kbdmux_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state);
375
376 delay[0] = kbd->kb_delay1;
377 delay[1] = kbd->kb_delay2;
378 kbdmux_ioctl(kbd, KDSETREPEAT, (caddr_t)delay);
379
380 #ifdef EVDEV_SUPPORT
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);
396
397 if (evdev_register(evdev))
398 evdev_free(evdev);
399 else
400 state->ks_evdev = evdev;
401 state->ks_evdev_state = 0;
402 #endif
403
404 KBD_INIT_DONE(kbd);
405 }
406
407 if (!KBD_IS_CONFIGURED(kbd)) {
408 if (kbd_register(kbd) < 0) {
409 error = ENXIO;
410 goto bad;
411 }
412
413 KBD_CONFIG_DONE(kbd);
414 }
415
416 return (0);
417 bad:
418 if (needfree) {
419 if (state != NULL)
420 kfree(state, M_KBDMUX);
421 if (keymap != NULL)
422 kfree(keymap, M_KBDMUX);
423 if (accmap != NULL)
424 kfree(accmap, M_KBDMUX);
425 if (fkeymap != NULL)
426 kfree(fkeymap, M_KBDMUX);
427 if (kbd != NULL) {
428 kfree(kbd, M_KBDMUX);
429 *kbdp = NULL; /* insure ref doesn't leak to caller */
430 }
431 }
432
433 return (error);
434 }
435
436 /*
437 * Finish using this keyboard
438 *
439 * NOTE: deregistration automatically unlocks lock.
440 */
441 static int
kbdmux_term(keyboard_t * kbd)442 kbdmux_term(keyboard_t *kbd)
443 {
444 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
445 kbdmux_kbd_t *k;
446
447 /* wait for interrupt task */
448 while (taskqueue_cancel(taskqueue_swi, &state->ks_task, NULL) != 0)
449 taskqueue_drain(taskqueue_swi, &state->ks_task);
450
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);
455
456 k->kbd = NULL;
457
458 kfree(k, M_KBDMUX);
459 }
460
461 kbd_unregister(kbd);
462
463 #ifdef EVDEV_SUPPORT
464 evdev_free(state->ks_evdev);
465 #endif
466
467 bzero(state, sizeof(*state));
468 kfree(state, M_KBDMUX);
469
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);
474
475 return (0);
476 }
477
478 /*
479 * Keyboard interrupt routine
480 */
481 static int
kbdmux_intr(keyboard_t * kbd,void * arg)482 kbdmux_intr(keyboard_t *kbd, void *arg)
483 {
484 int c;
485
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);
490 } else {
491 /* read and discard the input; no one is waiting for input */
492 do {
493 c = kbdmux_read_char(kbd, FALSE);
494 } while (c != NOKEY);
495 }
496
497 return (0);
498 }
499
500 /*
501 * Test the interface to the device
502 */
503 static int
kbdmux_test_if(keyboard_t * kbd)504 kbdmux_test_if(keyboard_t *kbd)
505 {
506 return (0);
507 }
508
509 /*
510 * Enable the access to the device; until this function is called,
511 * the client cannot read from the keyboard.
512 */
513 static int
kbdmux_enable(keyboard_t * kbd)514 kbdmux_enable(keyboard_t *kbd)
515 {
516 KBD_ACTIVATE(kbd);
517 return (0);
518 }
519
520 /*
521 * Disallow the access to the device
522 */
523 static int
kbdmux_disable(keyboard_t * kbd)524 kbdmux_disable(keyboard_t *kbd)
525 {
526 KBD_DEACTIVATE(kbd);
527 return (0);
528 }
529
530 /*
531 * Read one byte from the keyboard if it's allowed
532 */
533 static int
kbdmux_read(keyboard_t * kbd,int wait)534 kbdmux_read(keyboard_t *kbd, int wait)
535 {
536 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
537 int c, ret;
538
539 do {
540 c = kbdmux_kbd_getc(state);
541 } while (c == -1 && wait);
542
543 if (c != -1)
544 kbd->kb_count++;
545
546 ret = (KBD_IS_ACTIVE(kbd)? c : -1);
547
548 return ret;
549 }
550
551 /*
552 * Check if data is waiting
553 */
554 static int
kbdmux_check(keyboard_t * kbd)555 kbdmux_check(keyboard_t *kbd)
556 {
557 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
558 int ready;
559
560 if (!KBD_IS_ACTIVE(kbd))
561 return (FALSE);
562
563 ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
564
565 return (ready);
566 }
567
568 /*
569 * Read char from the keyboard (stolen from atkbd.c)
570 *
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.
576 */
577 static u_int
kbdmux_read_char(keyboard_t * kbd,int wait)578 kbdmux_read_char(keyboard_t *kbd, int wait)
579 {
580 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
581 u_int action;
582 int scancode, keycode;
583
584 next_code:
585
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) {
591 return (ERRKEY);
592 }
593 return (action);
594 }
595
596 /*
597 * See if there is something in the keyboard queue
598 */
599 scancode = kbdmux_kbd_getc(state);
600
601 if (scancode == -1) {
602 if (state->ks_flags & POLLING) {
603 kbdmux_kbd_t *k;
604
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)
609 continue;
610 if (scancode == NOKEY)
611 break;
612 if (!KBD_IS_BUSY(k->kbd))
613 continue;
614 kbdmux_kbd_putc(state, scancode);
615 }
616 }
617
618 if (state->ks_inq_length > 0)
619 goto next_code;
620 if (wait)
621 goto next_code;
622 } else {
623 if (wait) {
624 if (kbd->kb_flags & KB_POLLED) {
625 tsleep(&state->ks_task, PCATCH,
626 "kbdwai", hz/10);
627 } else {
628 lksleep(&state->ks_task,
629 &kbd->kb_lock, PCATCH,
630 "kbdwai", hz/10);
631 }
632 goto next_code;
633 }
634 }
635 return (NOKEY);
636 }
637
638 kbd->kb_count++;
639
640 #ifdef EVDEV_SUPPORT
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,
644 scancode);
645
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);
650 }
651 }
652 #endif
653
654 /* return the byte as is for the K_RAW mode */
655 if (state->ks_mode == K_RAW)
656 return (scancode);
657
658 /* translate the scan code into a keycode */
659 keycode = scancode & 0x7F;
660 switch (state->ks_prefix) {
661 case 0x00: /* normal scancode */
662 switch(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;
668 }
669 break;
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;
674 }
675 break;
676 case 0xE0:
677 case 0xE1:
678 state->ks_prefix = scancode;
679 goto next_code;
680 }
681 break;
682 case 0xE0: /* 0xE0 prefix */
683 state->ks_prefix = 0;
684 switch (keycode) {
685 case 0x1C: /* right enter key */
686 keycode = 0x59;
687 break;
688 case 0x1D: /* right ctrl key */
689 keycode = 0x5A;
690 break;
691 case 0x35: /* keypad divide key */
692 keycode = 0x5B;
693 break;
694 case 0x37: /* print scrn key */
695 keycode = 0x5C;
696 break;
697 case 0x38: /* right alt key (alt gr) */
698 keycode = 0x5D;
699 break;
700 case 0x46: /* ctrl-pause/break on AT 101 (see below) */
701 keycode = 0x68;
702 break;
703 case 0x47: /* grey home key */
704 keycode = 0x5E;
705 break;
706 case 0x48: /* grey up arrow key */
707 keycode = 0x5F;
708 break;
709 case 0x49: /* grey page up key */
710 keycode = 0x60;
711 break;
712 case 0x4B: /* grey left arrow key */
713 keycode = 0x61;
714 break;
715 case 0x4D: /* grey right arrow key */
716 keycode = 0x62;
717 break;
718 case 0x4F: /* grey end key */
719 keycode = 0x63;
720 break;
721 case 0x50: /* grey down arrow key */
722 keycode = 0x64;
723 break;
724 case 0x51: /* grey page down key */
725 keycode = 0x65;
726 break;
727 case 0x52: /* grey insert key */
728 keycode = 0x66;
729 break;
730 case 0x53: /* grey delete key */
731 keycode = 0x67;
732 break;
733 /* the following 3 are only used on the MS "Natural" keyboard */
734 case 0x5b: /* left Window key */
735 keycode = 0x69;
736 break;
737 case 0x5c: /* right Window key */
738 keycode = 0x6a;
739 break;
740 case 0x5d: /* menu key */
741 keycode = 0x6b;
742 break;
743 case 0x5e: /* power key */
744 keycode = 0x6d;
745 break;
746 case 0x5f: /* sleep key */
747 keycode = 0x6e;
748 break;
749 case 0x63: /* wake key */
750 keycode = 0x6f;
751 break;
752 case 0x64: /* [JP106USB] backslash, underscore */
753 keycode = 0x73;
754 break;
755 default: /* ignore everything else */
756 goto next_code;
757 }
758 break;
759 case 0xE1: /* 0xE1 prefix */
760 /*
761 * The pause/break key on the 101 keyboard produces:
762 * E1-1D-45 E1-9D-C5
763 * Ctrl-pause/break produces:
764 * E0-46 E0-C6 (See above.)
765 */
766 state->ks_prefix = 0;
767 if (keycode == 0x1D)
768 state->ks_prefix = 0x1D;
769 goto next_code;
770 /* NOT REACHED */
771 case 0x1D: /* pause / break */
772 state->ks_prefix = 0;
773 if (keycode != 0x45)
774 goto next_code;
775 keycode = 0x68;
776 break;
777 }
778
779 /* XXX assume 101/102 keys AT keyboard */
780 switch (keycode) {
781 case 0x5c: /* print screen */
782 if (state->ks_flags & ALTS)
783 keycode = 0x54; /* sysrq */
784 break;
785 case 0x68: /* pause/break */
786 if (state->ks_flags & CTLS)
787 keycode = 0x6c; /* break */
788 break;
789 }
790
791 /* return the key code in the K_CODE mode */
792 if (state->ks_mode == K_CODE)
793 return (keycode | (scancode & 0x80));
794
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)
803 return (ERRKEY);
804 goto next_code;
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)
809 return (ERRKEY);
810 goto next_code;
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)
815 return (ERRKEY);
816 goto next_code;
817 case 0x52: /* keypad 0 */
818 state->ks_composed_char *= 10;
819 if (state->ks_composed_char > UCHAR_MAX)
820 return (ERRKEY);
821 goto next_code;
822
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 */
828 goto next_code;
829
830 case 0x38: /* left alt key */
831 break;
832
833 default:
834 if (state->ks_composed_char > 0) {
835 state->ks_flags &= ~COMPOSE;
836 state->ks_composed_char = 0;
837 return (ERRKEY);
838 }
839 break;
840 }
841 }
842
843 /* keycode to key action */
844 action = genkbd_keyaction(kbd, keycode, scancode & 0x80,
845 &state->ks_state, &state->ks_accents);
846 if (action == NOKEY)
847 goto next_code;
848
849 return (action);
850 }
851
852 /*
853 * Check if char is waiting
854 */
855 static int
kbdmux_check_char(keyboard_t * kbd)856 kbdmux_check_char(keyboard_t *kbd)
857 {
858 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
859 int ready;
860
861 if (!KBD_IS_ACTIVE(kbd))
862 return (FALSE);
863
864 if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char != 0))
865 ready = TRUE;
866 else
867 ready = (state->ks_inq_length > 0) ? TRUE : FALSE;
868
869 return (ready);
870 }
871
872 /*
873 * Keyboard ioctl's
874 */
875 static int
kbdmux_ioctl(keyboard_t * kbd,u_long cmd,caddr_t arg)876 kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg)
877 {
878 static int delays[] = {
879 250, 500, 750, 1000
880 };
881
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
887 };
888
889 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
890 kbdmux_kbd_t *k;
891 keyboard_info_t *ki;
892 int error = 0, mode, i;
893
894 if (state == NULL)
895 return (ENXIO);
896
897 switch (cmd) {
898 case KBADDKBD: /* add keyboard to the mux */
899 ki = (keyboard_info_t *) arg;
900
901 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
902 strcmp(ki->kb_name, "*") == 0) {
903 return (EINVAL); /* bad input */
904 }
905
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)
909 break;
910
911 if (k != NULL)
912 return (0); /* keyboard already in the mux */
913
914 k = kmalloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO);
915 if (k == NULL)
916 return (ENOMEM); /* out of memory */
917
918 k->kbd = kbd_get_keyboard(
919 kbd_allocate(
920 ki->kb_name,
921 ki->kb_unit,
922 (void *) &k->kbd,
923 kbdmux_kbd_event, (void *) state));
924 if (k->kbd == NULL) {
925 kfree(k, M_KBDMUX);
926 return (EINVAL); /* bad keyboard */
927 }
928
929 kbd_enable(k->kbd);
930 kbd_clear_state(k->kbd);
931
932 /* set K_RAW mode on slave keyboard */
933 mode = K_RAW;
934 error = kbd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode);
935 if (error == 0) {
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);
939 }
940
941 if (error != 0) {
942 kbd_release(k->kbd, &k->kbd);
943 k->kbd = NULL;
944 kfree(k, M_KBDMUX);
945 return (error); /* could not set mode */
946 }
947
948 SLIST_INSERT_HEAD(&state->ks_kbds, k, next);
949 break;
950
951 case KBRELKBD: /* release keyboard from the mux */
952 ki = (keyboard_info_t *) arg;
953
954 if (ki == NULL || ki->kb_unit < 0 || ki->kb_name[0] == '\0' ||
955 strcmp(ki->kb_name, "*") == 0) {
956 return (EINVAL); /* bad input */
957 }
958
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)
962 break;
963
964 if (k != NULL) {
965 error = kbd_release(k->kbd, &k->kbd);
966 if (error == 0) {
967 SLIST_REMOVE(&state->ks_kbds, k, kbdmux_kbd, next);
968
969 k->kbd = NULL;
970
971 kfree(k, M_KBDMUX);
972 }
973 } else
974 error = ENXIO; /* keyboard is not in the mux */
975
976 break;
977
978 case KDGKBMODE: /* get kyboard mode */
979 *(int *)arg = state->ks_mode;
980 break;
981
982 case KDSKBMODE: /* set keyboard mode */
983 switch (*(int *)arg) {
984 case K_XLATE:
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);
989 }
990 /* FALLTHROUGH */
991
992 case K_RAW:
993 case K_CODE:
994 if (state->ks_mode != *(int *)arg) {
995 kbdmux_clear_state(kbd);
996 state->ks_mode = *(int *)arg;
997 }
998 break;
999
1000 default:
1001 error = EINVAL;
1002 break;
1003 }
1004 break;
1005
1006 case KDGETLED: /* get keyboard LED */
1007 *(int *)arg = KBD_LED_VAL(kbd);
1008 break;
1009
1010 case KDSETLED: /* set keyboard LED */
1011 /* NOTE: lock key state in ks_state won't be changed */
1012 if (*(int *)arg & ~LOCK_MASK)
1013 return (EINVAL);
1014
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);
1020 #endif
1021 /* KDSETLED on all slave keyboards */
1022 SLIST_FOREACH(k, &state->ks_kbds, next)
1023 kbd_ioctl(k->kbd, KDSETLED, arg);
1024 break;
1025
1026 case KDGKBSTATE: /* get lock key state */
1027 *(int *)arg = state->ks_state & LOCK_MASK;
1028 break;
1029
1030 case KDSKBSTATE: /* set lock key state */
1031 if (*(int *)arg & ~LOCK_MASK)
1032 return (EINVAL);
1033
1034 state->ks_state &= ~LOCK_MASK;
1035 state->ks_state |= *(int *)arg;
1036
1037 /* KDSKBSTATE on all slave keyboards */
1038 SLIST_FOREACH(k, &state->ks_kbds, next)
1039 kbd_ioctl(k->kbd, KDSKBSTATE, arg);
1040
1041 return (kbdmux_ioctl(kbd, KDSETLED, arg));
1042 /* NOT REACHED */
1043
1044 case KDSETREPEAT: /* set keyboard repeat rate (new interface) */
1045 /* lookup delay */
1046 for (i = NELEM(delays) - 1; i > 0; i --)
1047 if (((int *)arg)[0] >= delays[i])
1048 break;
1049 mode = i << 5;
1050
1051 /* lookup rate */
1052 for (i = NELEM(rates) - 1; i > 0; i --)
1053 if (((int *)arg)[1] >= rates[i])
1054 break;
1055 mode |= i;
1056
1057 if (mode & ~0x7f)
1058 return (EINVAL);
1059
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);
1066 #endif
1067 /* perform command on all slave keyboards */
1068 SLIST_FOREACH(k, &state->ks_kbds, next)
1069 kbd_ioctl(k->kbd, cmd, arg);
1070 break;
1071
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;
1076
1077 /* perform command on all slave keyboards */
1078 SLIST_FOREACH(k, &state->ks_kbds, next)
1079 kbd_ioctl(k->kbd, cmd, arg);
1080 /* FALLTHROUGH */
1081
1082 default:
1083 error = genkbd_commonioctl(kbd, cmd, arg);
1084 break;
1085 }
1086 return (error);
1087 }
1088
1089 /*
1090 * Lock the access to the keyboard
1091 */
1092 static int
kbdmux_lock(keyboard_t * kbd,int lock)1093 kbdmux_lock(keyboard_t *kbd, int lock)
1094 {
1095 return (1); /* XXX */
1096 }
1097
1098 /*
1099 * Clear the internal state of the keyboard
1100 *
1101 * NOTE: May be called unlocked from init
1102 */
1103 static void
kbdmux_clear_state(keyboard_t * kbd)1104 kbdmux_clear_state(keyboard_t *kbd)
1105 {
1106 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
1107
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;
1114 }
1115
1116 /*
1117 * Save the internal state
1118 */
1119 static int
kbdmux_get_state(keyboard_t * kbd,void * buf,size_t len)1120 kbdmux_get_state(keyboard_t *kbd, void *buf, size_t len)
1121 {
1122 if (len == 0)
1123 return (sizeof(kbdmux_state_t));
1124 if (len < sizeof(kbdmux_state_t))
1125 return (-1);
1126
1127 bcopy(kbd->kb_data, buf, sizeof(kbdmux_state_t)); /* XXX locking? */
1128
1129 return (0);
1130 }
1131
1132 /*
1133 * Set the internal state
1134 */
1135 static int
kbdmux_set_state(keyboard_t * kbd,void * buf,size_t len)1136 kbdmux_set_state(keyboard_t *kbd, void *buf, size_t len)
1137 {
1138 if (len < sizeof(kbdmux_state_t))
1139 return (ENOMEM);
1140
1141 bcopy(buf, kbd->kb_data, sizeof(kbdmux_state_t)); /* XXX locking? */
1142
1143 return (0);
1144 }
1145
1146 /*
1147 * Set polling
1148 *
1149 * Caller interlocks all keyboard calls. We must not lock here.
1150 */
1151 static int
kbdmux_poll(keyboard_t * kbd,int on)1152 kbdmux_poll(keyboard_t *kbd, int on)
1153 {
1154 kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data;
1155 kbdmux_kbd_t *k;
1156
1157 if (on)
1158 state->ks_flags |= POLLING;
1159 else
1160 state->ks_flags &= ~POLLING;
1161
1162 /* set poll on slave keyboards */
1163 SLIST_FOREACH(k, &state->ks_kbds, next)
1164 kbd_poll(k->kbd, on);
1165
1166 return (0);
1167 }
1168
1169 /*****************************************************************************
1170 *****************************************************************************
1171 ** Module
1172 *****************************************************************************
1173 *****************************************************************************/
1174
1175 KEYBOARD_DRIVER(kbdmux, kbdmuxsw, kbdmux_configure);
1176
1177 static int
kbdmux_modevent(module_t mod,int type,void * data)1178 kbdmux_modevent(module_t mod, int type, void *data)
1179 {
1180 keyboard_switch_t *sw;
1181 keyboard_t *kbd;
1182 int error;
1183
1184 switch (type) {
1185 case MOD_LOAD:
1186 if ((error = kbd_add_driver(&kbdmux_kbd_driver)) != 0)
1187 break;
1188
1189 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL) {
1190 kbd_delete_driver(&kbdmux_kbd_driver);
1191 error = ENXIO;
1192 break;
1193 }
1194
1195 kbd = NULL;
1196
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);
1200 break;
1201 }
1202
1203 #ifdef KBD_INSTALL_CDEV
1204 if ((error = kbd_attach(kbd)) != 0) {
1205 (*sw->term)(kbd);
1206 kbd_delete_driver(&kbdmux_kbd_driver);
1207 break;
1208 }
1209 #endif
1210
1211 if ((error = (*sw->enable)(kbd)) != 0) {
1212 (*sw->disable)(kbd);
1213 #ifdef KBD_INSTALL_CDEV
1214 kbd_detach(kbd);
1215 #endif
1216 (*sw->term)(kbd);
1217 kbd_delete_driver(&kbdmux_kbd_driver);
1218 break;
1219 }
1220 break;
1221
1222 case MOD_UNLOAD:
1223 if ((sw = kbd_get_switch(KEYBOARD_NAME)) == NULL)
1224 panic("kbd_get_switch(" KEYBOARD_NAME ") == NULL");
1225
1226 kbd = kbd_get_keyboard(kbd_find_keyboard(KEYBOARD_NAME, 0));
1227 if (kbd != NULL) {
1228 (*sw->disable)(kbd);
1229 #ifdef KBD_INSTALL_CDEV
1230 kbd_detach(kbd);
1231 #endif
1232 (*sw->term)(kbd);
1233 kbd_delete_driver(&kbdmux_kbd_driver);
1234 }
1235 error = 0;
1236 break;
1237
1238 default:
1239 error = EOPNOTSUPP;
1240 break;
1241 }
1242 return (error);
1243 }
1244
1245 DEV_MODULE(kbdmux, kbdmux_modevent, NULL);
1246 #ifdef EVDEV_SUPPORT
1247 MODULE_DEPEND(kbdmux, evdev, 1, 1, 1);
1248 #endif
1249