blob: 8a89f6e7715db19debaea61781dedc40d05597fc [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);
Alan Cox3db1ddb2012-07-17 17:06:41 +0100122static DEFINE_SPINLOCK(led_lock);
Jiri Slaby7b19ada2007-10-18 23:40:32 -0700123static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
Dmitry Torokhove0785572010-03-21 22:31:26 -0700125static bool dead_key_next;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126static int npadch = -1; /* -1 or number assembled on pad */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500127static unsigned int diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128static char rep; /* flag telling character repeat */
129
Alan Cox079c9532012-02-28 14:49:23 +0000130static int shift_state = 0;
131
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132static unsigned char ledstate = 0xff; /* undefined */
133static unsigned char ledioctl;
134
Linus Torvalds1da177e2005-04-16 15:20:36 -0700135/*
Samuel Thibault41ab4392007-10-18 23:39:12 -0700136 * Notifier list for console keyboard events
137 */
138static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list);
139
140int register_keyboard_notifier(struct notifier_block *nb)
141{
142 return atomic_notifier_chain_register(&keyboard_notifier_list, nb);
143}
144EXPORT_SYMBOL_GPL(register_keyboard_notifier);
145
146int unregister_keyboard_notifier(struct notifier_block *nb)
147{
148 return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb);
149}
150EXPORT_SYMBOL_GPL(unregister_keyboard_notifier);
151
152/*
Marvin Raaijmakersc8e4c772007-03-14 22:50:42 -0400153 * Translation of scancodes to keycodes. We set them on only the first
154 * keyboard in the list that accepts the scancode and keycode.
155 * Explanation for not choosing the first attached keyboard anymore:
156 * USB keyboards for example have two event devices: one for all "normal"
157 * keys and one for extra function keys (like "volume up", "make coffee",
158 * etc.). So this means that scancodes for the extra function keys won't
159 * be valid for the first event device, but will be for the second.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160 */
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800161
162struct getset_keycode_data {
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700163 struct input_keymap_entry ke;
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800164 int error;
165};
166
167static int getkeycode_helper(struct input_handle *handle, void *data)
168{
169 struct getset_keycode_data *d = data;
170
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700171 d->error = input_get_keycode(handle->dev, &d->ke);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800172
173 return d->error == 0; /* stop as soon as we successfully get one */
174}
175
Alan Cox079c9532012-02-28 14:49:23 +0000176static int getkeycode(unsigned int scancode)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177{
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700178 struct getset_keycode_data d = {
179 .ke = {
180 .flags = 0,
181 .len = sizeof(scancode),
182 .keycode = 0,
183 },
184 .error = -ENODEV,
185 };
186
187 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800189 input_handler_for_each_handle(&kbd_handler, &d, getkeycode_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700191 return d.error ?: d.ke.keycode;
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800192}
193
194static int setkeycode_helper(struct input_handle *handle, void *data)
195{
196 struct getset_keycode_data *d = data;
197
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700198 d->error = input_set_keycode(handle->dev, &d->ke);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800199
200 return d->error == 0; /* stop as soon as we successfully set one */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201}
202
Alan Cox079c9532012-02-28 14:49:23 +0000203static int setkeycode(unsigned int scancode, unsigned int keycode)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204{
Mauro Carvalho Chehab8613e4c2010-09-09 21:54:22 -0700205 struct getset_keycode_data d = {
206 .ke = {
207 .flags = 0,
208 .len = sizeof(scancode),
209 .keycode = keycode,
210 },
211 .error = -ENODEV,
212 };
213
214 memcpy(d.ke.scancode, &scancode, sizeof(scancode));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700215
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800216 input_handler_for_each_handle(&kbd_handler, &d, setkeycode_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800218 return d.error;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219}
220
221/*
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800222 * Making beeps and bells. Note that we prefer beeps to bells, but when
223 * shutting the sound off we do both.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 */
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800225
226static int kd_sound_helper(struct input_handle *handle, void *data)
227{
228 unsigned int *hz = data;
229 struct input_dev *dev = handle->dev;
230
231 if (test_bit(EV_SND, dev->evbit)) {
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800232 if (test_bit(SND_TONE, dev->sndbit)) {
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800233 input_inject_event(handle, EV_SND, SND_TONE, *hz);
Dmitry Torokhov18f7ad52009-12-15 16:26:53 -0800234 if (*hz)
235 return 0;
236 }
237 if (test_bit(SND_BELL, dev->sndbit))
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800238 input_inject_event(handle, EV_SND, SND_BELL, *hz ? 1 : 0);
239 }
240
241 return 0;
242}
243
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244static void kd_nosound(unsigned long ignored)
245{
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800246 static unsigned int zero;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800248 input_handler_for_each_handle(&kbd_handler, &zero, kd_sound_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249}
250
Ingo Molnar8d06afa2005-09-09 13:10:40 -0700251static DEFINE_TIMER(kd_mksound_timer, kd_nosound, 0, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252
253void kd_mksound(unsigned int hz, unsigned int ticks)
254{
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800255 del_timer_sync(&kd_mksound_timer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700256
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800257 input_handler_for_each_handle(&kbd_handler, &hz, kd_sound_helper);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800259 if (hz && ticks)
260 mod_timer(&kd_mksound_timer, jiffies + ticks);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261}
Samuel Thibaultf7511d52008-04-30 00:54:51 -0700262EXPORT_SYMBOL(kd_mksound);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263
264/*
265 * Setting the keyboard rate.
266 */
267
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800268static int kbd_rate_helper(struct input_handle *handle, void *data)
269{
270 struct input_dev *dev = handle->dev;
Mark Rustad9d329c12014-09-05 18:57:57 -0700271 struct kbd_repeat *rpt = data;
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800272
273 if (test_bit(EV_REP, dev->evbit)) {
274
Mark Rustad9d329c12014-09-05 18:57:57 -0700275 if (rpt[0].delay > 0)
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800276 input_inject_event(handle,
Mark Rustad9d329c12014-09-05 18:57:57 -0700277 EV_REP, REP_DELAY, rpt[0].delay);
278 if (rpt[0].period > 0)
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800279 input_inject_event(handle,
Mark Rustad9d329c12014-09-05 18:57:57 -0700280 EV_REP, REP_PERIOD, rpt[0].period);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800281
Mark Rustad9d329c12014-09-05 18:57:57 -0700282 rpt[1].delay = dev->rep[REP_DELAY];
283 rpt[1].period = dev->rep[REP_PERIOD];
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800284 }
285
286 return 0;
287}
288
Mark Rustad9d329c12014-09-05 18:57:57 -0700289int kbd_rate(struct kbd_repeat *rpt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290{
Mark Rustad9d329c12014-09-05 18:57:57 -0700291 struct kbd_repeat data[2] = { *rpt };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800293 input_handler_for_each_handle(&kbd_handler, data, kbd_rate_helper);
Mark Rustad9d329c12014-09-05 18:57:57 -0700294 *rpt = data[1]; /* Copy currently used settings */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 return 0;
297}
298
299/*
300 * Helper Functions.
301 */
302static void put_queue(struct vc_data *vc, int ch)
303{
Jiri Slaby92a19f92013-01-03 15:53:03 +0100304 tty_insert_flip_char(&vc->port, ch, 0);
Jiri Slaby6732c8b2013-01-03 15:53:07 +0100305 tty_schedule_flip(&vc->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306}
307
308static void puts_queue(struct vc_data *vc, char *cp)
309{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 while (*cp) {
Jiri Slaby92a19f92013-01-03 15:53:03 +0100311 tty_insert_flip_char(&vc->port, *cp, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 cp++;
313 }
Jiri Slaby6732c8b2013-01-03 15:53:07 +0100314 tty_schedule_flip(&vc->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315}
316
317static void applkey(struct vc_data *vc, int key, char mode)
318{
319 static char buf[] = { 0x1b, 'O', 0x00, 0x00 };
320
321 buf[1] = (mode ? 'O' : '[');
322 buf[2] = key;
323 puts_queue(vc, buf);
324}
325
326/*
327 * Many other routines do put_queue, but I think either
328 * they produce ASCII, or they produce some user-assigned
329 * string, and in both cases we might assume that it is
Jan Engelhardt759448f2007-07-15 23:40:40 -0700330 * in utf-8 already.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 */
Jan Engelhardt759448f2007-07-15 23:40:40 -0700332static void to_utf8(struct vc_data *vc, uint c)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700333{
334 if (c < 0x80)
335 /* 0******* */
336 put_queue(vc, c);
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500337 else if (c < 0x800) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700338 /* 110***** 10****** */
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500339 put_queue(vc, 0xc0 | (c >> 6));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700340 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhove0785572010-03-21 22:31:26 -0700341 } else if (c < 0x10000) {
342 if (c >= 0xD800 && c < 0xE000)
Jan Engelhardt759448f2007-07-15 23:40:40 -0700343 return;
344 if (c == 0xFFFF)
345 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 /* 1110**** 10****** 10****** */
347 put_queue(vc, 0xe0 | (c >> 12));
348 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
349 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhove0785572010-03-21 22:31:26 -0700350 } else if (c < 0x110000) {
Jan Engelhardt759448f2007-07-15 23:40:40 -0700351 /* 11110*** 10****** 10****** 10****** */
352 put_queue(vc, 0xf0 | (c >> 18));
353 put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
354 put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
355 put_queue(vc, 0x80 | (c & 0x3f));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357}
358
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500359/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 * Called after returning from RAW mode or when changing consoles - recompute
361 * shift_down[] and shift_state from key_down[] maybe called when keymap is
Alan Cox079c9532012-02-28 14:49:23 +0000362 * undefined, so that shiftkey release is seen. The caller must hold the
363 * kbd_event_lock.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 */
Alan Cox079c9532012-02-28 14:49:23 +0000365
366static void do_compute_shiftstate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367{
368 unsigned int i, j, k, sym, val;
369
370 shift_state = 0;
371 memset(shift_down, 0, sizeof(shift_down));
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500372
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 for (i = 0; i < ARRAY_SIZE(key_down); i++) {
374
375 if (!key_down[i])
376 continue;
377
378 k = i * BITS_PER_LONG;
379
380 for (j = 0; j < BITS_PER_LONG; j++, k++) {
381
382 if (!test_bit(k, key_down))
383 continue;
384
385 sym = U(key_maps[0][k]);
386 if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
387 continue;
388
389 val = KVAL(sym);
390 if (val == KVAL(K_CAPSSHIFT))
391 val = KVAL(K_SHIFT);
392
393 shift_down[val]++;
394 shift_state |= (1 << val);
395 }
396 }
397}
398
Alan Cox079c9532012-02-28 14:49:23 +0000399/* We still have to export this method to vt.c */
400void compute_shiftstate(void)
401{
402 unsigned long flags;
403 spin_lock_irqsave(&kbd_event_lock, flags);
404 do_compute_shiftstate();
405 spin_unlock_irqrestore(&kbd_event_lock, flags);
406}
407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408/*
409 * We have a combining character DIACR here, followed by the character CH.
410 * If the combination occurs in the table, return the corresponding value.
411 * Otherwise, if CH is a space or equals DIACR, return DIACR.
412 * Otherwise, conclude that DIACR was not combining after all,
413 * queue it and return CH.
414 */
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500415static unsigned int handle_diacr(struct vc_data *vc, unsigned int ch)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416{
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500417 unsigned int d = diacr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 unsigned int i;
419
420 diacr = 0;
421
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500422 if ((d & ~0xff) == BRL_UC_ROW) {
423 if ((ch & ~0xff) == BRL_UC_ROW)
424 return d | ch;
425 } else {
426 for (i = 0; i < accent_table_size; i++)
427 if (accent_table[i].diacr == d && accent_table[i].base == ch)
428 return accent_table[i].result;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429 }
430
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500431 if (ch == ' ' || ch == (BRL_UC_ROW|0) || ch == d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 return d;
433
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500434 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700435 to_utf8(vc, d);
436 else {
437 int c = conv_uni_to_8bit(d);
438 if (c != -1)
439 put_queue(vc, c);
440 }
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500441
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 return ch;
443}
444
445/*
446 * Special function handlers
447 */
David Howells7d12e782006-10-05 14:55:46 +0100448static void fn_enter(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449{
450 if (diacr) {
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500451 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700452 to_utf8(vc, diacr);
453 else {
454 int c = conv_uni_to_8bit(diacr);
455 if (c != -1)
456 put_queue(vc, c);
457 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700458 diacr = 0;
459 }
Dmitry Torokhove0785572010-03-21 22:31:26 -0700460
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 put_queue(vc, 13);
462 if (vc_kbd_mode(kbd, VC_CRLF))
463 put_queue(vc, 10);
464}
465
David Howells7d12e782006-10-05 14:55:46 +0100466static void fn_caps_toggle(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467{
468 if (rep)
469 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700470
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 chg_vc_kbd_led(kbd, VC_CAPSLOCK);
472}
473
David Howells7d12e782006-10-05 14:55:46 +0100474static void fn_caps_on(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475{
476 if (rep)
477 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700478
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 set_vc_kbd_led(kbd, VC_CAPSLOCK);
480}
481
David Howells7d12e782006-10-05 14:55:46 +0100482static void fn_show_ptregs(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700483{
David Howells7d12e782006-10-05 14:55:46 +0100484 struct pt_regs *regs = get_irq_regs();
Dmitry Torokhove0785572010-03-21 22:31:26 -0700485
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486 if (regs)
487 show_regs(regs);
488}
489
David Howells7d12e782006-10-05 14:55:46 +0100490static void fn_hold(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700491{
Alan Cox8ce73262010-06-01 22:52:56 +0200492 struct tty_struct *tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493
494 if (rep || !tty)
495 return;
496
497 /*
498 * Note: SCROLLOCK will be set (cleared) by stop_tty (start_tty);
499 * these routines are also activated by ^S/^Q.
500 * (And SCROLLOCK can also be set by the ioctl KDSKBLED.)
501 */
502 if (tty->stopped)
503 start_tty(tty);
504 else
505 stop_tty(tty);
506}
507
David Howells7d12e782006-10-05 14:55:46 +0100508static void fn_num(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700510 if (vc_kbd_mode(kbd, VC_APPLIC))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700511 applkey(vc, 'P', 1);
512 else
David Howells7d12e782006-10-05 14:55:46 +0100513 fn_bare_num(vc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514}
515
516/*
517 * Bind this to Shift-NumLock if you work in application keypad mode
518 * but want to be able to change the NumLock flag.
519 * Bind this to NumLock if you prefer that the NumLock key always
520 * changes the NumLock flag.
521 */
David Howells7d12e782006-10-05 14:55:46 +0100522static void fn_bare_num(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523{
524 if (!rep)
525 chg_vc_kbd_led(kbd, VC_NUMLOCK);
526}
527
David Howells7d12e782006-10-05 14:55:46 +0100528static void fn_lastcons(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529{
530 /* switch to the last used console, ChN */
531 set_console(last_console);
532}
533
David Howells7d12e782006-10-05 14:55:46 +0100534static void fn_dec_console(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535{
536 int i, cur = fg_console;
537
538 /* Currently switching? Queue this next switch relative to that. */
539 if (want_console != -1)
540 cur = want_console;
541
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500542 for (i = cur - 1; i != cur; i--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 if (i == -1)
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500544 i = MAX_NR_CONSOLES - 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 if (vc_cons_allocated(i))
546 break;
547 }
548 set_console(i);
549}
550
David Howells7d12e782006-10-05 14:55:46 +0100551static void fn_inc_console(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700552{
553 int i, cur = fg_console;
554
555 /* Currently switching? Queue this next switch relative to that. */
556 if (want_console != -1)
557 cur = want_console;
558
559 for (i = cur+1; i != cur; i++) {
560 if (i == MAX_NR_CONSOLES)
561 i = 0;
562 if (vc_cons_allocated(i))
563 break;
564 }
565 set_console(i);
566}
567
David Howells7d12e782006-10-05 14:55:46 +0100568static void fn_send_intr(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569{
Jiri Slaby92a19f92013-01-03 15:53:03 +0100570 tty_insert_flip_char(&vc->port, 0, TTY_BREAK);
Jiri Slaby6732c8b2013-01-03 15:53:07 +0100571 tty_schedule_flip(&vc->port);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572}
573
David Howells7d12e782006-10-05 14:55:46 +0100574static void fn_scroll_forw(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575{
576 scrollfront(vc, 0);
577}
578
David Howells7d12e782006-10-05 14:55:46 +0100579static void fn_scroll_back(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580{
581 scrollback(vc, 0);
582}
583
David Howells7d12e782006-10-05 14:55:46 +0100584static void fn_show_mem(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585{
David Rientjesb2b755b2011-03-24 15:18:15 -0700586 show_mem(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587}
588
David Howells7d12e782006-10-05 14:55:46 +0100589static void fn_show_state(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590{
591 show_state();
592}
593
David Howells7d12e782006-10-05 14:55:46 +0100594static void fn_boot_it(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595{
596 ctrl_alt_del();
597}
598
David Howells7d12e782006-10-05 14:55:46 +0100599static void fn_compose(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700601 dead_key_next = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602}
603
David Howells7d12e782006-10-05 14:55:46 +0100604static void fn_spawn_con(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605{
Eric W. Biederman81af8d62006-10-02 02:17:13 -0700606 spin_lock(&vt_spawn_con.lock);
607 if (vt_spawn_con.pid)
608 if (kill_pid(vt_spawn_con.pid, vt_spawn_con.sig, 1)) {
609 put_pid(vt_spawn_con.pid);
610 vt_spawn_con.pid = NULL;
611 }
612 spin_unlock(&vt_spawn_con.lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613}
614
David Howells7d12e782006-10-05 14:55:46 +0100615static void fn_SAK(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616{
Eric W. Biederman8b6312f2007-02-10 01:44:34 -0800617 struct work_struct *SAK_work = &vc_cons[fg_console].SAK_work;
Eric W. Biederman8b6312f2007-02-10 01:44:34 -0800618 schedule_work(SAK_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619}
620
David Howells7d12e782006-10-05 14:55:46 +0100621static void fn_null(struct vc_data *vc)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622{
Alan Cox079c9532012-02-28 14:49:23 +0000623 do_compute_shiftstate();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624}
625
626/*
627 * Special key handlers
628 */
David Howells7d12e782006-10-05 14:55:46 +0100629static void k_ignore(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630{
631}
632
David Howells7d12e782006-10-05 14:55:46 +0100633static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634{
635 if (up_flag)
636 return;
637 if (value >= ARRAY_SIZE(fn_handler))
638 return;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -0500639 if ((kbd->kbdmode == VC_RAW ||
Arthur Taylor9fc3de92011-02-04 13:55:50 -0800640 kbd->kbdmode == VC_MEDIUMRAW ||
641 kbd->kbdmode == VC_OFF) &&
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 value != KVAL(K_SAK))
643 return; /* SAK is allowed even in raw mode */
David Howells7d12e782006-10-05 14:55:46 +0100644 fn_handler[value](vc);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700645}
646
David Howells7d12e782006-10-05 14:55:46 +0100647static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -0700649 pr_err("k_lowercase was called - impossible\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650}
651
David Howells7d12e782006-10-05 14:55:46 +0100652static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653{
654 if (up_flag)
655 return; /* no action, if this is a key release */
656
657 if (diacr)
658 value = handle_diacr(vc, value);
659
660 if (dead_key_next) {
Dmitry Torokhove0785572010-03-21 22:31:26 -0700661 dead_key_next = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700662 diacr = value;
663 return;
664 }
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500665 if (kbd->kbdmode == VC_UNICODE)
Samuel Thibault04c71972007-10-16 23:27:04 -0700666 to_utf8(vc, value);
667 else {
668 int c = conv_uni_to_8bit(value);
669 if (c != -1)
670 put_queue(vc, c);
671 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672}
673
674/*
675 * Handle dead key. Note that we now may have several
676 * dead keys modifying the same character. Very useful
677 * for Vietnamese.
678 */
David Howells7d12e782006-10-05 14:55:46 +0100679static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680{
681 if (up_flag)
682 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700683
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 diacr = (diacr ? handle_diacr(vc, value) : value);
685}
686
David Howells7d12e782006-10-05 14:55:46 +0100687static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500688{
Jiri Bohacd2187eb2008-06-12 15:21:51 -0700689 k_unicode(vc, conv_8bit_to_uni(value), up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500690}
691
David Howells7d12e782006-10-05 14:55:46 +0100692static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500693{
David Howells7d12e782006-10-05 14:55:46 +0100694 k_deadunicode(vc, value, up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500695}
696
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697/*
698 * Obsolete - for backwards compatibility only
699 */
David Howells7d12e782006-10-05 14:55:46 +0100700static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700701{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400702 static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
Dmitry Torokhove0785572010-03-21 22:31:26 -0700703
704 k_deadunicode(vc, ret_diacr[value], up_flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700705}
706
David Howells7d12e782006-10-05 14:55:46 +0100707static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708{
709 if (up_flag)
710 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 set_console(value);
713}
714
David Howells7d12e782006-10-05 14:55:46 +0100715static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 if (up_flag)
718 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700719
720 if ((unsigned)value < ARRAY_SIZE(func_table)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 if (func_table[value])
722 puts_queue(vc, func_table[value]);
723 } else
Dmitry Torokhov9272e9a2010-03-21 22:31:26 -0700724 pr_err("k_fn called with value=%d\n", value);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725}
726
David Howells7d12e782006-10-05 14:55:46 +0100727static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728{
Brandon Philipse52b29c2006-11-04 22:09:08 -0500729 static const char cur_chars[] = "BDCA";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700730
731 if (up_flag)
732 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700733
Linus Torvalds1da177e2005-04-16 15:20:36 -0700734 applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
735}
736
David Howells7d12e782006-10-05 14:55:46 +0100737static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700738{
Andreas Mohr0f5e5602006-06-05 00:18:00 -0400739 static const char pad_chars[] = "0123456789+-*/\015,.?()#";
740 static const char app_map[] = "pqrstuvwxylSRQMnnmPQS";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
742 if (up_flag)
743 return; /* no action, if this is a key release */
744
745 /* kludge... shift forces cursor/number keys */
746 if (vc_kbd_mode(kbd, VC_APPLIC) && !shift_down[KG_SHIFT]) {
747 applkey(vc, app_map[value], 1);
748 return;
749 }
750
Dmitry Torokhove0785572010-03-21 22:31:26 -0700751 if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
752
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753 switch (value) {
Dmitry Torokhove0785572010-03-21 22:31:26 -0700754 case KVAL(K_PCOMMA):
755 case KVAL(K_PDOT):
756 k_fn(vc, KVAL(K_REMOVE), 0);
757 return;
758 case KVAL(K_P0):
759 k_fn(vc, KVAL(K_INSERT), 0);
760 return;
761 case KVAL(K_P1):
762 k_fn(vc, KVAL(K_SELECT), 0);
763 return;
764 case KVAL(K_P2):
765 k_cur(vc, KVAL(K_DOWN), 0);
766 return;
767 case KVAL(K_P3):
768 k_fn(vc, KVAL(K_PGDN), 0);
769 return;
770 case KVAL(K_P4):
771 k_cur(vc, KVAL(K_LEFT), 0);
772 return;
773 case KVAL(K_P6):
774 k_cur(vc, KVAL(K_RIGHT), 0);
775 return;
776 case KVAL(K_P7):
777 k_fn(vc, KVAL(K_FIND), 0);
778 return;
779 case KVAL(K_P8):
780 k_cur(vc, KVAL(K_UP), 0);
781 return;
782 case KVAL(K_P9):
783 k_fn(vc, KVAL(K_PGUP), 0);
784 return;
785 case KVAL(K_P5):
786 applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
787 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 }
Dmitry Torokhove0785572010-03-21 22:31:26 -0700789 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790
791 put_queue(vc, pad_chars[value]);
792 if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
793 put_queue(vc, 10);
794}
795
David Howells7d12e782006-10-05 14:55:46 +0100796static void k_shift(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797{
798 int old_state = shift_state;
799
800 if (rep)
801 return;
802 /*
803 * Mimic typewriter:
804 * a CapsShift key acts like Shift but undoes CapsLock
805 */
806 if (value == KVAL(K_CAPSSHIFT)) {
807 value = KVAL(K_SHIFT);
808 if (!up_flag)
809 clr_vc_kbd_led(kbd, VC_CAPSLOCK);
810 }
811
812 if (up_flag) {
813 /*
814 * handle the case that two shift or control
815 * keys are depressed simultaneously
816 */
817 if (shift_down[value])
818 shift_down[value]--;
819 } else
820 shift_down[value]++;
821
822 if (shift_down[value])
823 shift_state |= (1 << value);
824 else
825 shift_state &= ~(1 << value);
826
827 /* kludge */
828 if (up_flag && shift_state != old_state && npadch != -1) {
829 if (kbd->kbdmode == VC_UNICODE)
Jan Engelhardt759448f2007-07-15 23:40:40 -0700830 to_utf8(vc, npadch);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 else
832 put_queue(vc, npadch & 0xff);
833 npadch = -1;
834 }
835}
836
David Howells7d12e782006-10-05 14:55:46 +0100837static void k_meta(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838{
839 if (up_flag)
840 return;
841
842 if (vc_kbd_mode(kbd, VC_META)) {
843 put_queue(vc, '\033');
844 put_queue(vc, value);
845 } else
846 put_queue(vc, value | 0x80);
847}
848
David Howells7d12e782006-10-05 14:55:46 +0100849static void k_ascii(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850{
851 int base;
852
853 if (up_flag)
854 return;
855
856 if (value < 10) {
857 /* decimal input of code, while Alt depressed */
858 base = 10;
859 } else {
860 /* hexadecimal input of code, while AltGr depressed */
861 value -= 10;
862 base = 16;
863 }
864
865 if (npadch == -1)
866 npadch = value;
867 else
868 npadch = npadch * base + value;
869}
870
David Howells7d12e782006-10-05 14:55:46 +0100871static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872{
873 if (up_flag || rep)
874 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700875
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876 chg_vc_kbd_lock(kbd, value);
877}
878
David Howells7d12e782006-10-05 14:55:46 +0100879static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880{
David Howells7d12e782006-10-05 14:55:46 +0100881 k_shift(vc, value, up_flag);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 if (up_flag || rep)
883 return;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700884
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 chg_vc_kbd_slock(kbd, value);
886 /* try to make Alt, oops, AltGr and such work */
887 if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
888 kbd->slockstate = 0;
889 chg_vc_kbd_slock(kbd, value);
890 }
891}
892
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500893/* by default, 300ms interval for combination release */
Samuel Thibault77426d72006-04-26 00:14:10 -0400894static unsigned brl_timeout = 300;
895MODULE_PARM_DESC(brl_timeout, "Braille keys release delay in ms (0 for commit on first key release)");
896module_param(brl_timeout, uint, 0644);
897
898static unsigned brl_nbchords = 1;
899MODULE_PARM_DESC(brl_nbchords, "Number of chords that produce a braille pattern (0 for dead chords)");
900module_param(brl_nbchords, uint, 0644);
901
David Howells7d12e782006-10-05 14:55:46 +0100902static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
Samuel Thibault77426d72006-04-26 00:14:10 -0400903{
904 static unsigned long chords;
905 static unsigned committed;
906
907 if (!brl_nbchords)
David Howells7d12e782006-10-05 14:55:46 +0100908 k_deadunicode(vc, BRL_UC_ROW | pattern, up_flag);
Samuel Thibault77426d72006-04-26 00:14:10 -0400909 else {
910 committed |= pattern;
911 chords++;
912 if (chords == brl_nbchords) {
David Howells7d12e782006-10-05 14:55:46 +0100913 k_unicode(vc, BRL_UC_ROW | committed, up_flag);
Samuel Thibault77426d72006-04-26 00:14:10 -0400914 chords = 0;
915 committed = 0;
916 }
917 }
918}
919
David Howells7d12e782006-10-05 14:55:46 +0100920static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500921{
Dmitry Torokhove0785572010-03-21 22:31:26 -0700922 static unsigned pressed, committing;
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500923 static unsigned long releasestart;
924
925 if (kbd->kbdmode != VC_UNICODE) {
926 if (!up_flag)
Joe Perchese620e542014-11-09 22:46:35 -0800927 pr_warn("keyboard mode must be unicode for braille patterns\n");
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500928 return;
929 }
930
931 if (!value) {
David Howells7d12e782006-10-05 14:55:46 +0100932 k_unicode(vc, BRL_UC_ROW, up_flag);
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500933 return;
934 }
935
936 if (value > 8)
937 return;
938
Dmitry Torokhove0785572010-03-21 22:31:26 -0700939 if (!up_flag) {
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500940 pressed |= 1 << (value - 1);
941 if (!brl_timeout)
942 committing = pressed;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700943 } else if (brl_timeout) {
944 if (!committing ||
945 time_after(jiffies,
946 releasestart + msecs_to_jiffies(brl_timeout))) {
947 committing = pressed;
948 releasestart = jiffies;
949 }
950 pressed &= ~(1 << (value - 1));
951 if (!pressed && committing) {
952 k_brlcommit(vc, committing, 0);
953 committing = 0;
954 }
955 } else {
956 if (committing) {
957 k_brlcommit(vc, committing, 0);
958 committing = 0;
959 }
960 pressed &= ~(1 << (value - 1));
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -0500961 }
962}
963
Linus Torvalds1da177e2005-04-16 15:20:36 -0700964/*
965 * The leds display either (i) the status of NumLock, CapsLock, ScrollLock,
966 * or (ii) whatever pattern of lights people want to show using KDSETLED,
967 * or (iii) specified bits of specified words in kernel memory.
968 */
Alan Cox3db1ddb2012-07-17 17:06:41 +0100969static unsigned char getledstate(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970{
971 return ledstate;
972}
973
Mark Rustad9d329c12014-09-05 18:57:57 -0700974void setledstate(struct kbd_struct *kb, unsigned int led)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975{
Alan Cox079c9532012-02-28 14:49:23 +0000976 unsigned long flags;
Alan Cox3db1ddb2012-07-17 17:06:41 +0100977 spin_lock_irqsave(&led_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700978 if (!(led & ~7)) {
979 ledioctl = led;
Mark Rustad9d329c12014-09-05 18:57:57 -0700980 kb->ledmode = LED_SHOW_IOCTL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 } else
Mark Rustad9d329c12014-09-05 18:57:57 -0700982 kb->ledmode = LED_SHOW_FLAGS;
Dmitry Torokhove0785572010-03-21 22:31:26 -0700983
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984 set_leds();
Alan Cox3db1ddb2012-07-17 17:06:41 +0100985 spin_unlock_irqrestore(&led_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986}
987
988static inline unsigned char getleds(void)
989{
Mark Rustad9d329c12014-09-05 18:57:57 -0700990 struct kbd_struct *kb = kbd_table + fg_console;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700991
Mark Rustad9d329c12014-09-05 18:57:57 -0700992 if (kb->ledmode == LED_SHOW_IOCTL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 return ledioctl;
994
Mark Rustad9d329c12014-09-05 18:57:57 -0700995 return kb->ledflagstate;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996}
997
Dmitry Torokhov66d2a592009-12-01 21:54:35 -0800998static int kbd_update_leds_helper(struct input_handle *handle, void *data)
999{
1000 unsigned char leds = *(unsigned char *)data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001002 if (test_bit(EV_LED, handle->dev->evbit)) {
1003 input_inject_event(handle, EV_LED, LED_SCROLLL, !!(leds & 0x01));
1004 input_inject_event(handle, EV_LED, LED_NUML, !!(leds & 0x02));
1005 input_inject_event(handle, EV_LED, LED_CAPSL, !!(leds & 0x04));
1006 input_inject_event(handle, EV_SYN, SYN_REPORT, 0);
1007 }
1008
1009 return 0;
1010}
1011
Alan Cox079c9532012-02-28 14:49:23 +00001012/**
1013 * vt_get_leds - helper for braille console
1014 * @console: console to read
1015 * @flag: flag we want to check
1016 *
1017 * Check the status of a keyboard led flag and report it back
1018 */
1019int vt_get_leds(int console, int flag)
1020{
Mark Rustad9d329c12014-09-05 18:57:57 -07001021 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00001022 int ret;
Alan Cox3db1ddb2012-07-17 17:06:41 +01001023 unsigned long flags;
Alan Cox079c9532012-02-28 14:49:23 +00001024
Alan Cox3db1ddb2012-07-17 17:06:41 +01001025 spin_lock_irqsave(&led_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07001026 ret = vc_kbd_led(kb, flag);
Alan Cox3db1ddb2012-07-17 17:06:41 +01001027 spin_unlock_irqrestore(&led_lock, flags);
Alan Cox079c9532012-02-28 14:49:23 +00001028
1029 return ret;
1030}
1031EXPORT_SYMBOL_GPL(vt_get_leds);
1032
1033/**
1034 * vt_set_led_state - set LED state of a console
1035 * @console: console to set
1036 * @leds: LED bits
1037 *
1038 * Set the LEDs on a console. This is a wrapper for the VT layer
1039 * so that we can keep kbd knowledge internal
1040 */
1041void vt_set_led_state(int console, int leds)
1042{
Mark Rustad9d329c12014-09-05 18:57:57 -07001043 struct kbd_struct *kb = kbd_table + console;
1044 setledstate(kb, leds);
Alan Cox079c9532012-02-28 14:49:23 +00001045}
1046
1047/**
1048 * vt_kbd_con_start - Keyboard side of console start
1049 * @console: console
1050 *
1051 * Handle console start. This is a wrapper for the VT layer
1052 * so that we can keep kbd knowledge internal
Alan Cox84f904e2012-05-01 16:12:19 +01001053 *
1054 * FIXME: We eventually need to hold the kbd lock here to protect
1055 * the LED updating. We can't do it yet because fn_hold calls stop_tty
1056 * and start_tty under the kbd_event_lock, while normal tty paths
1057 * don't hold the lock. We probably need to split out an LED lock
1058 * but not during an -rc release!
Alan Cox079c9532012-02-28 14:49:23 +00001059 */
1060void vt_kbd_con_start(int console)
1061{
Mark Rustad9d329c12014-09-05 18:57:57 -07001062 struct kbd_struct *kb = kbd_table + console;
Alan Cox3db1ddb2012-07-17 17:06:41 +01001063 unsigned long flags;
1064 spin_lock_irqsave(&led_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07001065 clr_vc_kbd_led(kb, VC_SCROLLOCK);
Alan Cox079c9532012-02-28 14:49:23 +00001066 set_leds();
Alan Cox3db1ddb2012-07-17 17:06:41 +01001067 spin_unlock_irqrestore(&led_lock, flags);
Alan Cox079c9532012-02-28 14:49:23 +00001068}
1069
1070/**
1071 * vt_kbd_con_stop - Keyboard side of console stop
1072 * @console: console
1073 *
1074 * Handle console stop. This is a wrapper for the VT layer
1075 * so that we can keep kbd knowledge internal
1076 */
1077void vt_kbd_con_stop(int console)
1078{
Mark Rustad9d329c12014-09-05 18:57:57 -07001079 struct kbd_struct *kb = kbd_table + console;
Alan Cox3db1ddb2012-07-17 17:06:41 +01001080 unsigned long flags;
1081 spin_lock_irqsave(&led_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07001082 set_vc_kbd_led(kb, VC_SCROLLOCK);
Alan Cox079c9532012-02-28 14:49:23 +00001083 set_leds();
Alan Cox3db1ddb2012-07-17 17:06:41 +01001084 spin_unlock_irqrestore(&led_lock, flags);
Alan Cox079c9532012-02-28 14:49:23 +00001085}
1086
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001087/*
1088 * This is the tasklet that updates LED state on all keyboards
1089 * attached to the box. The reason we use tasklet is that we
1090 * need to handle the scenario when keyboard handler is not
Alan Cox84f904e2012-05-01 16:12:19 +01001091 * registered yet but we already getting updates from the VT to
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001092 * update led state.
1093 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094static void kbd_bh(unsigned long dummy)
1095{
Alan Cox3db1ddb2012-07-17 17:06:41 +01001096 unsigned char leds;
1097 unsigned long flags;
1098
1099 spin_lock_irqsave(&led_lock, flags);
1100 leds = getleds();
1101 spin_unlock_irqrestore(&led_lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102
1103 if (leds != ledstate) {
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001104 input_handler_for_each_handle(&kbd_handler, &leds,
1105 kbd_update_leds_helper);
1106 ledstate = leds;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001107 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001108}
1109
1110DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1111
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001113 defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
1114 defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
Hans-Christian Egtvedt3a4e8322007-12-04 13:15:41 +01001115 (defined(CONFIG_ARM) && defined(CONFIG_KEYBOARD_ATKBD) && !defined(CONFIG_ARCH_RPC)) ||\
1116 defined(CONFIG_AVR32)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117
1118#define HW_RAW(dev) (test_bit(EV_MSC, dev->evbit) && test_bit(MSC_RAW, dev->mscbit) &&\
1119 ((dev)->id.bustype == BUS_I8042) && ((dev)->id.vendor == 0x0001) && ((dev)->id.product == 0x0001))
1120
Andreas Mohr0f5e5602006-06-05 00:18:00 -04001121static const unsigned short x86_keycodes[256] =
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
1123 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
1124 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
1125 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
1126 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
1127 80, 81, 82, 83, 84,118, 86, 87, 88,115,120,119,121,112,123, 92,
Dmitry Torokhov896cdc72006-07-19 01:14:25 -04001128 284,285,309, 0,312, 91,327,328,329,331,333,335,336,337,338,339,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001129 367,288,302,304,350, 89,334,326,267,126,268,269,125,347,348,349,
1130 360,261,262,263,268,376,100,101,321,316,373,286,289,102,351,355,
Hans de Goede72a42f22007-07-03 01:55:18 -04001131 103,104,105,275,287,279,258,106,274,107,294,364,358,363,362,361,
1132 291,108,381,281,290,272,292,305,280, 99,112,257,306,359,113,114,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 264,117,271,374,379,265,266, 93, 94, 95, 85,259,375,260, 90,116,
1134 377,109,111,277,278,282,283,295,296,297,299,300,301,293,303,307,
1135 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330,
1136 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
1137
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001138#ifdef CONFIG_SPARC
Dmitry Torokhove0785572010-03-21 22:31:26 -07001139static int sparc_l1_a_state;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140extern void sun_do_break(void);
1141#endif
1142
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001143static int emulate_raw(struct vc_data *vc, unsigned int keycode,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001144 unsigned char up_flag)
1145{
Dmitry Torokhov896cdc72006-07-19 01:14:25 -04001146 int code;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001147
1148 switch (keycode) {
Dmitry Torokhov896cdc72006-07-19 01:14:25 -04001149
Dmitry Torokhove0785572010-03-21 22:31:26 -07001150 case KEY_PAUSE:
1151 put_queue(vc, 0xe1);
1152 put_queue(vc, 0x1d | up_flag);
1153 put_queue(vc, 0x45 | up_flag);
1154 break;
Dmitry Torokhov896cdc72006-07-19 01:14:25 -04001155
Dmitry Torokhove0785572010-03-21 22:31:26 -07001156 case KEY_HANGEUL:
1157 if (!up_flag)
1158 put_queue(vc, 0xf2);
1159 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160
Dmitry Torokhove0785572010-03-21 22:31:26 -07001161 case KEY_HANJA:
1162 if (!up_flag)
1163 put_queue(vc, 0xf1);
1164 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165
Dmitry Torokhove0785572010-03-21 22:31:26 -07001166 case KEY_SYSRQ:
1167 /*
1168 * Real AT keyboards (that's what we're trying
1169 * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
1170 * pressing PrtSc/SysRq alone, but simply 0x54
1171 * when pressing Alt+PrtSc/SysRq.
1172 */
1173 if (test_bit(KEY_LEFTALT, key_down) ||
1174 test_bit(KEY_RIGHTALT, key_down)) {
1175 put_queue(vc, 0x54 | up_flag);
1176 } else {
1177 put_queue(vc, 0xe0);
1178 put_queue(vc, 0x2a | up_flag);
1179 put_queue(vc, 0xe0);
1180 put_queue(vc, 0x37 | up_flag);
1181 }
1182 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
Dmitry Torokhove0785572010-03-21 22:31:26 -07001184 default:
1185 if (keycode > 255)
1186 return -1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001187
Dmitry Torokhove0785572010-03-21 22:31:26 -07001188 code = x86_keycodes[keycode];
1189 if (!code)
1190 return -1;
Dmitry Torokhov896cdc72006-07-19 01:14:25 -04001191
Dmitry Torokhove0785572010-03-21 22:31:26 -07001192 if (code & 0x100)
1193 put_queue(vc, 0xe0);
1194 put_queue(vc, (code & 0x7f) | up_flag);
1195
1196 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197 }
1198
1199 return 0;
1200}
1201
1202#else
1203
1204#define HW_RAW(dev) 0
1205
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char up_flag)
1207{
1208 if (keycode > 127)
1209 return -1;
1210
1211 put_queue(vc, keycode | up_flag);
1212 return 0;
1213}
1214#endif
1215
1216static void kbd_rawcode(unsigned char data)
1217{
1218 struct vc_data *vc = vc_cons[fg_console].d;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001219
Alan Jenkins0c09b2a2009-11-18 00:40:48 -08001220 kbd = kbd_table + vc->vc_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 if (kbd->kbdmode == VC_RAW)
1222 put_queue(vc, data);
1223}
1224
David Howells7d12e782006-10-05 14:55:46 +01001225static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226{
1227 struct vc_data *vc = vc_cons[fg_console].d;
1228 unsigned short keysym, *key_map;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001229 unsigned char type;
1230 bool raw_mode;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 struct tty_struct *tty;
1232 int shift_final;
Samuel Thibault41ab4392007-10-18 23:39:12 -07001233 struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
Dmitry Torokhove0785572010-03-21 22:31:26 -07001234 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Alan Cox8ce73262010-06-01 22:52:56 +02001236 tty = vc->port.tty;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237
1238 if (tty && (!tty->driver_data)) {
1239 /* No driver data? Strange. Okay we fix it then. */
1240 tty->driver_data = vc;
1241 }
1242
Alan Jenkins0c09b2a2009-11-18 00:40:48 -08001243 kbd = kbd_table + vc->vc_num;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001245#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 if (keycode == KEY_STOP)
1247 sparc_l1_a_state = down;
1248#endif
1249
1250 rep = (down == 2);
1251
Dmitry Torokhove0785572010-03-21 22:31:26 -07001252 raw_mode = (kbd->kbdmode == VC_RAW);
1253 if (raw_mode && !hw_raw)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 if (emulate_raw(vc, keycode, !down << 7))
Dmitry Torokhov9e35d202007-04-12 01:30:52 -04001255 if (keycode < BTN_MISC && printk_ratelimit())
Joe Perchese620e542014-11-09 22:46:35 -08001256 pr_warn("can't emulate rawmode for keycode %d\n",
1257 keycode);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258
Adrian Bunk0b57ee92005-12-22 21:03:47 -08001259#ifdef CONFIG_SPARC
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 if (keycode == KEY_A && sparc_l1_a_state) {
Dmitry Torokhove0785572010-03-21 22:31:26 -07001261 sparc_l1_a_state = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262 sun_do_break();
1263 }
1264#endif
1265
1266 if (kbd->kbdmode == VC_MEDIUMRAW) {
1267 /*
1268 * This is extended medium raw mode, with keys above 127
1269 * encoded as 0, high 7 bits, low 7 bits, with the 0 bearing
1270 * the 'up' flag if needed. 0 is reserved, so this shouldn't
1271 * interfere with anything else. The two bytes after 0 will
1272 * always have the up flag set not to interfere with older
1273 * applications. This allows for 16384 different keycodes,
1274 * which should be enough.
1275 */
1276 if (keycode < 128) {
1277 put_queue(vc, keycode | (!down << 7));
1278 } else {
1279 put_queue(vc, !down << 7);
1280 put_queue(vc, (keycode >> 7) | 0x80);
1281 put_queue(vc, keycode | 0x80);
1282 }
Dmitry Torokhove0785572010-03-21 22:31:26 -07001283 raw_mode = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 }
1285
1286 if (down)
1287 set_bit(keycode, key_down);
1288 else
1289 clear_bit(keycode, key_down);
1290
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001291 if (rep &&
1292 (!vc_kbd_mode(kbd, VC_REPEAT) ||
Alan Coxf34d7a52008-04-30 00:54:13 -07001293 (tty && !L_ECHO(tty) && tty_chars_in_buffer(tty)))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 /*
1295 * Don't repeat a key if the input buffers are not empty and the
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001296 * characters get aren't echoed locally. This makes key repeat
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 * usable with slow applications and under heavy loads.
1298 */
1299 return;
1300 }
1301
Samuel Thibault41ab4392007-10-18 23:39:12 -07001302 param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate;
Karl Dahlke0beb4f62008-04-15 01:30:32 -04001303 param.ledstate = kbd->ledflagstate;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 key_map = key_maps[shift_final];
1305
Dmitry Torokhove0785572010-03-21 22:31:26 -07001306 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1307 KBD_KEYCODE, &param);
1308 if (rc == NOTIFY_STOP || !key_map) {
1309 atomic_notifier_call_chain(&keyboard_notifier_list,
1310 KBD_UNBOUND_KEYCODE, &param);
Alan Cox079c9532012-02-28 14:49:23 +00001311 do_compute_shiftstate();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 kbd->slockstate = 0;
1313 return;
1314 }
1315
Dmitry Torokhove0785572010-03-21 22:31:26 -07001316 if (keycode < NR_KEYS)
Samuel Thibaultb9ec4e12006-04-02 00:10:28 -05001317 keysym = key_map[keycode];
Dmitry Torokhove0785572010-03-21 22:31:26 -07001318 else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
1319 keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
1320 else
1321 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 type = KTYP(keysym);
1324
1325 if (type < 0xf0) {
Samuel Thibault41ab4392007-10-18 23:39:12 -07001326 param.value = keysym;
Dmitry Torokhove0785572010-03-21 22:31:26 -07001327 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1328 KBD_UNICODE, &param);
1329 if (rc != NOTIFY_STOP)
1330 if (down && !raw_mode)
1331 to_utf8(vc, keysym);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 return;
1333 }
1334
1335 type -= 0xf0;
1336
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 if (type == KT_LETTER) {
1338 type = KT_LATIN;
1339 if (vc_kbd_led(kbd, VC_CAPSLOCK)) {
1340 key_map = key_maps[shift_final ^ (1 << KG_SHIFT)];
1341 if (key_map)
1342 keysym = key_map[keycode];
1343 }
1344 }
Samuel Thibault41ab4392007-10-18 23:39:12 -07001345
Dmitry Torokhove0785572010-03-21 22:31:26 -07001346 param.value = keysym;
1347 rc = atomic_notifier_call_chain(&keyboard_notifier_list,
1348 KBD_KEYSYM, &param);
1349 if (rc == NOTIFY_STOP)
Samuel Thibault41ab4392007-10-18 23:39:12 -07001350 return;
1351
Arthur Taylor9fc3de92011-02-04 13:55:50 -08001352 if ((raw_mode || kbd->kbdmode == VC_OFF) && type != KT_SPEC && type != KT_SHIFT)
Samuel Thibault41ab4392007-10-18 23:39:12 -07001353 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
David Howells7d12e782006-10-05 14:55:46 +01001355 (*k_handler[type])(vc, keysym & 0xff, !down);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
Karl Dahlke0beb4f62008-04-15 01:30:32 -04001357 param.ledstate = kbd->ledflagstate;
Samuel Thibault41ab4392007-10-18 23:39:12 -07001358 atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, &param);
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 if (type != KT_SLOCK)
1361 kbd->slockstate = 0;
1362}
1363
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001364static void kbd_event(struct input_handle *handle, unsigned int event_type,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 unsigned int event_code, int value)
1366{
Dmitry Torokhov21cea582009-11-29 23:40:58 -08001367 /* We are called with interrupts disabled, just take the lock */
1368 spin_lock(&kbd_event_lock);
1369
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 if (event_type == EV_MSC && event_code == MSC_RAW && HW_RAW(handle->dev))
1371 kbd_rawcode(value);
1372 if (event_type == EV_KEY)
David Howells7d12e782006-10-05 14:55:46 +01001373 kbd_keycode(event_code, value, HW_RAW(handle->dev));
Dmitry Torokhov21cea582009-11-29 23:40:58 -08001374
1375 spin_unlock(&kbd_event_lock);
1376
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 tasklet_schedule(&keyboard_tasklet);
1378 do_poke_blanked_console = 1;
1379 schedule_console_callback();
1380}
1381
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001382static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
1383{
1384 int i;
1385
1386 if (test_bit(EV_SND, dev->evbit))
1387 return true;
1388
Samuel Thibault53c1f762010-07-31 02:28:51 -07001389 if (test_bit(EV_KEY, dev->evbit)) {
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001390 for (i = KEY_RESERVED; i < BTN_MISC; i++)
1391 if (test_bit(i, dev->keybit))
1392 return true;
Samuel Thibault53c1f762010-07-31 02:28:51 -07001393 for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
1394 if (test_bit(i, dev->keybit))
1395 return true;
1396 }
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001397
1398 return false;
1399}
1400
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401/*
1402 * When a keyboard (or other input device) is found, the kbd_connect
1403 * function is called. The function then looks at the device, and if it
1404 * likes it, it can open it and get events from it. In this (kbd_connect)
1405 * function, we should decide which VT to bind that keyboard to initially.
1406 */
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001407static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
1408 const struct input_device_id *id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409{
1410 struct input_handle *handle;
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001411 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412
Dmitry Torokhov22479e12006-08-04 22:51:51 -04001413 handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
1414 if (!handle)
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001415 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 handle->dev = dev;
1418 handle->handler = handler;
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001419 handle->name = "kbd";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001421 error = input_register_handle(handle);
1422 if (error)
1423 goto err_free_handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001425 error = input_open_device(handle);
1426 if (error)
1427 goto err_unregister_handle;
1428
1429 return 0;
1430
1431 err_unregister_handle:
1432 input_unregister_handle(handle);
1433 err_free_handle:
1434 kfree(handle);
1435 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436}
1437
1438static void kbd_disconnect(struct input_handle *handle)
1439{
1440 input_close_device(handle);
Dmitry Torokhov5b2a0822007-04-12 01:29:46 -04001441 input_unregister_handle(handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 kfree(handle);
1443}
1444
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001445/*
1446 * Start keyboard handler on the new keyboard by refreshing LED state to
1447 * match the rest of the system.
1448 */
1449static void kbd_start(struct input_handle *handle)
1450{
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001451 tasklet_disable(&keyboard_tasklet);
Dmitry Torokhov66d2a592009-12-01 21:54:35 -08001452
1453 if (ledstate != 0xff)
1454 kbd_update_leds_helper(handle, &ledstate);
1455
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001456 tasklet_enable(&keyboard_tasklet);
1457}
1458
Dmitry Torokhov66e66112006-09-14 01:31:59 -04001459static const struct input_device_id kbd_ids[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 {
Alan Cox6aeed472012-02-24 12:47:29 +00001461 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1462 .evbit = { BIT_MASK(EV_KEY) },
1463 },
Dmitry Torokhovfe1e8602005-09-10 12:03:38 -05001464
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 {
Alan Cox6aeed472012-02-24 12:47:29 +00001466 .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
1467 .evbit = { BIT_MASK(EV_SND) },
1468 },
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
1470 { }, /* Terminating entry */
1471};
1472
1473MODULE_DEVICE_TABLE(input, kbd_ids);
1474
1475static struct input_handler kbd_handler = {
1476 .event = kbd_event,
Dmitry Torokhov0b7024ac2010-02-02 21:08:26 -08001477 .match = kbd_match,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 .connect = kbd_connect,
1479 .disconnect = kbd_disconnect,
Dmitry Torokhovc7e8dc62006-07-06 00:21:03 -04001480 .start = kbd_start,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 .name = "kbd",
1482 .id_table = kbd_ids,
1483};
1484
1485int __init kbd_init(void)
1486{
1487 int i;
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001488 int error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
Alan Cox6aeed472012-02-24 12:47:29 +00001490 for (i = 0; i < MAX_NR_CONSOLES; i++) {
Joshua Covb2d0b7a2012-04-13 21:08:26 +02001491 kbd_table[i].ledflagstate = kbd_defleds();
1492 kbd_table[i].default_ledflagstate = kbd_defleds();
Dmitry Torokhov2b192902006-07-19 01:13:26 -04001493 kbd_table[i].ledmode = LED_SHOW_FLAGS;
1494 kbd_table[i].lockstate = KBD_DEFLOCK;
1495 kbd_table[i].slockstate = 0;
1496 kbd_table[i].modeflags = KBD_DEFMODE;
Bill Nottingham2e8ecb92007-10-16 23:29:38 -07001497 kbd_table[i].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
Dmitry Torokhov2b192902006-07-19 01:13:26 -04001498 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499
Dmitry Torokhov4263cf02006-09-14 01:32:39 -04001500 error = input_register_handler(&kbd_handler);
1501 if (error)
1502 return error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503
1504 tasklet_enable(&keyboard_tasklet);
1505 tasklet_schedule(&keyboard_tasklet);
1506
1507 return 0;
1508}
Alan Cox247ff8e2012-02-24 12:47:11 +00001509
1510/* Ioctl support code */
1511
1512/**
1513 * vt_do_diacrit - diacritical table updates
1514 * @cmd: ioctl request
Mark Rustad9d329c12014-09-05 18:57:57 -07001515 * @udp: pointer to user data for ioctl
Alan Cox247ff8e2012-02-24 12:47:11 +00001516 * @perm: permissions check computed by caller
1517 *
1518 * Update the diacritical tables atomically and safely. Lock them
1519 * against simultaneous keypresses
1520 */
Mark Rustad9d329c12014-09-05 18:57:57 -07001521int vt_do_diacrit(unsigned int cmd, void __user *udp, int perm)
Alan Cox247ff8e2012-02-24 12:47:11 +00001522{
Alan Cox247ff8e2012-02-24 12:47:11 +00001523 unsigned long flags;
1524 int asize;
1525 int ret = 0;
1526
1527 switch (cmd) {
1528 case KDGKBDIACR:
1529 {
Mark Rustad9d329c12014-09-05 18:57:57 -07001530 struct kbdiacrs __user *a = udp;
1531 struct kbdiacr *dia;
Alan Cox247ff8e2012-02-24 12:47:11 +00001532 int i;
1533
Mark Rustad9d329c12014-09-05 18:57:57 -07001534 dia = kmalloc(MAX_DIACR * sizeof(struct kbdiacr),
Alan Cox247ff8e2012-02-24 12:47:11 +00001535 GFP_KERNEL);
Mark Rustad9d329c12014-09-05 18:57:57 -07001536 if (!dia)
Alan Cox247ff8e2012-02-24 12:47:11 +00001537 return -ENOMEM;
1538
1539 /* Lock the diacriticals table, make a copy and then
1540 copy it after we unlock */
1541 spin_lock_irqsave(&kbd_event_lock, flags);
1542
1543 asize = accent_table_size;
1544 for (i = 0; i < asize; i++) {
Mark Rustad9d329c12014-09-05 18:57:57 -07001545 dia[i].diacr = conv_uni_to_8bit(
Alan Cox247ff8e2012-02-24 12:47:11 +00001546 accent_table[i].diacr);
Mark Rustad9d329c12014-09-05 18:57:57 -07001547 dia[i].base = conv_uni_to_8bit(
Alan Cox247ff8e2012-02-24 12:47:11 +00001548 accent_table[i].base);
Mark Rustad9d329c12014-09-05 18:57:57 -07001549 dia[i].result = conv_uni_to_8bit(
Alan Cox247ff8e2012-02-24 12:47:11 +00001550 accent_table[i].result);
1551 }
1552 spin_unlock_irqrestore(&kbd_event_lock, flags);
1553
1554 if (put_user(asize, &a->kb_cnt))
1555 ret = -EFAULT;
Mark Rustad9d329c12014-09-05 18:57:57 -07001556 else if (copy_to_user(a->kbdiacr, dia,
Alan Cox247ff8e2012-02-24 12:47:11 +00001557 asize * sizeof(struct kbdiacr)))
1558 ret = -EFAULT;
Mark Rustad9d329c12014-09-05 18:57:57 -07001559 kfree(dia);
Alan Cox247ff8e2012-02-24 12:47:11 +00001560 return ret;
1561 }
1562 case KDGKBDIACRUC:
1563 {
Mark Rustad9d329c12014-09-05 18:57:57 -07001564 struct kbdiacrsuc __user *a = udp;
Alan Cox247ff8e2012-02-24 12:47:11 +00001565 void *buf;
1566
1567 buf = kmalloc(MAX_DIACR * sizeof(struct kbdiacruc),
1568 GFP_KERNEL);
1569 if (buf == NULL)
1570 return -ENOMEM;
1571
1572 /* Lock the diacriticals table, make a copy and then
1573 copy it after we unlock */
1574 spin_lock_irqsave(&kbd_event_lock, flags);
1575
1576 asize = accent_table_size;
1577 memcpy(buf, accent_table, asize * sizeof(struct kbdiacruc));
1578
1579 spin_unlock_irqrestore(&kbd_event_lock, flags);
1580
1581 if (put_user(asize, &a->kb_cnt))
1582 ret = -EFAULT;
1583 else if (copy_to_user(a->kbdiacruc, buf,
1584 asize*sizeof(struct kbdiacruc)))
1585 ret = -EFAULT;
1586 kfree(buf);
1587 return ret;
1588 }
1589
1590 case KDSKBDIACR:
1591 {
Mark Rustad9d329c12014-09-05 18:57:57 -07001592 struct kbdiacrs __user *a = udp;
1593 struct kbdiacr *dia = NULL;
Alan Cox247ff8e2012-02-24 12:47:11 +00001594 unsigned int ct;
1595 int i;
1596
1597 if (!perm)
1598 return -EPERM;
1599 if (get_user(ct, &a->kb_cnt))
1600 return -EFAULT;
1601 if (ct >= MAX_DIACR)
1602 return -EINVAL;
1603
1604 if (ct) {
Mark Rustad9d329c12014-09-05 18:57:57 -07001605 dia = kmalloc(sizeof(struct kbdiacr) * ct,
Alan Cox247ff8e2012-02-24 12:47:11 +00001606 GFP_KERNEL);
Mark Rustad9d329c12014-09-05 18:57:57 -07001607 if (!dia)
Alan Cox247ff8e2012-02-24 12:47:11 +00001608 return -ENOMEM;
1609
Mark Rustad9d329c12014-09-05 18:57:57 -07001610 if (copy_from_user(dia, a->kbdiacr,
Alan Cox247ff8e2012-02-24 12:47:11 +00001611 sizeof(struct kbdiacr) * ct)) {
Mark Rustad9d329c12014-09-05 18:57:57 -07001612 kfree(dia);
Alan Cox247ff8e2012-02-24 12:47:11 +00001613 return -EFAULT;
1614 }
1615 }
1616
1617 spin_lock_irqsave(&kbd_event_lock, flags);
1618 accent_table_size = ct;
1619 for (i = 0; i < ct; i++) {
1620 accent_table[i].diacr =
Mark Rustad9d329c12014-09-05 18:57:57 -07001621 conv_8bit_to_uni(dia[i].diacr);
Alan Cox247ff8e2012-02-24 12:47:11 +00001622 accent_table[i].base =
Mark Rustad9d329c12014-09-05 18:57:57 -07001623 conv_8bit_to_uni(dia[i].base);
Alan Cox247ff8e2012-02-24 12:47:11 +00001624 accent_table[i].result =
Mark Rustad9d329c12014-09-05 18:57:57 -07001625 conv_8bit_to_uni(dia[i].result);
Alan Cox247ff8e2012-02-24 12:47:11 +00001626 }
1627 spin_unlock_irqrestore(&kbd_event_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07001628 kfree(dia);
Alan Cox247ff8e2012-02-24 12:47:11 +00001629 return 0;
1630 }
1631
1632 case KDSKBDIACRUC:
1633 {
Mark Rustad9d329c12014-09-05 18:57:57 -07001634 struct kbdiacrsuc __user *a = udp;
Alan Cox247ff8e2012-02-24 12:47:11 +00001635 unsigned int ct;
1636 void *buf = NULL;
1637
1638 if (!perm)
1639 return -EPERM;
1640
1641 if (get_user(ct, &a->kb_cnt))
1642 return -EFAULT;
1643
1644 if (ct >= MAX_DIACR)
1645 return -EINVAL;
1646
1647 if (ct) {
1648 buf = kmalloc(ct * sizeof(struct kbdiacruc),
1649 GFP_KERNEL);
1650 if (buf == NULL)
1651 return -ENOMEM;
1652
1653 if (copy_from_user(buf, a->kbdiacruc,
1654 ct * sizeof(struct kbdiacruc))) {
1655 kfree(buf);
1656 return -EFAULT;
1657 }
1658 }
1659 spin_lock_irqsave(&kbd_event_lock, flags);
1660 if (ct)
1661 memcpy(accent_table, buf,
1662 ct * sizeof(struct kbdiacruc));
1663 accent_table_size = ct;
1664 spin_unlock_irqrestore(&kbd_event_lock, flags);
1665 kfree(buf);
1666 return 0;
1667 }
1668 }
1669 return ret;
1670}
Alan Cox079c9532012-02-28 14:49:23 +00001671
1672/**
1673 * vt_do_kdskbmode - set keyboard mode ioctl
1674 * @console: the console to use
1675 * @arg: the requested mode
1676 *
1677 * Update the keyboard mode bits while holding the correct locks.
1678 * Return 0 for success or an error code.
1679 */
1680int vt_do_kdskbmode(int console, unsigned int arg)
1681{
Mark Rustad9d329c12014-09-05 18:57:57 -07001682 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00001683 int ret = 0;
1684 unsigned long flags;
1685
1686 spin_lock_irqsave(&kbd_event_lock, flags);
1687 switch(arg) {
1688 case K_RAW:
Mark Rustad9d329c12014-09-05 18:57:57 -07001689 kb->kbdmode = VC_RAW;
Alan Cox079c9532012-02-28 14:49:23 +00001690 break;
1691 case K_MEDIUMRAW:
Mark Rustad9d329c12014-09-05 18:57:57 -07001692 kb->kbdmode = VC_MEDIUMRAW;
Alan Cox079c9532012-02-28 14:49:23 +00001693 break;
1694 case K_XLATE:
Mark Rustad9d329c12014-09-05 18:57:57 -07001695 kb->kbdmode = VC_XLATE;
Alan Cox079c9532012-02-28 14:49:23 +00001696 do_compute_shiftstate();
1697 break;
1698 case K_UNICODE:
Mark Rustad9d329c12014-09-05 18:57:57 -07001699 kb->kbdmode = VC_UNICODE;
Alan Cox079c9532012-02-28 14:49:23 +00001700 do_compute_shiftstate();
1701 break;
1702 case K_OFF:
Mark Rustad9d329c12014-09-05 18:57:57 -07001703 kb->kbdmode = VC_OFF;
Alan Cox079c9532012-02-28 14:49:23 +00001704 break;
1705 default:
1706 ret = -EINVAL;
1707 }
1708 spin_unlock_irqrestore(&kbd_event_lock, flags);
1709 return ret;
1710}
1711
1712/**
1713 * vt_do_kdskbmeta - set keyboard meta state
1714 * @console: the console to use
1715 * @arg: the requested meta state
1716 *
1717 * Update the keyboard meta bits while holding the correct locks.
1718 * Return 0 for success or an error code.
1719 */
1720int vt_do_kdskbmeta(int console, unsigned int arg)
1721{
Mark Rustad9d329c12014-09-05 18:57:57 -07001722 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00001723 int ret = 0;
1724 unsigned long flags;
1725
1726 spin_lock_irqsave(&kbd_event_lock, flags);
1727 switch(arg) {
1728 case K_METABIT:
Mark Rustad9d329c12014-09-05 18:57:57 -07001729 clr_vc_kbd_mode(kb, VC_META);
Alan Cox079c9532012-02-28 14:49:23 +00001730 break;
1731 case K_ESCPREFIX:
Mark Rustad9d329c12014-09-05 18:57:57 -07001732 set_vc_kbd_mode(kb, VC_META);
Alan Cox079c9532012-02-28 14:49:23 +00001733 break;
1734 default:
1735 ret = -EINVAL;
1736 }
1737 spin_unlock_irqrestore(&kbd_event_lock, flags);
1738 return ret;
1739}
1740
1741int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
1742 int perm)
1743{
1744 struct kbkeycode tmp;
1745 int kc = 0;
1746
1747 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
1748 return -EFAULT;
1749 switch (cmd) {
1750 case KDGETKEYCODE:
1751 kc = getkeycode(tmp.scancode);
1752 if (kc >= 0)
1753 kc = put_user(kc, &user_kbkc->keycode);
1754 break;
1755 case KDSETKEYCODE:
1756 if (!perm)
1757 return -EPERM;
1758 kc = setkeycode(tmp.scancode, tmp.keycode);
1759 break;
1760 }
1761 return kc;
1762}
1763
1764#define i (tmp.kb_index)
1765#define s (tmp.kb_table)
1766#define v (tmp.kb_value)
1767
1768int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
1769 int console)
1770{
Mark Rustad9d329c12014-09-05 18:57:57 -07001771 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00001772 struct kbentry tmp;
1773 ushort *key_map, *new_map, val, ov;
1774 unsigned long flags;
1775
1776 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
1777 return -EFAULT;
1778
1779 if (!capable(CAP_SYS_TTY_CONFIG))
1780 perm = 0;
1781
1782 switch (cmd) {
1783 case KDGKBENT:
1784 /* Ensure another thread doesn't free it under us */
1785 spin_lock_irqsave(&kbd_event_lock, flags);
1786 key_map = key_maps[s];
1787 if (key_map) {
1788 val = U(key_map[i]);
Mark Rustad9d329c12014-09-05 18:57:57 -07001789 if (kb->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
Alan Cox079c9532012-02-28 14:49:23 +00001790 val = K_HOLE;
1791 } else
1792 val = (i ? K_HOLE : K_NOSUCHMAP);
1793 spin_unlock_irqrestore(&kbd_event_lock, flags);
1794 return put_user(val, &user_kbe->kb_value);
1795 case KDSKBENT:
1796 if (!perm)
1797 return -EPERM;
1798 if (!i && v == K_NOSUCHMAP) {
1799 spin_lock_irqsave(&kbd_event_lock, flags);
1800 /* deallocate map */
1801 key_map = key_maps[s];
1802 if (s && key_map) {
1803 key_maps[s] = NULL;
1804 if (key_map[0] == U(K_ALLOCATED)) {
1805 kfree(key_map);
1806 keymap_count--;
1807 }
1808 }
1809 spin_unlock_irqrestore(&kbd_event_lock, flags);
1810 break;
1811 }
1812
1813 if (KTYP(v) < NR_TYPES) {
1814 if (KVAL(v) > max_vals[KTYP(v)])
1815 return -EINVAL;
1816 } else
Mark Rustad9d329c12014-09-05 18:57:57 -07001817 if (kb->kbdmode != VC_UNICODE)
Alan Cox079c9532012-02-28 14:49:23 +00001818 return -EINVAL;
1819
1820 /* ++Geert: non-PC keyboards may generate keycode zero */
1821#if !defined(__mc68000__) && !defined(__powerpc__)
1822 /* assignment to entry 0 only tests validity of args */
1823 if (!i)
1824 break;
1825#endif
1826
1827 new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
1828 if (!new_map)
1829 return -ENOMEM;
1830 spin_lock_irqsave(&kbd_event_lock, flags);
1831 key_map = key_maps[s];
1832 if (key_map == NULL) {
1833 int j;
1834
1835 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
1836 !capable(CAP_SYS_RESOURCE)) {
1837 spin_unlock_irqrestore(&kbd_event_lock, flags);
1838 kfree(new_map);
1839 return -EPERM;
1840 }
1841 key_maps[s] = new_map;
Dan Carpenter82896212012-03-10 11:59:23 +03001842 key_map = new_map;
Alan Cox079c9532012-02-28 14:49:23 +00001843 key_map[0] = U(K_ALLOCATED);
1844 for (j = 1; j < NR_KEYS; j++)
1845 key_map[j] = U(K_HOLE);
1846 keymap_count++;
1847 } else
1848 kfree(new_map);
1849
1850 ov = U(key_map[i]);
1851 if (v == ov)
1852 goto out;
1853 /*
1854 * Attention Key.
1855 */
1856 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
1857 spin_unlock_irqrestore(&kbd_event_lock, flags);
1858 return -EPERM;
1859 }
1860 key_map[i] = U(v);
1861 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
1862 do_compute_shiftstate();
1863out:
1864 spin_unlock_irqrestore(&kbd_event_lock, flags);
1865 break;
1866 }
1867 return 0;
1868}
1869#undef i
1870#undef s
1871#undef v
1872
1873/* FIXME: This one needs untangling and locking */
1874int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
1875{
1876 struct kbsentry *kbs;
1877 char *p;
1878 u_char *q;
1879 u_char __user *up;
1880 int sz;
1881 int delta;
1882 char *first_free, *fj, *fnw;
1883 int i, j, k;
1884 int ret;
1885
1886 if (!capable(CAP_SYS_TTY_CONFIG))
1887 perm = 0;
1888
1889 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
1890 if (!kbs) {
1891 ret = -ENOMEM;
1892 goto reterr;
1893 }
1894
1895 /* we mostly copy too much here (512bytes), but who cares ;) */
1896 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
1897 ret = -EFAULT;
1898 goto reterr;
1899 }
1900 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
1901 i = kbs->kb_func;
1902
1903 switch (cmd) {
1904 case KDGKBSENT:
1905 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
1906 a struct member */
1907 up = user_kdgkb->kb_string;
1908 p = func_table[i];
1909 if(p)
1910 for ( ; *p && sz; p++, sz--)
1911 if (put_user(*p, up++)) {
1912 ret = -EFAULT;
1913 goto reterr;
1914 }
1915 if (put_user('\0', up)) {
1916 ret = -EFAULT;
1917 goto reterr;
1918 }
1919 kfree(kbs);
1920 return ((p && *p) ? -EOVERFLOW : 0);
1921 case KDSKBSENT:
1922 if (!perm) {
1923 ret = -EPERM;
1924 goto reterr;
1925 }
1926
1927 q = func_table[i];
1928 first_free = funcbufptr + (funcbufsize - funcbufleft);
1929 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
1930 ;
1931 if (j < MAX_NR_FUNC)
1932 fj = func_table[j];
1933 else
1934 fj = first_free;
1935
1936 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
1937 if (delta <= funcbufleft) { /* it fits in current buf */
1938 if (j < MAX_NR_FUNC) {
1939 memmove(fj + delta, fj, first_free - fj);
1940 for (k = j; k < MAX_NR_FUNC; k++)
1941 if (func_table[k])
1942 func_table[k] += delta;
1943 }
1944 if (!q)
1945 func_table[i] = fj;
1946 funcbufleft -= delta;
1947 } else { /* allocate a larger buffer */
1948 sz = 256;
1949 while (sz < funcbufsize - funcbufleft + delta)
1950 sz <<= 1;
1951 fnw = kmalloc(sz, GFP_KERNEL);
1952 if(!fnw) {
1953 ret = -ENOMEM;
1954 goto reterr;
1955 }
1956
1957 if (!q)
1958 func_table[i] = fj;
1959 if (fj > funcbufptr)
1960 memmove(fnw, funcbufptr, fj - funcbufptr);
1961 for (k = 0; k < j; k++)
1962 if (func_table[k])
1963 func_table[k] = fnw + (func_table[k] - funcbufptr);
1964
1965 if (first_free > fj) {
1966 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
1967 for (k = j; k < MAX_NR_FUNC; k++)
1968 if (func_table[k])
1969 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
1970 }
1971 if (funcbufptr != func_buf)
1972 kfree(funcbufptr);
1973 funcbufptr = fnw;
1974 funcbufleft = funcbufleft - delta + sz - funcbufsize;
1975 funcbufsize = sz;
1976 }
1977 strcpy(func_table[i], kbs->kb_string);
1978 break;
1979 }
1980 ret = 0;
1981reterr:
1982 kfree(kbs);
1983 return ret;
1984}
1985
1986int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
1987{
Mark Rustad9d329c12014-09-05 18:57:57 -07001988 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00001989 unsigned long flags;
1990 unsigned char ucval;
1991
1992 switch(cmd) {
1993 /* the ioctls below read/set the flags usually shown in the leds */
1994 /* don't use them - they will go away without warning */
1995 case KDGKBLED:
1996 spin_lock_irqsave(&kbd_event_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07001997 ucval = kb->ledflagstate | (kb->default_ledflagstate << 4);
Alan Cox079c9532012-02-28 14:49:23 +00001998 spin_unlock_irqrestore(&kbd_event_lock, flags);
1999 return put_user(ucval, (char __user *)arg);
2000
2001 case KDSKBLED:
2002 if (!perm)
2003 return -EPERM;
2004 if (arg & ~0x77)
2005 return -EINVAL;
Alan Cox3db1ddb2012-07-17 17:06:41 +01002006 spin_lock_irqsave(&led_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07002007 kb->ledflagstate = (arg & 7);
2008 kb->default_ledflagstate = ((arg >> 4) & 7);
Alan Cox079c9532012-02-28 14:49:23 +00002009 set_leds();
Alan Cox3db1ddb2012-07-17 17:06:41 +01002010 spin_unlock_irqrestore(&led_lock, flags);
Alan Coxeea41ae2012-05-14 14:41:31 +01002011 return 0;
Alan Cox079c9532012-02-28 14:49:23 +00002012
2013 /* the ioctls below only set the lights, not the functions */
2014 /* for those, see KDGKBLED and KDSKBLED above */
2015 case KDGETLED:
2016 ucval = getledstate();
2017 return put_user(ucval, (char __user *)arg);
2018
2019 case KDSETLED:
2020 if (!perm)
2021 return -EPERM;
Mark Rustad9d329c12014-09-05 18:57:57 -07002022 setledstate(kb, arg);
Alan Cox079c9532012-02-28 14:49:23 +00002023 return 0;
2024 }
2025 return -ENOIOCTLCMD;
2026}
2027
2028int vt_do_kdgkbmode(int console)
2029{
Mark Rustad9d329c12014-09-05 18:57:57 -07002030 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00002031 /* This is a spot read so needs no locking */
Mark Rustad9d329c12014-09-05 18:57:57 -07002032 switch (kb->kbdmode) {
Alan Cox079c9532012-02-28 14:49:23 +00002033 case VC_RAW:
2034 return K_RAW;
2035 case VC_MEDIUMRAW:
2036 return K_MEDIUMRAW;
2037 case VC_UNICODE:
2038 return K_UNICODE;
2039 case VC_OFF:
2040 return K_OFF;
2041 default:
2042 return K_XLATE;
2043 }
2044}
2045
2046/**
2047 * vt_do_kdgkbmeta - report meta status
2048 * @console: console to report
2049 *
2050 * Report the meta flag status of this console
2051 */
2052int vt_do_kdgkbmeta(int console)
2053{
Mark Rustad9d329c12014-09-05 18:57:57 -07002054 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00002055 /* Again a spot read so no locking */
Mark Rustad9d329c12014-09-05 18:57:57 -07002056 return vc_kbd_mode(kb, VC_META) ? K_ESCPREFIX : K_METABIT;
Alan Cox079c9532012-02-28 14:49:23 +00002057}
2058
2059/**
2060 * vt_reset_unicode - reset the unicode status
2061 * @console: console being reset
2062 *
2063 * Restore the unicode console state to its default
2064 */
2065void vt_reset_unicode(int console)
2066{
2067 unsigned long flags;
2068
2069 spin_lock_irqsave(&kbd_event_lock, flags);
2070 kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
2071 spin_unlock_irqrestore(&kbd_event_lock, flags);
2072}
2073
2074/**
2075 * vt_get_shiftstate - shift bit state
2076 *
2077 * Report the shift bits from the keyboard state. We have to export
2078 * this to support some oddities in the vt layer.
2079 */
2080int vt_get_shift_state(void)
2081{
2082 /* Don't lock as this is a transient report */
2083 return shift_state;
2084}
2085
2086/**
2087 * vt_reset_keyboard - reset keyboard state
2088 * @console: console to reset
2089 *
2090 * Reset the keyboard bits for a console as part of a general console
2091 * reset event
2092 */
2093void vt_reset_keyboard(int console)
2094{
Mark Rustad9d329c12014-09-05 18:57:57 -07002095 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00002096 unsigned long flags;
2097
2098 spin_lock_irqsave(&kbd_event_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07002099 set_vc_kbd_mode(kb, VC_REPEAT);
2100 clr_vc_kbd_mode(kb, VC_CKMODE);
2101 clr_vc_kbd_mode(kb, VC_APPLIC);
2102 clr_vc_kbd_mode(kb, VC_CRLF);
2103 kb->lockstate = 0;
2104 kb->slockstate = 0;
Alan Cox3db1ddb2012-07-17 17:06:41 +01002105 spin_lock(&led_lock);
Mark Rustad9d329c12014-09-05 18:57:57 -07002106 kb->ledmode = LED_SHOW_FLAGS;
2107 kb->ledflagstate = kb->default_ledflagstate;
Alan Cox3db1ddb2012-07-17 17:06:41 +01002108 spin_unlock(&led_lock);
Alan Cox079c9532012-02-28 14:49:23 +00002109 /* do not do set_leds here because this causes an endless tasklet loop
2110 when the keyboard hasn't been initialized yet */
2111 spin_unlock_irqrestore(&kbd_event_lock, flags);
2112}
2113
2114/**
2115 * vt_get_kbd_mode_bit - read keyboard status bits
2116 * @console: console to read from
2117 * @bit: mode bit to read
2118 *
2119 * Report back a vt mode bit. We do this without locking so the
2120 * caller must be sure that there are no synchronization needs
2121 */
2122
2123int vt_get_kbd_mode_bit(int console, int bit)
2124{
Mark Rustad9d329c12014-09-05 18:57:57 -07002125 struct kbd_struct *kb = kbd_table + console;
2126 return vc_kbd_mode(kb, bit);
Alan Cox079c9532012-02-28 14:49:23 +00002127}
2128
2129/**
2130 * vt_set_kbd_mode_bit - read keyboard status bits
2131 * @console: console to read from
2132 * @bit: mode bit to read
2133 *
2134 * Set a vt mode bit. We do this without locking so the
2135 * caller must be sure that there are no synchronization needs
2136 */
2137
2138void vt_set_kbd_mode_bit(int console, int bit)
2139{
Mark Rustad9d329c12014-09-05 18:57:57 -07002140 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00002141 unsigned long flags;
2142
2143 spin_lock_irqsave(&kbd_event_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07002144 set_vc_kbd_mode(kb, bit);
Alan Cox079c9532012-02-28 14:49:23 +00002145 spin_unlock_irqrestore(&kbd_event_lock, flags);
2146}
2147
2148/**
2149 * vt_clr_kbd_mode_bit - read keyboard status bits
2150 * @console: console to read from
2151 * @bit: mode bit to read
2152 *
2153 * Report back a vt mode bit. We do this without locking so the
2154 * caller must be sure that there are no synchronization needs
2155 */
2156
2157void vt_clr_kbd_mode_bit(int console, int bit)
2158{
Mark Rustad9d329c12014-09-05 18:57:57 -07002159 struct kbd_struct *kb = kbd_table + console;
Alan Cox079c9532012-02-28 14:49:23 +00002160 unsigned long flags;
2161
2162 spin_lock_irqsave(&kbd_event_lock, flags);
Mark Rustad9d329c12014-09-05 18:57:57 -07002163 clr_vc_kbd_mode(kb, bit);
Alan Cox079c9532012-02-28 14:49:23 +00002164 spin_unlock_irqrestore(&kbd_event_lock, flags);
2165}