blob: b021a18176666981e701cfbe5fe75a2e60af4499 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * Written for linux by Johan Myreen as a translation from
3 * the assembly version by Linus (with diacriticals added)
4 *
5 * Some additional features added by Christoph Niemann (ChN), March 1993
6 *
7 * Loadable keymaps by Risto Kankkunen, May 1993
8 *
9 * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
10 * Added decr/incr_console, dynamic keymaps, Unicode support,
11 * dynamic function/string keys, led setting, Sept 1994
12 * `Sticky' modifier keys, 951006.
13 *
14 * 11-11-96: SAK should now work in the raw mode (Martin Mares)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050015 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070016 * Modified to provide 'generic' keyboard support by Hamish Macdonald
17 * Merge with the m68k keyboard driver and split-off of the PC low-level
18 * parts by Geert Uytterhoeven, May 1997
19 *
20 * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
21 * 30-07-98: Dead keys redone, aeb@cwi.nl.
22 * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
23 */
24
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -070025#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26
Jan Engelhardt759448f2007-07-15 23:40:40 -070027#include <linux/consolemap.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028#include <linux/module.h>
29#include <linux/sched.h>
30#include <linux/tty.h>
31#include <linux/tty_flip.h>
32#include <linux/mm.h>
33#include <linux/string.h>
34#include <linux/init.h>
35#include <linux/slab.h>
36
37#include <linux/kbd_kern.h>
38#include <linux/kbd_diacr.h>
39#include <linux/vt_kern.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/input.h>
Adrian Bunk83cc5ed2006-06-25 05:47:41 -070041#include <linux/reboot.h>
Samuel Thibault41ab4392007-10-18 23:39:12 -070042#include <linux/notifier.h>
Julia Lawallb39b0442008-04-17 09:28:25 -040043#include <linux/jiffies.h>
Greg Kroah-Hartman6623d642012-02-27 15:18:56 -080044#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Geert Uytterhoeven98c2b372011-09-11 13:59:29 +020046#include <asm/irq_regs.h>
47
Linus Torvalds1da177e2005-04-16 15:20:36 -070048extern void ctrl_alt_del(void);
49
50/*
51 * Exported functions/variables
52 */
53
54#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META))
55
Joshua Covb2d0b7a2012-04-13 21:08:26 +020056#if defined(CONFIG_X86) || defined(CONFIG_PARISC)
57#include <asm/kbdleds.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070058#else
Joshua Covb2d0b7a2012-04-13 21:08:26 +020059static inline int kbd_defleds(void)
60{
61 return 0;
62}
Linus Torvalds1da177e2005-04-16 15:20:36 -070063#endif
64
65#define KBD_DEFLOCK 0
66
Linus Torvalds1da177e2005-04-16 15:20:36 -070067/*
68 * Handler Tables.
69 */
70
71#define K_HANDLERS\
72 k_self, k_fn, k_spec, k_pad,\
73 k_dead, k_cons, k_cur, k_shift,\
74 k_meta, k_ascii, k_lock, k_lowercase,\
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -050075 k_slock, k_dead2, k_brl, k_ignore
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050077typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value,
David Howells7d12e782006-10-05 14:55:46 +010078 char up_flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -070079static k_handler_fn K_HANDLERS;
Dmitry Torokhov97f5f0c2010-03-21 22:31:26 -070080static k_handler_fn *k_handler[16] = { K_HANDLERS };
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82#define FN_HANDLERS\
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -050083 fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\
84 fn_show_state, fn_send_intr, fn_lastcons, fn_caps_toggle,\
85 fn_num, fn_hold, fn_scroll_forw, fn_scroll_back,\
86 fn_boot_it, fn_caps_on, fn_compose, fn_SAK,\
87 fn_dec_console, fn_inc_console, fn_spawn_con, fn_bare_num
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
David Howells7d12e782006-10-05 14:55:46 +010089typedef void (fn_handler_fn)(struct vc_data *vc);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090static fn_handler_fn FN_HANDLERS;
91static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
92
93/*
94 * Variables exported for vt_ioctl.c
95 */
96
Eric W. Biederman81af8d62006-10-02 02:17:13 -070097struct vt_spawn_console vt_spawn_con = {
Milind Arun Choudharyccc94252007-05-08 00:30:09 -070098 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
Eric W. Biederman81af8d62006-10-02 02:17:13 -070099 .pid = NULL,
100 .sig = 0,
101};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103
104/*
105 * Internal Data.
106 */
107
Alan Cox079c9532012-02-28 14:49:23 +0000108static struct kbd_struct kbd_table[MAX_NR_CONSOLES];
109static struct kbd_struct *kbd = kbd_table;
110
111/* maximum values each key_handler can handle */
112static const int max_vals[] = {
113 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
114 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
115 255, NR_LOCK - 1, 255, NR_BRL - 1
116};
117
118static const int NR_TYPES = ARRAY_SIZE(max_vals);
119
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120static struct input_handler kbd_handler;
Dmitry Torokhov21cea582009-11-29 23:40:58 -0800121static DEFINE_SPINLOCK(kbd_event_lock);
Jiri Slaby7b19ada2007-10-18 23:40:32 -0700122static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
Dmitry Torokhove0785572010-03-21 22:31:26 -0700124static bool dead_key_next;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125static int npadch = -1; /* -1 or number assembled on pad */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500126static unsigned int diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127static char rep; /* flag telling character repeat */
128
Alan Cox079c9532012-02-28 14:49:23 +0000129static int shift_state = 0;
130
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131static unsigned char ledstate = 0xff; /* undefined */
132static unsigned char ledioctl;
133
134static struct ledptr {
135 unsigned int *addr;
136 unsigned int mask;
137 unsigned char valid:1;
138} ledptrs[3];
139
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140/*
Samuel Thibault41ab4392007-10-18 23:39:12 -0700141 * Notifier list for console keyboard events
142 */
143static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
144
145int register_keyboard_notifier(struct notifier_block *nb)
146{
147 return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
148}
149EXPORT_SYMBOL_GPL(register_keyboard_notifier);
150
151int unregister_keyboard_notifier(struct notifier_block *nb)
152{
153 return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
154}
155EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
156
157/*
Marvin Raaijmakersc8e4c772007-03-14 22:50:42 -0400158 * Translation of scancodes to keycodes. We set them on only the first
159 * keyboard in the list that accepts the scancode and keycode.
160 * Explanation for not choosing the first attached keyboard anymore:
161 * USB keyboards for example have two event devices: one for all "normal"
162 * keys and one for extra function keys (like "volume up", "make coffee",
163 * etc.). So this means that scancodes for the extra function keys won't
164 * be valid for the first event device, but will be for the second.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 */
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800166
167struct getset_keycode_data {
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700168 struct input_keymap_entry ke;
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800169 int error;
170};
171
172static int getkeycode_helper(struct input_handle *handle, void *data)
173{
174 struct getset_keycode_data *d = data;
175
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700176 d->error = input_get_keycode(handle->dev, &d->ke);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800177
178 return d->error == 0; /* stop as soon as we successfully get one */
179}
180
Alan Cox079c9532012-02-28 14:49:23 +0000181static int getkeycode(unsigned int scancode)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182{
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700183 struct getset_keycode_data d = {
184 .ke = {
185 .flags = 0,
186 .len = sizeof(scancode),
187 .keycode = 0,
188 },
189 .error = -ENODEV,
190 };
191
192 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800194 input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700196 return d.error ?: d.ke.keycode;
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800197}
198
199static int setkeycode_helper(struct input_handle *handle, void *data)
200{
201 struct getset_keycode_data *d = data;
202
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700203 d->error = input_set_keycode(handle->dev, &d->ke);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800204
205 return d->error == 0; /* stop as soon as we successfully set one */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206}
207
Alan Cox079c9532012-02-28 14:49:23 +0000208static int setkeycode(unsigned int scancode, unsigned int keycode)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209{
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700210 struct getset_keycode_data d = {
211 .ke = {
212 .flags = 0,
213 .len = sizeof(scancode),
214 .keycode = keycode,
215 },
216 .error = -ENODEV,
217 };
218
219 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800221 input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800223 return d.error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224}
225
226/*
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800227 * Making beeps and bells. Note that we prefer beeps to bells, but when
228 * shutting the sound off we do both.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 */
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800230
231static int kd_sound_helper(struct input_handle *handle, void *data)
232{
233 unsigned int *hz = data;
234 struct input_dev *dev = handle->dev;
235
236 if (test_bit(EV_SND, dev->evbit)) {
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800237 if (test_bit(SND_TONE, dev->sndbit)) {
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800238 input_inject_event(handle, EV_SND, SND_TONE, *hz);
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800239 if (*hz)
240 return 0;
241 }
242 if (test_bit(SND_BELL, dev->sndbit))
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800243 input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
244 }
245
246 return 0;
247}
248
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249static void kd_nosound(unsigned long ignored)
250{
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800251 static unsigned int zero;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800253 input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254}
255
Ingo Molnar8d06afa2005-09-09 13:10:40 -0700256static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257
258void kd_mksound(unsigned int hz, unsigned int ticks)
259{
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800260 del_timer_sync(&kd_mksound_timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800262 input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800264 if (hz && ticks)
265 mod_timer(&kd_mksound_timer, jiffies + ticks);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266}
Samuel Thibaultf7511d52008-04-30 00:54:51 -0700267EXPORT_SYMBOL(kd_mksound);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700268
269/*
270 * Setting the keyboard rate.
271 */
272
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800273static int kbd_rate_helper(struct input_handle *handle, void *data)
274{
275 struct input_dev *dev = handle->dev;
276 struct kbd_repeat *rep = data;
277
278 if (test_bit(EV_REP, dev->evbit)) {
279
280 if (rep[0].delay > 0)
281 input_inject_event(handle,
282 EV_REP, REP_DELAY, rep[0].delay);
283 if (rep[0].period > 0)
284 input_inject_event(handle,
285 EV_REP, REP_PERIOD, rep[0].period);
286
287 rep[1].delay = dev->rep[REP_DELAY];
288 rep[1].period = dev->rep[REP_PERIOD];
289 }
290
291 return 0;
292}
293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294int kbd_rate(struct kbd_repeat *rep)
295{
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800296 struct kbd_repeat data[2] = { *rep };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800298 input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
299 *rep = data[1]; /* Copy currently used settings */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 return 0;
302}
303
304/*
305 * Helper Functions.
306 */
307static void put_queue(struct vc_data *vc, int ch)
308{
Alan Cox8ce73262010-06-01 22:52:56 +0200309 struct tty_struct *tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310
311 if (tty) {
312 tty_insert_flip_char(tty, ch, 0);
313 con_schedule_flip(tty);
314 }
315}
316
317static void puts_queue(struct vc_data *vc, char *cp)
318{
Alan Cox8ce73262010-06-01 22:52:56 +0200319 struct tty_struct *tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320
321 if (!tty)
322 return;
323
324 while (*cp) {
325 tty_insert_flip_char(tty, *cp, 0);
326 cp++;
327 }
328 con_schedule_flip(tty);
329}
330
331static void applkey(struct vc_data *vc, int key, char mode)
332{
333 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
334
335 buf[1] = (mode ? 'O' : '[');
336 buf[2] = key;
337 puts_queue(vc, buf);
338}
339
340/*
341 * Many other routines do put_queue, but I think either
342 * they produce ASCII, or they produce some user-assigned
343 * string, and in both cases we might assume that it is
Jan Engelhardt759448f2007-07-15 23:40:40 -0700344 * in utf-8 already.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 */
Jan Engelhardt759448f2007-07-15 23:40:40 -0700346static void to_utf8(struct vc_data *vc, uint c)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700347{
348 if (c < 0x80)
349 /* 0******* */
350 put_queue(vc, c);
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500351 else if (c < 0x800) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 /* 110***** 10****** */
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500353 put_queue(vc, 0xc0 | (c >> 6));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhove0785572010-03-21 22:31:26 -0700355 } else if (c < 0x10000) {
356 if (c >= 0xD800 && c < 0xE000)
Jan Engelhardt759448f2007-07-15 23:40:40 -0700357 return;
358 if (c == 0xFFFF)
359 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 /* 1110**** 10****** 10****** */
361 put_queue(vc, 0xe0 | (c >> 12));
362 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
363 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhove0785572010-03-21 22:31:26 -0700364 } else if (c < 0x110000) {
Jan Engelhardt759448f2007-07-15 23:40:40 -0700365 /* 11110*** 10****** 10****** 10****** */
366 put_queue(vc, 0xf0 | (c >> 18));
367 put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
368 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
369 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371}
372
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500373/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 * Called after returning from RAW mode or when changing consoles - recompute
375 * shift_down[] and shift_state from key_down[] maybe called when keymap is
Alan Cox079c9532012-02-28 14:49:23 +0000376 * undefined, so that shiftkey release is seen. The caller must hold the
377 * kbd_event_lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 */
Alan Cox079c9532012-02-28 14:49:23 +0000379
380static void do_compute_shiftstate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
382 unsigned int i, j, k, sym, val;
383
384 shift_state = 0;
385 memset(shift_down, 0, sizeof(shift_down));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500386
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 for (i = 0; i < ARRAY_SIZE(key_down); i++) {
388
389 if (!key_down[i])
390 continue;
391
392 k = i * BITS_PER_LONG;
393
394 for (j = 0; j < BITS_PER_LONG; j++, k++) {
395
396 if (!test_bit(k, key_down))
397 continue;
398
399 sym = U(key_maps[0][k]);
400 if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
401 continue;
402
403 val = KVAL(sym);
404 if (val == KVAL(K_CAPSSHIFT))
405 val = KVAL(K_SHIFT);
406
407 shift_down[val]++;
408 shift_state |= (1 << val);
409 }
410 }
411}
412
Alan Cox079c9532012-02-28 14:49:23 +0000413/* We still have to export this method to vt.c */
414void compute_shiftstate(void)
415{
416 unsigned long flags;
417 spin_lock_irqsave(&kbd_event_lock, flags);
418 do_compute_shiftstate();
419 spin_unlock_irqrestore(&kbd_event_lock, flags);
420}
421
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422/*
423 * We have a combining character DIACR here, followed by the character CH.
424 * If the combination occurs in the table, return the corresponding value.
425 * Otherwise, if CH is a space or equals DIACR, return DIACR.
426 * Otherwise, conclude that DIACR was not combining after all,
427 * queue it and return CH.
428 */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500429static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430{
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500431 unsigned int d = diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 unsigned int i;
433
434 diacr = 0;
435
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500436 if ((d & ~0xff) == BRL_UC_ROW) {
437 if ((ch & ~0xff) == BRL_UC_ROW)
438 return d | ch;
439 } else {
440 for (i = 0; i < accent_table_size; i++)
441 if (accent_table[i].diacr == d && accent_table[i].base == ch)
442 return accent_table[i].result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 }
444
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500445 if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446 return d;
447
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500448 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700449 to_utf8(vc, d);
450 else {
451 int c = conv_uni_to_8bit(d);
452 if (c != -1)
453 put_queue(vc, c);
454 }
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500455
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 return ch;
457}
458
459/*
460 * Special function handlers
461 */
David Howells7d12e782006-10-05 14:55:46 +0100462static void fn_enter(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463{
464 if (diacr) {
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500465 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700466 to_utf8(vc, diacr);
467 else {
468 int c = conv_uni_to_8bit(diacr);
469 if (c != -1)
470 put_queue(vc, c);
471 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 diacr = 0;
473 }
Dmitry Torokhove0785572010-03-21 22:31:26 -0700474
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 put_queue(vc, 13);
476 if (vc_kbd_mode(kbd, VC_CRLF))
477 put_queue(vc, 10);
478}
479
David Howells7d12e782006-10-05 14:55:46 +0100480static void fn_caps_toggle(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481{
482 if (rep)
483 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700484
Linus Torvalds1da177e2005-04-16 15:20:36 -0700485 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
486}
487
David Howells7d12e782006-10-05 14:55:46 +0100488static void fn_caps_on(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489{
490 if (rep)
491 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700492
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 set_vc_kbd_led(kbd, VC_CAPSLOCK);
494}
495
David Howells7d12e782006-10-05 14:55:46 +0100496static void fn_show_ptregs(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497{
David Howells7d12e782006-10-05 14:55:46 +0100498 struct pt_regs *regs = get_irq_regs();
Dmitry Torokhove0785572010-03-21 22:31:26 -0700499
Linus Torvalds1da177e2005-04-16 15:20:36 -0700500 if (regs)
501 show_regs(regs);
502}
503
David Howells7d12e782006-10-05 14:55:46 +0100504static void fn_hold(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505{
Alan Cox8ce73262010-06-01 22:52:56 +0200506 struct tty_struct *tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507
508 if (rep || !tty)
509 return;
510
511 /*
512 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
513 * these routines are also activated by ^S/^Q.
514 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
515 */
516 if (tty->stopped)
517 start_tty(tty);
518 else
519 stop_tty(tty);
520}
521
David Howells7d12e782006-10-05 14:55:46 +0100522static void fn_num(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700524 if (vc_kbd_mode(kbd, VC_APPLIC))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525 applkey(vc, 'P', 1);
526 else
David Howells7d12e782006-10-05 14:55:46 +0100527 fn_bare_num(vc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700528}
529
530/*
531 * Bind this to Shift-NumLock if you work in application keypad mode
532 * but want to be able to change the NumLock flag.
533 * Bind this to NumLock if you prefer that the NumLock key always
534 * changes the NumLock flag.
535 */
David Howells7d12e782006-10-05 14:55:46 +0100536static void fn_bare_num(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537{
538 if (!rep)
539 chg_vc_kbd_led(kbd, VC_NUMLOCK);
540}
541
David Howells7d12e782006-10-05 14:55:46 +0100542static void fn_lastcons(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543{
544 /* switch to the last used console, ChN */
545 set_console(last_console);
546}
547
David Howells7d12e782006-10-05 14:55:46 +0100548static void fn_dec_console(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549{
550 int i, cur = fg_console;
551
552 /* Currently switching? Queue this next switch relative to that. */
553 if (want_console != -1)
554 cur = want_console;
555
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500556 for (i = cur - 1; i != cur; i--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 if (i == -1)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500558 i = MAX_NR_CONSOLES - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559 if (vc_cons_allocated(i))
560 break;
561 }
562 set_console(i);
563}
564
David Howells7d12e782006-10-05 14:55:46 +0100565static void fn_inc_console(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566{
567 int i, cur = fg_console;
568
569 /* Currently switching? Queue this next switch relative to that. */
570 if (want_console != -1)
571 cur = want_console;
572
573 for (i = cur+1; i != cur; i++) {
574 if (i == MAX_NR_CONSOLES)
575 i = 0;
576 if (vc_cons_allocated(i))
577 break;
578 }
579 set_console(i);
580}
581
David Howells7d12e782006-10-05 14:55:46 +0100582static void fn_send_intr(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583{
Alan Cox8ce73262010-06-01 22:52:56 +0200584 struct tty_struct *tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585
586 if (!tty)
587 return;
588 tty_insert_flip_char(tty, 0, TTY_BREAK);
589 con_schedule_flip(tty);
590}
591
David Howells7d12e782006-10-05 14:55:46 +0100592static void fn_scroll_forw(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593{
594 scrollfront(vc, 0);
595}
596
David Howells7d12e782006-10-05 14:55:46 +0100597static void fn_scroll_back(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598{
599 scrollback(vc, 0);
600}
601
David Howells7d12e782006-10-05 14:55:46 +0100602static void fn_show_mem(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603{
David Rientjesb2b755b2011-03-24 15:18:15 -0700604 show_mem(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605}
606
David Howells7d12e782006-10-05 14:55:46 +0100607static void fn_show_state(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608{
609 show_state();
610}
611
David Howells7d12e782006-10-05 14:55:46 +0100612static void fn_boot_it(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613{
614 ctrl_alt_del();
615}
616
David Howells7d12e782006-10-05 14:55:46 +0100617static void fn_compose(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700619 dead_key_next = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620}
621
David Howells7d12e782006-10-05 14:55:46 +0100622static void fn_spawn_con(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623{
Eric W. Biederman81af8d62006-10-02 02:17:13 -0700624 spin_lock(&vt_spawn_con.lock);
625 if (vt_spawn_con.pid)
626 if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
627 put_pid(vt_spawn_con.pid);
628 vt_spawn_con.pid = NULL;
629 }
630 spin_unlock(&vt_spawn_con.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631}
632
David Howells7d12e782006-10-05 14:55:46 +0100633static void fn_SAK(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
Eric W. Biederman8b6312f2007-02-10 01:44:34 -0800635 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
Eric W. Biederman8b6312f2007-02-10 01:44:34 -0800636 schedule_work(SAK_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637}
638
David Howells7d12e782006-10-05 14:55:46 +0100639static void fn_null(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640{
Alan Cox079c9532012-02-28 14:49:23 +0000641 do_compute_shiftstate();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642}
643
644/*
645 * Special key handlers
646 */
David Howells7d12e782006-10-05 14:55:46 +0100647static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
649}
650
David Howells7d12e782006-10-05 14:55:46 +0100651static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652{
653 if (up_flag)
654 return;
655 if (value >= ARRAY_SIZE(fn_handler))
656 return;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500657 if ((kbd->kbdmode == VC_RAW ||
Arthur Taylor9fc3de92011-02-04 13:55:50 -0800658 kbd->kbdmode == VC_MEDIUMRAW ||
659 kbd->kbdmode == VC_OFF) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 value != KVAL(K_SAK))
661 return; /* SAK is allowed even in raw mode */
David Howells7d12e782006-10-05 14:55:46 +0100662 fn_handler[value](vc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663}
664
David Howells7d12e782006-10-05 14:55:46 +0100665static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666{
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -0700667 pr_err("k_lowercase was called - impossible\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668}
669
David Howells7d12e782006-10-05 14:55:46 +0100670static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700671{
672 if (up_flag)
673 return; /* no action, if this is a key release */
674
675 if (diacr)
676 value = handle_diacr(vc, value);
677
678 if (dead_key_next) {
Dmitry Torokhove0785572010-03-21 22:31:26 -0700679 dead_key_next = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 diacr = value;
681 return;
682 }
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500683 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700684 to_utf8(vc, value);
685 else {
686 int c = conv_uni_to_8bit(value);
687 if (c != -1)
688 put_queue(vc, c);
689 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700690}
691
692/*
693 * Handle dead key. Note that we now may have several
694 * dead keys modifying the same character. Very useful
695 * for Vietnamese.
696 */
David Howells7d12e782006-10-05 14:55:46 +0100697static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698{
699 if (up_flag)
700 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700701
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 diacr = (diacr ? handle_diacr(vc, value) : value);
703}
704
David Howells7d12e782006-10-05 14:55:46 +0100705static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500706{
Jiri Bohacd2187eb2008-06-12 15:21:51 -0700707 k_unicode(vc, conv_8bit_to_uni(value), up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500708}
709
David Howells7d12e782006-10-05 14:55:46 +0100710static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500711{
David Howells7d12e782006-10-05 14:55:46 +0100712 k_deadunicode(vc, value, up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500713}
714
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715/*
716 * Obsolete - for backwards compatibility only
717 */
David Howells7d12e782006-10-05 14:55:46 +0100718static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400720 static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
Dmitry Torokhove0785572010-03-21 22:31:26 -0700721
722 k_deadunicode(vc, ret_diacr[value], up_flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723}
724
David Howells7d12e782006-10-05 14:55:46 +0100725static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
727 if (up_flag)
728 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700729
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730 set_console(value);
731}
732
David Howells7d12e782006-10-05 14:55:46 +0100733static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 if (up_flag)
736 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700737
738 if ((unsigned)value < ARRAY_SIZE(func_table)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700739 if (func_table[value])
740 puts_queue(vc, func_table[value]);
741 } else
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -0700742 pr_err("k_fn called with value=%d\n", value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743}
744
David Howells7d12e782006-10-05 14:55:46 +0100745static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746{
Brandon Philipse52b29c2006-11-04 22:09:08 -0500747 static const char cur_chars[] = "BDCA";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748
749 if (up_flag)
750 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700751
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752 applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
753}
754
David Howells7d12e782006-10-05 14:55:46 +0100755static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400757 static const char pad_chars[] = "0123456789+-*/\015,.?()#";
758 static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759
760 if (up_flag)
761 return; /* no action, if this is a key release */
762
763 /* kludge... shift forces cursor/number keys */
764 if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
765 applkey(vc, app_map[value], 1);
766 return;
767 }
768
Dmitry Torokhove0785572010-03-21 22:31:26 -0700769 if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
770
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771 switch (value) {
Dmitry Torokhove0785572010-03-21 22:31:26 -0700772 case KVAL(K_PCOMMA):
773 case KVAL(K_PDOT):
774 k_fn(vc, KVAL(K_REMOVE), 0);
775 return;
776 case KVAL(K_P0):
777 k_fn(vc, KVAL(K_INSERT), 0);
778 return;
779 case KVAL(K_P1):
780 k_fn(vc, KVAL(K_SELECT), 0);
781 return;
782 case KVAL(K_P2):
783 k_cur(vc, KVAL(K_DOWN), 0);
784 return;
785 case KVAL(K_P3):
786 k_fn(vc, KVAL(K_PGDN), 0);
787 return;
788 case KVAL(K_P4):
789 k_cur(vc, KVAL(K_LEFT), 0);
790 return;
791 case KVAL(K_P6):
792 k_cur(vc, KVAL(K_RIGHT), 0);
793 return;
794 case KVAL(K_P7):
795 k_fn(vc, KVAL(K_FIND), 0);
796 return;
797 case KVAL(K_P8):
798 k_cur(vc, KVAL(K_UP), 0);
799 return;
800 case KVAL(K_P9):
801 k_fn(vc, KVAL(K_PGUP), 0);
802 return;
803 case KVAL(K_P5):
804 applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
805 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 }
Dmitry Torokhove0785572010-03-21 22:31:26 -0700807 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808
809 put_queue(vc, pad_chars[value]);
810 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
811 put_queue(vc, 10);
812}
813
David Howells7d12e782006-10-05 14:55:46 +0100814static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815{
816 int old_state = shift_state;
817
818 if (rep)
819 return;
820 /*
821 * Mimic typewriter:
822 * a CapsShift key acts like Shift but undoes CapsLock
823 */
824 if (value == KVAL(K_CAPSSHIFT)) {
825 value = KVAL(K_SHIFT);
826 if (!up_flag)
827 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
828 }
829
830 if (up_flag) {
831 /*
832 * handle the case that two shift or control
833 * keys are depressed simultaneously
834 */
835 if (shift_down[value])
836 shift_down[value]--;
837 } else
838 shift_down[value]++;
839
840 if (shift_down[value])
841 shift_state |= (1 << value);
842 else
843 shift_state &= ~(1 << value);
844
845 /* kludge */
846 if (up_flag && shift_state != old_state && npadch != -1) {
847 if (kbd->kbdmode == VC_UNICODE)
Jan Engelhardt759448f2007-07-15 23:40:40 -0700848 to_utf8(vc, npadch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849 else
850 put_queue(vc, npadch & 0xff);
851 npadch = -1;
852 }
853}
854
David Howells7d12e782006-10-05 14:55:46 +0100855static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856{
857 if (up_flag)
858 return;
859
860 if (vc_kbd_mode(kbd, VC_META)) {
861 put_queue(vc, '\033');
862 put_queue(vc, value);
863 } else
864 put_queue(vc, value | 0x80);
865}
866
David Howells7d12e782006-10-05 14:55:46 +0100867static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700868{
869 int base;
870
871 if (up_flag)
872 return;
873
874 if (value < 10) {
875 /* decimal input of code, while Alt depressed */
876 base = 10;
877 } else {
878 /* hexadecimal input of code, while AltGr depressed */
879 value -= 10;
880 base = 16;
881 }
882
883 if (npadch == -1)
884 npadch = value;
885 else
886 npadch = npadch * base + value;
887}
888
David Howells7d12e782006-10-05 14:55:46 +0100889static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890{
891 if (up_flag || rep)
892 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700893
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 chg_vc_kbd_lock(kbd, value);
895}
896
David Howells7d12e782006-10-05 14:55:46 +0100897static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898{
David Howells7d12e782006-10-05 14:55:46 +0100899 k_shift(vc, value, up_flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 if (up_flag || rep)
901 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700902
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 chg_vc_kbd_slock(kbd, value);
904 /* try to make Alt, oops, AltGr and such work */
905 if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
906 kbd->slockstate = 0;
907 chg_vc_kbd_slock(kbd, value);
908 }
909}
910
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500911/* by default, 300ms interval for combination release */
Samuel Thibault77426d72006-04-26 00:14:10 -0400912static unsigned brl_timeout = 300;
913MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
914module_param(brl_timeout, uint, 0644);
915
916static unsigned brl_nbchords = 1;
917MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
918module_param(brl_nbchords, uint, 0644);
919
David Howells7d12e782006-10-05 14:55:46 +0100920static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
Samuel Thibault77426d72006-04-26 00:14:10 -0400921{
922 static unsigned long chords;
923 static unsigned committed;
924
925 if (!brl_nbchords)
David Howells7d12e782006-10-05 14:55:46 +0100926 k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
Samuel Thibault77426d72006-04-26 00:14:10 -0400927 else {
928 committed |= pattern;
929 chords++;
930 if (chords == brl_nbchords) {
David Howells7d12e782006-10-05 14:55:46 +0100931 k_unicode(vc, BRL_UC_ROW | committed, up_flag);
Samuel Thibault77426d72006-04-26 00:14:10 -0400932 chords = 0;
933 committed = 0;
934 }
935 }
936}
937
David Howells7d12e782006-10-05 14:55:46 +0100938static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500939{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700940 static unsigned pressed, committing;
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500941 static unsigned long releasestart;
942
943 if (kbd->kbdmode != VC_UNICODE) {
944 if (!up_flag)
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -0700945 pr_warning("keyboard mode must be unicode for braille patterns\n");
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500946 return;
947 }
948
949 if (!value) {
David Howells7d12e782006-10-05 14:55:46 +0100950 k_unicode(vc, BRL_UC_ROW, up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500951 return;
952 }
953
954 if (value > 8)
955 return;
956
Dmitry Torokhove0785572010-03-21 22:31:26 -0700957 if (!up_flag) {
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500958 pressed |= 1 << (value - 1);
959 if (!brl_timeout)
960 committing = pressed;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700961 } else if (brl_timeout) {
962 if (!committing ||
963 time_after(jiffies,
964 releasestart + msecs_to_jiffies(brl_timeout))) {
965 committing = pressed;
966 releasestart = jiffies;
967 }
968 pressed &= ~(1 << (value - 1));
969 if (!pressed && committing) {
970 k_brlcommit(vc, committing, 0);
971 committing = 0;
972 }
973 } else {
974 if (committing) {
975 k_brlcommit(vc, committing, 0);
976 committing = 0;
977 }
978 pressed &= ~(1 << (value - 1));
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500979 }
980}
981
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982/*
983 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
984 * or (ii) whatever pattern of lights people want to show using KDSETLED,
985 * or (iii) specified bits of specified words in kernel memory.
986 */
987unsigned char getledstate(void)
988{
989 return ledstate;
990}
991
992void setledstate(struct kbd_struct *kbd, unsigned int led)
993{
Alan Cox079c9532012-02-28 14:49:23 +0000994 unsigned long flags;
995 spin_lock_irqsave(&kbd_event_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996 if (!(led & ~7)) {
997 ledioctl = led;
998 kbd->ledmode = LED_SHOW_IOCTL;
999 } else
1000 kbd->ledmode = LED_SHOW_FLAGS;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 set_leds();
Alan Cox079c9532012-02-28 14:49:23 +00001003 spin_unlock_irqrestore(&kbd_event_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
1006static inline unsigned char getleds(void)
1007{
1008 struct kbd_struct *kbd = kbd_table + fg_console;
1009 unsigned char leds;
1010 int i;
1011
1012 if (kbd->ledmode == LED_SHOW_IOCTL)
1013 return ledioctl;
1014
1015 leds = kbd->ledflagstate;
1016
1017 if (kbd->ledmode == LED_SHOW_MEM) {
1018 for (i = 0; i < 3; i++)
1019 if (ledptrs[i].valid) {
1020 if (*ledptrs[i].addr & ledptrs[i].mask)
1021 leds |= (1 << i);
1022 else
1023 leds &= ~(1 << i);
1024 }
1025 }
1026 return leds;
1027}
1028
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001029static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1030{
1031 unsigned char leds = *(unsigned char *)data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001033 if (test_bit(EV_LED, handle->dev->evbit)) {
1034 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1035 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1036 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1037 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1038 }
1039
1040 return 0;
1041}
1042
Alan Cox079c9532012-02-28 14:49:23 +00001043/**
1044 * vt_get_leds - helper for braille console
1045 * @console: console to read
1046 * @flag: flag we want to check
1047 *
1048 * Check the status of a keyboard led flag and report it back
1049 */
1050int vt_get_leds(int console, int flag)
1051{
1052 unsigned long flags;
1053 struct kbd_struct * kbd = kbd_table + console;
1054 int ret;
1055
1056 spin_lock_irqsave(&kbd_event_lock, flags);
1057 ret = vc_kbd_led(kbd, flag);
1058 spin_unlock_irqrestore(&kbd_event_lock, flags);
1059
1060 return ret;
1061}
1062EXPORT_SYMBOL_GPL(vt_get_leds);
1063
1064/**
1065 * vt_set_led_state - set LED state of a console
1066 * @console: console to set
1067 * @leds: LED bits
1068 *
1069 * Set the LEDs on a console. This is a wrapper for the VT layer
1070 * so that we can keep kbd knowledge internal
1071 */
1072void vt_set_led_state(int console, int leds)
1073{
1074 struct kbd_struct * kbd = kbd_table + console;
1075 setledstate(kbd, leds);
1076}
1077
1078/**
1079 * vt_kbd_con_start - Keyboard side of console start
1080 * @console: console
1081 *
1082 * Handle console start. This is a wrapper for the VT layer
1083 * so that we can keep kbd knowledge internal
1084 */
1085void vt_kbd_con_start(int console)
1086{
1087 struct kbd_struct * kbd = kbd_table + console;
1088 unsigned long flags;
1089 spin_lock_irqsave(&kbd_event_lock, flags);
1090 clr_vc_kbd_led(kbd, VC_SCROLLOCK);
1091 set_leds();
1092 spin_unlock_irqrestore(&kbd_event_lock, flags);
1093}
1094
1095/**
1096 * vt_kbd_con_stop - Keyboard side of console stop
1097 * @console: console
1098 *
1099 * Handle console stop. This is a wrapper for the VT layer
1100 * so that we can keep kbd knowledge internal
1101 */
1102void vt_kbd_con_stop(int console)
1103{
1104 struct kbd_struct * kbd = kbd_table + console;
1105 unsigned long flags;
1106 spin_lock_irqsave(&kbd_event_lock, flags);
1107 set_vc_kbd_led(kbd, VC_SCROLLOCK);
1108 set_leds();
1109 spin_unlock_irqrestore(&kbd_event_lock, flags);
1110}
1111
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001112/*
1113 * This is the tasklet that updates LED state on all keyboards
1114 * attached to the box. The reason we use tasklet is that we
1115 * need to handle the scenario when keyboard handler is not
1116 * registered yet but we already getting updates form VT to
1117 * update led state.
1118 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001119static void kbd_bh(unsigned long dummy)
1120{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001121 unsigned char leds = getleds();
1122
1123 if (leds != ledstate) {
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001124 input_handler_for_each_handle(&kbd_handler, &leds,
1125 kbd_update_leds_helper);
1126 ledstate = leds;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001127 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128}
1129
1130DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1131
Linus Torvalds1da177e2005-04-16 15:20:36 -07001132#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001133 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1134 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
Hans-Christian Egtvedt3a4e8322007-12-04 13:15:41 +01001135 (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
1136 defined(CONFIG_AVR32)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001137
1138#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
1139 ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
1140
Andreas Mohr0f5e5602006-06-05 00:18:00 -04001141static const unsigned short x86_keycodes[256] =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001142 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1143 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1144 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
1145 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1146 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1147 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001148 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001149 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1150 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
Hans de Goede72a42f22007-07-03 01:55:18 -04001151 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
1152 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1154 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1155 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1156 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1157
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001158#ifdef CONFIG_SPARC
Dmitry Torokhove0785572010-03-21 22:31:26 -07001159static int sparc_l1_a_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160extern void sun_do_break(void);
1161#endif
1162
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001163static int emulate_raw(struct vc_data *vc, unsigned int keycode,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 unsigned char up_flag)
1165{
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001166 int code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167
1168 switch (keycode) {
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001169
Dmitry Torokhove0785572010-03-21 22:31:26 -07001170 case KEY_PAUSE:
1171 put_queue(vc, 0xe1);
1172 put_queue(vc, 0x1d | up_flag);
1173 put_queue(vc, 0x45 | up_flag);
1174 break;
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001175
Dmitry Torokhove0785572010-03-21 22:31:26 -07001176 case KEY_HANGEUL:
1177 if (!up_flag)
1178 put_queue(vc, 0xf2);
1179 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180
Dmitry Torokhove0785572010-03-21 22:31:26 -07001181 case KEY_HANJA:
1182 if (!up_flag)
1183 put_queue(vc, 0xf1);
1184 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001185
Dmitry Torokhove0785572010-03-21 22:31:26 -07001186 case KEY_SYSRQ:
1187 /*
1188 * Real AT keyboards (that's what we're trying
1189 * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
1190 * pressing PrtSc/SysRq alone, but simply 0x54
1191 * when pressing Alt+PrtSc/SysRq.
1192 */
1193 if (test_bit(KEY_LEFTALT, key_down) ||
1194 test_bit(KEY_RIGHTALT, key_down)) {
1195 put_queue(vc, 0x54 | up_flag);
1196 } else {
1197 put_queue(vc, 0xe0);
1198 put_queue(vc, 0x2a | up_flag);
1199 put_queue(vc, 0xe0);
1200 put_queue(vc, 0x37 | up_flag);
1201 }
1202 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001203
Dmitry Torokhove0785572010-03-21 22:31:26 -07001204 default:
1205 if (keycode > 255)
1206 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
Dmitry Torokhove0785572010-03-21 22:31:26 -07001208 code = x86_keycodes[keycode];
1209 if (!code)
1210 return -1;
Dmitry Torokhov896cdc7b2006-07-19 01:14:25 -04001211
Dmitry Torokhove0785572010-03-21 22:31:26 -07001212 if (code & 0x100)
1213 put_queue(vc, 0xe0);
1214 put_queue(vc, (code & 0x7f) | up_flag);
1215
1216 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001217 }
1218
1219 return 0;
1220}
1221
1222#else
1223
1224#define HW_RAW(dev) 0
1225
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
1227{
1228 if (keycode > 127)
1229 return -1;
1230
1231 put_queue(vc, keycode | up_flag);
1232 return 0;
1233}
1234#endif
1235
1236static void kbd_rawcode(unsigned char data)
1237{
1238 struct vc_data *vc = vc_cons[fg_console].d;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001239
Alan Jenkins0c09b2a2009-11-18 00:40:48 -08001240 kbd = kbd_table + vc->vc_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 if (kbd->kbdmode == VC_RAW)
1242 put_queue(vc, data);
1243}
1244
David Howells7d12e782006-10-05 14:55:46 +01001245static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246{
1247 struct vc_data *vc = vc_cons[fg_console].d;
1248 unsigned short keysym, *key_map;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001249 unsigned char type;
1250 bool raw_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 struct tty_struct *tty;
1252 int shift_final;
Samuel Thibault41ab4392007-10-18 23:39:12 -07001253 struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
Dmitry Torokhove0785572010-03-21 22:31:26 -07001254 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255
Alan Cox8ce73262010-06-01 22:52:56 +02001256 tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257
1258 if (tty && (!tty->driver_data)) {
1259 /* No driver data? Strange. Okay we fix it then. */
1260 tty->driver_data = vc;
1261 }
1262
Alan Jenkins0c09b2a2009-11-18 00:40:48 -08001263 kbd = kbd_table + vc->vc_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001265#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 if (keycode == KEY_STOP)
1267 sparc_l1_a_state = down;
1268#endif
1269
1270 rep = (down == 2);
1271
Dmitry Torokhove0785572010-03-21 22:31:26 -07001272 raw_mode = (kbd->kbdmode == VC_RAW);
1273 if (raw_mode && !hw_raw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 if (emulate_raw(vc, keycode, !down << 7))
Dmitry Torokhov9e35d202007-04-12 01:30:52 -04001275 if (keycode < BTN_MISC && printk_ratelimit())
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -07001276 pr_warning("can't emulate rawmode for keycode %d\n",
1277 keycode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001279#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001280 if (keycode == KEY_A && sparc_l1_a_state) {
Dmitry Torokhove0785572010-03-21 22:31:26 -07001281 sparc_l1_a_state = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 sun_do_break();
1283 }
1284#endif
1285
1286 if (kbd->kbdmode == VC_MEDIUMRAW) {
1287 /*
1288 * This is extended medium raw mode, with keys above 127
1289 * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
1290 * the 'up' flag if needed. 0 is reserved, so this shouldn't
1291 * interfere with anything else. The two bytes after 0 will
1292 * always have the up flag set not to interfere with older
1293 * applications. This allows for 16384 different keycodes,
1294 * which should be enough.
1295 */
1296 if (keycode < 128) {
1297 put_queue(vc, keycode | (!down << 7));
1298 } else {
1299 put_queue(vc, !down << 7);
1300 put_queue(vc, (keycode >> 7) | 0x80);
1301 put_queue(vc, keycode | 0x80);
1302 }
Dmitry Torokhove0785572010-03-21 22:31:26 -07001303 raw_mode = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 }
1305
1306 if (down)
1307 set_bit(keycode, key_down);
1308 else
1309 clear_bit(keycode, key_down);
1310
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001311 if (rep &&
1312 (!vc_kbd_mode(kbd, VC_REPEAT) ||
Alan Coxf34d7a52008-04-30 00:54:13 -07001313 (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314 /*
1315 * Don't repeat a key if the input buffers are not empty and the
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001316 * characters get aren't echoed locally. This makes key repeat
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 * usable with slow applications and under heavy loads.
1318 */
1319 return;
1320 }
1321
Samuel Thibault41ab4392007-10-18 23:39:12 -07001322 param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
Karl Dahlke0beb4f62008-04-15 01:30:32 -04001323 param.ledstate = kbd->ledflagstate;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 key_map = key_maps[shift_final];
1325
Dmitry Torokhove0785572010-03-21 22:31:26 -07001326 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1327 KBD_KEYCODE, &param);
1328 if (rc == NOTIFY_STOP || !key_map) {
1329 atomic_notifier_call_chain(&keyboard_notifier_list,
1330 KBD_UNBOUND_KEYCODE, &param);
Alan Cox079c9532012-02-28 14:49:23 +00001331 do_compute_shiftstate();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 kbd->slockstate = 0;
1333 return;
1334 }
1335
Dmitry Torokhove0785572010-03-21 22:31:26 -07001336 if (keycode < NR_KEYS)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -05001337 keysym = key_map[keycode];
Dmitry Torokhove0785572010-03-21 22:31:26 -07001338 else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1339 keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
1340 else
1341 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343 type = KTYP(keysym);
1344
1345 if (type < 0xf0) {
Samuel Thibault41ab4392007-10-18 23:39:12 -07001346 param.value = keysym;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001347 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1348 KBD_UNICODE, &param);
1349 if (rc != NOTIFY_STOP)
1350 if (down && !raw_mode)
1351 to_utf8(vc, keysym);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 return;
1353 }
1354
1355 type -= 0xf0;
1356
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 if (type == KT_LETTER) {
1358 type = KT_LATIN;
1359 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1360 key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
1361 if (key_map)
1362 keysym = key_map[keycode];
1363 }
1364 }
Samuel Thibault41ab4392007-10-18 23:39:12 -07001365
Dmitry Torokhove0785572010-03-21 22:31:26 -07001366 param.value = keysym;
1367 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1368 KBD_KEYSYM, &param);
1369 if (rc == NOTIFY_STOP)
Samuel Thibault41ab4392007-10-18 23:39:12 -07001370 return;
1371
Arthur Taylor9fc3de92011-02-04 13:55:50 -08001372 if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
Samuel Thibault41ab4392007-10-18 23:39:12 -07001373 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374
David Howells7d12e782006-10-05 14:55:46 +01001375 (*k_handler[type])(vc, keysym & 0xff, !down);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
Karl Dahlke0beb4f62008-04-15 01:30:32 -04001377 param.ledstate = kbd->ledflagstate;
Samuel Thibault41ab4392007-10-18 23:39:12 -07001378 atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
1379
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 if (type != KT_SLOCK)
1381 kbd->slockstate = 0;
1382}
1383
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001384static void kbd_event(struct input_handle *handle, unsigned int event_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 unsigned int event_code, int value)
1386{
Dmitry Torokhov21cea582009-11-29 23:40:58 -08001387 /* We are called with interrupts disabled, just take the lock */
1388 spin_lock(&kbd_event_lock);
1389
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1391 kbd_rawcode(value);
1392 if (event_type == EV_KEY)
David Howells7d12e782006-10-05 14:55:46 +01001393 kbd_keycode(event_code, value, HW_RAW(handle->dev));
Dmitry Torokhov21cea582009-11-29 23:40:58 -08001394
1395 spin_unlock(&kbd_event_lock);
1396
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397 tasklet_schedule(&keyboard_tasklet);
1398 do_poke_blanked_console = 1;
1399 schedule_console_callback();
1400}
1401
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001402static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1403{
1404 int i;
1405
1406 if (test_bit(EV_SND, dev->evbit))
1407 return true;
1408
Samuel Thibault53c1f762010-07-31 02:28:51 -07001409 if (test_bit(EV_KEY, dev->evbit)) {
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001410 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1411 if (test_bit(i, dev->keybit))
1412 return true;
Samuel Thibault53c1f762010-07-31 02:28:51 -07001413 for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
1414 if (test_bit(i, dev->keybit))
1415 return true;
1416 }
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001417
1418 return false;
1419}
1420
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421/*
1422 * When a keyboard (or other input device) is found, the kbd_connect
1423 * function is called. The function then looks at the device, and if it
1424 * likes it, it can open it and get events from it. In this (kbd_connect)
1425 * function, we should decide which VT to bind that keyboard to initially.
1426 */
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001427static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1428 const struct input_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429{
1430 struct input_handle *handle;
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001431 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432
Dmitry Torokhov22479e12006-08-04 22:51:51 -04001433 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1434 if (!handle)
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001435 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 handle->dev = dev;
1438 handle->handler = handler;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001439 handle->name = "kbd";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001441 error = input_register_handle(handle);
1442 if (error)
1443 goto err_free_handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001445 error = input_open_device(handle);
1446 if (error)
1447 goto err_unregister_handle;
1448
1449 return 0;
1450
1451 err_unregister_handle:
1452 input_unregister_handle(handle);
1453 err_free_handle:
1454 kfree(handle);
1455 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456}
1457
1458static void kbd_disconnect(struct input_handle *handle)
1459{
1460 input_close_device(handle);
Dmitry Torokhov5b2a08262007-04-12 01:29:46 -04001461 input_unregister_handle(handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 kfree(handle);
1463}
1464
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001465/*
1466 * Start keyboard handler on the new keyboard by refreshing LED state to
1467 * match the rest of the system.
1468 */
1469static void kbd_start(struct input_handle *handle)
1470{
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001471 tasklet_disable(&keyboard_tasklet);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001472
1473 if (ledstate != 0xff)
1474 kbd_update_leds_helper(handle, &ledstate);
1475
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001476 tasklet_enable(&keyboard_tasklet);
1477}
1478
Dmitry Torokhov66e66112006-09-14 01:31:59 -04001479static const struct input_device_id kbd_ids[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 {
Alan Cox6aeed472012-02-24 12:47:29 +00001481 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1482 .evbit = { BIT_MASK(EV_KEY) },
1483 },
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001484
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 {
Alan Cox6aeed472012-02-24 12:47:29 +00001486 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1487 .evbit = { BIT_MASK(EV_SND) },
1488 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
1490 { }, /* Terminating entry */
1491};
1492
1493MODULE_DEVICE_TABLE(input, kbd_ids);
1494
1495static struct input_handler kbd_handler = {
1496 .event = kbd_event,
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001497 .match = kbd_match,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 .connect = kbd_connect,
1499 .disconnect = kbd_disconnect,
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001500 .start = kbd_start,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 .name = "kbd",
1502 .id_table = kbd_ids,
1503};
1504
1505int __init kbd_init(void)
1506{
1507 int i;
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001508 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
Alan Cox6aeed472012-02-24 12:47:29 +00001510 for (i = 0; i < MAX_NR_CONSOLES; i++) {
Joshua Covb2d0b7a2012-04-13 21:08:26 +02001511 kbd_table[i].ledflagstate = kbd_defleds();
1512 kbd_table[i].default_ledflagstate = kbd_defleds();
Dmitry Torokhov2b192902006-07-19 01:13:26 -04001513 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1514 kbd_table[i].lockstate = KBD_DEFLOCK;
1515 kbd_table[i].slockstate = 0;
1516 kbd_table[i].modeflags = KBD_DEFMODE;
Bill Nottingham2e8ecb92007-10-16 23:29:38 -07001517 kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
Dmitry Torokhov2b192902006-07-19 01:13:26 -04001518 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001520 error = input_register_handler(&kbd_handler);
1521 if (error)
1522 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523
1524 tasklet_enable(&keyboard_tasklet);
1525 tasklet_schedule(&keyboard_tasklet);
1526
1527 return 0;
1528}
Alan Cox247ff8e2012-02-24 12:47:11 +00001529
1530/* Ioctl support code */
1531
1532/**
1533 * vt_do_diacrit - diacritical table updates
1534 * @cmd: ioctl request
1535 * @up: pointer to user data for ioctl
1536 * @perm: permissions check computed by caller
1537 *
1538 * Update the diacritical tables atomically and safely. Lock them
1539 * against simultaneous keypresses
1540 */
1541int vt_do_diacrit(unsigned int cmd, void __user *up, int perm)
1542{
1543 struct kbdiacrs __user *a = up;
1544 unsigned long flags;
1545 int asize;
1546 int ret = 0;
1547
1548 switch (cmd) {
1549 case KDGKBDIACR:
1550 {
1551 struct kbdiacr *diacr;
1552 int i;
1553
1554 diacr = kmalloc(MAX_DIACR * sizeof(struct kbdiacr),
1555 GFP_KERNEL);
1556 if (diacr == NULL)
1557 return -ENOMEM;
1558
1559 /* Lock the diacriticals table, make a copy and then
1560 copy it after we unlock */
1561 spin_lock_irqsave(&kbd_event_lock, flags);
1562
1563 asize = accent_table_size;
1564 for (i = 0; i < asize; i++) {
1565 diacr[i].diacr = conv_uni_to_8bit(
1566 accent_table[i].diacr);
1567 diacr[i].base = conv_uni_to_8bit(
1568 accent_table[i].base);
1569 diacr[i].result = conv_uni_to_8bit(
1570 accent_table[i].result);
1571 }
1572 spin_unlock_irqrestore(&kbd_event_lock, flags);
1573
1574 if (put_user(asize, &a->kb_cnt))
1575 ret = -EFAULT;
1576 else if (copy_to_user(a->kbdiacr, diacr,
1577 asize * sizeof(struct kbdiacr)))
1578 ret = -EFAULT;
1579 kfree(diacr);
1580 return ret;
1581 }
1582 case KDGKBDIACRUC:
1583 {
1584 struct kbdiacrsuc __user *a = up;
1585 void *buf;
1586
1587 buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc),
1588 GFP_KERNEL);
1589 if (buf == NULL)
1590 return -ENOMEM;
1591
1592 /* Lock the diacriticals table, make a copy and then
1593 copy it after we unlock */
1594 spin_lock_irqsave(&kbd_event_lock, flags);
1595
1596 asize = accent_table_size;
1597 memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc));
1598
1599 spin_unlock_irqrestore(&kbd_event_lock, flags);
1600
1601 if (put_user(asize, &a->kb_cnt))
1602 ret = -EFAULT;
1603 else if (copy_to_user(a->kbdiacruc, buf,
1604 asize*sizeof(struct kbdiacruc)))
1605 ret = -EFAULT;
1606 kfree(buf);
1607 return ret;
1608 }
1609
1610 case KDSKBDIACR:
1611 {
1612 struct kbdiacrs __user *a = up;
1613 struct kbdiacr *diacr = NULL;
1614 unsigned int ct;
1615 int i;
1616
1617 if (!perm)
1618 return -EPERM;
1619 if (get_user(ct, &a->kb_cnt))
1620 return -EFAULT;
1621 if (ct >= MAX_DIACR)
1622 return -EINVAL;
1623
1624 if (ct) {
1625 diacr = kmalloc(sizeof(struct kbdiacr) * ct,
1626 GFP_KERNEL);
1627 if (diacr == NULL)
1628 return -ENOMEM;
1629
1630 if (copy_from_user(diacr, a->kbdiacr,
1631 sizeof(struct kbdiacr) * ct)) {
1632 kfree(diacr);
1633 return -EFAULT;
1634 }
1635 }
1636
1637 spin_lock_irqsave(&kbd_event_lock, flags);
1638 accent_table_size = ct;
1639 for (i = 0; i < ct; i++) {
1640 accent_table[i].diacr =
1641 conv_8bit_to_uni(diacr[i].diacr);
1642 accent_table[i].base =
1643 conv_8bit_to_uni(diacr[i].base);
1644 accent_table[i].result =
1645 conv_8bit_to_uni(diacr[i].result);
1646 }
1647 spin_unlock_irqrestore(&kbd_event_lock, flags);
1648 kfree(diacr);
1649 return 0;
1650 }
1651
1652 case KDSKBDIACRUC:
1653 {
1654 struct kbdiacrsuc __user *a = up;
1655 unsigned int ct;
1656 void *buf = NULL;
1657
1658 if (!perm)
1659 return -EPERM;
1660
1661 if (get_user(ct, &a->kb_cnt))
1662 return -EFAULT;
1663
1664 if (ct >= MAX_DIACR)
1665 return -EINVAL;
1666
1667 if (ct) {
1668 buf = kmalloc(ct * sizeof(struct kbdiacruc),
1669 GFP_KERNEL);
1670 if (buf == NULL)
1671 return -ENOMEM;
1672
1673 if (copy_from_user(buf, a->kbdiacruc,
1674 ct * sizeof(struct kbdiacruc))) {
1675 kfree(buf);
1676 return -EFAULT;
1677 }
1678 }
1679 spin_lock_irqsave(&kbd_event_lock, flags);
1680 if (ct)
1681 memcpy(accent_table, buf,
1682 ct * sizeof(struct kbdiacruc));
1683 accent_table_size = ct;
1684 spin_unlock_irqrestore(&kbd_event_lock, flags);
1685 kfree(buf);
1686 return 0;
1687 }
1688 }
1689 return ret;
1690}
Alan Cox079c9532012-02-28 14:49:23 +00001691
1692/**
1693 * vt_do_kdskbmode - set keyboard mode ioctl
1694 * @console: the console to use
1695 * @arg: the requested mode
1696 *
1697 * Update the keyboard mode bits while holding the correct locks.
1698 * Return 0 for success or an error code.
1699 */
1700int vt_do_kdskbmode(int console, unsigned int arg)
1701{
1702 struct kbd_struct * kbd = kbd_table + console;
1703 int ret = 0;
1704 unsigned long flags;
1705
1706 spin_lock_irqsave(&kbd_event_lock, flags);
1707 switch(arg) {
1708 case K_RAW:
1709 kbd->kbdmode = VC_RAW;
1710 break;
1711 case K_MEDIUMRAW:
1712 kbd->kbdmode = VC_MEDIUMRAW;
1713 break;
1714 case K_XLATE:
1715 kbd->kbdmode = VC_XLATE;
1716 do_compute_shiftstate();
1717 break;
1718 case K_UNICODE:
1719 kbd->kbdmode = VC_UNICODE;
1720 do_compute_shiftstate();
1721 break;
1722 case K_OFF:
1723 kbd->kbdmode = VC_OFF;
1724 break;
1725 default:
1726 ret = -EINVAL;
1727 }
1728 spin_unlock_irqrestore(&kbd_event_lock, flags);
1729 return ret;
1730}
1731
1732/**
1733 * vt_do_kdskbmeta - set keyboard meta state
1734 * @console: the console to use
1735 * @arg: the requested meta state
1736 *
1737 * Update the keyboard meta bits while holding the correct locks.
1738 * Return 0 for success or an error code.
1739 */
1740int vt_do_kdskbmeta(int console, unsigned int arg)
1741{
1742 struct kbd_struct * kbd = kbd_table + console;
1743 int ret = 0;
1744 unsigned long flags;
1745
1746 spin_lock_irqsave(&kbd_event_lock, flags);
1747 switch(arg) {
1748 case K_METABIT:
1749 clr_vc_kbd_mode(kbd, VC_META);
1750 break;
1751 case K_ESCPREFIX:
1752 set_vc_kbd_mode(kbd, VC_META);
1753 break;
1754 default:
1755 ret = -EINVAL;
1756 }
1757 spin_unlock_irqrestore(&kbd_event_lock, flags);
1758 return ret;
1759}
1760
1761int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
1762 int perm)
1763{
1764 struct kbkeycode tmp;
1765 int kc = 0;
1766
1767 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
1768 return -EFAULT;
1769 switch (cmd) {
1770 case KDGETKEYCODE:
1771 kc = getkeycode(tmp.scancode);
1772 if (kc >= 0)
1773 kc = put_user(kc, &user_kbkc->keycode);
1774 break;
1775 case KDSETKEYCODE:
1776 if (!perm)
1777 return -EPERM;
1778 kc = setkeycode(tmp.scancode, tmp.keycode);
1779 break;
1780 }
1781 return kc;
1782}
1783
1784#define i (tmp.kb_index)
1785#define s (tmp.kb_table)
1786#define v (tmp.kb_value)
1787
1788int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
1789 int console)
1790{
1791 struct kbd_struct * kbd = kbd_table + console;
1792 struct kbentry tmp;
1793 ushort *key_map, *new_map, val, ov;
1794 unsigned long flags;
1795
1796 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
1797 return -EFAULT;
1798
1799 if (!capable(CAP_SYS_TTY_CONFIG))
1800 perm = 0;
1801
1802 switch (cmd) {
1803 case KDGKBENT:
1804 /* Ensure another thread doesn't free it under us */
1805 spin_lock_irqsave(&kbd_event_lock, flags);
1806 key_map = key_maps[s];
1807 if (key_map) {
1808 val = U(key_map[i]);
1809 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
1810 val = K_HOLE;
1811 } else
1812 val = (i ? K_HOLE : K_NOSUCHMAP);
1813 spin_unlock_irqrestore(&kbd_event_lock, flags);
1814 return put_user(val, &user_kbe->kb_value);
1815 case KDSKBENT:
1816 if (!perm)
1817 return -EPERM;
1818 if (!i && v == K_NOSUCHMAP) {
1819 spin_lock_irqsave(&kbd_event_lock, flags);
1820 /* deallocate map */
1821 key_map = key_maps[s];
1822 if (s && key_map) {
1823 key_maps[s] = NULL;
1824 if (key_map[0] == U(K_ALLOCATED)) {
1825 kfree(key_map);
1826 keymap_count--;
1827 }
1828 }
1829 spin_unlock_irqrestore(&kbd_event_lock, flags);
1830 break;
1831 }
1832
1833 if (KTYP(v) < NR_TYPES) {
1834 if (KVAL(v) > max_vals[KTYP(v)])
1835 return -EINVAL;
1836 } else
1837 if (kbd->kbdmode != VC_UNICODE)
1838 return -EINVAL;
1839
1840 /* ++Geert: non-PC keyboards may generate keycode zero */
1841#if !defined(__mc68000__) && !defined(__powerpc__)
1842 /* assignment to entry 0 only tests validity of args */
1843 if (!i)
1844 break;
1845#endif
1846
1847 new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
1848 if (!new_map)
1849 return -ENOMEM;
1850 spin_lock_irqsave(&kbd_event_lock, flags);
1851 key_map = key_maps[s];
1852 if (key_map == NULL) {
1853 int j;
1854
1855 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
1856 !capable(CAP_SYS_RESOURCE)) {
1857 spin_unlock_irqrestore(&kbd_event_lock, flags);
1858 kfree(new_map);
1859 return -EPERM;
1860 }
1861 key_maps[s] = new_map;
Dan Carpenter82896212012-03-10 11:59:23 +03001862 key_map = new_map;
Alan Cox079c9532012-02-28 14:49:23 +00001863 key_map[0] = U(K_ALLOCATED);
1864 for (j = 1; j < NR_KEYS; j++)
1865 key_map[j] = U(K_HOLE);
1866 keymap_count++;
1867 } else
1868 kfree(new_map);
1869
1870 ov = U(key_map[i]);
1871 if (v == ov)
1872 goto out;
1873 /*
1874 * Attention Key.
1875 */
1876 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
1877 spin_unlock_irqrestore(&kbd_event_lock, flags);
1878 return -EPERM;
1879 }
1880 key_map[i] = U(v);
1881 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
1882 do_compute_shiftstate();
1883out:
1884 spin_unlock_irqrestore(&kbd_event_lock, flags);
1885 break;
1886 }
1887 return 0;
1888}
1889#undef i
1890#undef s
1891#undef v
1892
1893/* FIXME: This one needs untangling and locking */
1894int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
1895{
1896 struct kbsentry *kbs;
1897 char *p;
1898 u_char *q;
1899 u_char __user *up;
1900 int sz;
1901 int delta;
1902 char *first_free, *fj, *fnw;
1903 int i, j, k;
1904 int ret;
1905
1906 if (!capable(CAP_SYS_TTY_CONFIG))
1907 perm = 0;
1908
1909 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
1910 if (!kbs) {
1911 ret = -ENOMEM;
1912 goto reterr;
1913 }
1914
1915 /* we mostly copy too much here (512bytes), but who cares ;) */
1916 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
1917 ret = -EFAULT;
1918 goto reterr;
1919 }
1920 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
1921 i = kbs->kb_func;
1922
1923 switch (cmd) {
1924 case KDGKBSENT:
1925 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
1926 a struct member */
1927 up = user_kdgkb->kb_string;
1928 p = func_table[i];
1929 if(p)
1930 for ( ; *p && sz; p++, sz--)
1931 if (put_user(*p, up++)) {
1932 ret = -EFAULT;
1933 goto reterr;
1934 }
1935 if (put_user('\0', up)) {
1936 ret = -EFAULT;
1937 goto reterr;
1938 }
1939 kfree(kbs);
1940 return ((p && *p) ? -EOVERFLOW : 0);
1941 case KDSKBSENT:
1942 if (!perm) {
1943 ret = -EPERM;
1944 goto reterr;
1945 }
1946
1947 q = func_table[i];
1948 first_free = funcbufptr + (funcbufsize - funcbufleft);
1949 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
1950 ;
1951 if (j < MAX_NR_FUNC)
1952 fj = func_table[j];
1953 else
1954 fj = first_free;
1955
1956 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
1957 if (delta <= funcbufleft) { /* it fits in current buf */
1958 if (j < MAX_NR_FUNC) {
1959 memmove(fj + delta, fj, first_free - fj);
1960 for (k = j; k < MAX_NR_FUNC; k++)
1961 if (func_table[k])
1962 func_table[k] += delta;
1963 }
1964 if (!q)
1965 func_table[i] = fj;
1966 funcbufleft -= delta;
1967 } else { /* allocate a larger buffer */
1968 sz = 256;
1969 while (sz < funcbufsize - funcbufleft + delta)
1970 sz <<= 1;
1971 fnw = kmalloc(sz, GFP_KERNEL);
1972 if(!fnw) {
1973 ret = -ENOMEM;
1974 goto reterr;
1975 }
1976
1977 if (!q)
1978 func_table[i] = fj;
1979 if (fj > funcbufptr)
1980 memmove(fnw, funcbufptr, fj - funcbufptr);
1981 for (k = 0; k < j; k++)
1982 if (func_table[k])
1983 func_table[k] = fnw + (func_table[k] - funcbufptr);
1984
1985 if (first_free > fj) {
1986 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
1987 for (k = j; k < MAX_NR_FUNC; k++)
1988 if (func_table[k])
1989 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
1990 }
1991 if (funcbufptr != func_buf)
1992 kfree(funcbufptr);
1993 funcbufptr = fnw;
1994 funcbufleft = funcbufleft - delta + sz - funcbufsize;
1995 funcbufsize = sz;
1996 }
1997 strcpy(func_table[i], kbs->kb_string);
1998 break;
1999 }
2000 ret = 0;
2001reterr:
2002 kfree(kbs);
2003 return ret;
2004}
2005
2006int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
2007{
2008 struct kbd_struct * kbd = kbd_table + console;
2009 unsigned long flags;
2010 unsigned char ucval;
2011
2012 switch(cmd) {
2013 /* the ioctls below read/set the flags usually shown in the leds */
2014 /* don't use them - they will go away without warning */
2015 case KDGKBLED:
2016 spin_lock_irqsave(&kbd_event_lock, flags);
2017 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
2018 spin_unlock_irqrestore(&kbd_event_lock, flags);
2019 return put_user(ucval, (char __user *)arg);
2020
2021 case KDSKBLED:
2022 if (!perm)
2023 return -EPERM;
2024 if (arg & ~0x77)
2025 return -EINVAL;
2026 spin_lock_irqsave(&kbd_event_lock, flags);
2027 kbd->ledflagstate = (arg & 7);
2028 kbd->default_ledflagstate = ((arg >> 4) & 7);
2029 set_leds();
2030 spin_unlock_irqrestore(&kbd_event_lock, flags);
2031 break;
2032
2033 /* the ioctls below only set the lights, not the functions */
2034 /* for those, see KDGKBLED and KDSKBLED above */
2035 case KDGETLED:
2036 ucval = getledstate();
2037 return put_user(ucval, (char __user *)arg);
2038
2039 case KDSETLED:
2040 if (!perm)
2041 return -EPERM;
2042 setledstate(kbd, arg);
2043 return 0;
2044 }
2045 return -ENOIOCTLCMD;
2046}
2047
2048int vt_do_kdgkbmode(int console)
2049{
2050 struct kbd_struct * kbd = kbd_table + console;
2051 /* This is a spot read so needs no locking */
2052 switch (kbd->kbdmode) {
2053 case VC_RAW:
2054 return K_RAW;
2055 case VC_MEDIUMRAW:
2056 return K_MEDIUMRAW;
2057 case VC_UNICODE:
2058 return K_UNICODE;
2059 case VC_OFF:
2060 return K_OFF;
2061 default:
2062 return K_XLATE;
2063 }
2064}
2065
2066/**
2067 * vt_do_kdgkbmeta - report meta status
2068 * @console: console to report
2069 *
2070 * Report the meta flag status of this console
2071 */
2072int vt_do_kdgkbmeta(int console)
2073{
2074 struct kbd_struct * kbd = kbd_table + console;
2075 /* Again a spot read so no locking */
2076 return vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT;
2077}
2078
2079/**
2080 * vt_reset_unicode - reset the unicode status
2081 * @console: console being reset
2082 *
2083 * Restore the unicode console state to its default
2084 */
2085void vt_reset_unicode(int console)
2086{
2087 unsigned long flags;
2088
2089 spin_lock_irqsave(&kbd_event_lock, flags);
2090 kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
2091 spin_unlock_irqrestore(&kbd_event_lock, flags);
2092}
2093
2094/**
2095 * vt_get_shiftstate - shift bit state
2096 *
2097 * Report the shift bits from the keyboard state. We have to export
2098 * this to support some oddities in the vt layer.
2099 */
2100int vt_get_shift_state(void)
2101{
2102 /* Don't lock as this is a transient report */
2103 return shift_state;
2104}
2105
2106/**
2107 * vt_reset_keyboard - reset keyboard state
2108 * @console: console to reset
2109 *
2110 * Reset the keyboard bits for a console as part of a general console
2111 * reset event
2112 */
2113void vt_reset_keyboard(int console)
2114{
2115 struct kbd_struct * kbd = kbd_table + console;
2116 unsigned long flags;
2117
2118 spin_lock_irqsave(&kbd_event_lock, flags);
2119 set_vc_kbd_mode(kbd, VC_REPEAT);
2120 clr_vc_kbd_mode(kbd, VC_CKMODE);
2121 clr_vc_kbd_mode(kbd, VC_APPLIC);
2122 clr_vc_kbd_mode(kbd, VC_CRLF);
2123 kbd->lockstate = 0;
2124 kbd->slockstate = 0;
2125 kbd->ledmode = LED_SHOW_FLAGS;
2126 kbd->ledflagstate = kbd->default_ledflagstate;
2127 /* do not do set_leds here because this causes an endless tasklet loop
2128 when the keyboard hasn't been initialized yet */
2129 spin_unlock_irqrestore(&kbd_event_lock, flags);
2130}
2131
2132/**
2133 * vt_get_kbd_mode_bit - read keyboard status bits
2134 * @console: console to read from
2135 * @bit: mode bit to read
2136 *
2137 * Report back a vt mode bit. We do this without locking so the
2138 * caller must be sure that there are no synchronization needs
2139 */
2140
2141int vt_get_kbd_mode_bit(int console, int bit)
2142{
2143 struct kbd_struct * kbd = kbd_table + console;
2144 return vc_kbd_mode(kbd, bit);
2145}
2146
2147/**
2148 * vt_set_kbd_mode_bit - read keyboard status bits
2149 * @console: console to read from
2150 * @bit: mode bit to read
2151 *
2152 * Set a vt mode bit. We do this without locking so the
2153 * caller must be sure that there are no synchronization needs
2154 */
2155
2156void vt_set_kbd_mode_bit(int console, int bit)
2157{
2158 struct kbd_struct * kbd = kbd_table + console;
2159 unsigned long flags;
2160
2161 spin_lock_irqsave(&kbd_event_lock, flags);
2162 set_vc_kbd_mode(kbd, bit);
2163 spin_unlock_irqrestore(&kbd_event_lock, flags);
2164}
2165
2166/**
2167 * vt_clr_kbd_mode_bit - read keyboard status bits
2168 * @console: console to read from
2169 * @bit: mode bit to read
2170 *
2171 * Report back a vt mode bit. We do this without locking so the
2172 * caller must be sure that there are no synchronization needs
2173 */
2174
2175void vt_clr_kbd_mode_bit(int console, int bit)
2176{
2177 struct kbd_struct * kbd = kbd_table + console;
2178 unsigned long flags;
2179
2180 spin_lock_irqsave(&kbd_event_lock, flags);
2181 clr_vc_kbd_mode(kbd, bit);
2182 spin_unlock_irqrestore(&kbd_event_lock, flags);
2183}