/* keyboard interrupt routine */ static int atkbd_intr(keyboard_t *kbd, void *arg) { atkbd_state_t *state; int delay[2]; int c; if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { /* let the callback function to process the input */ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, kbd->kb_callback.kc_arg); } else { /* read and discard the input; no one is waiting for input */ do { c = atkbd_read_char(kbd, FALSE); } while (c != NOKEY); if (!KBD_HAS_DEVICE(kbd)) { /* * The keyboard was not detected before; * it must have been reconnected! */ state = (atkbd_state_t *)kbd->kb_data; init_keyboard(state->kbdc, &kbd->kb_type, kbd->kb_config); atkbd_ioctl(kbd, KDSETLED, (caddr_t)&state->ks_state); get_typematic(kbd); delay[0] = kbd->kb_delay1; delay[1] = kbd->kb_delay2; atkbd_ioctl(kbd, KDSETREPEAT, (caddr_t)delay); KBD_FOUND_DEVICE(kbd); } } return 0; }
static void akbd_repeat(void *xsc) { struct adb_kbd_softc *sc = xsc; int notify_kbd = 0; /* Fake an up/down key repeat so long as we have the free buffers */ mtx_lock(&sc->sc_mutex); if (sc->buffers < 7) { sc->buffer[sc->buffers++] = sc->last_press | (1 << 7); sc->buffer[sc->buffers++] = sc->last_press; notify_kbd = 1; } mtx_unlock(&sc->sc_mutex); if (notify_kbd && KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); } /* Reschedule the callout */ callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay2), akbd_repeat, sc); }
static void sunkbd_repeat(void *v) { struct sunkbd_softc *sc = v; if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { if (sc->sc_repeat_key != -1) { sc->sc_repeating = 1; sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); } } }
/* keyboard interrupt routine */ static int pckbd_intr(keyboard_t *kbd, void *arg) { int c; if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { /* let the callback function to process the input */ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, kbd->kb_callback.kc_arg); } else { /* read and discard the input; no one is waiting for input */ do { c = pckbd_read_char(kbd, FALSE); } while (c != NOKEY); } return 0; }
static void sunkbd_uart_intr(void *arg) { struct sunkbd_softc *sc = arg; int pend; if (sc->sc_uart->sc_leaving) return; pend = atomic_readandclear_32(&sc->sc_uart->sc_ttypend); if (!(pend & SER_INT_MASK)) return; if (pend & SER_INT_RXREADY) { if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); } } }
static int vt_allocate_keyboard(struct vt_device *vd) { int idx0, idx; keyboard_t *k0, *k; keyboard_info_t ki; idx0 = kbd_allocate("kbdmux", -1, (void *)&vd->vd_keyboard, vt_kbdevent, vd); /* XXX: kb_token lost */ vd->vd_keyboard = idx0; if (idx0 != -1) { DPRINTF(20, "%s: kbdmux allocated, idx = %d\n", __func__, idx0); k0 = kbd_get_keyboard(idx0); for (idx = kbd_find_keyboard2("*", -1, 0); idx != -1; idx = kbd_find_keyboard2("*", -1, idx + 1)) { 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; kbdd_ioctl(k0, KBADDKBD, (caddr_t) &ki); } } else { DPRINTF(20, "%s: no kbdmux allocated\n", __func__); idx0 = kbd_allocate("*", -1, (void *)&vd->vd_keyboard, vt_kbdevent, vd); } DPRINTF(20, "%s: vd_keyboard = %d\n", __func__, vd->vd_keyboard); return (idx0); }
static void pl050_kmi_intr(void *arg) { struct kmi_softc *sc = arg; uint32_t c; KMI_CTX_LOCK_ASSERT(); if ((sc->sc_flags & KMI_FLAG_POLLING) != 0) return; if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { /* let the callback function process the input */ (sc->sc_kbd.kb_callback.kc_func) (&sc->sc_kbd, KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); } else { /* read and discard the input, no one is waiting for it */ do { c = kmi_read_char_locked(&sc->sc_kbd, 0); } while (c != NOKEY); } }
static int ukbd_interrupt(keyboard_t *kbd, void *arg) { usbd_status status = (usbd_status)arg; ukbd_state_t *state; struct ukbd_data *ud; struct timeval tv; u_long now; int mod, omod; int key, c; int i, j; DPRINTFN(5, ("ukbd_intr: status=%d\n", status)); if (status == USBD_CANCELLED) return 0; state = (ukbd_state_t *)kbd->kb_data; ud = &state->ks_ndata; if (status != USBD_NORMAL_COMPLETION) { DPRINTF(("ukbd_intr: status=%d\n", status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(state->ks_intrpipe); return 0; } if (ud->keycode[0] == KEY_ERROR) { return 0; /* ignore */ } getmicrouptime(&tv); now = (u_long)tv.tv_sec*1000 + (u_long)tv.tv_usec/1000; #define ADDKEY1(c) \ if (state->ks_inputs < INPUTBUFSIZE) { \ state->ks_input[state->ks_inputtail] = (c); \ ++state->ks_inputs; \ state->ks_inputtail = (state->ks_inputtail + 1)%INPUTBUFSIZE; \ } mod = ud->modifiers; omod = state->ks_odata.modifiers; if (mod != omod) { for (i = 0; i < NMOD; i++) if (( mod & ukbd_mods[i].mask) != (omod & ukbd_mods[i].mask)) ADDKEY1(ukbd_mods[i].key | (mod & ukbd_mods[i].mask ? KEY_PRESS : KEY_RELEASE)); } /* Check for released keys. */ for (i = 0; i < NKEYCODE; i++) { key = state->ks_odata.keycode[i]; if (key == 0) continue; for (j = 0; j < NKEYCODE; j++) { if (ud->keycode[j] == 0) continue; if (key == ud->keycode[j]) goto rfound; } ADDKEY1(key | KEY_RELEASE); rfound: ; } /* Check for pressed keys. */ for (i = 0; i < NKEYCODE; i++) { key = ud->keycode[i]; if (key == 0) continue; state->ks_ntime[i] = now + kbd->kb_delay1; for (j = 0; j < NKEYCODE; j++) { if (state->ks_odata.keycode[j] == 0) continue; if (key == state->ks_odata.keycode[j]) { state->ks_ntime[i] = state->ks_otime[j]; if (state->ks_otime[j] > now) goto pfound; state->ks_ntime[i] = now + kbd->kb_delay2; break; } } 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: ; } state->ks_odata = *ud; bcopy(state->ks_ntime, state->ks_otime, sizeof(state->ks_ntime)); if (state->ks_inputs <= 0) { return 0; } #ifdef USB_DEBUG for (i = state->ks_inputhead, j = 0; j < state->ks_inputs; ++j, i = (i + 1)%INPUTBUFSIZE) { c = state->ks_input[i]; DPRINTF(("0x%x (%d) %s\n", c, c, (c & KEY_RELEASE) ? "released":"pressed")); } if (ud->modifiers) DPRINTF(("mod:0x%04x ", ud->modifiers)); for (i = 0; i < NKEYCODE; i++) { if (ud->keycode[i]) DPRINTF(("%d ", ud->keycode[i])); } DPRINTF(("\n")); #endif /* USB_DEBUG */ if (state->ks_polling) { return 0; } if (KBD_IS_ACTIVE(kbd) && KBD_IS_BUSY(kbd)) { /* let the callback function to process the input */ (*kbd->kb_callback.kc_func)(kbd, KBDIO_KEYINPUT, kbd->kb_callback.kc_arg); } else { /* read and discard the input; no one is waiting for it */ do { c = ukbd_read_char(kbd, FALSE); } while (c != NOKEY); } return 0; }
static u_int adb_kbd_receive_packet(device_t dev, u_char status, u_char command, u_char reg, int len, u_char *data) { struct adb_kbd_softc *sc; sc = device_get_softc(dev); if (command != ADB_COMMAND_TALK) return 0; if (reg != 0 || len != 2) return (0); mtx_lock(&sc->sc_mutex); /* 0x7f is always the power button */ if (data[0] == 0x7f && devctl_process_running()) { devctl_notify("PMU", "Button", "pressed", NULL); mtx_unlock(&sc->sc_mutex); return (0); } else if (data[0] == 0xff) { mtx_unlock(&sc->sc_mutex); return (0); /* Ignore power button release. */ } if ((data[0] & 0x7f) == 57 && sc->buffers < 7) { /* Fake the down/up cycle for caps lock */ sc->buffer[sc->buffers++] = data[0] & 0x7f; sc->buffer[sc->buffers++] = (data[0] & 0x7f) | (1 << 7); } else { sc->buffer[sc->buffers++] = data[0]; } if (sc->buffer[sc->buffers-1] < 0xff) sc->last_press = sc->buffer[sc->buffers-1]; if ((data[1] & 0x7f) == 57 && sc->buffers < 7) { /* Fake the down/up cycle for caps lock */ sc->buffer[sc->buffers++] = data[1] & 0x7f; sc->buffer[sc->buffers++] = (data[1] & 0x7f) | (1 << 7); } else { sc->buffer[sc->buffers++] = data[1]; } if (sc->buffer[sc->buffers-1] < 0xff) sc->last_press = sc->buffer[sc->buffers-1]; /* Stop any existing key repeating */ callout_stop(&sc->sc_repeater); /* Schedule a repeat callback on keydown */ if (!(sc->last_press & (1 << 7))) { callout_reset(&sc->sc_repeater, ms_to_ticks(sc->sc_kbd.kb_delay1), akbd_repeat, sc); } mtx_unlock(&sc->sc_mutex); cv_broadcast(&sc->sc_cv); if (KBD_IS_ACTIVE(&sc->sc_kbd) && KBD_IS_BUSY(&sc->sc_kbd)) { sc->sc_kbd.kb_callback.kc_func(&sc->sc_kbd, KBDIO_KEYINPUT, sc->sc_kbd.kb_callback.kc_arg); } return (0); }