^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Written for linux by Johan Myreen as a translation from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * the assembly version by Linus (with diacriticals added)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Some additional features added by Christoph Niemann (ChN), March 1993
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Loadable keymaps by Risto Kankkunen, May 1993
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Added decr/incr_console, dynamic keymaps, Unicode support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * dynamic function/string keys, led setting, Sept 1994
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * `Sticky' modifier keys, 951006.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * 11-11-96: SAK should now work in the raw mode (Martin Mares)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * Modified to provide 'generic' keyboard support by Hamish Macdonald
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Merge with the m68k keyboard driver and split-off of the PC low-level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * parts by Geert Uytterhoeven, May 1997
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * 30-07-98: Dead keys redone, aeb@cwi.nl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/consolemap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/sched/debug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/leds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/kbd_kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/kbd_diacr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/vt_kern.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <asm/irq_regs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) extern void ctrl_alt_del(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * Exported functions/variables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #if defined(CONFIG_X86) || defined(CONFIG_PARISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <asm/kbdleds.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static inline int kbd_defleds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define KBD_DEFLOCK 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Handler Tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define K_HANDLERS\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) k_self, k_fn, k_spec, k_pad,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) k_dead, k_cons, k_cur, k_shift,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) k_meta, k_ascii, k_lock, k_lowercase,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) k_slock, k_dead2, k_brl, k_ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) char up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static k_handler_fn K_HANDLERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) static k_handler_fn *k_handler[16] = { K_HANDLERS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define FN_HANDLERS\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) typedef void (fn_handler_fn)(struct vc_data *vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) static fn_handler_fn FN_HANDLERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Variables exported for vt_ioctl.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct vt_spawn_console vt_spawn_con = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) .pid = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) .sig = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Internal Data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct kbd_struct kbd_table[MAX_NR_CONSOLES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static struct kbd_struct *kbd = kbd_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* maximum values each key_handler can handle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const int max_vals[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 255, NR_LOCK - 1, 255, NR_BRL - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static const int NR_TYPES = ARRAY_SIZE(max_vals);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static struct input_handler kbd_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static DEFINE_SPINLOCK(kbd_event_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static DEFINE_SPINLOCK(led_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static DEFINE_SPINLOCK(func_buf_lock); /* guard 'func_buf' and friends */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static bool dead_key_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) /* Handles a number being assembled on the number pad */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static bool npadch_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static unsigned int npadch_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static unsigned int diacr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static char rep; /* flag telling character repeat */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int shift_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static unsigned int ledstate = -1U; /* undefined */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static unsigned char ledioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * Notifier list for console keyboard events
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) int register_keyboard_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) EXPORT_SYMBOL_GPL(register_keyboard_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int unregister_keyboard_notifier(struct notifier_block *nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * Translation of scancodes to keycodes. We set them on only the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * keyboard in the list that accepts the scancode and keycode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Explanation for not choosing the first attached keyboard anymore:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * USB keyboards for example have two event devices: one for all "normal"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) * keys and one for extra function keys (like "volume up", "make coffee",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * etc.). So this means that scancodes for the extra function keys won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) * be valid for the first event device, but will be for the second.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct getset_keycode_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct input_keymap_entry ke;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static int getkeycode_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct getset_keycode_data *d = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) d->error = input_get_keycode(handle->dev, &d->ke);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return d->error == 0; /* stop as soon as we successfully get one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int getkeycode(unsigned int scancode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) struct getset_keycode_data d = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) .ke = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .len = sizeof(scancode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) .keycode = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .error = -ENODEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) memcpy(d.ke.scancode, &scancode, sizeof(scancode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return d.error ?: d.ke.keycode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static int setkeycode_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct getset_keycode_data *d = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) d->error = input_set_keycode(handle->dev, &d->ke);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return d->error == 0; /* stop as soon as we successfully set one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int setkeycode(unsigned int scancode, unsigned int keycode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct getset_keycode_data d = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) .ke = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .len = sizeof(scancode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .keycode = keycode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) .error = -ENODEV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) memcpy(d.ke.scancode, &scancode, sizeof(scancode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return d.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * Making beeps and bells. Note that we prefer beeps to bells, but when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * shutting the sound off we do both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) static int kd_sound_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) unsigned int *hz = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) struct input_dev *dev = handle->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (test_bit(EV_SND, dev->evbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (test_bit(SND_TONE, dev->sndbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) input_inject_event(handle, EV_SND, SND_TONE, *hz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (*hz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) if (test_bit(SND_BELL, dev->sndbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static void kd_nosound(struct timer_list *unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static unsigned int zero;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static DEFINE_TIMER(kd_mksound_timer, kd_nosound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) void kd_mksound(unsigned int hz, unsigned int ticks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) del_timer_sync(&kd_mksound_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (hz && ticks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mod_timer(&kd_mksound_timer, jiffies + ticks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) EXPORT_SYMBOL(kd_mksound);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Setting the keyboard rate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int kbd_rate_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct input_dev *dev = handle->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct kbd_repeat *rpt = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (test_bit(EV_REP, dev->evbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (rpt[0].delay > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) input_inject_event(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) EV_REP, REP_DELAY, rpt[0].delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if (rpt[0].period > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) input_inject_event(handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) EV_REP, REP_PERIOD, rpt[0].period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) rpt[1].delay = dev->rep[REP_DELAY];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) rpt[1].period = dev->rep[REP_PERIOD];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int kbd_rate(struct kbd_repeat *rpt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct kbd_repeat data[2] = { *rpt };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) *rpt = data[1]; /* Copy currently used settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Helper Functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static void put_queue(struct vc_data *vc, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) tty_insert_flip_char(&vc->port, ch, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) tty_schedule_flip(&vc->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static void puts_queue(struct vc_data *vc, char *cp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) while (*cp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) tty_insert_flip_char(&vc->port, *cp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) cp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) tty_schedule_flip(&vc->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) static void applkey(struct vc_data *vc, int key, char mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) buf[1] = (mode ? 'O' : '[');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) buf[2] = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) puts_queue(vc, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * Many other routines do put_queue, but I think either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * they produce ASCII, or they produce some user-assigned
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * string, and in both cases we might assume that it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * in utf-8 already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static void to_utf8(struct vc_data *vc, uint c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (c < 0x80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) /* 0******* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) put_queue(vc, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) else if (c < 0x800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /* 110***** 10****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) put_queue(vc, 0xc0 | (c >> 6));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) put_queue(vc, 0x80 | (c & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) } else if (c < 0x10000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (c >= 0xD800 && c < 0xE000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (c == 0xFFFF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* 1110**** 10****** 10****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) put_queue(vc, 0xe0 | (c >> 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) put_queue(vc, 0x80 | (c & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) } else if (c < 0x110000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* 11110*** 10****** 10****** 10****** */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) put_queue(vc, 0xf0 | (c >> 18));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) put_queue(vc, 0x80 | (c & 0x3f));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * Called after returning from RAW mode or when changing consoles - recompute
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * shift_down[] and shift_state from key_down[] maybe called when keymap is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * undefined, so that shiftkey release is seen. The caller must hold the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * kbd_event_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) static void do_compute_shiftstate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned int k, sym, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) shift_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) memset(shift_down, 0, sizeof(shift_down));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) sym = U(key_maps[0][k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) val = KVAL(sym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (val == KVAL(K_CAPSSHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) val = KVAL(K_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) shift_down[val]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) shift_state |= BIT(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* We still have to export this method to vt.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) void compute_shiftstate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * We have a combining character DIACR here, followed by the character CH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * If the combination occurs in the table, return the corresponding value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * Otherwise, if CH is a space or equals DIACR, return DIACR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * Otherwise, conclude that DIACR was not combining after all,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * queue it and return CH.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned int d = diacr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) diacr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if ((d & ~0xff) == BRL_UC_ROW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if ((ch & ~0xff) == BRL_UC_ROW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return d | ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (i = 0; i < accent_table_size; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (accent_table[i].diacr == d && accent_table[i].base == ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return accent_table[i].result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (kbd->kbdmode == VC_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) to_utf8(vc, d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) int c = conv_uni_to_8bit(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) if (c != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) put_queue(vc, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * Special function handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static void fn_enter(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (diacr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (kbd->kbdmode == VC_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) to_utf8(vc, diacr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int c = conv_uni_to_8bit(diacr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (c != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) put_queue(vc, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) diacr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) put_queue(vc, 13);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (vc_kbd_mode(kbd, VC_CRLF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) put_queue(vc, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static void fn_caps_toggle(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) chg_vc_kbd_led(kbd, VC_CAPSLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static void fn_caps_on(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) set_vc_kbd_led(kbd, VC_CAPSLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static void fn_show_ptregs(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct pt_regs *regs = get_irq_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) if (regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) show_regs(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static void fn_hold(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct tty_struct *tty = vc->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (rep || !tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) * these routines are also activated by ^S/^Q.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (tty->stopped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) start_tty(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) stop_tty(tty);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void fn_num(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (vc_kbd_mode(kbd, VC_APPLIC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) applkey(vc, 'P', 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) fn_bare_num(vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Bind this to Shift-NumLock if you work in application keypad mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * but want to be able to change the NumLock flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * Bind this to NumLock if you prefer that the NumLock key always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * changes the NumLock flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static void fn_bare_num(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (!rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) chg_vc_kbd_led(kbd, VC_NUMLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static void fn_lastcons(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /* switch to the last used console, ChN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) set_console(last_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static void fn_dec_console(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) int i, cur = fg_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Currently switching? Queue this next switch relative to that. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (want_console != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) cur = want_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) for (i = cur - 1; i != cur; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (i == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) i = MAX_NR_CONSOLES - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (vc_cons_allocated(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) set_console(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) static void fn_inc_console(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) int i, cur = fg_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Currently switching? Queue this next switch relative to that. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (want_console != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) cur = want_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) for (i = cur+1; i != cur; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (i == MAX_NR_CONSOLES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) if (vc_cons_allocated(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) set_console(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static void fn_send_intr(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) tty_insert_flip_char(&vc->port, 0, TTY_BREAK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) tty_schedule_flip(&vc->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) static void fn_scroll_forw(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) scrollfront(vc, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) static void fn_scroll_back(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) scrollback(vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static void fn_show_mem(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) show_mem(0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) static void fn_show_state(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) show_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) static void fn_boot_it(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) ctrl_alt_del();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) static void fn_compose(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dead_key_next = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static void fn_spawn_con(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) spin_lock(&vt_spawn_con.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (vt_spawn_con.pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) put_pid(vt_spawn_con.pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) vt_spawn_con.pid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) spin_unlock(&vt_spawn_con.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) static void fn_SAK(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) schedule_work(SAK_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static void fn_null(struct vc_data *vc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * Special key handlers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) if (value >= ARRAY_SIZE(fn_handler))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if ((kbd->kbdmode == VC_RAW ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) kbd->kbdmode == VC_MEDIUMRAW ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) kbd->kbdmode == VC_OFF) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) value != KVAL(K_SAK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return; /* SAK is allowed even in raw mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) fn_handler[value](vc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pr_err("k_lowercase was called - impossible\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) return; /* no action, if this is a key release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (diacr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) value = handle_diacr(vc, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (dead_key_next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) dead_key_next = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) diacr = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (kbd->kbdmode == VC_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) to_utf8(vc, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) int c = conv_uni_to_8bit(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (c != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) put_queue(vc, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * Handle dead key. Note that we now may have several
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * dead keys modifying the same character. Very useful
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * for Vietnamese.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) diacr = (diacr ? handle_diacr(vc, value) : value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) k_unicode(vc, conv_8bit_to_uni(value), up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) k_deadunicode(vc, value, up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Obsolete - for backwards compatibility only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) static const unsigned char ret_diacr[NR_DEAD] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) '`', /* dead_grave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) '\'', /* dead_acute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) '^', /* dead_circumflex */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) '~', /* dead_tilda */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) '"', /* dead_diaeresis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ',', /* dead_cedilla */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) '_', /* dead_macron */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 'U', /* dead_breve */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) '.', /* dead_abovedot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) '*', /* dead_abovering */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) '=', /* dead_doubleacute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 'c', /* dead_caron */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 'k', /* dead_ogonek */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 'i', /* dead_iota */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) '#', /* dead_voiced_sound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 'o', /* dead_semivoiced_sound */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) '!', /* dead_belowdot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) '?', /* dead_hook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) '+', /* dead_horn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) '-', /* dead_stroke */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ')', /* dead_abovecomma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) '(', /* dead_abovereversedcomma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) ':', /* dead_doublegrave */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 'n', /* dead_invertedbreve */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ';', /* dead_belowcomma */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) '$', /* dead_currency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) '@', /* dead_greek */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) k_deadunicode(vc, ret_diacr[value], up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) set_console(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) if ((unsigned)value < ARRAY_SIZE(func_table)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) spin_lock_irqsave(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) if (func_table[value])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) puts_queue(vc, func_table[value]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) spin_unlock_irqrestore(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) pr_err("k_fn called with value=%d\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static const char cur_chars[] = "BDCA";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) static const char pad_chars[] = "0123456789+-*/\015,.?()#";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return; /* no action, if this is a key release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /* kludge... shift forces cursor/number keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) applkey(vc, app_map[value], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) switch (value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case KVAL(K_PCOMMA):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) case KVAL(K_PDOT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) k_fn(vc, KVAL(K_REMOVE), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) case KVAL(K_P0):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) k_fn(vc, KVAL(K_INSERT), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) case KVAL(K_P1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) k_fn(vc, KVAL(K_SELECT), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) case KVAL(K_P2):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) k_cur(vc, KVAL(K_DOWN), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) case KVAL(K_P3):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) k_fn(vc, KVAL(K_PGDN), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) case KVAL(K_P4):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) k_cur(vc, KVAL(K_LEFT), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) case KVAL(K_P6):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) k_cur(vc, KVAL(K_RIGHT), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) case KVAL(K_P7):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) k_fn(vc, KVAL(K_FIND), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case KVAL(K_P8):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) k_cur(vc, KVAL(K_UP), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case KVAL(K_P9):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) k_fn(vc, KVAL(K_PGUP), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) case KVAL(K_P5):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) put_queue(vc, pad_chars[value]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) put_queue(vc, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) int old_state = shift_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) * Mimic typewriter:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * a CapsShift key acts like Shift but undoes CapsLock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (value == KVAL(K_CAPSSHIFT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) value = KVAL(K_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) clr_vc_kbd_led(kbd, VC_CAPSLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) if (up_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * handle the case that two shift or control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * keys are depressed simultaneously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (shift_down[value])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) shift_down[value]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) shift_down[value]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (shift_down[value])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) shift_state |= (1 << value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) shift_state &= ~(1 << value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /* kludge */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (up_flag && shift_state != old_state && npadch_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (kbd->kbdmode == VC_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) to_utf8(vc, npadch_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) put_queue(vc, npadch_value & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) npadch_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (vc_kbd_mode(kbd, VC_META)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) put_queue(vc, '\033');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) put_queue(vc, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) put_queue(vc, value | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) unsigned int base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) if (value < 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* decimal input of code, while Alt depressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) base = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* hexadecimal input of code, while AltGr depressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) value -= 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) base = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!npadch_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) npadch_value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) npadch_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) npadch_value = npadch_value * base + value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (up_flag || rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) chg_vc_kbd_lock(kbd, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) k_shift(vc, value, up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (up_flag || rep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) chg_vc_kbd_slock(kbd, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* try to make Alt, oops, AltGr and such work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) kbd->slockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) chg_vc_kbd_slock(kbd, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* by default, 300ms interval for combination release */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) static unsigned brl_timeout = 300;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) module_param(brl_timeout, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) static unsigned brl_nbchords = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) module_param(brl_nbchords, uint, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) static unsigned long chords;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) static unsigned committed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (!brl_nbchords)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) committed |= pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) chords++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (chords == brl_nbchords) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) k_unicode(vc, BRL_UC_ROW | committed, up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) chords = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) committed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static unsigned pressed, committing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static unsigned long releasestart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) if (kbd->kbdmode != VC_UNICODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (!up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) pr_warn("keyboard mode must be unicode for braille patterns\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (!value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) k_unicode(vc, BRL_UC_ROW, up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (value > 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!up_flag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) pressed |= 1 << (value - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) if (!brl_timeout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) committing = pressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) } else if (brl_timeout) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) if (!committing ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) time_after(jiffies,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) releasestart + msecs_to_jiffies(brl_timeout))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) committing = pressed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) releasestart = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) pressed &= ~(1 << (value - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (!pressed && committing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) k_brlcommit(vc, committing, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) committing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (committing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) k_brlcommit(vc, committing, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) committing = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) pressed &= ~(1 << (value - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) #if IS_ENABLED(CONFIG_INPUT_LEDS) && IS_ENABLED(CONFIG_LEDS_TRIGGERS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct kbd_led_trigger {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct led_trigger trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) unsigned int mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) static int kbd_led_trigger_activate(struct led_classdev *cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) struct kbd_led_trigger *trigger =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) container_of(cdev->trigger, struct kbd_led_trigger, trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) tasklet_disable(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (ledstate != -1U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) led_trigger_event(&trigger->trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) ledstate & trigger->mask ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) LED_FULL : LED_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) tasklet_enable(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) #define KBD_LED_TRIGGER(_led_bit, _name) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) .trigger = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) .name = _name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) .activate = kbd_led_trigger_activate, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) .mask = BIT(_led_bit), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) #define KBD_LOCKSTATE_TRIGGER(_led_bit, _name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) KBD_LED_TRIGGER((_led_bit) + 8, _name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) static struct kbd_led_trigger kbd_led_triggers[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrolllock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) KBD_LED_TRIGGER(VC_NUMLOCK, "kbd-numlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) KBD_LED_TRIGGER(VC_CAPSLOCK, "kbd-capslock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) KBD_LED_TRIGGER(VC_KANALOCK, "kbd-kanalock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) KBD_LOCKSTATE_TRIGGER(VC_SHIFTLOCK, "kbd-shiftlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) KBD_LOCKSTATE_TRIGGER(VC_ALTGRLOCK, "kbd-altgrlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) KBD_LOCKSTATE_TRIGGER(VC_CTRLLOCK, "kbd-ctrllock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) KBD_LOCKSTATE_TRIGGER(VC_ALTLOCK, "kbd-altlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) KBD_LOCKSTATE_TRIGGER(VC_SHIFTLLOCK, "kbd-shiftllock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) KBD_LOCKSTATE_TRIGGER(VC_SHIFTRLOCK, "kbd-shiftrlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) KBD_LOCKSTATE_TRIGGER(VC_CTRLLLOCK, "kbd-ctrlllock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) KBD_LOCKSTATE_TRIGGER(VC_CTRLRLOCK, "kbd-ctrlrlock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void kbd_propagate_led_state(unsigned int old_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) unsigned int new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct kbd_led_trigger *trigger;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) unsigned int changed = old_state ^ new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) trigger = &kbd_led_triggers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) if (changed & trigger->mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) led_trigger_event(&trigger->trigger,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) new_state & trigger->mask ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) LED_FULL : LED_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int kbd_update_leds_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) unsigned int led_state = *(unsigned int *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (test_bit(EV_LED, handle->dev->evbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) kbd_propagate_led_state(~led_state, led_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static void kbd_init_leds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) for (i = 0; i < ARRAY_SIZE(kbd_led_triggers); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) error = led_trigger_register(&kbd_led_triggers[i].trigger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) pr_err("error %d while registering trigger %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) error, kbd_led_triggers[i].trigger.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static int kbd_update_leds_helper(struct input_handle *handle, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) unsigned int leds = *(unsigned int *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (test_bit(EV_LED, handle->dev->evbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) static void kbd_propagate_led_state(unsigned int old_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) unsigned int new_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) input_handler_for_each_handle(&kbd_handler, &new_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) kbd_update_leds_helper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) static void kbd_init_leds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) * or (ii) whatever pattern of lights people want to show using KDSETLED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * or (iii) specified bits of specified words in kernel memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) static unsigned char getledstate(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) return ledstate & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) void setledstate(struct kbd_struct *kb, unsigned int led)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (!(led & ~7)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) ledioctl = led;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) kb->ledmode = LED_SHOW_IOCTL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) kb->ledmode = LED_SHOW_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) set_leds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) static inline unsigned char getleds(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) struct kbd_struct *kb = kbd_table + fg_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (kb->ledmode == LED_SHOW_IOCTL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return ledioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return kb->ledflagstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * vt_get_leds - helper for braille console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) * @console: console to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * @flag: flag we want to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * Check the status of a keyboard led flag and report it back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) int vt_get_leds(int console, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = vc_kbd_led(kb, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) EXPORT_SYMBOL_GPL(vt_get_leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * vt_set_led_state - set LED state of a console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * @console: console to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * @leds: LED bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * Set the LEDs on a console. This is a wrapper for the VT layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * so that we can keep kbd knowledge internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) void vt_set_led_state(int console, int leds)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) setledstate(kb, leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * vt_kbd_con_start - Keyboard side of console start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) * @console: console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) * Handle console start. This is a wrapper for the VT layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) * so that we can keep kbd knowledge internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) * FIXME: We eventually need to hold the kbd lock here to protect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) * the LED updating. We can't do it yet because fn_hold calls stop_tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) * and start_tty under the kbd_event_lock, while normal tty paths
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) * don't hold the lock. We probably need to split out an LED lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) * but not during an -rc release!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) void vt_kbd_con_start(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) clr_vc_kbd_led(kb, VC_SCROLLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) set_leds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * vt_kbd_con_stop - Keyboard side of console stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * @console: console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * Handle console stop. This is a wrapper for the VT layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) * so that we can keep kbd knowledge internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) void vt_kbd_con_stop(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) set_vc_kbd_led(kb, VC_SCROLLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) set_leds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) * This is the tasklet that updates LED state of LEDs using standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * keyboard triggers. The reason we use tasklet is that we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * handle the scenario when keyboard handler is not registered yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) * but we already getting updates from the VT to update led state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static void kbd_bh(unsigned long dummy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) unsigned int leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) leds = getleds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) leds |= (unsigned int)kbd->lockstate << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) if (leds != ledstate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) kbd_propagate_led_state(ledstate, leds);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ledstate = leds;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) DECLARE_TASKLET_DISABLED_OLD(keyboard_tasklet, kbd_bh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) #define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static const unsigned short x86_keycodes[256] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int sparc_l1_a_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) extern void sun_do_break(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) static int emulate_raw(struct vc_data *vc, unsigned int keycode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) unsigned char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) switch (keycode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case KEY_PAUSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) put_queue(vc, 0xe1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) put_queue(vc, 0x1d | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) put_queue(vc, 0x45 | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) case KEY_HANGEUL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (!up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) put_queue(vc, 0xf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) case KEY_HANJA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) put_queue(vc, 0xf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) case KEY_SYSRQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) * Real AT keyboards (that's what we're trying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) * to emulate here) emit 0xe0 0x2a 0xe0 0x37 when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * pressing PrtSc/SysRq alone, but simply 0x54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * when pressing Alt+PrtSc/SysRq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) if (test_bit(KEY_LEFTALT, key_down) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) test_bit(KEY_RIGHTALT, key_down)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) put_queue(vc, 0x54 | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) put_queue(vc, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) put_queue(vc, 0x2a | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) put_queue(vc, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) put_queue(vc, 0x37 | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (keycode > 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) code = x86_keycodes[keycode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) if (!code)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) if (code & 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) put_queue(vc, 0xe0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) put_queue(vc, (code & 0x7f) | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) #define HW_RAW(dev) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) if (keycode > 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) put_queue(vc, keycode | up_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) static void kbd_rawcode(unsigned char data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) struct vc_data *vc = vc_cons[fg_console].d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) kbd = kbd_table + vc->vc_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) if (kbd->kbdmode == VC_RAW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) put_queue(vc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct vc_data *vc = vc_cons[fg_console].d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) unsigned short keysym, *key_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) unsigned char type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) bool raw_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) struct tty_struct *tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) int shift_final;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) tty = vc->port.tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (tty && (!tty->driver_data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) /* No driver data? Strange. Okay we fix it then. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) tty->driver_data = vc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) kbd = kbd_table + vc->vc_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (keycode == KEY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) sparc_l1_a_state = down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) rep = (down == 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) raw_mode = (kbd->kbdmode == VC_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (raw_mode && !hw_raw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) if (emulate_raw(vc, keycode, !down << 7))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (keycode < BTN_MISC && printk_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) pr_warn("can't emulate rawmode for keycode %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) keycode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) #ifdef CONFIG_SPARC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (keycode == KEY_A && sparc_l1_a_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) sparc_l1_a_state = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) sun_do_break();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) if (kbd->kbdmode == VC_MEDIUMRAW) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * This is extended medium raw mode, with keys above 127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * the 'up' flag if needed. 0 is reserved, so this shouldn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) * interfere with anything else. The two bytes after 0 will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * always have the up flag set not to interfere with older
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) * applications. This allows for 16384 different keycodes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) * which should be enough.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (keycode < 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) put_queue(vc, keycode | (!down << 7));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) put_queue(vc, !down << 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) put_queue(vc, (keycode >> 7) | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) put_queue(vc, keycode | 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) raw_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (down)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) set_bit(keycode, key_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) clear_bit(keycode, key_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (rep &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) (!vc_kbd_mode(kbd, VC_REPEAT) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * Don't repeat a key if the input buffers are not empty and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * characters get aren't echoed locally. This makes key repeat
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * usable with slow applications and under heavy loads.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) param.ledstate = kbd->ledflagstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) key_map = key_maps[shift_final];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) rc = atomic_notifier_call_chain(&keyboard_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) KBD_KEYCODE, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) if (rc == NOTIFY_STOP || !key_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) atomic_notifier_call_chain(&keyboard_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) KBD_UNBOUND_KEYCODE, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) kbd->slockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) if (keycode < NR_KEYS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) keysym = key_map[keycode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) type = KTYP(keysym);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) if (type < 0xf0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) param.value = keysym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) rc = atomic_notifier_call_chain(&keyboard_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) KBD_UNICODE, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) if (rc != NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (down && !raw_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) k_unicode(vc, keysym, !down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) type -= 0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (type == KT_LETTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) type = KT_LATIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) if (key_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) keysym = key_map[keycode];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) param.value = keysym;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) rc = atomic_notifier_call_chain(&keyboard_notifier_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) KBD_KEYSYM, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) if (rc == NOTIFY_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) (*k_handler[type])(vc, keysym & 0xff, !down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) param.ledstate = kbd->ledflagstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) if (type != KT_SLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) kbd->slockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) static void kbd_event(struct input_handle *handle, unsigned int event_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) unsigned int event_code, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) /* We are called with interrupts disabled, just take the lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) spin_lock(&kbd_event_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) kbd_rawcode(value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) if (event_type == EV_KEY && event_code <= KEY_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) kbd_keycode(event_code, value, HW_RAW(handle->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) spin_unlock(&kbd_event_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) tasklet_schedule(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) do_poke_blanked_console = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) schedule_console_callback();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (test_bit(EV_SND, dev->evbit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (test_bit(EV_KEY, dev->evbit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) for (i = KEY_RESERVED; i < BTN_MISC; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (test_bit(i, dev->keybit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (test_bit(i, dev->keybit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) * When a keyboard (or other input device) is found, the kbd_connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) * function is called. The function then looks at the device, and if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) * likes it, it can open it and get events from it. In this (kbd_connect)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * function, we should decide which VT to bind that keyboard to initially.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) const struct input_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) struct input_handle *handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) if (!handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) handle->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) handle->handler = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) handle->name = "kbd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) error = input_register_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) goto err_free_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) error = input_open_device(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) goto err_unregister_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) err_unregister_handle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) input_unregister_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) err_free_handle:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) kfree(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) static void kbd_disconnect(struct input_handle *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) input_close_device(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) input_unregister_handle(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) kfree(handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * Start keyboard handler on the new keyboard by refreshing LED state to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * match the rest of the system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) static void kbd_start(struct input_handle *handle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) tasklet_disable(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if (ledstate != -1U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) kbd_update_leds_helper(handle, &ledstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) tasklet_enable(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) static const struct input_device_id kbd_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) .evbit = { BIT_MASK(EV_KEY) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) .evbit = { BIT_MASK(EV_SND) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) { }, /* Terminating entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) MODULE_DEVICE_TABLE(input, kbd_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) static struct input_handler kbd_handler = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) .event = kbd_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .match = kbd_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .connect = kbd_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .disconnect = kbd_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .start = kbd_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .name = "kbd",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .id_table = kbd_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) int __init kbd_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) for (i = 0; i < MAX_NR_CONSOLES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) kbd_table[i].ledflagstate = kbd_defleds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) kbd_table[i].default_ledflagstate = kbd_defleds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) kbd_table[i].ledmode = LED_SHOW_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) kbd_table[i].lockstate = KBD_DEFLOCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) kbd_table[i].slockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) kbd_table[i].modeflags = KBD_DEFMODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) kbd_init_leds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) error = input_register_handler(&kbd_handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) tasklet_enable(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) tasklet_schedule(&keyboard_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) /* Ioctl support code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) * vt_do_diacrit - diacritical table updates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) * @cmd: ioctl request
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) * @udp: pointer to user data for ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) * @perm: permissions check computed by caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) * Update the diacritical tables atomically and safely. Lock them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) * against simultaneous keypresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) int asize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) case KDGKBDIACR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) struct kbdiacrs __user *a = udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) struct kbdiacr *dia;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) dia = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) if (!dia)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) /* Lock the diacriticals table, make a copy and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) copy it after we unlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) asize = accent_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) for (i = 0; i < asize; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) dia[i].diacr = conv_uni_to_8bit(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) accent_table[i].diacr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) dia[i].base = conv_uni_to_8bit(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) accent_table[i].base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dia[i].result = conv_uni_to_8bit(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) accent_table[i].result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) if (put_user(asize, &a->kb_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) else if (copy_to_user(a->kbdiacr, dia,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) asize * sizeof(struct kbdiacr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) kfree(dia);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) case KDGKBDIACRUC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) struct kbdiacrsuc __user *a = udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) void *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) buf = kmalloc_array(MAX_DIACR, sizeof(struct kbdiacruc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) /* Lock the diacriticals table, make a copy and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) copy it after we unlock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) asize = accent_table_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) if (put_user(asize, &a->kb_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) else if (copy_to_user(a->kbdiacruc, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) asize*sizeof(struct kbdiacruc)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) case KDSKBDIACR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) struct kbdiacrs __user *a = udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) struct kbdiacr *dia = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) unsigned int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) if (get_user(ct, &a->kb_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (ct >= MAX_DIACR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) if (ct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) dia = memdup_user(a->kbdiacr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) sizeof(struct kbdiacr) * ct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (IS_ERR(dia))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) return PTR_ERR(dia);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) accent_table_size = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) for (i = 0; i < ct; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) accent_table[i].diacr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) conv_8bit_to_uni(dia[i].diacr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) accent_table[i].base =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) conv_8bit_to_uni(dia[i].base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) accent_table[i].result =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) conv_8bit_to_uni(dia[i].result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) kfree(dia);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) case KDSKBDIACRUC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) struct kbdiacrsuc __user *a = udp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) unsigned int ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) void *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) if (get_user(ct, &a->kb_cnt))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) if (ct >= MAX_DIACR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (ct) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) buf = memdup_user(a->kbdiacruc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) ct * sizeof(struct kbdiacruc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (IS_ERR(buf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) return PTR_ERR(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (ct)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) memcpy(accent_table, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) ct * sizeof(struct kbdiacruc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) accent_table_size = ct;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) * vt_do_kdskbmode - set keyboard mode ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) * @console: the console to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) * @arg: the requested mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) * Update the keyboard mode bits while holding the correct locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) * Return 0 for success or an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) int vt_do_kdskbmode(int console, unsigned int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) switch(arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) case K_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) kb->kbdmode = VC_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) case K_MEDIUMRAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) kb->kbdmode = VC_MEDIUMRAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) case K_XLATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) kb->kbdmode = VC_XLATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) case K_UNICODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) kb->kbdmode = VC_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) case K_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) kb->kbdmode = VC_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) * vt_do_kdskbmeta - set keyboard meta state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) * @console: the console to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) * @arg: the requested meta state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) * Update the keyboard meta bits while holding the correct locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) * Return 0 for success or an error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) int vt_do_kdskbmeta(int console, unsigned int arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) switch(arg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) case K_METABIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) clr_vc_kbd_mode(kb, VC_META);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) case K_ESCPREFIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) set_vc_kbd_mode(kb, VC_META);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) int perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) struct kbkeycode tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) int kc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) case KDGETKEYCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) kc = getkeycode(tmp.scancode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) if (kc >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) kc = put_user(kc, &user_kbkc->keycode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) case KDSETKEYCODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) kc = setkeycode(tmp.scancode, tmp.keycode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) return kc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) #define i (tmp.kb_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) #define s (tmp.kb_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) #define v (tmp.kb_value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) struct kbentry tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) ushort *key_map, *new_map, val, ov;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (!capable(CAP_SYS_TTY_CONFIG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) case KDGKBENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* Ensure another thread doesn't free it under us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) key_map = key_maps[s];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (key_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) val = U(key_map[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) val = K_HOLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) val = (i ? K_HOLE : K_NOSUCHMAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) return put_user(val, &user_kbe->kb_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) case KDSKBENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) if (!i && v == K_NOSUCHMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) /* deallocate map */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) key_map = key_maps[s];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) if (s && key_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) key_maps[s] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) if (key_map[0] == U(K_ALLOCATED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) kfree(key_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) keymap_count--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) if (KTYP(v) < NR_TYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) if (KVAL(v) > max_vals[KTYP(v)])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) if (kb->kbdmode != VC_UNICODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) /* ++Geert: non-PC keyboards may generate keycode zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) #if !defined(__mc68000__) && !defined(__powerpc__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) /* assignment to entry 0 only tests validity of args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) if (!i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) if (!new_map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) key_map = key_maps[s];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) if (key_map == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) !capable(CAP_SYS_RESOURCE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) kfree(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) key_maps[s] = new_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) key_map = new_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) key_map[0] = U(K_ALLOCATED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) for (j = 1; j < NR_KEYS; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) key_map[j] = U(K_HOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) keymap_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) kfree(new_map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) ov = U(key_map[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) if (v == ov)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) * Attention Key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) key_map[i] = U(v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) do_compute_shiftstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) #undef i
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) #undef s
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) #undef v
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) /* FIXME: This one needs untangling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) struct kbsentry *kbs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) u_char *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) int sz, fnw_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) int delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) char *first_free, *fj, *fnw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (!capable(CAP_SYS_TTY_CONFIG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) if (!kbs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) /* we mostly copy too much here (512bytes), but who cares ;) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) i = array_index_nospec(kbs->kb_func, MAX_NR_FUNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) case KDGKBSENT: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) /* size should have been a struct member */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) ssize_t len = sizeof(user_kdgkb->kb_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) spin_lock_irqsave(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) len = strlcpy(kbs->kb_string, func_table[i] ? : "", len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) spin_unlock_irqrestore(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) ret = copy_to_user(user_kdgkb->kb_string, kbs->kb_string,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) len + 1) ? -EFAULT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) case KDSKBSENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) if (!perm) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) ret = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) fnw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) fnw_sz = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* race aginst other writers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) spin_lock_irqsave(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) q = func_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /* fj pointer to next entry after 'q' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) first_free = funcbufptr + (funcbufsize - funcbufleft);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) if (j < MAX_NR_FUNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) fj = func_table[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) fj = first_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) /* buffer usage increase by new entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if (delta <= funcbufleft) { /* it fits in current buf */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (j < MAX_NR_FUNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /* make enough space for new entry at 'fj' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) memmove(fj + delta, fj, first_free - fj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) for (k = j; k < MAX_NR_FUNC; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) if (func_table[k])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) func_table[k] += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) if (!q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) func_table[i] = fj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) funcbufleft -= delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) } else { /* allocate a larger buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) sz = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) while (sz < funcbufsize - funcbufleft + delta)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) sz <<= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) if (fnw_sz != sz) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) spin_unlock_irqrestore(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) kfree(fnw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) fnw = kmalloc(sz, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) fnw_sz = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) if (!fnw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) goto reterr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) if (!q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) func_table[i] = fj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) /* copy data before insertion point to new location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) if (fj > funcbufptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) memmove(fnw, funcbufptr, fj - funcbufptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) for (k = 0; k < j; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) if (func_table[k])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) func_table[k] = fnw + (func_table[k] - funcbufptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) /* copy data after insertion point to new location */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) if (first_free > fj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) for (k = j; k < MAX_NR_FUNC; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) if (func_table[k])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) if (funcbufptr != func_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) kfree(funcbufptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) funcbufptr = fnw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) funcbufleft = funcbufleft - delta + sz - funcbufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) funcbufsize = sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) /* finally insert item itself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) strcpy(func_table[i], kbs->kb_string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) spin_unlock_irqrestore(&func_buf_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) reterr:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) kfree(kbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) unsigned char ucval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) switch(cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) /* the ioctls below read/set the flags usually shown in the leds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) /* don't use them - they will go away without warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) case KDGKBLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) ucval = kb->ledflagstate | (kb->default_ledflagstate << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) return put_user(ucval, (char __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) case KDSKBLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) if (arg & ~0x77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) spin_lock_irqsave(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) kb->ledflagstate = (arg & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) kb->default_ledflagstate = ((arg >> 4) & 7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) set_leds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) spin_unlock_irqrestore(&led_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) /* the ioctls below only set the lights, not the functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) /* for those, see KDGKBLED and KDSKBLED above */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) case KDGETLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) ucval = getledstate();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) return put_user(ucval, (char __user *)arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) case KDSETLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) if (!perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) setledstate(kb, arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) return -ENOIOCTLCMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) int vt_do_kdgkbmode(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) /* This is a spot read so needs no locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) switch (kb->kbdmode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) case VC_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) return K_RAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) case VC_MEDIUMRAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) return K_MEDIUMRAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) case VC_UNICODE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) return K_UNICODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) case VC_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) return K_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) return K_XLATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) * vt_do_kdgkbmeta - report meta status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * @console: console to report
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) * Report the meta flag status of this console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) int vt_do_kdgkbmeta(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) /* Again a spot read so no locking */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) return vc_kbd_mode(kb, VC_META) ? K_ESCPREFIX : K_METABIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) * vt_reset_unicode - reset the unicode status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) * @console: console being reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) * Restore the unicode console state to its default
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) void vt_reset_unicode(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) * vt_get_shiftstate - shift bit state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) * Report the shift bits from the keyboard state. We have to export
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) * this to support some oddities in the vt layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) int vt_get_shift_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) /* Don't lock as this is a transient report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) return shift_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * vt_reset_keyboard - reset keyboard state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * @console: console to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) * Reset the keyboard bits for a console as part of a general console
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) * reset event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) void vt_reset_keyboard(int console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) set_vc_kbd_mode(kb, VC_REPEAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) clr_vc_kbd_mode(kb, VC_CKMODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) clr_vc_kbd_mode(kb, VC_APPLIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) clr_vc_kbd_mode(kb, VC_CRLF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) kb->lockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) kb->slockstate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) spin_lock(&led_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) kb->ledmode = LED_SHOW_FLAGS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) kb->ledflagstate = kb->default_ledflagstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) spin_unlock(&led_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) /* do not do set_leds here because this causes an endless tasklet loop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) when the keyboard hasn't been initialized yet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) * vt_get_kbd_mode_bit - read keyboard status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * @console: console to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) * @bit: mode bit to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) * Report back a vt mode bit. We do this without locking so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) * caller must be sure that there are no synchronization needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) int vt_get_kbd_mode_bit(int console, int bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) return vc_kbd_mode(kb, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * vt_set_kbd_mode_bit - read keyboard status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * @console: console to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * @bit: mode bit to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) * Set a vt mode bit. We do this without locking so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) * caller must be sure that there are no synchronization needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) void vt_set_kbd_mode_bit(int console, int bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) set_vc_kbd_mode(kb, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) * vt_clr_kbd_mode_bit - read keyboard status bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) * @console: console to read from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) * @bit: mode bit to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) * Report back a vt mode bit. We do this without locking so the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) * caller must be sure that there are no synchronization needs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) void vt_clr_kbd_mode_bit(int console, int bit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) struct kbd_struct *kb = kbd_table + console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) spin_lock_irqsave(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) clr_vc_kbd_mode(kb, bit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) spin_unlock_irqrestore(&kbd_event_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) }