diff options
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r-- | drivers/char/vt.c | 235 |
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 | ||
104 | struct con_driver { | 112 | struct 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 | ||
131 | extern void vcs_make_devfs(struct tty_struct *tty); | 139 | extern void vcs_make_sysfs(struct tty_struct *tty); |
132 | extern void vcs_remove_devfs(struct tty_struct *tty); | 140 | extern void vcs_remove_sysfs(struct tty_struct *tty); |
133 | |||
134 | extern void console_map_init(void); | ||
135 | #ifdef CONFIG_PROM_CONSOLE | ||
136 | extern void prom_con_init(void); | ||
137 | #endif | ||
138 | #ifdef CONFIG_MDA_CONSOLE | ||
139 | extern int mda_console_init(void); | ||
140 | #endif | ||
141 | 141 | ||
142 | struct vc vc_cons [MAX_NR_CONSOLES]; | 142 | struct 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); | |||
152 | static void save_cur(struct vc_data *vc); | 152 | static void save_cur(struct vc_data *vc); |
153 | static void reset_terminal(struct vc_data *vc, int do_clear); | 153 | static void reset_terminal(struct vc_data *vc, int do_clear); |
154 | static void con_flush_chars(struct tty_struct *tty); | 154 | static void con_flush_chars(struct tty_struct *tty); |
155 | static void set_vesa_blanking(char __user *p); | 155 | static int set_vesa_blanking(char __user *p); |
156 | static void set_cursor(struct vc_data *vc); | 156 | static void set_cursor(struct vc_data *vc); |
157 | static void hide_cursor(struct vc_data *vc); | 157 | static void hide_cursor(struct vc_data *vc); |
158 | static void console_callback(void *ignored); | 158 | static void console_callback(struct work_struct *ignored); |
159 | static void blank_screen_t(unsigned long dummy); | 159 | static void blank_screen_t(unsigned long dummy); |
160 | static void set_palette(struct vc_data *vc); | 160 | static 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 */ | |||
174 | static int blankinterval = 10*60*HZ; | 174 | static int blankinterval = 10*60*HZ; |
175 | static int vesa_off_interval; | 175 | static int vesa_off_interval; |
176 | 176 | ||
177 | static DECLARE_WORK(console_work, console_callback, NULL); | 177 | static 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 | ||
882 | int 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 | ||
882 | void vc_disallocate(unsigned int currcons) | 892 | void 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 */ |
2022 | rescan_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); | 2087 | replacement_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 | ||
2101 | display_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 | */ |
2128 | static void console_callback(void *ignored) | 2157 | static 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 | */ |
2516 | static void con_close(struct tty_struct *tty, struct file *filp) | 2545 | static 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 | } |
2640 | console_initcall(con_init); | 2669 | console_initcall(con_init); |
2641 | 2670 | ||
2642 | static struct tty_operations con_ops = { | 2671 | static 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 | ||
2997 | static ssize_t store_bind(struct class_device *class_device, | 3026 | static 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 | ||
3011 | static ssize_t show_bind(struct class_device *class_device, char *buf) | 3040 | static 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 | ||
3019 | static ssize_t show_name(struct class_device *class_device, char *buf) | 3049 | static 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 | ||
3029 | static struct class_device_attribute class_device_attrs[] = { | 3060 | static 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 | ||
3034 | static int vtconsole_init_class_device(struct con_driver *con) | 3065 | static 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 | ||
3046 | static void vtconsole_deinit_class_device(struct con_driver *con) | 3087 | static 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 | |||
3151 | err: | 3194 | err: |
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 = ®istered_con_driver[i]; | 3288 | struct con_driver *con = ®istered_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 | ||
3274 | static void set_vesa_blanking(char __user *p) | 3316 | static 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 | ||
3281 | void do_blank_screen(int entering_gfx) | 3327 | void do_blank_screen(int entering_gfx) |
@@ -3765,6 +3811,7 @@ EXPORT_SYMBOL(default_blu); | |||
3765 | EXPORT_SYMBOL(update_region); | 3811 | EXPORT_SYMBOL(update_region); |
3766 | EXPORT_SYMBOL(redraw_screen); | 3812 | EXPORT_SYMBOL(redraw_screen); |
3767 | EXPORT_SYMBOL(vc_resize); | 3813 | EXPORT_SYMBOL(vc_resize); |
3814 | EXPORT_SYMBOL(vc_lock_resize); | ||
3768 | EXPORT_SYMBOL(fg_console); | 3815 | EXPORT_SYMBOL(fg_console); |
3769 | EXPORT_SYMBOL(console_blank_hook); | 3816 | EXPORT_SYMBOL(console_blank_hook); |
3770 | EXPORT_SYMBOL(console_blanked); | 3817 | EXPORT_SYMBOL(console_blanked); |