From bcc53404f2f90340de9a9ea266fa17c631507651 Mon Sep 17 00:00:00 2001 From: Alex Hornung Date: Wed, 9 Sep 2009 14:54:18 +0100 Subject: [PATCH] kbdmux - make it work for us * port kbdmux to DragonFly. * change syscons to use kbdmux, if available. * change kbd to use kbdmux, if available. * cleanup kbd. * use a simple buffer instead of clists for kbd. * move kbd_ macros from syscons.h to kbdregs.h * use kbd_ macros everywhere instead of unreadable stuff. * sync ukbd with FreeBSD's latest ukbd before their switch to usb4bsd. Partially-Obtained-from: FreeBSD --- sys/conf/files | 1 + sys/dev/misc/atkbd/atkbd_isa.c | 4 +- sys/dev/misc/kbd/atkbd.c | 8 +-- sys/dev/misc/kbd/kbd.c | 155 ++++++++++++++++++++++++++++++----------- sys/dev/misc/kbd/kbdreg.h | 50 +++++++++++++ sys/dev/misc/kbdmux/kbdmux.c | 119 ++++++++++++------------------- sys/dev/misc/syscons/syscons.c | 52 ++++++++++++-- sys/dev/misc/syscons/syscons.h | 20 ------ sys/dev/usbmisc/ukbd/ukbd.c | 120 +++++++++++-------------------- sys/sys/kbio.h | 3 + 10 files changed, 309 insertions(+), 223 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index 7275900dae..2449b8344b 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1496,6 +1496,7 @@ bus/isa/isa_common.c optional isa bus/isa/isahint.c optional isa bus/isa/pnpeat.c optional isa dev/misc/joy/joy.c optional joy +dev/misc/kbdmux/kbdmux.c optional kbdmux dev/misc/orm/orm.c optional isa bus/isa/pnp.c optional isa bus/isa/pnpparse.c optional isa diff --git a/sys/dev/misc/atkbd/atkbd_isa.c b/sys/dev/misc/atkbd/atkbd_isa.c index 7319ab1b20..02eaa64418 100644 --- a/sys/dev/misc/atkbd/atkbd_isa.c +++ b/sys/dev/misc/atkbd/atkbd_isa.c @@ -125,7 +125,7 @@ atkbdresume(device_t dev) kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME, device_get_unit(dev))); if (kbd) - (*kbdsw[kbd->kb_index]->clear_state)(kbd); + kbd_clear_state(kbd); return 0; } @@ -135,7 +135,7 @@ atkbd_isa_intr(void *arg) keyboard_t *kbd; kbd = (keyboard_t *)arg; - (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); + kbd_intr(kbd, NULL); } DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0); diff --git a/sys/dev/misc/kbd/atkbd.c b/sys/dev/misc/kbd/atkbd.c index 59de1f7af4..cb1d0f6509 100644 --- a/sys/dev/misc/kbd/atkbd.c +++ b/sys/dev/misc/kbd/atkbd.c @@ -149,15 +149,15 @@ atkbd_timeout(void *arg) */ crit_enter(); kbd = (keyboard_t *)arg; - if ((*kbdsw[kbd->kb_index]->lock)(kbd, TRUE)) { + if (kbd_lock(kbd, TRUE)) { /* * We have seen the lock flag is not set. Let's reset * the flag early, otherwise the LED update routine fails * which may want the lock during the interrupt routine. */ - (*kbdsw[kbd->kb_index]->lock)(kbd, FALSE); - if ((*kbdsw[kbd->kb_index]->check_char)(kbd)) - (*kbdsw[kbd->kb_index]->intr)(kbd, NULL); + kbd_lock(kbd, FALSE); + if (kbd_check_char(kbd)) + kbd_intr(kbd, NULL); } callout_reset(&kbd->kb_atkbd_timeout_ch, hz / 10, atkbd_timeout, arg); crit_exit(); diff --git a/sys/dev/misc/kbd/kbd.c b/sys/dev/misc/kbd/kbd.c index 2e69d3dcc4..c4266d9457 100644 --- a/sys/dev/misc/kbd/kbd.c +++ b/sys/dev/misc/kbd/kbd.c @@ -32,6 +32,7 @@ * Interrupt note: keyboards use clist functions and since usb keyboard * interrupts are not protected by spltty(), we must use a critical section * to protect against corruption. + * XXX: this keyboard driver doesn't use clist functions anymore! */ #include "opt_kbd.h" @@ -55,11 +56,16 @@ #define KBD_INDEX(dev) minor(dev) +#define KB_QSIZE 512 +#define KB_BUFSIZE 64 + struct genkbd_softc { int gkb_flags; /* flag/status bits */ #define KB_ASLEEP (1 << 0) - struct clist gkb_q; /* input queue */ struct selinfo gkb_rsel; + char gkb_q[KB_QSIZE]; /* input queue */ + unsigned int gkb_q_start; + unsigned int gkb_q_length; }; typedef struct genkbd_softc *genkbd_softc_t; @@ -194,8 +200,12 @@ kbd_register(keyboard_t *kbd) { const keyboard_driver_t **list; const keyboard_driver_t *p; + keyboard_t *mux; + keyboard_info_t ki; int index; + mux = kbd_get_keyboard(kbd_find_keyboard("kbdmux", -1)); + for (index = 0; index < keyboards; ++index) { if (keyboard[index] == NULL) break; @@ -218,6 +228,14 @@ kbd_register(keyboard_t *kbd) if (strcmp(p->name, kbd->kb_name) == 0) { keyboard[index] = kbd; kbdsw[index] = p->kbdsw; + + if (mux != NULL) { + bzero(&ki, sizeof(ki)); + strcpy(ki.kb_name, kbd->kb_name); + ki.kb_unit = kbd->kb_unit; + kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki); + } + return index; } } @@ -226,6 +244,14 @@ kbd_register(keyboard_t *kbd) if (strcmp(p->name, kbd->kb_name) == 0) { keyboard[index] = kbd; kbdsw[index] = p->kbdsw; + + if (mux != NULL) { + bzero(&ki, sizeof(ki)); + strcpy(ki.kb_name, kbd->kb_name); + ki.kb_unit = kbd->kb_unit; + kbd_ioctl(mux, KBADDKBD, (caddr_t) &ki); + } + return index; } } @@ -291,10 +317,12 @@ kbd_get_switch(char *driver) * cdev driver, use these functions to claim and release a keyboard for * exclusive use. */ - -/* find the keyboard specified by a driver name and a unit number */ +/* + * find the keyboard specified by a driver name and a unit number + * starting at given index + */ int -kbd_find_keyboard(char *driver, int unit) +kbd_find_keyboard2(char *driver, int unit, int index, int legacy) { int i; int pref; @@ -303,7 +331,10 @@ kbd_find_keyboard(char *driver, int unit) pref = 0; pref_index = -1; - for (i = 0; i < keyboards; ++i) { + if ((index < 0) || (index >= keyboards)) + return (-1); + + for (i = index; i < keyboards; ++i) { if (keyboard[i] == NULL) continue; if (!KBD_IS_VALID(keyboard[i])) @@ -312,14 +343,33 @@ kbd_find_keyboard(char *driver, int unit) continue; if ((unit != -1) && (keyboard[i]->kb_unit != unit)) continue; - if (pref <= keyboard[i]->kb_pref) { - pref = keyboard[i]->kb_pref; - pref_index = i; + /* + * If we are in legacy mode, we do the old preference magic and + * don't return on the first found unit. + */ + if (legacy) { + if (pref <= keyboard[i]->kb_pref) { + pref = keyboard[i]->kb_pref; + pref_index = i; + } + } else { + return i; } } + + if (!legacy) + KKASSERT(pref_index == -1); + return (pref_index); } +/* find the keyboard specified by a driver name and a unit number */ +int +kbd_find_keyboard(char *driver, int unit) +{ + return (kbd_find_keyboard2(driver, unit, 0, 1)); +} + /* allocate a keyboard */ int kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func, @@ -341,7 +391,7 @@ kbd_allocate(char *driver, int unit, void *id, kbd_callback_func_t *func, KBD_BUSY(keyboard[index]); keyboard[index]->kb_callback.kc_func = func; keyboard[index]->kb_callback.kc_arg = arg; - (*kbdsw[index]->clear_state)(keyboard[index]); + kbd_clear_state(keyboard[index]); } crit_exit(); return index; @@ -362,7 +412,7 @@ kbd_release(keyboard_t *kbd, void *id) KBD_UNBUSY(kbd); kbd->kb_callback.kc_func = NULL; kbd->kb_callback.kc_arg = NULL; - (*kbdsw[kbd->kb_index]->clear_state)(kbd); + kbd_clear_state(kbd); error = 0; } crit_exit(); @@ -517,8 +567,38 @@ kbd_detach(keyboard_t *kbd) * driver functions. */ -#define KB_QSIZE 512 -#define KB_BUFSIZE 64 +static void +genkbd_putc(genkbd_softc_t sc, char c) +{ + unsigned int p; + + if (sc->gkb_q_length == KB_QSIZE) + return; + + p = (sc->gkb_q_start + sc->gkb_q_length) % KB_QSIZE; + sc->gkb_q[p] = c; + sc->gkb_q_length++; +} + +static size_t +genkbd_getc(genkbd_softc_t sc, char *buf, size_t len) +{ + + /* Determine copy size. */ + if (sc->gkb_q_length == 0) + return (0); + if (len >= sc->gkb_q_length) + len = sc->gkb_q_length; + if (len >= KB_QSIZE - sc->gkb_q_start) + len = KB_QSIZE - sc->gkb_q_start; + + /* Copy out data and progress offset. */ + memcpy(buf, sc->gkb_q + sc->gkb_q_start, len); + sc->gkb_q_start = (sc->gkb_q_start + len) % KB_QSIZE; + sc->gkb_q_length -= len; + + return (len); +} static kbd_callback_func_t genkbd_event; @@ -551,12 +631,7 @@ genkbdopen(struct dev_open_args *ap) * the device may still be missing (!KBD_HAS_DEVICE(kbd)). */ -#if 0 - bzero(&sc->gkb_q, sizeof(sc->gkb_q)); -#endif - clist_alloc_cblocks(&sc->gkb_q, KB_QSIZE, KB_QSIZE/2); /* XXX */ - sc->gkb_rsel.si_flags = 0; - sc->gkb_rsel.si_pid = 0; + sc->gkb_q_length = 0; crit_exit(); return 0; @@ -580,9 +655,6 @@ genkbdclose(struct dev_close_args *ap) /* XXX: we shall be forgiving and don't report error... */ } else { kbd_release(kbd, (void *)sc); -#if 0 - clist_free_cblocks(&sc->gkb_q); -#endif } crit_exit(); return 0; @@ -607,8 +679,8 @@ genkbdread(struct dev_read_args *ap) crit_exit(); return ENXIO; } - while (sc->gkb_q.c_cc == 0) { - if (ap->a_ioflag & IO_NDELAY) { + while (sc->gkb_q_length == 0) { + if (ap->a_ioflag & IO_NDELAY) { /* O_NONBLOCK? */ crit_exit(); return EWOULDBLOCK; } @@ -631,8 +703,8 @@ genkbdread(struct dev_read_args *ap) error = 0; while (uio->uio_resid > 0) { len = (int)szmin(uio->uio_resid, sizeof(buffer)); - len = q_to_b(&sc->gkb_q, buffer, len); - if (len == 0) + len = genkbd_getc(sc, buffer, len); + if (len <= 0) break; error = uiomove(buffer, (size_t)len, uio); if (error) @@ -664,7 +736,7 @@ genkbdioctl(struct dev_ioctl_args *ap) kbd = kbd_get_keyboard(KBD_INDEX(dev)); if ((kbd == NULL) || !KBD_IS_VALID(kbd)) return ENXIO; - error = (*kbdsw[kbd->kb_index]->ioctl)(kbd, ap->a_cmd, ap->a_data); + error = kbd_ioctl(kbd, ap->a_cmd, ap->a_data); if (error == ENOIOCTL) error = ENODEV; return error; @@ -685,7 +757,7 @@ genkbdpoll(struct dev_poll_args *ap) if ((sc == NULL) || (kbd == NULL) || !KBD_IS_VALID(kbd)) { revents = POLLHUP; /* the keyboard has gone */ } else if (ap->a_events & (POLLIN | POLLRDNORM)) { - if (sc->gkb_q.c_cc > 0) + if (sc->gkb_q_length > 0) revents = ap->a_events & (POLLIN | POLLRDNORM); else selrecord(curthread, &sc->gkb_rsel); @@ -724,12 +796,12 @@ genkbd_event(keyboard_t *kbd, int event, void *arg) } /* obtain the current key input mode */ - if ((*kbdsw[kbd->kb_index]->ioctl)(kbd, KDGKBMODE, (caddr_t)&mode)) + if (kbd_ioctl(kbd, KDGKBMODE, (caddr_t)&mode)) mode = K_XLATE; /* read all pending input */ - while ((*kbdsw[kbd->kb_index]->check_char)(kbd)) { - c = (*kbdsw[kbd->kb_index]->read_char)(kbd, FALSE); + while (kbd_check_char(kbd)) { + c = kbd_read_char(kbd, FALSE); if (c == NOKEY) continue; if (c == ERRKEY) /* XXX: ring bell? */ @@ -740,7 +812,7 @@ genkbd_event(keyboard_t *kbd, int event, void *arg) /* store the byte as is for K_RAW and K_CODE modes */ if (mode != K_XLATE) { - clist_putc(KEYCHAR(c), &sc->gkb_q); + genkbd_putc(sc, KEYCHAR(c)); continue; } @@ -755,9 +827,9 @@ genkbd_event(keyboard_t *kbd, int event, void *arg) /* ignore them... */ continue; case BTAB: /* a backtab: ESC [ Z */ - clist_putc(0x1b, &sc->gkb_q); - clist_putc('[', &sc->gkb_q); - clist_putc('Z', &sc->gkb_q); + genkbd_putc(sc, 0x1b); + genkbd_putc(sc, '['); + genkbd_putc(sc, 'Z'); continue; } } @@ -765,25 +837,24 @@ genkbd_event(keyboard_t *kbd, int event, void *arg) /* normal chars, normal chars with the META, function keys */ switch (KEYFLAGS(c)) { case 0: /* a normal char */ - clist_putc(KEYCHAR(c), &sc->gkb_q); + genkbd_putc(sc, KEYCHAR(c)); break; case MKEY: /* the META flag: prepend ESC */ - clist_putc(0x1b, &sc->gkb_q); - clist_putc(KEYCHAR(c), &sc->gkb_q); + genkbd_putc(sc, 0x1b); + genkbd_putc(sc, KEYCHAR(c)); break; case FKEY | SPCLKEY: /* a function key, return string */ - cp = (*kbdsw[kbd->kb_index]->get_fkeystr)(kbd, - KEYCHAR(c), &len); + cp = kbd_get_fkeystr(kbd, KEYCHAR(c), &len); if (cp != NULL) { while (len-- > 0) - clist_putc(*cp++, &sc->gkb_q); + genkbd_putc(sc, *cp++); } break; } } /* wake up sleeping/polling processes */ - if (sc->gkb_q.c_cc > 0) { + if (sc->gkb_q_length > 0) { if (sc->gkb_flags & KB_ASLEEP) { sc->gkb_flags &= ~KB_ASLEEP; wakeup((caddr_t)sc); @@ -973,7 +1044,7 @@ genkbd_diag(keyboard_t *kbd, int level) (s) |= l ## DOWN; \ (s) ^= l ## ED; \ i = (s) & LOCK_MASK; \ - (*kbdsw[(k)->kb_index]->ioctl)((k), KDSETLED, (caddr_t)&i); \ + kbd_ioctl((k), KDSETLED, (caddr_t)&i); \ } static u_int diff --git a/sys/dev/misc/kbd/kbdreg.h b/sys/dev/misc/kbd/kbdreg.h index cc126c237e..b97527ceed 100644 --- a/sys/dev/misc/kbd/kbdreg.h +++ b/sys/dev/misc/kbd/kbdreg.h @@ -62,6 +62,7 @@ struct keyboard { #define KB_INITIALIZED (1 << 19) /* device initialized */ #define KB_REGISTERED (1 << 20) /* device registered to kbdio */ #define KB_BUSY (1 << 21) /* device used by a client */ +#define KB_POLLED (1 << 22) /* device is polled */ int kb_active; /* 0: inactive */ void *kb_token; /* id of the current client */ keyboard_callback_t kb_callback;/* callback function */ @@ -114,6 +115,9 @@ struct keyboard { #define KBD_IS_BUSY(k) ((k)->kb_flags & KB_BUSY) #define KBD_BUSY(k) ((k)->kb_flags |= KB_BUSY) #define KBD_UNBUSY(k) ((k)->kb_flags &= ~KB_BUSY) +#define KBD_IS_POLLED(k) ((k)->kb_flags & KB_POLLED) +#define KBD_POLL(k) ((k)->kb_flags |= KB_POLLED) +#define KBD_UNPOLL(k) ((k)->kb_flags &= ~KB_POLLED) #define KBD_IS_ACTIVE(k) ((k)->kb_active) #define KBD_ACTIVATE(k) (++(k)->kb_active) #define KBD_DEACTIVATE(k) (--(k)->kb_active) @@ -164,6 +168,50 @@ typedef struct keyboard_switch { kbd_diag_t *diag; } keyboard_switch_t; +/* + * Keyboard disciplines: call actual handlers via kbdsw[]. + */ +#define kbd_probe(kbd, unit, arg, flags) \ + (*kbdsw[(kbd)->kb_index]->probe)((unit), (arg), (flags)) +#define kbd_init(kbd, unit, kbdpp, arg, flags) \ + (*kbdsw[(kbd)->kb_index]->init)((unit), (kbdpp), (arg), (flags)) +#define kbd_term(kbd) \ + (*kbdsw[(kbd)->kb_index]->term)((kbd)) +#define kbd_intr(kbd, arg) \ + (*kbdsw[(kbd)->kb_index]->intr)((kbd), (arg)) +#define kbd_test_if(kbd) \ + (*kbdsw[(kbd)->kb_index]->test_if)((kbd)) +#define kbd_enable(kbd) \ + (*kbdsw[(kbd)->kb_index]->enable)((kbd)) +#define kbd_disable(kbd) \ + (*kbdsw[(kbd)->kb_index]->disable)((kbd)) +#define kbd_read(kbd, wait) \ + (*kbdsw[(kbd)->kb_index]->read)((kbd), (wait)) +#define kbd_check(kbd) \ + (*kbdsw[(kbd)->kb_index]->check)((kbd)) +#define kbd_read_char(kbd, wait) \ + (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait)) +#define kbd_check_char(kbd) \ + (*kbdsw[(kbd)->kb_index]->check_char)((kbd)) +#define kbd_ioctl(kbd, cmd, arg) \ + (((kbd) == NULL) ? \ + ENODEV : \ + (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg))) +#define kbd_lock(kbd, lockf) \ + (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf)) +#define kbd_clear_state(kbd) \ + (*kbdsw[(kbd)->kb_index]->clear_state)((kbd)) +#define kbd_get_state(kbd, buf, len) \ + (*kbdsw[(kbd)->kb_index]->get_state)((kbd), (buf), (len)) +#define kbd_set_state(kbd, buf, len) \ + (*kbdsw[(kbd)->kb_index]->set_state)((kbd), (buf), (len)) +#define kbd_get_fkeystr(kbd, fkey, len) \ + (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len)) +#define kbd_poll(kbd, on) \ + (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on)) +#define kbd_diag(kbd, level) \ + (*kbdsw[(kbd)->kb_index]->diag)((kbd), (leve)) + /* keyboard driver */ typedef struct keyboard_driver { SLIST_ENTRY(keyboard_driver) link; @@ -205,6 +253,7 @@ int kbd_release(keyboard_t *kbd, void *id); int kbd_change_callback(keyboard_t *kbd, void *id, kbd_callback_func_t *func, void *arg); int kbd_find_keyboard(char *driver, int unit); +int kbd_find_keyboard2(char *driver, int unit, int index, int legacy); keyboard_t *kbd_get_keyboard(int index); /* a back door for the console driver to tickle the keyboard driver XXX */ @@ -255,6 +304,7 @@ int kbd_detach(keyboard_t *kbd); #define LED_MASK (LED_CAP | LED_NUM | LED_SCR) */ +#define KB_PRI_MUX 10 #define KB_PRI_ATKBD 50 #define KB_PRI_USB 60 diff --git a/sys/dev/misc/kbdmux/kbdmux.c b/sys/dev/misc/kbdmux/kbdmux.c index 26afbe403e..1ec93e668f 100644 --- a/sys/dev/misc/kbdmux/kbdmux.c +++ b/sys/dev/misc/kbdmux/kbdmux.c @@ -31,9 +31,6 @@ * $FreeBSD$ */ -#include "opt_compat.h" -#include "opt_kbd.h" - #include #include #include @@ -53,8 +50,8 @@ #include #include #include -#include -#include +#include +#include #define KEYBOARD_NAME "kbdmux" @@ -75,9 +72,12 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor"); * Just like the rest of keyboard drivers and syscons(4) do. * Note that callout is initialized as not MP-safe to make sure * Giant is held. + * XXX: I don't think we are MP-Safing the callout, maybe we + * should, using get_mplock() around it? NFI */ #if 0 /* not yet */ +#error "This stuff still needs porting!" #define KBDMUX_LOCK_DECL_GLOBAL \ struct mtx ks_lock #define KBDMUX_LOCK_INIT(s) \ @@ -95,7 +95,7 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor"); #define KBDMUX_CALLOUT_INIT(s) \ callout_init_mtx(&(s)->ks_timo, &(s)->ks_lock, 0) #define KBDMUX_QUEUE_INTR(s) \ - taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task) + taskqueue_enqueue(taskqueue_swi, &(s)->ks_task) #else #define KBDMUX_LOCK_DECL_GLOBAL @@ -110,11 +110,11 @@ MALLOC_DEFINE(M_KBDMUX, KEYBOARD_NAME, "Keyboard multiplexor"); #define KBDMUX_LOCK_ASSERT(s, w) #define KBDMUX_SLEEP(s, f, d, t) \ - tsleep(&(s)->f, PCATCH | (PZERO + 1), (d), (t)) + tsleep(&(s)->f, PCATCH | (84 + 1), (d), (t)) #define KBDMUX_CALLOUT_INIT(s) \ - callout_init(&(s)->ks_timo, 0) + callout_init(&(s)->ks_timo) #define KBDMUX_QUEUE_INTR(s) \ - taskqueue_enqueue(taskqueue_swi_giant, &(s)->ks_task) + taskqueue_enqueue(taskqueue_swi, &(s)->ks_task) #endif /* not yet */ /* @@ -205,7 +205,7 @@ kbdmux_kbd_intr(void *xkbd, int pending) keyboard_t *kbd = (keyboard_t *) xkbd; kbdmux_state_t *state = (kbdmux_state_t *) kbd->kb_data; - kbdd_intr(kbd, NULL); + kbd_intr(kbd, NULL); KBDMUX_LOCK(state); @@ -266,8 +266,8 @@ kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg) * NOKEY. */ - while (kbdd_check_char(kbd)) { - c = kbdd_read_char(kbd, 0); + while (kbd_check_char(kbd)) { + c = kbd_read_char(kbd, 0); if (c == NOKEY) break; if (c == ERRKEY) @@ -301,7 +301,7 @@ kbdmux_kbd_event(keyboard_t *kbd, int event, void *arg) k->kbd = NULL; - free(k, M_KBDMUX); + kfree(k, M_KBDMUX); } KBDMUX_UNLOCK(state); @@ -398,11 +398,11 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags) int error, needfree, fkeymap_size, delay[2]; if (*kbdp == NULL) { - *kbdp = kbd = malloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO); - state = malloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO); - keymap = malloc(sizeof(key_map), M_KBDMUX, M_NOWAIT); - accmap = malloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT); - fkeymap = malloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT); + *kbdp = kbd = kmalloc(sizeof(*kbd), M_KBDMUX, M_NOWAIT | M_ZERO); + state = kmalloc(sizeof(*state), M_KBDMUX, M_NOWAIT | M_ZERO); + keymap = kmalloc(sizeof(key_map), M_KBDMUX, M_NOWAIT); + accmap = kmalloc(sizeof(accent_map), M_KBDMUX, M_NOWAIT); + fkeymap = kmalloc(sizeof(fkey_tab), M_KBDMUX, M_NOWAIT); fkeymap_size = sizeof(fkey_tab)/sizeof(fkey_tab[0]); needfree = 1; @@ -430,7 +430,8 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags) if (!KBD_IS_PROBED(kbd)) { /* XXX assume 101/102 keys keyboard */ - kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, 0, 0); + kbd_init_struct(kbd, KEYBOARD_NAME, KB_101, unit, flags, + KB_PRI_MUX, 0, 0); bcopy(&key_map, keymap, sizeof(key_map)); bcopy(&accent_map, accmap, sizeof(accent_map)); bcopy(fkey_tab, fkeymap, @@ -476,15 +477,15 @@ kbdmux_init(int unit, keyboard_t **kbdp, void *arg, int flags) bad: if (needfree) { if (state != NULL) - free(state, M_KBDMUX); + kfree(state, M_KBDMUX); if (keymap != NULL) - free(keymap, M_KBDMUX); + kfree(keymap, M_KBDMUX); if (accmap != NULL) - free(accmap, M_KBDMUX); + kfree(accmap, M_KBDMUX); if (fkeymap != NULL) - free(fkeymap, M_KBDMUX); + kfree(fkeymap, M_KBDMUX); if (kbd != NULL) { - free(kbd, M_KBDMUX); + kfree(kbd, M_KBDMUX); *kbdp = NULL; /* insure ref doesn't leak to caller */ } } @@ -517,7 +518,7 @@ kbdmux_term(keyboard_t *kbd) k->kbd = NULL; - free(k, M_KBDMUX); + kfree(k, M_KBDMUX); } KBDMUX_UNLOCK(state); @@ -526,12 +527,12 @@ kbdmux_term(keyboard_t *kbd) KBDMUX_LOCK_DESTROY(state); bzero(state, sizeof(*state)); - free(state, M_KBDMUX); + kfree(state, M_KBDMUX); - free(kbd->kb_keymap, M_KBDMUX); - free(kbd->kb_accentmap, M_KBDMUX); - free(kbd->kb_fkeytab, M_KBDMUX); - free(kbd, M_KBDMUX); + kfree(kbd->kb_keymap, M_KBDMUX); + kfree(kbd->kb_accentmap, M_KBDMUX); + kfree(kbd->kb_fkeytab, M_KBDMUX); + kfree(kbd, M_KBDMUX); return (0); } @@ -662,8 +663,8 @@ next_code: kbdmux_kbd_t *k; SLIST_FOREACH(k, &state->ks_kbds, next) { - while (kbdd_check_char(k->kbd)) { - scancode = kbdd_read_char(k->kbd, 0); + while (kbd_check_char(k->kbd)) { + scancode = kbd_read_char(k->kbd, 0); if (scancode == NOKEY) break; if (scancode == ERRKEY) @@ -944,9 +945,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) kbdmux_kbd_t *k; keyboard_info_t *ki; int error = 0, mode; -#ifdef COMPAT_FREEBSD6 - int ival; -#endif if (state == NULL) return (ENXIO); @@ -972,7 +970,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) return (0); /* keyboard already in the mux */ } - k = malloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO); + k = kmalloc(sizeof(*k), M_KBDMUX, M_NOWAIT | M_ZERO); if (k == NULL) { KBDMUX_UNLOCK(state); @@ -987,21 +985,21 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) kbdmux_kbd_event, (void *) state)); if (k->kbd == NULL) { KBDMUX_UNLOCK(state); - free(k, M_KBDMUX); + kfree(k, M_KBDMUX); return (EINVAL); /* bad keyboard */ } - kbdd_enable(k->kbd); - kbdd_clear_state(k->kbd); + kbd_enable(k->kbd); + kbd_clear_state(k->kbd); /* set K_RAW mode on slave keyboard */ mode = K_RAW; - error = kbdd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode); + error = kbd_ioctl(k->kbd, KDSKBMODE, (caddr_t)&mode); if (error == 0) { /* set lock keys state on slave keyboard */ mode = state->ks_state & LOCK_MASK; - error = kbdd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode); + error = kbd_ioctl(k->kbd, KDSKBSTATE, (caddr_t)&mode); } if (error != 0) { @@ -1010,7 +1008,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) kbd_release(k->kbd, &k->kbd); k->kbd = NULL; - free(k, M_KBDMUX); + kfree(k, M_KBDMUX); return (error); /* could not set mode */ } @@ -1041,7 +1039,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) k->kbd = NULL; - free(k, M_KBDMUX); + kfree(k, M_KBDMUX); } } else error = ENXIO; /* keyboard is not in the mux */ @@ -1055,12 +1053,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) KBDMUX_UNLOCK(state); break; -#ifdef COMPAT_FREEBSD6 - case _IO('K', 7): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif case KDSKBMODE: /* set keyboard mode */ KBDMUX_LOCK(state); @@ -1095,12 +1087,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) KBDMUX_UNLOCK(state); break; -#ifdef COMPAT_FREEBSD6 - case _IO('K', 66): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif case KDSETLED: /* set keyboard LED */ KBDMUX_LOCK(state); @@ -1115,7 +1101,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) /* KDSETLED on all slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next) - kbdd_ioctl(k->kbd, KDSETLED, arg); + kbd_ioctl(k->kbd, KDSETLED, arg); KBDMUX_UNLOCK(state); break; @@ -1126,12 +1112,6 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) KBDMUX_UNLOCK(state); break; -#ifdef COMPAT_FREEBSD6 - case _IO('K', 20): - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif case KDSKBSTATE: /* set lock key state */ KBDMUX_LOCK(state); @@ -1146,20 +1126,13 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) /* KDSKBSTATE on all slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next) - kbdd_ioctl(k->kbd, KDSKBSTATE, arg); + kbd_ioctl(k->kbd, KDSKBSTATE, arg); KBDMUX_UNLOCK(state); return (kbdmux_ioctl(kbd, KDSETLED, arg)); /* NOT REACHED */ -#ifdef COMPAT_FREEBSD6 - case _IO('K', 67): - cmd = KDSETRAD; - ival = IOCPARM_IVAL(arg); - arg = (caddr_t)&ival; - /* FALLTHROUGH */ -#endif case KDSETREPEAT: /* set keyboard repeat rate (new interface) */ case KDSETRAD: /* set keyboard repeat rate (old interface) */ KBDMUX_LOCK(state); @@ -1192,7 +1165,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) /* perform command on all slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next) - kbdd_ioctl(k->kbd, cmd, arg); + kbd_ioctl(k->kbd, cmd, arg); KBDMUX_UNLOCK(state); break; @@ -1205,7 +1178,7 @@ kbdmux_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) /* perform command on all slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next) - kbdd_ioctl(k->kbd, cmd, arg); + kbd_ioctl(k->kbd, cmd, arg); KBDMUX_UNLOCK(state); /* FALLTHROUGH */ @@ -1301,7 +1274,7 @@ kbdmux_poll(keyboard_t *kbd, int on) /* set poll on slave keyboards */ SLIST_FOREACH(k, &state->ks_kbds, next) - kbdd_poll(k->kbd, on); + kbd_poll(k->kbd, on); KBDMUX_UNLOCK(state); diff --git a/sys/dev/misc/syscons/syscons.c b/sys/dev/misc/syscons/syscons.c index 3d056d2206..95cbc53dae 100644 --- a/sys/dev/misc/syscons/syscons.c +++ b/sys/dev/misc/syscons/syscons.c @@ -180,6 +180,7 @@ static int save_kbd_state(scr_stat *scp); static int update_kbd_state(scr_stat *scp, int state, int mask); static int update_kbd_leds(scr_stat *scp, int which); static timeout_t blink_screen; +static int sc_allocate_keyboard(sc_softc_t *sc, int unit); #define CDEV_MAJOR 12 @@ -1120,6 +1121,13 @@ scioctl(struct dev_ioctl_args *ap) *(int *)data = scp->status & LED_MASK; return 0; + case KBADDKBD: /* add/remove keyboard to/from mux */ + case KBRELKBD: + error = kbd_ioctl(sc->kbd, cmd, data); + if (error == ENOIOCTL) + error = ENODEV; + return error; + case CONS_SETKBD: /* set the new keyboard */ { keyboard_t *newkbd; @@ -1609,8 +1617,7 @@ scrn_timer(void *arg) if ((sc->kbd == NULL) && (sc->config & SC_AUTODETECT_KBD)) { /* try to allocate a keyboard automatically */ if (++kbd_interval >= 25) { - sc->keyboard = kbd_allocate("*", -1, (void *)&sc->keyboard, - sckbdevent, sc); + sc->keyboard = sc_allocate_keyboard(sc, -1); if (sc->keyboard >= 0) { sc->kbd = kbd_get_keyboard(sc->keyboard); kbd_ioctl(sc->kbd, KDSKBMODE, @@ -2513,8 +2520,7 @@ scinit(int unit, int flags) sc->adapter = vid_allocate("*", unit, (void *)&sc->adapter); sc->adp = vid_get_adapter(sc->adapter); /* assert((sc->adapter >= 0) && (sc->adp != NULL)) */ - sc->keyboard = kbd_allocate("*", unit, (void *)&sc->keyboard, - sckbdevent, sc); + sc->keyboard = sc_allocate_keyboard(sc, unit); DPRINTF(1, ("sc%d: keyboard %d\n", unit, sc->keyboard)); sc->kbd = kbd_get_keyboard(sc->keyboard); if (sc->kbd != NULL) { @@ -3466,3 +3472,41 @@ blink_screen(void *arg) callout_reset(&scp->blink_screen_ch, hz / 10, blink_screen, scp); } } + + +/* + * Allocate active keyboard. Try to allocate "kbdmux" keyboard first, and, + * if found, add all non-busy keyboards to "kbdmux". Otherwise look for + * any keyboard. + */ + +static int +sc_allocate_keyboard(sc_softc_t *sc, int unit) +{ + int idx0, idx; + keyboard_t *k0, *k; + keyboard_info_t ki; + + idx0 = kbd_allocate("kbdmux", -1, (void *)&sc->keyboard, sckbdevent, sc); + if (idx0 != -1) { + k0 = kbd_get_keyboard(idx0); + + for (idx = kbd_find_keyboard2("*", -1, 0, 0); + idx != -1; + idx = kbd_find_keyboard2("*", -1, idx + 1, 0)) { + k = kbd_get_keyboard(idx); + + if (idx == idx0 || KBD_IS_BUSY(k)) + continue; + + bzero(&ki, sizeof(ki)); + strcpy(ki.kb_name, k->kb_name); + ki.kb_unit = k->kb_unit; + + kbd_ioctl(k0, KBADDKBD, (caddr_t) &ki); + } + } else + idx0 = kbd_allocate("*", unit, (void *)&sc->keyboard, sckbdevent, sc); + + return (idx0); +} diff --git a/sys/dev/misc/syscons/syscons.h b/sys/dev/misc/syscons/syscons.h index 3f0b114452..a1a609628d 100644 --- a/sys/dev/misc/syscons/syscons.h +++ b/sys/dev/misc/syscons/syscons.h @@ -495,26 +495,6 @@ typedef struct { #define ISSIGVALID(sig) ((sig) > 0 && (sig) < NSIG) -#define kbd_read_char(kbd, wait) \ - (*kbdsw[(kbd)->kb_index]->read_char)((kbd), (wait)) -#define kbd_check_char(kbd) \ - (*kbdsw[(kbd)->kb_index]->check_char)((kbd)) -#define kbd_enable(kbd) \ - (*kbdsw[(kbd)->kb_index]->enable)((kbd)) -#define kbd_disable(kbd) \ - (*kbdsw[(kbd)->kb_index]->disable)((kbd)) -#define kbd_lock(kbd, lockf) \ - (*kbdsw[(kbd)->kb_index]->lock)((kbd), (lockf)) -#define kbd_ioctl(kbd, cmd, arg) \ - (((kbd) == NULL) ? \ - ENODEV : (*kbdsw[(kbd)->kb_index]->ioctl)((kbd), (cmd), (arg))) -#define kbd_clear_state(kbd) \ - (*kbdsw[(kbd)->kb_index]->clear_state)((kbd)) -#define kbd_get_fkeystr(kbd, fkey, len) \ - (*kbdsw[(kbd)->kb_index]->get_fkeystr)((kbd), (fkey), (len)) -#define kbd_poll(kbd, on) \ - (*kbdsw[(kbd)->kb_index]->poll)((kbd), (on)) - /* syscons.c */ int sc_probe_unit(int unit, int flags); int sc_attach_unit(int unit, int flags); diff --git a/sys/dev/usbmisc/ukbd/ukbd.c b/sys/dev/usbmisc/ukbd/ukbd.c index a4537ce2b4..e895d90147 100644 --- a/sys/dev/usbmisc/ukbd/ukbd.c +++ b/sys/dev/usbmisc/ukbd/ukbd.c @@ -119,7 +119,6 @@ typedef void usbd_disco_t(void *); static int ukbd_resume(device_t self); static usbd_intr_t ukbd_intr; static int ukbd_driver_load(module_t mod, int what, void *arg); -static int ukbd_default_term(keyboard_t *kbd); static keyboard_t default_kbd; @@ -177,12 +176,12 @@ ukbd_attach(device_t self) void *arg[2]; int unit = device_get_unit(self); + sc->sc_dev = self; + sw = kbd_get_switch(DRIVER_NAME); if (sw == NULL) return ENXIO; - sc->sc_dev = self; - arg[0] = (void *)uaa; arg[1] = (void *)ukbd_intr; kbd = NULL; @@ -214,22 +213,16 @@ ukbd_detach(device_t self) DPRINTF(("%s: keyboard not attached!?\n", device_get_nameunit(self))); return ENXIO; } - (*kbdsw[kbd->kb_index]->disable)(kbd); + kbd_disable(kbd); #ifdef KBD_INSTALL_CDEV - if (kbd != &default_kbd) { - error = kbd_detach(kbd); - if (error) - return error; - } + error = kbd_detach(kbd); + if (error) + return error; #endif - if (kbd == &default_kbd) { - ukbd_default_term(kbd); - } else { - error = (*kbdsw[kbd->kb_index]->term)(kbd); - if (error) - return error; - } + error = kbd_term(kbd); + if (error) + return error; DPRINTF(("%s: disconnected\n", device_get_nameunit(self))); @@ -244,7 +237,7 @@ ukbd_resume(device_t self) kbd = kbd_get_keyboard(kbd_find_keyboard(DRIVER_NAME, device_get_unit(self))); if (kbd) - (*kbdsw[kbd->kb_index]->clear_state)(kbd); + kbd_clear_state(kbd); return (0); } @@ -253,7 +246,7 @@ ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) { keyboard_t *kbd = (keyboard_t *)addr; - (*kbdsw[kbd->kb_index]->intr)(kbd, (void *)status); + kbd_intr(kbd, (void *)status); } DRIVER_MODULE(ukbd, uhub, ukbd_driver, ukbd_devclass, ukbd_driver_load, 0); @@ -317,11 +310,11 @@ static u_int8_t ukbd_trtab[256] = { 104, 102, 94, 96, 103, 99, 101, 98, /* 48 - 4F */ 97, 100, 95, 69, 91, 55, 74, 78, /* 50 - 57 */ 89, 79, 80, 81, 75, 76, 77, 71, /* 58 - 5F */ - 72, 73, 82, 83, 86, 107, NN, NN, /* 60 - 67 */ + 72, 73, 82, 83, 86, 107, 122, NN, /* 60 - 67 */ NN, NN, NN, NN, NN, NN, NN, NN, /* 68 - 6F */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 70 - 77 */ - NN, NN, NN, NN, NN, NN, NN, NN, /* 78 - 7F */ - NN, NN, NN, NN, NN, NN, NN, 115, /* 80 - 87 */ + NN, NN, NN, NN, 115, 108, 111, 113, /* 70 - 77 */ + 109, 110, 112, 118, 114, 116, 117, 119, /* 78 - 7F */ + 121, 120, NN, NN, NN, NN, NN, 115, /* 80 - 87 */ 112, 125, 121, 123, NN, NN, NN, NN, /* 88 - 8F */ NN, NN, NN, NN, NN, NN, NN, NN, /* 90 - 97 */ NN, NN, NN, NN, NN, NN, NN, NN, /* 98 - 9F */ @@ -571,13 +564,9 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) } if (!KBD_IS_PROBED(kbd)) { - if (KBD_IS_CONFIGURED(kbd)) { - kbd_reinit_struct(kbd, flags, KB_PRI_USB); - } else { - kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, - unit, flags, KB_PRI_USB, - 0, 0); - } + kbd_init_struct(kbd, DRIVER_NAME, KB_OTHER, + unit, flags, KB_PRI_USB, + 0, 0); bzero(state, sizeof(*state)); bcopy(&key_map, keymap, sizeof(key_map)); bcopy(&accent_map, accmap, sizeof(accent_map)); @@ -598,12 +587,7 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) * translation mode to, well, translation mode so we don't * get garbage. */ - if (!KBD_IS_CONFIGURED(kbd)) { - state->ks_mode = K_XLATE; - kbd->kb_savemode = state->ks_mode; - } else { - state->ks_mode = kbd->kb_savemode; - } + state->ks_mode = K_XLATE; state->ks_iface = uaa->iface; state->ks_uaa = uaa; state->ks_ifstate = 0; @@ -622,14 +606,14 @@ ukbd_init(int unit, keyboard_t **kbdp, void *arg, int flags) ukbd_ioctl(kbd, KDSETLED, (caddr_t)&(state->ks_state)); } if (!KBD_IS_CONFIGURED(kbd)) { - if (kbd_register(kbd) < 0) + if (kbd_register(kbd) < 0) { + kbd->kb_flags = 0; + /* XXX: Missing free()'s */ return ENXIO; - KBD_CONFIG_DONE(kbd); - } - if (!KBD_IS_INITIALIZED(kbd) && !(flags & KB_CONF_PROBE_ONLY)) { + } if (ukbd_enable_intr(kbd, TRUE, (usbd_intr_t *)data[1]) == 0) ukbd_timeout((void *)kbd); - KBD_INIT_DONE(kbd); + KBD_CONFIG_DONE(kbd); } return 0; } @@ -647,7 +631,7 @@ ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func) state->ks_ifstate |= INTRENABLED; err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr, - USBD_SHORT_XFER_OK | USBD_CALLBACK_LAST, + USBD_SHORT_XFER_OK, &state->ks_intrpipe, kbd, &state->ks_ndata, sizeof(state->ks_ndata), func, @@ -702,36 +686,6 @@ ukbd_term(keyboard_t *kbd) return error; } -/* - * Finish using the default keyboard. Shutdown the USB side of the keyboard - * but do not unregister it. - */ -static int -ukbd_default_term(keyboard_t *kbd) -{ - ukbd_state_t *state; - - crit_enter(); - - state = (ukbd_state_t *)kbd->kb_data; - DPRINTF(("ukbd_default_term: ks_ifstate=0x%x\n", state->ks_ifstate)); - - callout_stop(&state->ks_timeout); - - if (state->ks_ifstate & INTRENABLED) - ukbd_enable_intr(kbd, FALSE, NULL); - if (state->ks_ifstate & INTRENABLED) { - crit_exit(); - DPRINTF(("ukbd_term: INTRENABLED!\n")); - return ENXIO; - } - KBD_LOST_DEVICE(kbd); - KBD_LOST_PROBE(kbd); - KBD_LOST_INIT(kbd); - crit_exit(); - return (0); -} - /* keyboard interrupt routine */ static void @@ -743,7 +697,7 @@ ukbd_timeout(void *arg) kbd = (keyboard_t *)arg; state = (ukbd_state_t *)kbd->kb_data; crit_enter(); - (*kbdsw[kbd->kb_index]->intr)(kbd, (void *)USBD_NORMAL_COMPLETION); + kbd_intr(kbd, (void *)USBD_NORMAL_COMPLETION); callout_reset(&state->ks_timeout, hz / 40, ukbd_timeout, arg); crit_exit(); } @@ -832,6 +786,15 @@ ukbd_interrupt(keyboard_t *kbd, void *arg) } } ADDKEY1(key | KEY_PRESS); + /* + * If any other key is presently down, force its repeat to be + * well in the future (100s). This makes the last key to be + * pressed do the autorepeat. + */ + for (j = 0; j < NKEYCODE; j++) { + if (j != i) + state->ks_ntime[j] = now + 100 * 1000; + } pfound: ; } @@ -958,7 +921,7 @@ ukbd_read(keyboard_t *kbd, int wait) #endif /* UKBD_EMULATE_ATSCANCODE */ usbcode = ukbd_getc(state, wait); - if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd) || (usbcode == -1)) + if (!KBD_IS_ACTIVE(kbd) || (usbcode == -1)) return -1; ++kbd->kb_count; #ifdef UKBD_EMULATE_ATSCANCODE @@ -994,7 +957,7 @@ ukbd_read(keyboard_t *kbd, int wait) static int ukbd_check(keyboard_t *kbd) { - if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd)) + if (!KBD_IS_ACTIVE(kbd)) return FALSE; #ifdef UKBD_EMULATE_ATSCANCODE if (((ukbd_state_t *)kbd->kb_data)->ks_buffered_char[0]) @@ -1197,7 +1160,7 @@ ukbd_check_char(keyboard_t *kbd) { ukbd_state_t *state; - if (!KBD_IS_ACTIVE(kbd) || !KBD_HAS_DEVICE(kbd)) + if (!KBD_IS_ACTIVE(kbd)) return FALSE; state = (ukbd_state_t *)kbd->kb_data; if (!(state->ks_flags & COMPOSE) && (state->ks_composed_char > 0)) @@ -1255,7 +1218,8 @@ ukbd_ioctl(keyboard_t *kbd, u_long cmd, caddr_t arg) } i = *(int *)arg; /* replace CAPS LED with ALTGR LED for ALTGR keyboards */ - if (kbd->kb_keymap->n_keys > ALTGR_OFFSET) { + if (state->ks_mode == K_XLATE && + kbd->kb_keymap->n_keys > ALTGR_OFFSET) { if (i & ALKED) i |= CLKED; else @@ -1384,9 +1348,9 @@ ukbd_poll(keyboard_t *kbd, int on) crit_enter(); if (on) { - if (state->ks_polling == 0) - usbd_set_polling(dev, on); ++state->ks_polling; + if (state->ks_polling == 1) + usbd_set_polling(dev, on); } else { --state->ks_polling; if (state->ks_polling == 0) diff --git a/sys/sys/kbio.h b/sys/sys/kbio.h index b5ee14fcc5..e920bb02d9 100644 --- a/sys/sys/kbio.h +++ b/sys/sys/kbio.h @@ -78,6 +78,8 @@ struct keyboard_info { int kb_flags; /* internal flags */ }; typedef struct keyboard_info keyboard_info_t; +#define KBADDKBD _IOW('K', 68, keyboard_info_t) /* add keyboard */ +#define KBRELKBD _IOW('K', 69, keyboard_info_t) /* release keyboard */ #define KDGKBINFO _IOR('K', 101, keyboard_info_t) /* set/get keyboard repeat rate (new interface) */ @@ -176,6 +178,7 @@ typedef struct keymap keymap_t; #define RALTA 0xa0 /* right alt key / alt lock */ #define HALT 0xa1 /* halt machine */ #define PDWN 0xa2 /* halt machine and power down */ +#define PASTE 0xa3 /* paste from cut-paste buffer */ #define F(x) ((x)+F_FN-1) #define S(x) ((x)+F_SCR-1) -- 2.11.4.GIT