aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r--drivers/char/vt.c235
1 files changed, 141 insertions, 94 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index da7e66a2a38b..a8239dac994f 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -63,6 +63,13 @@
63 * 63 *
64 * Removed console_lock, enabled interrupts across all console operations 64 * Removed console_lock, enabled interrupts across all console operations
65 * 13 March 2001, Andrew Morton 65 * 13 March 2001, Andrew Morton
66 *
67 * Fixed UTF-8 mode so alternate charset modes always work according
68 * to control sequences interpreted in do_con_trol function
69 * preserving backward VT100 semigraphics compatibility,
70 * malformed UTF sequences represented as sequences of replacement glyphs,
71 * original codes or '?' as a last resort if replacement glyph is undefined
72 * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
66 */ 73 */
67 74
68#include <linux/module.h> 75#include <linux/module.h>
@@ -99,12 +106,13 @@
99#define MAX_NR_CON_DRIVER 16 106#define MAX_NR_CON_DRIVER 16
100 107
101#define CON_DRIVER_FLAG_MODULE 1 108#define CON_DRIVER_FLAG_MODULE 1
102#define CON_DRIVER_FLAG_INIT 2 109#define CON_DRIVER_FLAG_INIT 2
110#define CON_DRIVER_FLAG_ATTR 4
103 111
104struct con_driver { 112struct con_driver {
105 const struct consw *con; 113 const struct consw *con;
106 const char *desc; 114 const char *desc;
107 struct class_device *class_dev; 115 struct device *dev;
108 int node; 116 int node;
109 int first; 117 int first;
110 int last; 118 int last;
@@ -128,16 +136,8 @@ const struct consw *conswitchp;
128#define DEFAULT_BELL_PITCH 750 136#define DEFAULT_BELL_PITCH 750
129#define DEFAULT_BELL_DURATION (HZ/8) 137#define DEFAULT_BELL_DURATION (HZ/8)
130 138
131extern void vcs_make_devfs(struct tty_struct *tty); 139extern void vcs_make_sysfs(struct tty_struct *tty);
132extern void vcs_remove_devfs(struct tty_struct *tty); 140extern void vcs_remove_sysfs(struct tty_struct *tty);
133
134extern void console_map_init(void);
135#ifdef CONFIG_PROM_CONSOLE
136extern void prom_con_init(void);
137#endif
138#ifdef CONFIG_MDA_CONSOLE
139extern int mda_console_init(void);
140#endif
141 141
142struct vc vc_cons [MAX_NR_CONSOLES]; 142struct vc vc_cons [MAX_NR_CONSOLES];
143 143
@@ -152,10 +152,10 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y);
152static void save_cur(struct vc_data *vc); 152static void save_cur(struct vc_data *vc);
153static void reset_terminal(struct vc_data *vc, int do_clear); 153static void reset_terminal(struct vc_data *vc, int do_clear);
154static void con_flush_chars(struct tty_struct *tty); 154static void con_flush_chars(struct tty_struct *tty);
155static void set_vesa_blanking(char __user *p); 155static int set_vesa_blanking(char __user *p);
156static void set_cursor(struct vc_data *vc); 156static void set_cursor(struct vc_data *vc);
157static void hide_cursor(struct vc_data *vc); 157static void hide_cursor(struct vc_data *vc);
158static void console_callback(void *ignored); 158static void console_callback(struct work_struct *ignored);
159static void blank_screen_t(unsigned long dummy); 159static void blank_screen_t(unsigned long dummy);
160static void set_palette(struct vc_data *vc); 160static void set_palette(struct vc_data *vc);
161 161
@@ -174,7 +174,7 @@ static int vesa_blank_mode; /* 0:none 1:suspendV 2:suspendH 3:powerdown */
174static int blankinterval = 10*60*HZ; 174static int blankinterval = 10*60*HZ;
175static int vesa_off_interval; 175static int vesa_off_interval;
176 176
177static DECLARE_WORK(console_work, console_callback, NULL); 177static DECLARE_WORK(console_work, console_callback);
178 178
179/* 179/*
180 * fg_console is the current virtual console, 180 * fg_console is the current virtual console,
@@ -730,7 +730,8 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
730 visual_init(vc, currcons, 1); 730 visual_init(vc, currcons, 1);
731 if (!*vc->vc_uni_pagedir_loc) 731 if (!*vc->vc_uni_pagedir_loc)
732 con_set_default_unimap(vc); 732 con_set_default_unimap(vc);
733 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL); 733 if (!vc->vc_kmalloced)
734 vc->vc_screenbuf = kmalloc(vc->vc_screenbuf_size, GFP_KERNEL);
734 if (!vc->vc_screenbuf) { 735 if (!vc->vc_screenbuf) {
735 kfree(vc); 736 kfree(vc);
736 vc_cons[currcons].d = NULL; 737 vc_cons[currcons].d = NULL;
@@ -878,14 +879,24 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
878 return err; 879 return err;
879} 880}
880 881
882int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
883{
884 int rc;
885
886 acquire_console_sem();
887 rc = vc_resize(vc, cols, lines);
888 release_console_sem();
889 return rc;
890}
881 891
882void vc_disallocate(unsigned int currcons) 892void vc_deallocate(unsigned int currcons)
883{ 893{
884 WARN_CONSOLE_UNLOCKED(); 894 WARN_CONSOLE_UNLOCKED();
885 895
886 if (vc_cons_allocated(currcons)) { 896 if (vc_cons_allocated(currcons)) {
887 struct vc_data *vc = vc_cons[currcons].d; 897 struct vc_data *vc = vc_cons[currcons].d;
888 vc->vc_sw->con_deinit(vc); 898 vc->vc_sw->con_deinit(vc);
899 put_pid(vc->vt_pid);
889 module_put(vc->vc_sw->owner); 900 module_put(vc->vc_sw->owner);
890 if (vc->vc_kmalloced) 901 if (vc->vc_kmalloced)
891 kfree(vc->vc_screenbuf); 902 kfree(vc->vc_screenbuf);
@@ -2005,17 +2016,23 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2005 /* Do no translation at all in control states */ 2016 /* Do no translation at all in control states */
2006 if (vc->vc_state != ESnormal) { 2017 if (vc->vc_state != ESnormal) {
2007 tc = c; 2018 tc = c;
2008 } else if (vc->vc_utf) { 2019 } else if (vc->vc_utf && !vc->vc_disp_ctrl) {
2009 /* Combine UTF-8 into Unicode */ 2020 /* Combine UTF-8 into Unicode */
2010 /* Incomplete characters silently ignored */ 2021 /* Malformed sequences as sequences of replacement glyphs */
2022rescan_last_byte:
2011 if(c > 0x7f) { 2023 if(c > 0x7f) {
2012 if (vc->vc_utf_count > 0 && (c & 0xc0) == 0x80) { 2024 if (vc->vc_utf_count) {
2013 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); 2025 if ((c & 0xc0) == 0x80) {
2014 vc->vc_utf_count--; 2026 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2015 if (vc->vc_utf_count == 0) 2027 if (--vc->vc_utf_count) {
2016 tc = c = vc->vc_utf_char; 2028 vc->vc_npar++;
2017 else continue; 2029 continue;
2030 }
2031 tc = c = vc->vc_utf_char;
2032 } else
2033 goto replacement_glyph;
2018 } else { 2034 } else {
2035 vc->vc_npar = 0;
2019 if ((c & 0xe0) == 0xc0) { 2036 if ((c & 0xe0) == 0xc0) {
2020 vc->vc_utf_count = 1; 2037 vc->vc_utf_count = 1;
2021 vc->vc_utf_char = (c & 0x1f); 2038 vc->vc_utf_char = (c & 0x1f);
@@ -2032,14 +2049,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2032 vc->vc_utf_count = 5; 2049 vc->vc_utf_count = 5;
2033 vc->vc_utf_char = (c & 0x01); 2050 vc->vc_utf_char = (c & 0x01);
2034 } else 2051 } else
2035 vc->vc_utf_count = 0; 2052 goto replacement_glyph;
2036 continue; 2053 continue;
2037 } 2054 }
2038 } else { 2055 } else {
2056 if (vc->vc_utf_count)
2057 goto replacement_glyph;
2039 tc = c; 2058 tc = c;
2040 vc->vc_utf_count = 0;
2041 } 2059 }
2042 } else { /* no utf */ 2060 } else { /* no utf or alternate charset mode */
2043 tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c]; 2061 tc = vc->vc_translate[vc->vc_toggle_meta ? (c | 0x80) : c];
2044 } 2062 }
2045 2063
@@ -2054,31 +2072,33 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2054 * direct-to-font zone in UTF-8 mode. 2072 * direct-to-font zone in UTF-8 mode.
2055 */ 2073 */
2056 ok = tc && (c >= 32 || 2074 ok = tc && (c >= 32 ||
2057 (!vc->vc_utf && !(((vc->vc_disp_ctrl ? CTRL_ALWAYS 2075 !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
2058 : CTRL_ACTION) >> c) & 1))) 2076 vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
2059 && (c != 127 || vc->vc_disp_ctrl) 2077 && (c != 127 || vc->vc_disp_ctrl)
2060 && (c != 128+27); 2078 && (c != 128+27);
2061 2079
2062 if (vc->vc_state == ESnormal && ok) { 2080 if (vc->vc_state == ESnormal && ok) {
2063 /* Now try to find out how to display it */ 2081 /* Now try to find out how to display it */
2064 tc = conv_uni_to_pc(vc, tc); 2082 tc = conv_uni_to_pc(vc, tc);
2065 if ( tc == -4 ) { 2083 if (tc & ~charmask) {
2084 if ( tc == -4 ) {
2066 /* If we got -4 (not found) then see if we have 2085 /* If we got -4 (not found) then see if we have
2067 defined a replacement character (U+FFFD) */ 2086 defined a replacement character (U+FFFD) */
2068 tc = conv_uni_to_pc(vc, 0xfffd); 2087replacement_glyph:
2069 2088 tc = conv_uni_to_pc(vc, 0xfffd);
2070 /* One reason for the -4 can be that we just 2089 if (!(tc & ~charmask))
2071 did a clear_unimap(); 2090 goto display_glyph;
2072 try at least to show something. */ 2091 } else if ( tc != -3 )
2073 if (tc == -4) 2092 continue; /* nothing to display */
2074 tc = c; 2093 /* no hash table or no replacement --
2075 } else if ( tc == -3 ) { 2094 * hope for the best */
2076 /* Bad hash table -- hope for the best */ 2095 if ( c & ~charmask )
2077 tc = c; 2096 tc = '?';
2078 } 2097 else
2079 if (tc & ~charmask) 2098 tc = c;
2080 continue; /* Conversion failed */ 2099 }
2081 2100
2101display_glyph:
2082 if (vc->vc_need_wrap || vc->vc_decim) 2102 if (vc->vc_need_wrap || vc->vc_decim)
2083 FLUSH 2103 FLUSH
2084 if (vc->vc_need_wrap) { 2104 if (vc->vc_need_wrap) {
@@ -2102,6 +2122,15 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
2102 vc->vc_x++; 2122 vc->vc_x++;
2103 draw_to = (vc->vc_pos += 2); 2123 draw_to = (vc->vc_pos += 2);
2104 } 2124 }
2125 if (vc->vc_utf_count) {
2126 if (vc->vc_npar) {
2127 vc->vc_npar--;
2128 goto display_glyph;
2129 }
2130 vc->vc_utf_count = 0;
2131 c = orig;
2132 goto rescan_last_byte;
2133 }
2105 continue; 2134 continue;
2106 } 2135 }
2107 FLUSH 2136 FLUSH
@@ -2125,7 +2154,7 @@ out:
2125 * with other console code and prevention of re-entrancy is 2154 * with other console code and prevention of re-entrancy is
2126 * ensured with console_sem. 2155 * ensured with console_sem.
2127 */ 2156 */
2128static void console_callback(void *ignored) 2157static void console_callback(struct work_struct *ignored)
2129{ 2158{
2130 acquire_console_sem(); 2159 acquire_console_sem();
2131 2160
@@ -2340,7 +2369,7 @@ int tioclinux(struct tty_struct *tty, unsigned long arg)
2340 ret = __put_user(data, p); 2369 ret = __put_user(data, p);
2341 break; 2370 break;
2342 case TIOCL_SETVESABLANK: 2371 case TIOCL_SETVESABLANK:
2343 set_vesa_blanking(p); 2372 ret = set_vesa_blanking(p);
2344 break; 2373 break;
2345 case TIOCL_GETKMSGREDIRECT: 2374 case TIOCL_GETKMSGREDIRECT:
2346 data = kmsg_redirect; 2375 data = kmsg_redirect;
@@ -2498,7 +2527,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2498 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols; 2527 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
2499 } 2528 }
2500 release_console_sem(); 2529 release_console_sem();
2501 vcs_make_devfs(tty); 2530 vcs_make_sysfs(tty);
2502 return ret; 2531 return ret;
2503 } 2532 }
2504 } 2533 }
@@ -2511,7 +2540,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
2511 * and taking a ref against the tty while we're in the process of forgetting 2540 * and taking a ref against the tty while we're in the process of forgetting
2512 * about it and cleaning things up. 2541 * about it and cleaning things up.
2513 * 2542 *
2514 * This is because vcs_remove_devfs() can sleep and will drop the BKL. 2543 * This is because vcs_remove_sysfs() can sleep and will drop the BKL.
2515 */ 2544 */
2516static void con_close(struct tty_struct *tty, struct file *filp) 2545static void con_close(struct tty_struct *tty, struct file *filp)
2517{ 2546{
@@ -2524,7 +2553,7 @@ static void con_close(struct tty_struct *tty, struct file *filp)
2524 vc->vc_tty = NULL; 2553 vc->vc_tty = NULL;
2525 tty->driver_data = NULL; 2554 tty->driver_data = NULL;
2526 release_console_sem(); 2555 release_console_sem();
2527 vcs_remove_devfs(tty); 2556 vcs_remove_sysfs(tty);
2528 mutex_unlock(&tty_mutex); 2557 mutex_unlock(&tty_mutex);
2529 /* 2558 /*
2530 * tty_mutex is released, but we still hold BKL, so there is 2559 * tty_mutex is released, but we still hold BKL, so there is
@@ -2639,7 +2668,7 @@ static int __init con_init(void)
2639} 2668}
2640console_initcall(con_init); 2669console_initcall(con_init);
2641 2670
2642static struct tty_operations con_ops = { 2671static const struct tty_operations con_ops = {
2643 .open = con_open, 2672 .open = con_open,
2644 .close = con_close, 2673 .close = con_close,
2645 .write = con_write, 2674 .write = con_write,
@@ -2994,10 +3023,10 @@ static inline int vt_unbind(struct con_driver *con)
2994} 3023}
2995#endif /* CONFIG_VT_HW_CONSOLE_BINDING */ 3024#endif /* CONFIG_VT_HW_CONSOLE_BINDING */
2996 3025
2997static ssize_t store_bind(struct class_device *class_device, 3026static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
2998 const char *buf, size_t count) 3027 const char *buf, size_t count)
2999{ 3028{
3000 struct con_driver *con = class_get_devdata(class_device); 3029 struct con_driver *con = dev_get_drvdata(dev);
3001 int bind = simple_strtoul(buf, NULL, 0); 3030 int bind = simple_strtoul(buf, NULL, 0);
3002 3031
3003 if (bind) 3032 if (bind)
@@ -3008,17 +3037,19 @@ static ssize_t store_bind(struct class_device *class_device,
3008 return count; 3037 return count;
3009} 3038}
3010 3039
3011static ssize_t show_bind(struct class_device *class_device, char *buf) 3040static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
3041 char *buf)
3012{ 3042{
3013 struct con_driver *con = class_get_devdata(class_device); 3043 struct con_driver *con = dev_get_drvdata(dev);
3014 int bind = con_is_bound(con->con); 3044 int bind = con_is_bound(con->con);
3015 3045
3016 return snprintf(buf, PAGE_SIZE, "%i\n", bind); 3046 return snprintf(buf, PAGE_SIZE, "%i\n", bind);
3017} 3047}
3018 3048
3019static ssize_t show_name(struct class_device *class_device, char *buf) 3049static ssize_t show_name(struct device *dev, struct device_attribute *attr,
3050 char *buf)
3020{ 3051{
3021 struct con_driver *con = class_get_devdata(class_device); 3052 struct con_driver *con = dev_get_drvdata(dev);
3022 3053
3023 return snprintf(buf, PAGE_SIZE, "%s %s\n", 3054 return snprintf(buf, PAGE_SIZE, "%s %s\n",
3024 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)", 3055 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
@@ -3026,30 +3057,42 @@ static ssize_t show_name(struct class_device *class_device, char *buf)
3026 3057
3027} 3058}
3028 3059
3029static struct class_device_attribute class_device_attrs[] = { 3060static struct device_attribute device_attrs[] = {
3030 __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind), 3061 __ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind),
3031 __ATTR(name, S_IRUGO, show_name, NULL), 3062 __ATTR(name, S_IRUGO, show_name, NULL),
3032}; 3063};
3033 3064
3034static int vtconsole_init_class_device(struct con_driver *con) 3065static int vtconsole_init_device(struct con_driver *con)
3035{ 3066{
3036 int i; 3067 int i;
3068 int error = 0;
3037 3069
3038 class_set_devdata(con->class_dev, con); 3070 con->flag |= CON_DRIVER_FLAG_ATTR;
3039 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) 3071 dev_set_drvdata(con->dev, con);
3040 class_device_create_file(con->class_dev, 3072 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
3041 &class_device_attrs[i]); 3073 error = device_create_file(con->dev, &device_attrs[i]);
3074 if (error)
3075 break;
3076 }
3042 3077
3043 return 0; 3078 if (error) {
3079 while (--i >= 0)
3080 device_remove_file(con->dev, &device_attrs[i]);
3081 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3082 }
3083
3084 return error;
3044} 3085}
3045 3086
3046static void vtconsole_deinit_class_device(struct con_driver *con) 3087static void vtconsole_deinit_device(struct con_driver *con)
3047{ 3088{
3048 int i; 3089 int i;
3049 3090
3050 for (i = 0; i < ARRAY_SIZE(class_device_attrs); i++) 3091 if (con->flag & CON_DRIVER_FLAG_ATTR) {
3051 class_device_remove_file(con->class_dev, 3092 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
3052 &class_device_attrs[i]); 3093 device_remove_file(con->dev, &device_attrs[i]);
3094 con->flag &= ~CON_DRIVER_FLAG_ATTR;
3095 }
3053} 3096}
3054 3097
3055/** 3098/**
@@ -3135,19 +3178,19 @@ int register_con_driver(const struct consw *csw, int first, int last)
3135 if (retval) 3178 if (retval)
3136 goto err; 3179 goto err;
3137 3180
3138 con_driver->class_dev = class_device_create(vtconsole_class, NULL, 3181 con_driver->dev = device_create(vtconsole_class, NULL,
3139 MKDEV(0, con_driver->node), 3182 MKDEV(0, con_driver->node),
3140 NULL, "vtcon%i", 3183 "vtcon%i", con_driver->node);
3141 con_driver->node);
3142 3184
3143 if (IS_ERR(con_driver->class_dev)) { 3185 if (IS_ERR(con_driver->dev)) {
3144 printk(KERN_WARNING "Unable to create class_device for %s; " 3186 printk(KERN_WARNING "Unable to create device for %s; "
3145 "errno = %ld\n", con_driver->desc, 3187 "errno = %ld\n", con_driver->desc,
3146 PTR_ERR(con_driver->class_dev)); 3188 PTR_ERR(con_driver->dev));
3147 con_driver->class_dev = NULL; 3189 con_driver->dev = NULL;
3148 } else { 3190 } else {
3149 vtconsole_init_class_device(con_driver); 3191 vtconsole_init_device(con_driver);
3150 } 3192 }
3193
3151err: 3194err:
3152 release_console_sem(); 3195 release_console_sem();
3153 module_put(owner); 3196 module_put(owner);
@@ -3181,12 +3224,12 @@ int unregister_con_driver(const struct consw *csw)
3181 3224
3182 if (con_driver->con == csw && 3225 if (con_driver->con == csw &&
3183 con_driver->flag & CON_DRIVER_FLAG_MODULE) { 3226 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3184 vtconsole_deinit_class_device(con_driver); 3227 vtconsole_deinit_device(con_driver);
3185 class_device_destroy(vtconsole_class, 3228 device_destroy(vtconsole_class,
3186 MKDEV(0, con_driver->node)); 3229 MKDEV(0, con_driver->node));
3187 con_driver->con = NULL; 3230 con_driver->con = NULL;
3188 con_driver->desc = NULL; 3231 con_driver->desc = NULL;
3189 con_driver->class_dev = NULL; 3232 con_driver->dev = NULL;
3190 con_driver->node = 0; 3233 con_driver->node = 0;
3191 con_driver->flag = 0; 3234 con_driver->flag = 0;
3192 con_driver->first = 0; 3235 con_driver->first = 0;
@@ -3244,19 +3287,18 @@ static int __init vtconsole_class_init(void)
3244 for (i = 0; i < MAX_NR_CON_DRIVER; i++) { 3287 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3245 struct con_driver *con = &registered_con_driver[i]; 3288 struct con_driver *con = &registered_con_driver[i];
3246 3289
3247 if (con->con && !con->class_dev) { 3290 if (con->con && !con->dev) {
3248 con->class_dev = 3291 con->dev = device_create(vtconsole_class, NULL,
3249 class_device_create(vtconsole_class, NULL, 3292 MKDEV(0, con->node),
3250 MKDEV(0, con->node), NULL, 3293 "vtcon%i", con->node);
3251 "vtcon%i", con->node);
3252 3294
3253 if (IS_ERR(con->class_dev)) { 3295 if (IS_ERR(con->dev)) {
3254 printk(KERN_WARNING "Unable to create " 3296 printk(KERN_WARNING "Unable to create "
3255 "class_device for %s; errno = %ld\n", 3297 "device for %s; errno = %ld\n",
3256 con->desc, PTR_ERR(con->class_dev)); 3298 con->desc, PTR_ERR(con->dev));
3257 con->class_dev = NULL; 3299 con->dev = NULL;
3258 } else { 3300 } else {
3259 vtconsole_init_class_device(con); 3301 vtconsole_init_device(con);
3260 } 3302 }
3261 } 3303 }
3262 } 3304 }
@@ -3271,11 +3313,15 @@ postcore_initcall(vtconsole_class_init);
3271 * Screen blanking 3313 * Screen blanking
3272 */ 3314 */
3273 3315
3274static void set_vesa_blanking(char __user *p) 3316static int set_vesa_blanking(char __user *p)
3275{ 3317{
3276 unsigned int mode; 3318 unsigned int mode;
3277 get_user(mode, p + 1); 3319
3278 vesa_blank_mode = (mode < 4) ? mode : 0; 3320 if (get_user(mode, p + 1))
3321 return -EFAULT;
3322
3323 vesa_blank_mode = (mode < 4) ? mode : 0;
3324 return 0;
3279} 3325}
3280 3326
3281void do_blank_screen(int entering_gfx) 3327void do_blank_screen(int entering_gfx)
@@ -3765,6 +3811,7 @@ EXPORT_SYMBOL(default_blu);
3765EXPORT_SYMBOL(update_region); 3811EXPORT_SYMBOL(update_region);
3766EXPORT_SYMBOL(redraw_screen); 3812EXPORT_SYMBOL(redraw_screen);
3767EXPORT_SYMBOL(vc_resize); 3813EXPORT_SYMBOL(vc_resize);
3814EXPORT_SYMBOL(vc_lock_resize);
3768EXPORT_SYMBOL(fg_console); 3815EXPORT_SYMBOL(fg_console);
3769EXPORT_SYMBOL(console_blank_hook); 3816EXPORT_SYMBOL(console_blank_hook);
3770EXPORT_SYMBOL(console_blanked); 3817EXPORT_SYMBOL(console_blanked);