73 #include <linux/module.h>
74 #include <linux/types.h>
75 #include <linux/sched.h>
76 #include <linux/tty.h>
78 #include <linux/kernel.h>
79 #include <linux/string.h>
80 #include <linux/errno.h>
82 #include <linux/slab.h>
98 #include <linux/bitops.h>
100 #include <linux/device.h>
104 #include <linux/ctype.h>
106 #define MAX_NR_CON_DRIVER 16
108 #define CON_DRIVER_FLAG_MODULE 1
109 #define CON_DRIVER_FLAG_INIT 2
110 #define CON_DRIVER_FLAG_ATTR 4
130 #define CTRL_ACTION 0x0d00ff81
131 #define CTRL_ALWAYS 0x0800f501
136 #define DEFAULT_BELL_PITCH 750
137 #define DEFAULT_BELL_DURATION (HZ/8)
141 #ifndef VT_SINGLE_DRIVER
147 unsigned int cols,
int do_clear);
148 static void gotoxy(
struct vc_data *
vc,
int new_x,
int new_y);
149 static void save_cur(
struct vc_data *
vc);
150 static void reset_terminal(
struct vc_data *
vc,
int do_clear);
151 static void con_flush_chars(
struct tty_struct *tty);
152 static int set_vesa_blanking(
char __user *
p);
153 static void set_cursor(
struct vc_data *
vc);
154 static void hide_cursor(
struct vc_data *
vc);
156 static void blank_screen_t(
unsigned long dummy);
157 static void set_palette(
struct vc_data *
vc);
159 static int printable;
172 static int ignore_poke;
177 static int vesa_blank_mode;
178 static int vesa_off_interval;
179 static int blankinterval = 10*60;
180 core_param(consoleblank, blankinterval,
int, 0444);
193 static int saved_fg_console;
194 static int saved_last_console;
195 static int saved_want_console;
196 static int saved_vc_mode;
197 static int saved_console_blanked;
205 static struct vc_data *master_display_fg;
217 static int scrollback_delta;
225 static DEFINE_TIMER(console_timer, blank_screen_t, 0, 0);
226 static int blank_state;
227 static int blank_timer_expired;
240 static struct device *tty0dev;
265 static void notify_update(
struct vc_data *
vc)
274 #define IS_FG(vc) ((vc)->vc_num == fg_console)
276 #ifdef VT_BUF_VRAM_ONLY
277 #define DO_UPDATE(vc) 0
279 #define DO_UPDATE(vc) (CON_IS_VISIBLE(vc) && !console_blanked)
282 static inline unsigned short *screenpos(
struct vc_data *
vc,
int offset,
int viewed)
287 p = (
unsigned short *)(vc->
vc_origin + offset);
288 else if (!vc->
vc_sw->con_screen_pos)
291 p = vc->
vc_sw->con_screen_pos(vc, offset);
296 static inline void scrolldelta(
int lines)
301 scrollback_delta += lines;
310 static void scrup(
struct vc_data *
vc,
unsigned int t,
unsigned int b,
int nr)
312 unsigned short *
d, *
s;
316 if (b > vc->
vc_rows || t >= b || nr < 1)
327 static void scrdown(
struct vc_data *vc,
unsigned int t,
unsigned int b,
int nr)
334 if (b > vc->
vc_rows || t >= b || nr < 1)
346 #ifndef VT_BUF_VRAM_ONLY
351 if (!vc->
vc_sw->con_getxy) {
357 start = vc->
vc_sw->con_getxy(vc, start, &nxx, &nyy);
364 while (xx < vc->vc_cols && count) {
367 vc->
vc_sw->con_putcs(vc, q, p-q, yy, startx);
377 vc->
vc_sw->con_putcs(vc, q, p-q, yy, startx);
382 if (vc->
vc_sw->con_getxy) {
396 do_update_region(vc, start, count);
403 static u8 build_attr(
struct vc_data *vc,
u8 _color,
u8 _intensity,
u8 _blink,
404 u8 _underline,
u8 _reverse,
u8 _italic)
406 if (vc->
vc_sw->con_build_attr)
407 return vc->
vc_sw->con_build_attr(vc, _color, _intensity,
408 _blink, _underline, _reverse, _italic);
410 #ifndef VT_BUF_VRAM_ONLY
426 (_underline ? 4 : 0) |
433 else if (_intensity == 0)
436 a = ((
a) & 0x88) | ((((
a) >> 4) | ((
a) << 4)) & 0x77);
450 static void update_attr(
struct vc_data *vc)
466 p = screenpos(vc, offset, viewed);
467 if (vc->
vc_sw->con_invert_region)
468 vc->
vc_sw->con_invert_region(vc, p, count);
469 #ifndef VT_BUF_VRAM_ONLY
485 a = ((
a) & 0x11ff) | (((
a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
492 a = ((
a) & 0x88ff) | (((
a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
500 do_update_region(vc, (
unsigned long) p, count);
506 static int old_offset = -1;
507 static unsigned short old;
508 static unsigned short oldx, oldy;
512 if (old_offset != -1 && old_offset >= 0 &&
513 old_offset < vc->vc_screenbuf_size) {
514 scr_writew(old, screenpos(vc, old_offset, 1));
516 vc->
vc_sw->con_putc(vc, old, oldy, oldx);
521 if (offset != -1 && offset >= 0 &&
525 p = screenpos(vc, offset, 1);
530 oldx = (offset >> 1) % vc->
vc_cols;
531 oldy = (offset >> 1) / vc->
vc_cols;
532 vc->
vc_sw->con_putc(vc,
new, oldy, oldx);
538 static void insert_char(
struct vc_data *vc,
unsigned int nr)
540 unsigned short *p = (
unsigned short *) vc->
vc_pos;
546 do_update_region(vc, (
unsigned long) p,
550 static void delete_char(
struct vc_data *vc,
unsigned int nr)
552 unsigned short *p = (
unsigned short *) vc->
vc_pos;
559 do_update_region(vc, (
unsigned long) p,
563 static int softcursor_original;
565 static void add_softcursor(
struct vc_data *vc)
570 if (! (type & 0x10))
return;
571 if (softcursor_original != -1)
return;
572 softcursor_original =
i;
573 i |= ((type >> 8) & 0xff00 );
574 i ^= ((
type) & 0xff00 );
575 if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
576 if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
582 static void hide_softcursor(
struct vc_data *vc)
584 if (softcursor_original != -1) {
587 vc->
vc_sw->con_putc(vc, softcursor_original,
589 softcursor_original = -1;
593 static void hide_cursor(
struct vc_data *vc)
601 static void set_cursor(
struct vc_data *vc)
616 static void set_origin(
struct vc_data *vc)
621 !vc->
vc_sw->con_set_origin ||
622 !vc->
vc_sw->con_set_origin(vc))
629 static inline void save_screen(
struct vc_data *vc)
633 if (vc->
vc_sw->con_save_screen)
634 vc->
vc_sw->con_save_screen(vc);
641 static void clear_buffer_attributes(
struct vc_data *vc)
643 unsigned short *p = (
unsigned short *)vc->
vc_origin;
647 for (; count > 0; count--, p++) {
689 update = vc->
vc_sw->con_switch(vc);
699 clear_buffer_attributes(vc);
704 vt_force_oops_output(vc))
724 static void visual_init(
struct vc_data *vc,
int num,
int init)
728 module_put(vc->
vc_sw->owner);
730 #ifndef VT_SINGLE_DRIVER
731 if (con_driver_map[num])
732 vc->
vc_sw = con_driver_map[num];
734 __module_get(vc->
vc_sw->owner);
743 vc->
vc_sw->con_init(vc, init);
777 visual_init(vc, currcons, 1);
806 err = vc->
vc_sw->con_resize(vc, width, height, user);
816 #define VC_RESIZE_MAXCOL (32767)
817 #define VC_RESIZE_MAXROW (32767)
836 unsigned int cols,
unsigned int lines)
838 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
840 unsigned int old_rows, old_row_size;
841 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
843 unsigned short *newscreen;
856 new_cols = (cols ? cols : vc->
vc_cols);
857 new_rows = (lines ? lines : vc->
vc_rows);
858 new_row_size = new_cols << 1;
859 new_screen_size = new_row_size * new_rows;
871 err = resize_screen(vc, new_cols, new_rows, user);
882 rlth =
min(old_row_size, new_row_size);
883 rrem = new_row_size - rlth;
885 new_origin = (
long) newscreen;
886 new_scr_end = new_origin + new_screen_size;
888 if (vc->
vc_y > new_rows) {
889 if (old_rows - vc->
vc_y < new_rows) {
894 old_origin += (old_rows - new_rows) * old_row_size;
900 old_origin += (vc->
vc_y - new_rows/2) * old_row_size;
904 end = old_origin + old_row_size *
min(old_rows, new_rows);
908 while (old_origin < end) {
910 (
unsigned short *) old_origin, rlth);
912 scr_memsetw((
void *)(new_origin + rlth),
914 old_origin += old_row_size;
915 new_origin += new_row_size;
917 if (new_scr_end > new_origin)
919 new_scr_end - new_origin);
935 memset(&ws, 0,
sizeof(ws));
962 return vc_do_resize(vc->
port.tty, vc, cols, rows);
998 vc->
vc_sw->con_deinit(vc);
1000 module_put(vc->
vc_sw->owner);
1012 #define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x))
1013 #define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x))
1014 #define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x))
1016 #define decarm VC_REPEAT
1017 #define decckm VC_CKMODE
1018 #define kbdapplic VC_APPLIC
1024 #define VT100ID "\033[?1;2c"
1025 #define VT102ID "\033[?6c"
1028 8,12,10,14, 9,13,11,15 };
1032 0x55,0xff,0x55,0xff,0x55,0xff,0x55,0xff};
1034 0x55,0x55,0xff,0xff,0x55,0x55,0xff,0xff};
1036 0x55,0x55,0x55,0x55,0xff,0xff,0xff,0xff};
1047 static void gotoxy(
struct vc_data *vc,
int new_x,
int new_y)
1069 else if (new_y >= max_y)
1070 vc->
vc_y = max_y - 1;
1078 static void gotoxay(
struct vc_data *vc,
int new_x,
int new_y)
1087 scrolldelta(-lines);
1097 static void lf(
struct vc_data *vc)
1109 notify_write(vc,
'\n');
1112 static void ri(
struct vc_data *vc)
1119 else if (vc->
vc_y > 0) {
1126 static inline void cr(
struct vc_data *vc)
1130 notify_write(vc,
'\r');
1133 static inline void bs(
struct vc_data *vc)
1139 notify_write(vc,
'\b');
1143 static inline void del(
struct vc_data *vc)
1148 static void csi_J(
struct vc_data *vc,
int vpar)
1151 unsigned short *
start;
1156 start = (
unsigned short *)vc->
vc_pos;
1160 start = (
unsigned short *)vc->
vc_origin;
1169 start = (
unsigned short *)vc->
vc_origin;
1176 do_update_region(vc, (
unsigned long) start, count);
1180 static void csi_K(
struct vc_data *vc,
int vpar)
1183 unsigned short *
start;
1188 start = (
unsigned short *)vc->
vc_pos;
1191 start = (
unsigned short *)(vc->
vc_pos - (vc->
vc_x << 1));
1192 count = vc->
vc_x + 1;
1195 start = (
unsigned short *)(vc->
vc_pos - (vc->
vc_x << 1));
1204 do_update_region(vc, (
unsigned long) start, count);
1207 static void csi_X(
struct vc_data *vc,
int vpar)
1221 static void default_attr(
struct vc_data *vc)
1232 static void csi_m(
struct vc_data *vc)
1236 for (i = 0; i <= vc->
vc_npar; i++)
1333 static void respond_string(
const char *p,
struct tty_struct *tty)
1336 tty_insert_flip_char(tty, *p, 0);
1347 respond_string(buf, tty);
1350 static inline void status_report(
struct tty_struct *tty)
1352 respond_string(
"\033[0n", tty);
1355 static inline void respond_ID(
struct tty_struct * tty)
1364 sprintf(buf,
"\033[M%c%c%c", (
char)(
' ' + butt), (
char)(
'!' + mrx),
1366 respond_string(buf, tty);
1380 for (i = 0; i <= vc->
vc_npar; i++)
1446 static void setterm_command(
struct vc_data *vc)
1473 blankinterval = ((vc->
vc_par[1] < 60) ? vc->
vc_par[1] : 60) * 60;
1497 vesa_off_interval = ((vc->
vc_par[1] < 60) ? vc->
vc_par[1] : 60) * 60 *
HZ;
1506 static void csi_at(
struct vc_data *vc,
unsigned int nr)
1512 insert_char(vc, nr);
1516 static void csi_L(
struct vc_data *vc,
unsigned int nr)
1527 static void csi_P(
struct vc_data *vc,
unsigned int nr)
1533 delete_char(vc, nr);
1537 static void csi_M(
struct vc_data *vc,
unsigned int nr)
1548 static void save_cur(
struct vc_data *vc)
1564 static void restore_cur(
struct vc_data *vc)
1586 static void reset_terminal(
struct vc_data *vc,
int do_clear)
1661 notify_write(vc,
'\t');
1663 case 10:
case 11:
case 12:
1738 reset_terminal(vc, 1);
1755 }
else if (c==
'R') {
1765 int i = vc->
vc_par[0] * 3,
j = 1;
1794 }
else if (c>=
'0' && c<=
'9') {
1832 else if (vc->
vc_par[0] == 6)
1833 cursor_report(vc, tty);
1890 csi_J(vc, vc->
vc_par[0]);
1893 csi_K(vc, vc->
vc_par[0]);
1896 csi_L(vc, vc->
vc_par[0]);
1899 csi_M(vc, vc->
vc_par[0]);
1902 csi_P(vc, vc->
vc_par[0]);
1911 else if (vc->
vc_par[0] == 3) {
1951 csi_X(vc, vc->
vc_par[0]);
1954 csi_at(vc, vc->
vc_par[0]);
1957 setterm_command(vc);
2033 if (ucs < table[0].
first || ucs > table[max].
last)
2035 while (max >= min) {
2036 mid = (min +
max) / 2;
2037 if (ucs > table[mid].last)
2039 else if (ucs < table[mid].
first)
2047 static int is_double_width(
uint32_t ucs)
2049 static const struct interval double_width[] = {
2050 { 0x1100, 0x115F }, { 0x2329, 0x232A }, { 0x2E80, 0x303E },
2051 { 0x3040, 0xA4CF }, { 0xAC00, 0xD7A3 }, { 0xF900, 0xFAFF },
2052 { 0xFE10, 0xFE19 }, { 0xFE30, 0xFE6F }, { 0xFF00, 0xFF60 },
2053 { 0xFFE0, 0xFFE6 }, { 0x20000, 0x2FFFD }, { 0x30000, 0x3FFFD }
2055 return bisearch(ucs, double_width,
ARRAY_SIZE(double_width) - 1);
2059 static int do_con_write(
struct tty_struct *tty,
const unsigned char *
buf,
int count)
2061 #ifdef VT_BUF_VRAM_ONLY
2062 #define FLUSH do { } while(0);
2064 #define FLUSH if (draw_x >= 0) { \
2065 vc->vc_sw->con_putcs(vc, (u16 *)draw_from, (u16 *)draw_to - (u16 *)draw_from, vc->vc_y, draw_x); \
2070 int c,
tc, ok,
n = 0, draw_x = -1;
2071 unsigned int currcons;
2072 unsigned long draw_from = 0, draw_to = 0;
2079 u16 himask, charmask;
2097 pr_warn_once(
"con_write: tty %d not allocated\n", currcons+1);
2103 charmask = himask ? 0x1ff : 0xff;
2111 while (!tty->
stopped && count) {
2132 if ((c & 0xc0) == 0x80) {
2134 static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
2145 if (c <= utf8_length_changes[vc->
vc_npar - 1] ||
2146 c > utf8_length_changes[vc->
vc_npar])
2160 }
else if (c > 0x7f) {
2163 if ((c & 0xe0) == 0xc0) {
2166 }
else if ((c & 0xf0) == 0xe0) {
2169 }
else if ((c & 0xf8) == 0xf0) {
2172 }
else if ((c & 0xfc) == 0xf8) {
2175 }
else if ((c & 0xfe) == 0xfc) {
2192 if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
2201 &
param) == NOTIFY_STOP)
2214 ok = tc && (c >= 32 ||
2222 if (is_double_width(c))
2227 if (tc & ~charmask) {
2228 if (tc == -1 || tc == -2) {
2245 if (tc < 0) tc =
'?';
2255 vc_attr = (vc->
vc_attr) ^ 0x08;
2274 ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
2275 (vc_attr << 8) + tc,
2283 draw_to = vc->
vc_pos + 2;
2286 draw_to = (vc->
vc_pos += 2);
2289 if (!--width)
break;
2292 if (tc < 0) tc =
' ';
2294 notify_write(vc, c);
2305 goto rescan_last_byte;
2310 do_con_trol(tty, vc, orig);
2348 if (scrollback_delta) {
2352 vc->
vc_sw->con_scrolldelta(vc, scrollback_delta);
2353 scrollback_delta = 0;
2355 if (blank_timer_expired) {
2357 blank_timer_expired = 0;
2390 #ifdef CONFIG_VT_CONSOLE
2413 int vt_kmsg_redirect(
int new)
2415 static int kmsg_con;
2418 return xchg(&kmsg_con,
new);
2429 static void vt_console_print(
struct console *co,
const char *b,
unsigned count)
2442 if (!spin_trylock(&printing_lock))
2447 vc =
vc_cons[kmsg_console - 1].d;
2472 if (c == 10 || c == 13 || c == 8 || vc->
vc_need_wrap) {
2492 if (c == 10 || c == 13)
2496 notify_write(vc, c);
2518 spin_unlock(&printing_lock);
2527 static struct console vt_console_driver = {
2529 .write = vt_console_print,
2530 .device = vt_console_device,
2604 ret = set_vesa_blanking(p);
2618 vt_kmsg_redirect(data);
2660 static int con_write(
struct tty_struct *tty,
const unsigned char *buf,
int count)
2664 retval = do_con_write(tty, buf, count);
2665 con_flush_chars(tty);
2670 static int con_put_char(
struct tty_struct *tty,
unsigned char ch)
2674 return do_con_write(tty, &ch, 1);
2677 static int con_write_room(
struct tty_struct *tty)
2684 static int con_chars_in_buffer(
struct tty_struct *tty)
2694 static void con_throttle(
struct tty_struct *tty)
2698 static void con_unthrottle(
struct tty_struct *tty)
2713 console_num = tty->
index;
2722 static void con_start(
struct tty_struct *tty)
2727 console_num = tty->
index;
2733 static void con_flush_chars(
struct tty_struct *tty)
2753 unsigned int currcons = tty->
index;
2782 tty->termios.c_iflag |=
IUTF8;
2784 tty->termios.c_iflag &= ~
IUTF8;
2802 static void con_shutdown(
struct tty_struct *tty)
2811 static int default_italic_color = 2;
2812 static int default_underline_color = 3;
2816 static void vc_init(
struct vc_data *vc,
unsigned int rows,
2817 unsigned int cols,
int do_clear)
2829 for (j=k=0; j<16; j++) {
2839 reset_terminal(vc, do_clear);
2848 static int __init con_init(
void)
2850 const char *display_desc =
NULL;
2852 unsigned int currcons = 0,
i;
2858 if (!display_desc) {
2867 if (con_driver->
con ==
NULL) {
2869 con_driver->
desc = display_desc;
2871 con_driver->
first = 0;
2878 con_driver_map[i] = conswitchp;
2880 if (blankinterval) {
2882 mod_timer(&console_timer, jiffies + (blankinterval *
HZ));
2889 visual_init(vc, currcons, 1);
2892 currcons || !vc->
vc_sw->con_save_screen);
2895 master_display_fg = vc =
vc_cons[currcons].d;
2901 pr_info(
"Console: %s %s %dx%d\n",
2908 #ifdef CONFIG_VT_CONSOLE
2916 .install = con_install,
2920 .write_room = con_write_room,
2921 .put_char = con_put_char,
2922 .flush_chars = con_flush_chars,
2923 .chars_in_buffer = con_chars_in_buffer,
2925 #ifdef CONFIG_COMPAT
2930 .throttle = con_throttle,
2931 .unthrottle = con_unthrottle,
2932 .resize = vt_resize,
2933 .shutdown = con_shutdown
2936 static struct cdev vc0_cdev;
2950 panic(
"Couldn't register /dev/tty0 driver\n");
2952 if (IS_ERR(tty0dev))
2959 console_driver = alloc_tty_driver(MAX_NR_CONSOLES);
2960 if (!console_driver)
2961 panic(
"Couldn't allocate console driver\n");
2963 console_driver->
name =
"tty";
2974 panic(
"Couldn't register console driver\n");
2977 #ifdef CONFIG_MDA_CONSOLE
2983 #ifndef VT_SINGLE_DRIVER
2985 static struct class *vtconsole_class;
2987 static int bind_con_driver(
const struct consw *csw,
int first,
int last,
2992 struct con_driver *con_driver;
2995 if (!try_module_get(owner))
3002 con_driver = ®istered_con_driver[
i];
3004 if (con_driver->
con == csw) {
3005 desc = con_driver->
desc;
3021 module_put(conswitchp->
owner);
3023 __module_get(owner);
3027 first =
max(first, con_driver->
first);
3028 last =
min(last, con_driver->
last);
3030 for (i = first; i <=
last; i++) {
3034 if (con_driver_map[i])
3035 module_put(con_driver_map[i]->owner);
3036 __module_get(owner);
3037 con_driver_map[
i] = csw;
3039 if (!vc || !vc->
vc_sw)
3050 vc->
vc_sw->con_deinit(vc);
3052 visual_init(vc, i, 0);
3061 clear_buffer_attributes(vc);
3064 pr_info(
"Console: switching ");
3066 printk(
"consoles %d-%d ", first+1, last+1);
3070 printk(
"to %s %s %dx%d\n",
3088 #ifdef CONFIG_VT_HW_CONSOLE_BINDING
3089 static int con_is_graphics(
const struct consw *csw,
int first,
int last)
3093 for (i = first; i <= last; i++) {
3126 struct con_driver *con_driver =
NULL, *con_back =
NULL;
3129 if (!try_module_get(owner))
3136 con_driver = ®istered_con_driver[
i];
3138 if (con_driver->
con == csw &&
3154 con_back = ®istered_con_driver[
i];
3156 if (con_back->con &&
3158 defcsw = con_back->con;
3174 first =
max(first, con_driver->
first);
3175 last =
min(last, con_driver->
last);
3177 for (i = first; i <=
last; i++) {
3178 if (con_driver_map[i] == csw) {
3179 module_put(csw->
owner);
3180 con_driver_map[
i] =
NULL;
3193 conswitchp = defconsw;
3201 bind_con_driver(defcsw, first, last, deflt);
3209 static int vt_bind(
struct con_driver *
con)
3212 int i, more = 1, first = -1, last = -1, deflt = 0;
3221 struct con_driver *con = ®istered_con_driver[
i];
3235 for (i = con->
first; i <= con->last; i++) {
3236 if (con_driver_map[i] == defcsw) {
3241 }
else if (first != -1)
3245 if (first == 0 && last == MAX_NR_CONSOLES -1)
3249 bind_con_driver(csw, first, last, deflt);
3260 static int vt_unbind(
struct con_driver *con)
3263 int i, more = 1, first = -1, last = -1, deflt = 0;
3274 for (i = con->
first; i <= con->last; i++) {
3275 if (con_driver_map[i] == csw) {
3280 }
else if (first != -1)
3284 if (first == 0 && last == MAX_NR_CONSOLES -1)
3299 static inline int vt_bind(
struct con_driver *con)
3303 static inline int vt_unbind(
struct con_driver *con)
3310 const char *buf,
size_t count)
3348 static int vtconsole_init_device(
struct con_driver *con)
3355 for (i = 0; i <
ARRAY_SIZE(device_attrs); i++) {
3370 static void vtconsole_deinit_device(
struct con_driver *con)
3375 for (i = 0; i <
ARRAY_SIZE(device_attrs); i++)
3395 if (con_driver_map[i] == csw) {
3428 if (vc->
vc_sw->con_debug_enter)
3429 ret = vc->
vc_sw->con_debug_enter(vc);
3430 #ifdef CONFIG_KGDB_KDB
3435 const char *setargs[3] = {
3448 const char *setargs[3] = {
3486 if (vc->
vc_sw->con_debug_leave)
3487 ret = vc->
vc_sw->con_debug_leave(vc);
3505 struct con_driver *con_driver;
3509 if (!try_module_get(owner))
3515 con_driver = ®istered_con_driver[
i];
3518 if (con_driver->
con == csw)
3533 con_driver = ®istered_con_driver[
i];
3535 if (con_driver->
con ==
NULL) {
3536 con_driver->
con = csw;
3538 con_driver->
node =
i;
3556 if (IS_ERR(con_driver->
dev)) {
3558 "errno = %ld\n", con_driver->
desc,
3559 PTR_ERR(con_driver->
dev));
3562 vtconsole_init_device(con_driver);
3594 struct con_driver *con_driver = ®istered_con_driver[
i];
3596 if (con_driver->
con == csw &&
3598 vtconsole_deinit_device(con_driver);
3604 con_driver->
node = 0;
3605 con_driver->
flag = 0;
3606 con_driver->
first = 0;
3607 con_driver->
last = 0;
3637 bind_con_driver(csw, first, last, deflt);
3651 static int __init vtconsole_class_init(
void)
3656 if (IS_ERR(vtconsole_class)) {
3658 "errno = %ld\n", PTR_ERR(vtconsole_class));
3659 vtconsole_class =
NULL;
3664 struct con_driver *con = ®istered_con_driver[
i];
3666 if (con->
con && !con->
dev) {
3672 if (IS_ERR(con->
dev)) {
3674 "device for %s; errno = %ld\n",
3675 con->
desc, PTR_ERR(con->
dev));
3678 vtconsole_init_device(con);
3693 static int set_vesa_blanking(
char __user *p)
3700 vesa_blank_mode = (mode < 4) ? mode : 0;
3714 vc->
vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
3723 vc->
vc_sw->con_blank(vc, -1, 1);
3742 blank_timer_expired = 0;
3746 i = vc->
vc_sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0);
3754 if (vesa_off_interval && vesa_blank_mode) {
3783 pr_warning(
"unblank_screen: tty %d not allocated ??\n",
3792 if (blankinterval) {
3798 if (vc->
vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc))
3825 static void blank_screen_t(
unsigned long dummy)
3828 mod_timer(&console_timer, jiffies + (blankinterval *
HZ));
3831 blank_timer_expired = 1;
3851 blank_timer_expired = 0;
3857 else if (blankinterval) {
3867 static void set_palette(
struct vc_data *vc)
3872 vc->
vc_sw->con_set_palette(vc, color_table);
3883 unsigned char colormap[3*16];
3889 for (i = k = 0; i < 16; i++) {
3890 default_red[
i] = colormap[k++];
3891 default_grn[
i] = colormap[k++];
3892 default_blu[
i] = colormap[k++];
3897 for (j = k = 0; j < 16; j++) {
3898 vc_cons[
i].d->vc_palette[k++] = default_red[
j];
3899 vc_cons[
i].d->vc_palette[k++] = default_grn[
j];
3900 vc_cons[
i].d->vc_palette[k++] = default_blu[
j];
3912 unsigned char colormap[3*16];
3915 for (i = k = 0; i < 16; i++) {
3916 colormap[k++] = default_red[
i];
3917 colormap[k++] = default_grn[
i];
3918 colormap[k++] = default_blu[
i];
3931 for (j=k=0; j<16; j++) {
3952 #define max_font_size 65536
3970 else if (vc->
vc_sw->con_font_get)
3971 rc = vc->
vc_sw->con_font_get(vc, &font);
3987 if (font.
width != 8)
4029 for (h = 32; h > 0; h--)
4031 if (
get_user(tmp, &charmap[32*i+h-1]))
4046 font.height = op->
height;
4047 font.width = op->
width;
4049 if (IS_ERR(font.data))
4050 return PTR_ERR(font.data);
4054 else if (vc->
vc_sw->con_font_set)
4055 rc = vc->
vc_sw->con_font_set(vc, &font, op->
flags);
4083 if (vc->
vc_sw->con_font_default)
4084 rc = vc->
vc_sw->con_font_default(vc, &font, s);
4104 else if (!vc->
vc_sw->con_font_copy)
4108 else if (con == vc->
vc_num)
4111 rc = vc->
vc_sw->con_font_copy(vc, con);
4120 return con_font_set(vc, op);
4122 return con_font_get(vc, op);
4124 return con_font_default(vc, op);
4126 return con_font_copy(vc, op);
4150 return screenpos(vc, 2 * w_offset, viewed);
4162 gotoxy(vc, p[0], p[1]);
4168 if ((
unsigned long)org == vc->
vc_pos && softcursor_original != -1)
4169 return softcursor_original;
4176 if ((
unsigned long)org == vc->
vc_pos) {
4177 softcursor_original = -1;
4203 #ifndef VT_SINGLE_DRIVER