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