aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2012-02-28 09:49:23 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-03-08 13:50:35 -0500
commit079c9534a96da9a85a2a2f9715851050fbfbf749 (patch)
tree0e3782ff6d341f38c6f0b3840cb3c8f2bc922df8 /drivers/tty/vt
parent0fb8379dab9f97e4c56de8f9ea772c10eda27561 (diff)
vt:tackle kbd_table
Keyboard struct lifetime is easy, but the locking is not and is completely ignored by the existing code. Tackle this one head on - Make the kbd_table private so we can run down all direct users - Hoick the relevant ioctl handlers into the keyboard layer - Lock them with the keyboard lock so they don't change mid keypress - Add helpers for things like console stop/start so we isolate the poking around properly - Tweak the braille console so it still builds There are a couple of FIXME locking cases left for ioctls that are so hideous they should be addressed in a later patch. After this patch the kbd_table is private and all the keyboard jiggery pokery is in one place. This update fixes speakup and also a memory leak in the original. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/vt')
-rw-r--r--drivers/tty/vt/keyboard.c621
-rw-r--r--drivers/tty/vt/selection.c9
-rw-r--r--drivers/tty/vt/vt.c27
-rw-r--r--drivers/tty/vt/vt_ioctl.c325
4 files changed, 627 insertions, 355 deletions
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 898e359c5424..70d0593d3bc6 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -68,8 +68,6 @@ extern void ctrl_alt_del(void);
68 68
69#define KBD_DEFLOCK 0 69#define KBD_DEFLOCK 0
70 70
71void compute_shiftstate(void);
72
73/* 71/*
74 * Handler Tables. 72 * Handler Tables.
75 */ 73 */
@@ -100,35 +98,29 @@ static fn_handler_fn *fn_handler[] = { FN_HANDLERS };
100 * Variables exported for vt_ioctl.c 98 * Variables exported for vt_ioctl.c
101 */ 99 */
102 100
103/* maximum values each key_handler can handle */
104const int max_vals[] = {
105 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
106 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
107 255, NR_LOCK - 1, 255, NR_BRL - 1
108};
109
110const int NR_TYPES = ARRAY_SIZE(max_vals);
111
112struct kbd_struct kbd_table[MAX_NR_CONSOLES];
113EXPORT_SYMBOL_GPL(kbd_table);
114static struct kbd_struct *kbd = kbd_table;
115
116struct vt_spawn_console vt_spawn_con = { 101struct vt_spawn_console vt_spawn_con = {
117 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock), 102 .lock = __SPIN_LOCK_UNLOCKED(vt_spawn_con.lock),
118 .pid = NULL, 103 .pid = NULL,
119 .sig = 0, 104 .sig = 0,
120}; 105};
121 106
122/*
123 * Variables exported for vt.c
124 */
125
126int shift_state = 0;
127 107
128/* 108/*
129 * Internal Data. 109 * Internal Data.
130 */ 110 */
131 111
112static struct kbd_struct kbd_table[MAX_NR_CONSOLES];
113static struct kbd_struct *kbd = kbd_table;
114
115/* maximum values each key_handler can handle */
116static const int max_vals[] = {
117 255, ARRAY_SIZE(func_table) - 1, ARRAY_SIZE(fn_handler) - 1, NR_PAD - 1,
118 NR_DEAD - 1, 255, 3, NR_SHIFT - 1, 255, NR_ASCII - 1, NR_LOCK - 1,
119 255, NR_LOCK - 1, 255, NR_BRL - 1
120};
121
122static const int NR_TYPES = ARRAY_SIZE(max_vals);
123
132static struct input_handler kbd_handler; 124static struct input_handler kbd_handler;
133static DEFINE_SPINLOCK(kbd_event_lock); 125static DEFINE_SPINLOCK(kbd_event_lock);
134static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ 126static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
@@ -138,6 +130,8 @@ static int npadch = -1; /* -1 or number assembled on pad */
138static unsigned int diacr; 130static unsigned int diacr;
139static char rep; /* flag telling character repeat */ 131static char rep; /* flag telling character repeat */
140 132
133static int shift_state = 0;
134
141static unsigned char ledstate = 0xff; /* undefined */ 135static unsigned char ledstate = 0xff; /* undefined */
142static unsigned char ledioctl; 136static unsigned char ledioctl;
143 137
@@ -188,7 +182,7 @@ static int getkeycode_helper(struct input_handle *handle, void *data)
188 return d->error == 0; /* stop as soon as we successfully get one */ 182 return d->error == 0; /* stop as soon as we successfully get one */
189} 183}
190 184
191int getkeycode(unsigned int scancode) 185static int getkeycode(unsigned int scancode)
192{ 186{
193 struct getset_keycode_data d = { 187 struct getset_keycode_data d = {
194 .ke = { 188 .ke = {
@@ -215,7 +209,7 @@ static int setkeycode_helper(struct input_handle *handle, void *data)
215 return d->error == 0; /* stop as soon as we successfully set one */ 209 return d->error == 0; /* stop as soon as we successfully set one */
216} 210}
217 211
218int setkeycode(unsigned int scancode, unsigned int keycode) 212static int setkeycode(unsigned int scancode, unsigned int keycode)
219{ 213{
220 struct getset_keycode_data d = { 214 struct getset_keycode_data d = {
221 .ke = { 215 .ke = {
@@ -383,9 +377,11 @@ static void to_utf8(struct vc_data *vc, uint c)
383/* 377/*
384 * Called after returning from RAW mode or when changing consoles - recompute 378 * Called after returning from RAW mode or when changing consoles - recompute
385 * shift_down[] and shift_state from key_down[] maybe called when keymap is 379 * shift_down[] and shift_state from key_down[] maybe called when keymap is
386 * undefined, so that shiftkey release is seen 380 * undefined, so that shiftkey release is seen. The caller must hold the
381 * kbd_event_lock.
387 */ 382 */
388void compute_shiftstate(void) 383
384static void do_compute_shiftstate(void)
389{ 385{
390 unsigned int i, j, k, sym, val; 386 unsigned int i, j, k, sym, val;
391 387
@@ -418,6 +414,15 @@ void compute_shiftstate(void)
418 } 414 }
419} 415}
420 416
417/* We still have to export this method to vt.c */
418void compute_shiftstate(void)
419{
420 unsigned long flags;
421 spin_lock_irqsave(&kbd_event_lock, flags);
422 do_compute_shiftstate();
423 spin_unlock_irqrestore(&kbd_event_lock, flags);
424}
425
421/* 426/*
422 * We have a combining character DIACR here, followed by the character CH. 427 * We have a combining character DIACR here, followed by the character CH.
423 * If the combination occurs in the table, return the corresponding value. 428 * If the combination occurs in the table, return the corresponding value.
@@ -637,7 +642,7 @@ static void fn_SAK(struct vc_data *vc)
637 642
638static void fn_null(struct vc_data *vc) 643static void fn_null(struct vc_data *vc)
639{ 644{
640 compute_shiftstate(); 645 do_compute_shiftstate();
641} 646}
642 647
643/* 648/*
@@ -990,6 +995,8 @@ unsigned char getledstate(void)
990 995
991void setledstate(struct kbd_struct *kbd, unsigned int led) 996void setledstate(struct kbd_struct *kbd, unsigned int led)
992{ 997{
998 unsigned long flags;
999 spin_lock_irqsave(&kbd_event_lock, flags);
993 if (!(led & ~7)) { 1000 if (!(led & ~7)) {
994 ledioctl = led; 1001 ledioctl = led;
995 kbd->ledmode = LED_SHOW_IOCTL; 1002 kbd->ledmode = LED_SHOW_IOCTL;
@@ -997,6 +1004,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
997 kbd->ledmode = LED_SHOW_FLAGS; 1004 kbd->ledmode = LED_SHOW_FLAGS;
998 1005
999 set_leds(); 1006 set_leds();
1007 spin_unlock_irqrestore(&kbd_event_lock, flags);
1000} 1008}
1001 1009
1002static inline unsigned char getleds(void) 1010static inline unsigned char getleds(void)
@@ -1036,6 +1044,75 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
1036 return 0; 1044 return 0;
1037} 1045}
1038 1046
1047/**
1048 * vt_get_leds - helper for braille console
1049 * @console: console to read
1050 * @flag: flag we want to check
1051 *
1052 * Check the status of a keyboard led flag and report it back
1053 */
1054int vt_get_leds(int console, int flag)
1055{
1056 unsigned long flags;
1057 struct kbd_struct * kbd = kbd_table + console;
1058 int ret;
1059
1060 spin_lock_irqsave(&kbd_event_lock, flags);
1061 ret = vc_kbd_led(kbd, flag);
1062 spin_unlock_irqrestore(&kbd_event_lock, flags);
1063
1064 return ret;
1065}
1066EXPORT_SYMBOL_GPL(vt_get_leds);
1067
1068/**
1069 * vt_set_led_state - set LED state of a console
1070 * @console: console to set
1071 * @leds: LED bits
1072 *
1073 * Set the LEDs on a console. This is a wrapper for the VT layer
1074 * so that we can keep kbd knowledge internal
1075 */
1076void vt_set_led_state(int console, int leds)
1077{
1078 struct kbd_struct * kbd = kbd_table + console;
1079 setledstate(kbd, leds);
1080}
1081
1082/**
1083 * vt_kbd_con_start - Keyboard side of console start
1084 * @console: console
1085 *
1086 * Handle console start. This is a wrapper for the VT layer
1087 * so that we can keep kbd knowledge internal
1088 */
1089void vt_kbd_con_start(int console)
1090{
1091 struct kbd_struct * kbd = kbd_table + console;
1092 unsigned long flags;
1093 spin_lock_irqsave(&kbd_event_lock, flags);
1094 clr_vc_kbd_led(kbd, VC_SCROLLOCK);
1095 set_leds();
1096 spin_unlock_irqrestore(&kbd_event_lock, flags);
1097}
1098
1099/**
1100 * vt_kbd_con_stop - Keyboard side of console stop
1101 * @console: console
1102 *
1103 * Handle console stop. This is a wrapper for the VT layer
1104 * so that we can keep kbd knowledge internal
1105 */
1106void vt_kbd_con_stop(int console)
1107{
1108 struct kbd_struct * kbd = kbd_table + console;
1109 unsigned long flags;
1110 spin_lock_irqsave(&kbd_event_lock, flags);
1111 set_vc_kbd_led(kbd, VC_SCROLLOCK);
1112 set_leds();
1113 spin_unlock_irqrestore(&kbd_event_lock, flags);
1114}
1115
1039/* 1116/*
1040 * This is the tasklet that updates LED state on all keyboards 1117 * This is the tasklet that updates LED state on all keyboards
1041 * attached to the box. The reason we use tasklet is that we 1118 * attached to the box. The reason we use tasklet is that we
@@ -1255,7 +1332,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
1255 if (rc == NOTIFY_STOP || !key_map) { 1332 if (rc == NOTIFY_STOP || !key_map) {
1256 atomic_notifier_call_chain(&keyboard_notifier_list, 1333 atomic_notifier_call_chain(&keyboard_notifier_list,
1257 KBD_UNBOUND_KEYCODE, &param); 1334 KBD_UNBOUND_KEYCODE, &param);
1258 compute_shiftstate(); 1335 do_compute_shiftstate();
1259 kbd->slockstate = 0; 1336 kbd->slockstate = 0;
1260 return; 1337 return;
1261 } 1338 }
@@ -1615,3 +1692,495 @@ int vt_do_diacrit(unsigned int cmd, void __user *up, int perm)
1615 } 1692 }
1616 return ret; 1693 return ret;
1617} 1694}
1695
1696/**
1697 * vt_do_kdskbmode - set keyboard mode ioctl
1698 * @console: the console to use
1699 * @arg: the requested mode
1700 *
1701 * Update the keyboard mode bits while holding the correct locks.
1702 * Return 0 for success or an error code.
1703 */
1704int vt_do_kdskbmode(int console, unsigned int arg)
1705{
1706 struct kbd_struct * kbd = kbd_table + console;
1707 int ret = 0;
1708 unsigned long flags;
1709
1710 spin_lock_irqsave(&kbd_event_lock, flags);
1711 switch(arg) {
1712 case K_RAW:
1713 kbd->kbdmode = VC_RAW;
1714 break;
1715 case K_MEDIUMRAW:
1716 kbd->kbdmode = VC_MEDIUMRAW;
1717 break;
1718 case K_XLATE:
1719 kbd->kbdmode = VC_XLATE;
1720 do_compute_shiftstate();
1721 break;
1722 case K_UNICODE:
1723 kbd->kbdmode = VC_UNICODE;
1724 do_compute_shiftstate();
1725 break;
1726 case K_OFF:
1727 kbd->kbdmode = VC_OFF;
1728 break;
1729 default:
1730 ret = -EINVAL;
1731 }
1732 spin_unlock_irqrestore(&kbd_event_lock, flags);
1733 return ret;
1734}
1735
1736/**
1737 * vt_do_kdskbmeta - set keyboard meta state
1738 * @console: the console to use
1739 * @arg: the requested meta state
1740 *
1741 * Update the keyboard meta bits while holding the correct locks.
1742 * Return 0 for success or an error code.
1743 */
1744int vt_do_kdskbmeta(int console, unsigned int arg)
1745{
1746 struct kbd_struct * kbd = kbd_table + console;
1747 int ret = 0;
1748 unsigned long flags;
1749
1750 spin_lock_irqsave(&kbd_event_lock, flags);
1751 switch(arg) {
1752 case K_METABIT:
1753 clr_vc_kbd_mode(kbd, VC_META);
1754 break;
1755 case K_ESCPREFIX:
1756 set_vc_kbd_mode(kbd, VC_META);
1757 break;
1758 default:
1759 ret = -EINVAL;
1760 }
1761 spin_unlock_irqrestore(&kbd_event_lock, flags);
1762 return ret;
1763}
1764
1765int vt_do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc,
1766 int perm)
1767{
1768 struct kbkeycode tmp;
1769 int kc = 0;
1770
1771 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
1772 return -EFAULT;
1773 switch (cmd) {
1774 case KDGETKEYCODE:
1775 kc = getkeycode(tmp.scancode);
1776 if (kc >= 0)
1777 kc = put_user(kc, &user_kbkc->keycode);
1778 break;
1779 case KDSETKEYCODE:
1780 if (!perm)
1781 return -EPERM;
1782 kc = setkeycode(tmp.scancode, tmp.keycode);
1783 break;
1784 }
1785 return kc;
1786}
1787
1788#define i (tmp.kb_index)
1789#define s (tmp.kb_table)
1790#define v (tmp.kb_value)
1791
1792int vt_do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm,
1793 int console)
1794{
1795 struct kbd_struct * kbd = kbd_table + console;
1796 struct kbentry tmp;
1797 ushort *key_map, *new_map, val, ov;
1798 unsigned long flags;
1799
1800 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
1801 return -EFAULT;
1802
1803 if (!capable(CAP_SYS_TTY_CONFIG))
1804 perm = 0;
1805
1806 switch (cmd) {
1807 case KDGKBENT:
1808 /* Ensure another thread doesn't free it under us */
1809 spin_lock_irqsave(&kbd_event_lock, flags);
1810 key_map = key_maps[s];
1811 if (key_map) {
1812 val = U(key_map[i]);
1813 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
1814 val = K_HOLE;
1815 } else
1816 val = (i ? K_HOLE : K_NOSUCHMAP);
1817 spin_unlock_irqrestore(&kbd_event_lock, flags);
1818 return put_user(val, &user_kbe->kb_value);
1819 case KDSKBENT:
1820 if (!perm)
1821 return -EPERM;
1822 if (!i && v == K_NOSUCHMAP) {
1823 spin_lock_irqsave(&kbd_event_lock, flags);
1824 /* deallocate map */
1825 key_map = key_maps[s];
1826 if (s && key_map) {
1827 key_maps[s] = NULL;
1828 if (key_map[0] == U(K_ALLOCATED)) {
1829 kfree(key_map);
1830 keymap_count--;
1831 }
1832 }
1833 spin_unlock_irqrestore(&kbd_event_lock, flags);
1834 break;
1835 }
1836
1837 if (KTYP(v) < NR_TYPES) {
1838 if (KVAL(v) > max_vals[KTYP(v)])
1839 return -EINVAL;
1840 } else
1841 if (kbd->kbdmode != VC_UNICODE)
1842 return -EINVAL;
1843
1844 /* ++Geert: non-PC keyboards may generate keycode zero */
1845#if !defined(__mc68000__) && !defined(__powerpc__)
1846 /* assignment to entry 0 only tests validity of args */
1847 if (!i)
1848 break;
1849#endif
1850
1851 new_map = kmalloc(sizeof(plain_map), GFP_KERNEL);
1852 if (!new_map)
1853 return -ENOMEM;
1854 spin_lock_irqsave(&kbd_event_lock, flags);
1855 key_map = key_maps[s];
1856 if (key_map == NULL) {
1857 int j;
1858
1859 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
1860 !capable(CAP_SYS_RESOURCE)) {
1861 spin_unlock_irqrestore(&kbd_event_lock, flags);
1862 kfree(new_map);
1863 return -EPERM;
1864 }
1865 key_maps[s] = new_map;
1866 key_map[0] = U(K_ALLOCATED);
1867 for (j = 1; j < NR_KEYS; j++)
1868 key_map[j] = U(K_HOLE);
1869 keymap_count++;
1870 } else
1871 kfree(new_map);
1872
1873 ov = U(key_map[i]);
1874 if (v == ov)
1875 goto out;
1876 /*
1877 * Attention Key.
1878 */
1879 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN)) {
1880 spin_unlock_irqrestore(&kbd_event_lock, flags);
1881 return -EPERM;
1882 }
1883 key_map[i] = U(v);
1884 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
1885 do_compute_shiftstate();
1886out:
1887 spin_unlock_irqrestore(&kbd_event_lock, flags);
1888 break;
1889 }
1890 return 0;
1891}
1892#undef i
1893#undef s
1894#undef v
1895
1896/* FIXME: This one needs untangling and locking */
1897int vt_do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
1898{
1899 struct kbsentry *kbs;
1900 char *p;
1901 u_char *q;
1902 u_char __user *up;
1903 int sz;
1904 int delta;
1905 char *first_free, *fj, *fnw;
1906 int i, j, k;
1907 int ret;
1908
1909 if (!capable(CAP_SYS_TTY_CONFIG))
1910 perm = 0;
1911
1912 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
1913 if (!kbs) {
1914 ret = -ENOMEM;
1915 goto reterr;
1916 }
1917
1918 /* we mostly copy too much here (512bytes), but who cares ;) */
1919 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
1920 ret = -EFAULT;
1921 goto reterr;
1922 }
1923 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
1924 i = kbs->kb_func;
1925
1926 switch (cmd) {
1927 case KDGKBSENT:
1928 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
1929 a struct member */
1930 up = user_kdgkb->kb_string;
1931 p = func_table[i];
1932 if(p)
1933 for ( ; *p && sz; p++, sz--)
1934 if (put_user(*p, up++)) {
1935 ret = -EFAULT;
1936 goto reterr;
1937 }
1938 if (put_user('\0', up)) {
1939 ret = -EFAULT;
1940 goto reterr;
1941 }
1942 kfree(kbs);
1943 return ((p && *p) ? -EOVERFLOW : 0);
1944 case KDSKBSENT:
1945 if (!perm) {
1946 ret = -EPERM;
1947 goto reterr;
1948 }
1949
1950 q = func_table[i];
1951 first_free = funcbufptr + (funcbufsize - funcbufleft);
1952 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
1953 ;
1954 if (j < MAX_NR_FUNC)
1955 fj = func_table[j];
1956 else
1957 fj = first_free;
1958
1959 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
1960 if (delta <= funcbufleft) { /* it fits in current buf */
1961 if (j < MAX_NR_FUNC) {
1962 memmove(fj + delta, fj, first_free - fj);
1963 for (k = j; k < MAX_NR_FUNC; k++)
1964 if (func_table[k])
1965 func_table[k] += delta;
1966 }
1967 if (!q)
1968 func_table[i] = fj;
1969 funcbufleft -= delta;
1970 } else { /* allocate a larger buffer */
1971 sz = 256;
1972 while (sz < funcbufsize - funcbufleft + delta)
1973 sz <<= 1;
1974 fnw = kmalloc(sz, GFP_KERNEL);
1975 if(!fnw) {
1976 ret = -ENOMEM;
1977 goto reterr;
1978 }
1979
1980 if (!q)
1981 func_table[i] = fj;
1982 if (fj > funcbufptr)
1983 memmove(fnw, funcbufptr, fj - funcbufptr);
1984 for (k = 0; k < j; k++)
1985 if (func_table[k])
1986 func_table[k] = fnw + (func_table[k] - funcbufptr);
1987
1988 if (first_free > fj) {
1989 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
1990 for (k = j; k < MAX_NR_FUNC; k++)
1991 if (func_table[k])
1992 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
1993 }
1994 if (funcbufptr != func_buf)
1995 kfree(funcbufptr);
1996 funcbufptr = fnw;
1997 funcbufleft = funcbufleft - delta + sz - funcbufsize;
1998 funcbufsize = sz;
1999 }
2000 strcpy(func_table[i], kbs->kb_string);
2001 break;
2002 }
2003 ret = 0;
2004reterr:
2005 kfree(kbs);
2006 return ret;
2007}
2008
2009int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
2010{
2011 struct kbd_struct * kbd = kbd_table + console;
2012 unsigned long flags;
2013 unsigned char ucval;
2014
2015 switch(cmd) {
2016 /* the ioctls below read/set the flags usually shown in the leds */
2017 /* don't use them - they will go away without warning */
2018 case KDGKBLED:
2019 spin_lock_irqsave(&kbd_event_lock, flags);
2020 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
2021 spin_unlock_irqrestore(&kbd_event_lock, flags);
2022 return put_user(ucval, (char __user *)arg);
2023
2024 case KDSKBLED:
2025 if (!perm)
2026 return -EPERM;
2027 if (arg & ~0x77)
2028 return -EINVAL;
2029 spin_lock_irqsave(&kbd_event_lock, flags);
2030 kbd->ledflagstate = (arg & 7);
2031 kbd->default_ledflagstate = ((arg >> 4) & 7);
2032 set_leds();
2033 spin_unlock_irqrestore(&kbd_event_lock, flags);
2034 break;
2035
2036 /* the ioctls below only set the lights, not the functions */
2037 /* for those, see KDGKBLED and KDSKBLED above */
2038 case KDGETLED:
2039 ucval = getledstate();
2040 return put_user(ucval, (char __user *)arg);
2041
2042 case KDSETLED:
2043 if (!perm)
2044 return -EPERM;
2045 setledstate(kbd, arg);
2046 return 0;
2047 }
2048 return -ENOIOCTLCMD;
2049}
2050
2051int vt_do_kdgkbmode(int console)
2052{
2053 struct kbd_struct * kbd = kbd_table + console;
2054 /* This is a spot read so needs no locking */
2055 switch (kbd->kbdmode) {
2056 case VC_RAW:
2057 return K_RAW;
2058 case VC_MEDIUMRAW:
2059 return K_MEDIUMRAW;
2060 case VC_UNICODE:
2061 return K_UNICODE;
2062 case VC_OFF:
2063 return K_OFF;
2064 default:
2065 return K_XLATE;
2066 }
2067}
2068
2069/**
2070 * vt_do_kdgkbmeta - report meta status
2071 * @console: console to report
2072 *
2073 * Report the meta flag status of this console
2074 */
2075int vt_do_kdgkbmeta(int console)
2076{
2077 struct kbd_struct * kbd = kbd_table + console;
2078 /* Again a spot read so no locking */
2079 return vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT;
2080}
2081
2082/**
2083 * vt_reset_unicode - reset the unicode status
2084 * @console: console being reset
2085 *
2086 * Restore the unicode console state to its default
2087 */
2088void vt_reset_unicode(int console)
2089{
2090 unsigned long flags;
2091
2092 spin_lock_irqsave(&kbd_event_lock, flags);
2093 kbd_table[console].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE;
2094 spin_unlock_irqrestore(&kbd_event_lock, flags);
2095}
2096
2097/**
2098 * vt_get_shiftstate - shift bit state
2099 *
2100 * Report the shift bits from the keyboard state. We have to export
2101 * this to support some oddities in the vt layer.
2102 */
2103int vt_get_shift_state(void)
2104{
2105 /* Don't lock as this is a transient report */
2106 return shift_state;
2107}
2108
2109/**
2110 * vt_reset_keyboard - reset keyboard state
2111 * @console: console to reset
2112 *
2113 * Reset the keyboard bits for a console as part of a general console
2114 * reset event
2115 */
2116void vt_reset_keyboard(int console)
2117{
2118 struct kbd_struct * kbd = kbd_table + console;
2119 unsigned long flags;
2120
2121 spin_lock_irqsave(&kbd_event_lock, flags);
2122 set_vc_kbd_mode(kbd, VC_REPEAT);
2123 clr_vc_kbd_mode(kbd, VC_CKMODE);
2124 clr_vc_kbd_mode(kbd, VC_APPLIC);
2125 clr_vc_kbd_mode(kbd, VC_CRLF);
2126 kbd->lockstate = 0;
2127 kbd->slockstate = 0;
2128 kbd->ledmode = LED_SHOW_FLAGS;
2129 kbd->ledflagstate = kbd->default_ledflagstate;
2130 /* do not do set_leds here because this causes an endless tasklet loop
2131 when the keyboard hasn't been initialized yet */
2132 spin_unlock_irqrestore(&kbd_event_lock, flags);
2133}
2134
2135/**
2136 * vt_get_kbd_mode_bit - read keyboard status bits
2137 * @console: console to read from
2138 * @bit: mode bit to read
2139 *
2140 * Report back a vt mode bit. We do this without locking so the
2141 * caller must be sure that there are no synchronization needs
2142 */
2143
2144int vt_get_kbd_mode_bit(int console, int bit)
2145{
2146 struct kbd_struct * kbd = kbd_table + console;
2147 return vc_kbd_mode(kbd, bit);
2148}
2149
2150/**
2151 * vt_set_kbd_mode_bit - read keyboard status bits
2152 * @console: console to read from
2153 * @bit: mode bit to read
2154 *
2155 * Set a vt mode bit. We do this without locking so the
2156 * caller must be sure that there are no synchronization needs
2157 */
2158
2159void vt_set_kbd_mode_bit(int console, int bit)
2160{
2161 struct kbd_struct * kbd = kbd_table + console;
2162 unsigned long flags;
2163
2164 spin_lock_irqsave(&kbd_event_lock, flags);
2165 set_vc_kbd_mode(kbd, bit);
2166 spin_unlock_irqrestore(&kbd_event_lock, flags);
2167}
2168
2169/**
2170 * vt_clr_kbd_mode_bit - read keyboard status bits
2171 * @console: console to read from
2172 * @bit: mode bit to read
2173 *
2174 * Report back a vt mode bit. We do this without locking so the
2175 * caller must be sure that there are no synchronization needs
2176 */
2177
2178void vt_clr_kbd_mode_bit(int console, int bit)
2179{
2180 struct kbd_struct * kbd = kbd_table + console;
2181 unsigned long flags;
2182
2183 spin_lock_irqsave(&kbd_event_lock, flags);
2184 clr_vc_kbd_mode(kbd, bit);
2185 spin_unlock_irqrestore(&kbd_event_lock, flags);
2186}
diff --git a/drivers/tty/vt/selection.c b/drivers/tty/vt/selection.c
index 7a0a12ae5458..738e45a35131 100644
--- a/drivers/tty/vt/selection.c
+++ b/drivers/tty/vt/selection.c
@@ -30,6 +30,7 @@
30 30
31extern void poke_blanked_console(void); 31extern void poke_blanked_console(void);
32 32
33/* FIXME: all this needs locking */
33/* Variables for selection control. */ 34/* Variables for selection control. */
34/* Use a dynamic buffer, instead of static (Dec 1994) */ 35/* Use a dynamic buffer, instead of static (Dec 1994) */
35struct vc_data *sel_cons; /* must not be deallocated */ 36struct vc_data *sel_cons; /* must not be deallocated */
@@ -138,7 +139,7 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
138 char *bp, *obp; 139 char *bp, *obp;
139 int i, ps, pe, multiplier; 140 int i, ps, pe, multiplier;
140 u16 c; 141 u16 c;
141 struct kbd_struct *kbd = kbd_table + fg_console; 142 int mode;
142 143
143 poke_blanked_console(); 144 poke_blanked_console();
144 145
@@ -182,7 +183,11 @@ int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *t
182 clear_selection(); 183 clear_selection();
183 sel_cons = vc_cons[fg_console].d; 184 sel_cons = vc_cons[fg_console].d;
184 } 185 }
185 use_unicode = kbd && kbd->kbdmode == VC_UNICODE; 186 mode = vt_do_kdgkbmode(fg_console);
187 if (mode == K_UNICODE)
188 use_unicode = 1;
189 else
190 use_unicode = 0;
186 191
187 switch (sel_mode) 192 switch (sel_mode)
188 { 193 {
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index e716839fab6e..ecdcc8a8f0ca 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1028,9 +1028,9 @@ void vc_deallocate(unsigned int currcons)
1028 * VT102 emulator 1028 * VT102 emulator
1029 */ 1029 */
1030 1030
1031#define set_kbd(vc, x) set_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) 1031#define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x))
1032#define clr_kbd(vc, x) clr_vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) 1032#define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x))
1033#define is_kbd(vc, x) vc_kbd_mode(kbd_table + (vc)->vc_num, (x)) 1033#define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x))
1034 1034
1035#define decarm VC_REPEAT 1035#define decarm VC_REPEAT
1036#define decckm VC_CKMODE 1036#define decckm VC_CKMODE
@@ -1652,16 +1652,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
1652 vc->vc_deccm = global_cursor_default; 1652 vc->vc_deccm = global_cursor_default;
1653 vc->vc_decim = 0; 1653 vc->vc_decim = 0;
1654 1654
1655 set_kbd(vc, decarm); 1655 vt_reset_keyboard(vc->vc_num);
1656 clr_kbd(vc, decckm);
1657 clr_kbd(vc, kbdapplic);
1658 clr_kbd(vc, lnm);
1659 kbd_table[vc->vc_num].lockstate = 0;
1660 kbd_table[vc->vc_num].slockstate = 0;
1661 kbd_table[vc->vc_num].ledmode = LED_SHOW_FLAGS;
1662 kbd_table[vc->vc_num].ledflagstate = kbd_table[vc->vc_num].default_ledflagstate;
1663 /* do not do set_leds here because this causes an endless tasklet loop
1664 when the keyboard hasn't been initialized yet */
1665 1656
1666 vc->vc_cursor_type = cur_default; 1657 vc->vc_cursor_type = cur_default;
1667 vc->vc_complement_mask = vc->vc_s_complement_mask; 1658 vc->vc_complement_mask = vc->vc_s_complement_mask;
@@ -1979,7 +1970,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
1979 case 'q': /* DECLL - but only 3 leds */ 1970 case 'q': /* DECLL - but only 3 leds */
1980 /* map 0,1,2,3 to 0,1,2,4 */ 1971 /* map 0,1,2,3 to 0,1,2,4 */
1981 if (vc->vc_par[0] < 4) 1972 if (vc->vc_par[0] < 4)
1982 setledstate(kbd_table + vc->vc_num, 1973 vt_set_led_state(vc->vc_num,
1983 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4); 1974 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
1984 return; 1975 return;
1985 case 'r': 1976 case 'r':
@@ -2642,7 +2633,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2642 * kernel-internal variable; programs not closely 2633 * kernel-internal variable; programs not closely
2643 * related to the kernel should not use this. 2634 * related to the kernel should not use this.
2644 */ 2635 */
2645 data = shift_state; 2636 data = vt_get_shift_state();
2646 ret = __put_user(data, p); 2637 ret = __put_user(data, p);
2647 break; 2638 break;
2648 case TIOCL_GETMOUSEREPORTING: 2639 case TIOCL_GETMOUSEREPORTING:
@@ -2753,8 +2744,7 @@ static void con_stop(struct tty_struct *tty)
2753 console_num = tty->index; 2744 console_num = tty->index;
2754 if (!vc_cons_allocated(console_num)) 2745 if (!vc_cons_allocated(console_num))
2755 return; 2746 return;
2756 set_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); 2747 vt_kbd_con_stop(console_num);
2757 set_leds();
2758} 2748}
2759 2749
2760/* 2750/*
@@ -2768,8 +2758,7 @@ static void con_start(struct tty_struct *tty)
2768 console_num = tty->index; 2758 console_num = tty->index;
2769 if (!vc_cons_allocated(console_num)) 2759 if (!vc_cons_allocated(console_num))
2770 return; 2760 return;
2771 clr_vc_kbd_led(kbd_table + console_num, VC_SCROLLOCK); 2761 vt_kbd_con_start(console_num);
2772 set_leds();
2773} 2762}
2774 2763
2775static void con_flush_chars(struct tty_struct *tty) 2764static void con_flush_chars(struct tty_struct *tty)
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 80af0f9bef5b..28ca0aa8664f 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -195,232 +195,7 @@ int vt_waitactive(int n)
195#define GPLAST 0x3df 195#define GPLAST 0x3df
196#define GPNUM (GPLAST - GPFIRST + 1) 196#define GPNUM (GPLAST - GPFIRST + 1)
197 197
198#define i (tmp.kb_index)
199#define s (tmp.kb_table)
200#define v (tmp.kb_value)
201static inline int
202do_kdsk_ioctl(int cmd, struct kbentry __user *user_kbe, int perm, struct kbd_struct *kbd)
203{
204 struct kbentry tmp;
205 ushort *key_map, val, ov;
206
207 if (copy_from_user(&tmp, user_kbe, sizeof(struct kbentry)))
208 return -EFAULT;
209
210 if (!capable(CAP_SYS_TTY_CONFIG))
211 perm = 0;
212
213 switch (cmd) {
214 case KDGKBENT:
215 key_map = key_maps[s];
216 if (key_map) {
217 val = U(key_map[i]);
218 if (kbd->kbdmode != VC_UNICODE && KTYP(val) >= NR_TYPES)
219 val = K_HOLE;
220 } else
221 val = (i ? K_HOLE : K_NOSUCHMAP);
222 return put_user(val, &user_kbe->kb_value);
223 case KDSKBENT:
224 if (!perm)
225 return -EPERM;
226 if (!i && v == K_NOSUCHMAP) {
227 /* deallocate map */
228 key_map = key_maps[s];
229 if (s && key_map) {
230 key_maps[s] = NULL;
231 if (key_map[0] == U(K_ALLOCATED)) {
232 kfree(key_map);
233 keymap_count--;
234 }
235 }
236 break;
237 }
238
239 if (KTYP(v) < NR_TYPES) {
240 if (KVAL(v) > max_vals[KTYP(v)])
241 return -EINVAL;
242 } else
243 if (kbd->kbdmode != VC_UNICODE)
244 return -EINVAL;
245
246 /* ++Geert: non-PC keyboards may generate keycode zero */
247#if !defined(__mc68000__) && !defined(__powerpc__)
248 /* assignment to entry 0 only tests validity of args */
249 if (!i)
250 break;
251#endif
252
253 if (!(key_map = key_maps[s])) {
254 int j;
255
256 if (keymap_count >= MAX_NR_OF_USER_KEYMAPS &&
257 !capable(CAP_SYS_RESOURCE))
258 return -EPERM;
259
260 key_map = kmalloc(sizeof(plain_map),
261 GFP_KERNEL);
262 if (!key_map)
263 return -ENOMEM;
264 key_maps[s] = key_map;
265 key_map[0] = U(K_ALLOCATED);
266 for (j = 1; j < NR_KEYS; j++)
267 key_map[j] = U(K_HOLE);
268 keymap_count++;
269 }
270 ov = U(key_map[i]);
271 if (v == ov)
272 break; /* nothing to do */
273 /*
274 * Attention Key.
275 */
276 if (((ov == K_SAK) || (v == K_SAK)) && !capable(CAP_SYS_ADMIN))
277 return -EPERM;
278 key_map[i] = U(v);
279 if (!s && (KTYP(ov) == KT_SHIFT || KTYP(v) == KT_SHIFT))
280 compute_shiftstate();
281 break;
282 }
283 return 0;
284}
285#undef i
286#undef s
287#undef v
288
289static inline int
290do_kbkeycode_ioctl(int cmd, struct kbkeycode __user *user_kbkc, int perm)
291{
292 struct kbkeycode tmp;
293 int kc = 0;
294
295 if (copy_from_user(&tmp, user_kbkc, sizeof(struct kbkeycode)))
296 return -EFAULT;
297 switch (cmd) {
298 case KDGETKEYCODE:
299 kc = getkeycode(tmp.scancode);
300 if (kc >= 0)
301 kc = put_user(kc, &user_kbkc->keycode);
302 break;
303 case KDSETKEYCODE:
304 if (!perm)
305 return -EPERM;
306 kc = setkeycode(tmp.scancode, tmp.keycode);
307 break;
308 }
309 return kc;
310}
311
312static inline int
313do_kdgkb_ioctl(int cmd, struct kbsentry __user *user_kdgkb, int perm)
314{
315 struct kbsentry *kbs;
316 char *p;
317 u_char *q;
318 u_char __user *up;
319 int sz;
320 int delta;
321 char *first_free, *fj, *fnw;
322 int i, j, k;
323 int ret;
324
325 if (!capable(CAP_SYS_TTY_CONFIG))
326 perm = 0;
327
328 kbs = kmalloc(sizeof(*kbs), GFP_KERNEL);
329 if (!kbs) {
330 ret = -ENOMEM;
331 goto reterr;
332 }
333
334 /* we mostly copy too much here (512bytes), but who cares ;) */
335 if (copy_from_user(kbs, user_kdgkb, sizeof(struct kbsentry))) {
336 ret = -EFAULT;
337 goto reterr;
338 }
339 kbs->kb_string[sizeof(kbs->kb_string)-1] = '\0';
340 i = kbs->kb_func;
341
342 switch (cmd) {
343 case KDGKBSENT:
344 sz = sizeof(kbs->kb_string) - 1; /* sz should have been
345 a struct member */
346 up = user_kdgkb->kb_string;
347 p = func_table[i];
348 if(p)
349 for ( ; *p && sz; p++, sz--)
350 if (put_user(*p, up++)) {
351 ret = -EFAULT;
352 goto reterr;
353 }
354 if (put_user('\0', up)) {
355 ret = -EFAULT;
356 goto reterr;
357 }
358 kfree(kbs);
359 return ((p && *p) ? -EOVERFLOW : 0);
360 case KDSKBSENT:
361 if (!perm) {
362 ret = -EPERM;
363 goto reterr;
364 }
365 198
366 q = func_table[i];
367 first_free = funcbufptr + (funcbufsize - funcbufleft);
368 for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++)
369 ;
370 if (j < MAX_NR_FUNC)
371 fj = func_table[j];
372 else
373 fj = first_free;
374
375 delta = (q ? -strlen(q) : 1) + strlen(kbs->kb_string);
376 if (delta <= funcbufleft) { /* it fits in current buf */
377 if (j < MAX_NR_FUNC) {
378 memmove(fj + delta, fj, first_free - fj);
379 for (k = j; k < MAX_NR_FUNC; k++)
380 if (func_table[k])
381 func_table[k] += delta;
382 }
383 if (!q)
384 func_table[i] = fj;
385 funcbufleft -= delta;
386 } else { /* allocate a larger buffer */
387 sz = 256;
388 while (sz < funcbufsize - funcbufleft + delta)
389 sz <<= 1;
390 fnw = kmalloc(sz, GFP_KERNEL);
391 if(!fnw) {
392 ret = -ENOMEM;
393 goto reterr;
394 }
395
396 if (!q)
397 func_table[i] = fj;
398 if (fj > funcbufptr)
399 memmove(fnw, funcbufptr, fj - funcbufptr);
400 for (k = 0; k < j; k++)
401 if (func_table[k])
402 func_table[k] = fnw + (func_table[k] - funcbufptr);
403
404 if (first_free > fj) {
405 memmove(fnw + (fj - funcbufptr) + delta, fj, first_free - fj);
406 for (k = j; k < MAX_NR_FUNC; k++)
407 if (func_table[k])
408 func_table[k] = fnw + (func_table[k] - funcbufptr) + delta;
409 }
410 if (funcbufptr != func_buf)
411 kfree(funcbufptr);
412 funcbufptr = fnw;
413 funcbufleft = funcbufleft - delta + sz - funcbufsize;
414 funcbufsize = sz;
415 }
416 strcpy(func_table[i], kbs->kb_string);
417 break;
418 }
419 ret = 0;
420reterr:
421 kfree(kbs);
422 return ret;
423}
424 199
425static inline int 200static inline int
426do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op) 201do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
@@ -497,7 +272,6 @@ int vt_ioctl(struct tty_struct *tty,
497{ 272{
498 struct vc_data *vc = tty->driver_data; 273 struct vc_data *vc = tty->driver_data;
499 struct console_font_op op; /* used in multiple places here */ 274 struct console_font_op op; /* used in multiple places here */
500 struct kbd_struct * kbd;
501 unsigned int console; 275 unsigned int console;
502 unsigned char ucval; 276 unsigned char ucval;
503 unsigned int uival; 277 unsigned int uival;
@@ -523,7 +297,6 @@ int vt_ioctl(struct tty_struct *tty,
523 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG)) 297 if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
524 perm = 1; 298 perm = 1;
525 299
526 kbd = kbd_table + console;
527 switch (cmd) { 300 switch (cmd) {
528 case TIOCLINUX: 301 case TIOCLINUX:
529 ret = tioclinux(tty, arg); 302 ret = tioclinux(tty, arg);
@@ -565,7 +338,8 @@ int vt_ioctl(struct tty_struct *tty,
565 * this is naive. 338 * this is naive.
566 */ 339 */
567 ucval = KB_101; 340 ucval = KB_101;
568 goto setchar; 341 ret = put_user(ucval, (char __user *)arg);
342 break;
569 343
570 /* 344 /*
571 * These cannot be implemented on any machine that implements 345 * These cannot be implemented on any machine that implements
@@ -670,68 +444,25 @@ int vt_ioctl(struct tty_struct *tty,
670 case KDSKBMODE: 444 case KDSKBMODE:
671 if (!perm) 445 if (!perm)
672 goto eperm; 446 goto eperm;
673 switch(arg) { 447 ret = vt_do_kdskbmode(console, arg);
674 case K_RAW: 448 if (ret == 0)
675 kbd->kbdmode = VC_RAW; 449 tty_ldisc_flush(tty);
676 break;
677 case K_MEDIUMRAW:
678 kbd->kbdmode = VC_MEDIUMRAW;
679 break;
680 case K_XLATE:
681 kbd->kbdmode = VC_XLATE;
682 compute_shiftstate();
683 break;
684 case K_UNICODE:
685 kbd->kbdmode = VC_UNICODE;
686 compute_shiftstate();
687 break;
688 case K_OFF:
689 kbd->kbdmode = VC_OFF;
690 break;
691 default:
692 ret = -EINVAL;
693 goto out;
694 }
695 tty_ldisc_flush(tty);
696 break; 450 break;
697 451
698 case KDGKBMODE: 452 case KDGKBMODE:
699 switch (kbd->kbdmode) { 453 uival = vt_do_kdgkbmode(console);
700 case VC_RAW: 454 ret = put_user(uival, (int __user *)arg);
701 uival = K_RAW; 455 break;
702 break;
703 case VC_MEDIUMRAW:
704 uival = K_MEDIUMRAW;
705 break;
706 case VC_UNICODE:
707 uival = K_UNICODE;
708 break;
709 case VC_OFF:
710 uival = K_OFF;
711 break;
712 default:
713 uival = K_XLATE;
714 break;
715 }
716 goto setint;
717 456
718 /* this could be folded into KDSKBMODE, but for compatibility 457 /* this could be folded into KDSKBMODE, but for compatibility
719 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */ 458 reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
720 case KDSKBMETA: 459 case KDSKBMETA:
721 switch(arg) { 460 ret = vt_do_kdskbmeta(console, arg);
722 case K_METABIT:
723 clr_vc_kbd_mode(kbd, VC_META);
724 break;
725 case K_ESCPREFIX:
726 set_vc_kbd_mode(kbd, VC_META);
727 break;
728 default:
729 ret = -EINVAL;
730 }
731 break; 461 break;
732 462
733 case KDGKBMETA: 463 case KDGKBMETA:
734 uival = (vc_kbd_mode(kbd, VC_META) ? K_ESCPREFIX : K_METABIT); 464 /* FIXME: should review whether this is worth locking */
465 uival = vt_do_kdgkbmeta(console);
735 setint: 466 setint:
736 ret = put_user(uival, (int __user *)arg); 467 ret = put_user(uival, (int __user *)arg);
737 break; 468 break;
@@ -740,17 +471,17 @@ int vt_ioctl(struct tty_struct *tty,
740 case KDSETKEYCODE: 471 case KDSETKEYCODE:
741 if(!capable(CAP_SYS_TTY_CONFIG)) 472 if(!capable(CAP_SYS_TTY_CONFIG))
742 perm = 0; 473 perm = 0;
743 ret = do_kbkeycode_ioctl(cmd, up, perm); 474 ret = vt_do_kbkeycode_ioctl(cmd, up, perm);
744 break; 475 break;
745 476
746 case KDGKBENT: 477 case KDGKBENT:
747 case KDSKBENT: 478 case KDSKBENT:
748 ret = do_kdsk_ioctl(cmd, up, perm, kbd); 479 ret = vt_do_kdsk_ioctl(cmd, up, perm, console);
749 break; 480 break;
750 481
751 case KDGKBSENT: 482 case KDGKBSENT:
752 case KDSKBSENT: 483 case KDSKBSENT:
753 ret = do_kdgkb_ioctl(cmd, up, perm); 484 ret = vt_do_kdgkb_ioctl(cmd, up, perm);
754 break; 485 break;
755 486
756 /* Diacritical processing. Handled in keyboard.c as it has 487 /* Diacritical processing. Handled in keyboard.c as it has
@@ -765,33 +496,10 @@ int vt_ioctl(struct tty_struct *tty,
765 /* the ioctls below read/set the flags usually shown in the leds */ 496 /* the ioctls below read/set the flags usually shown in the leds */
766 /* don't use them - they will go away without warning */ 497 /* don't use them - they will go away without warning */
767 case KDGKBLED: 498 case KDGKBLED:
768 ucval = kbd->ledflagstate | (kbd->default_ledflagstate << 4);
769 goto setchar;
770
771 case KDSKBLED: 499 case KDSKBLED:
772 if (!perm)
773 goto eperm;
774 if (arg & ~0x77) {
775 ret = -EINVAL;
776 break;
777 }
778 kbd->ledflagstate = (arg & 7);
779 kbd->default_ledflagstate = ((arg >> 4) & 7);
780 set_leds();
781 break;
782
783 /* the ioctls below only set the lights, not the functions */
784 /* for those, see KDGKBLED and KDSKBLED above */
785 case KDGETLED: 500 case KDGETLED:
786 ucval = getledstate();
787 setchar:
788 ret = put_user(ucval, (char __user *)arg);
789 break;
790
791 case KDSETLED: 501 case KDSETLED:
792 if (!perm) 502 ret = vt_do_kdskled(console, cmd, arg, perm);
793 goto eperm;
794 setledstate(kbd, arg);
795 break; 503 break;
796 504
797 /* 505 /*
@@ -1286,7 +994,7 @@ eperm:
1286void reset_vc(struct vc_data *vc) 994void reset_vc(struct vc_data *vc)
1287{ 995{
1288 vc->vc_mode = KD_TEXT; 996 vc->vc_mode = KD_TEXT;
1289 kbd_table[vc->vc_num].kbdmode = default_utf8 ? VC_UNICODE : VC_XLATE; 997 vt_reset_unicode(vc->vc_num);
1290 vc->vt_mode.mode = VT_AUTO; 998 vc->vt_mode.mode = VT_AUTO;
1291 vc->vt_mode.waitv = 0; 999 vc->vt_mode.waitv = 0;
1292 vc->vt_mode.relsig = 0; 1000 vc->vt_mode.relsig = 0;
@@ -1309,6 +1017,7 @@ void vc_SAK(struct work_struct *work)
1309 console_lock(); 1017 console_lock();
1310 vc = vc_con->d; 1018 vc = vc_con->d;
1311 if (vc) { 1019 if (vc) {
1020 /* FIXME: review tty ref counting */
1312 tty = vc->port.tty; 1021 tty = vc->port.tty;
1313 /* 1022 /*
1314 * SAK should also work in all raw modes and reset 1023 * SAK should also work in all raw modes and reset