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