diff options
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r-- | drivers/char/vt.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 44f03ddd8871..c734f9b1263a 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #include <asm/system.h> | 105 | #include <asm/system.h> |
106 | #include <linux/uaccess.h> | 106 | #include <linux/uaccess.h> |
107 | #include <linux/kdb.h> | 107 | #include <linux/kdb.h> |
108 | #include <linux/ctype.h> | ||
108 | 109 | ||
109 | #define MAX_NR_CON_DRIVER 16 | 110 | #define MAX_NR_CON_DRIVER 16 |
110 | 111 | ||
@@ -286,8 +287,12 @@ static inline unsigned short *screenpos(struct vc_data *vc, int offset, int view | |||
286 | return p; | 287 | return p; |
287 | } | 288 | } |
288 | 289 | ||
290 | /* Called from the keyboard irq path.. */ | ||
289 | static inline void scrolldelta(int lines) | 291 | static inline void scrolldelta(int lines) |
290 | { | 292 | { |
293 | /* FIXME */ | ||
294 | /* scrolldelta needs some kind of consistency lock, but the BKL was | ||
295 | and still is not protecting versus the scheduled back end */ | ||
291 | scrollback_delta += lines; | 296 | scrollback_delta += lines; |
292 | schedule_console_callback(); | 297 | schedule_console_callback(); |
293 | } | 298 | } |
@@ -704,7 +709,10 @@ void redraw_screen(struct vc_data *vc, int is_switch) | |||
704 | update_attr(vc); | 709 | update_attr(vc); |
705 | clear_buffer_attributes(vc); | 710 | clear_buffer_attributes(vc); |
706 | } | 711 | } |
707 | if (update && vc->vc_mode != KD_GRAPHICS) | 712 | |
713 | /* Forcibly update if we're panicing */ | ||
714 | if ((update && vc->vc_mode != KD_GRAPHICS) || | ||
715 | vt_force_oops_output(vc)) | ||
708 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); | 716 | do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); |
709 | } | 717 | } |
710 | set_cursor(vc); | 718 | set_cursor(vc); |
@@ -742,6 +750,7 @@ static void visual_init(struct vc_data *vc, int num, int init) | |||
742 | vc->vc_hi_font_mask = 0; | 750 | vc->vc_hi_font_mask = 0; |
743 | vc->vc_complement_mask = 0; | 751 | vc->vc_complement_mask = 0; |
744 | vc->vc_can_do_color = 0; | 752 | vc->vc_can_do_color = 0; |
753 | vc->vc_panic_force_write = false; | ||
745 | vc->vc_sw->con_init(vc, init); | 754 | vc->vc_sw->con_init(vc, init); |
746 | if (!vc->vc_complement_mask) | 755 | if (!vc->vc_complement_mask) |
747 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; | 756 | vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800; |
@@ -774,6 +783,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ | |||
774 | if (!vc) | 783 | if (!vc) |
775 | return -ENOMEM; | 784 | return -ENOMEM; |
776 | vc_cons[currcons].d = vc; | 785 | vc_cons[currcons].d = vc; |
786 | tty_port_init(&vc->port); | ||
777 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 787 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
778 | visual_init(vc, currcons, 1); | 788 | visual_init(vc, currcons, 1); |
779 | if (!*vc->vc_uni_pagedir_loc) | 789 | if (!*vc->vc_uni_pagedir_loc) |
@@ -963,12 +973,12 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, | |||
963 | * Resize a virtual console as seen from the console end of things. We | 973 | * Resize a virtual console as seen from the console end of things. We |
964 | * use the common vc_do_resize methods to update the structures. The | 974 | * use the common vc_do_resize methods to update the structures. The |
965 | * caller must hold the console sem to protect console internals and | 975 | * caller must hold the console sem to protect console internals and |
966 | * vc->vc_tty | 976 | * vc->port.tty |
967 | */ | 977 | */ |
968 | 978 | ||
969 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) | 979 | int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) |
970 | { | 980 | { |
971 | return vc_do_resize(vc->vc_tty, vc, cols, rows); | 981 | return vc_do_resize(vc->port.tty, vc, cols, rows); |
972 | } | 982 | } |
973 | 983 | ||
974 | /** | 984 | /** |
@@ -1796,8 +1806,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c) | |||
1796 | vc->vc_state = ESnormal; | 1806 | vc->vc_state = ESnormal; |
1797 | return; | 1807 | return; |
1798 | case ESpalette: | 1808 | case ESpalette: |
1799 | if ( (c>='0'&&c<='9') || (c>='A'&&c<='F') || (c>='a'&&c<='f') ) { | 1809 | if (isxdigit(c)) { |
1800 | vc->vc_par[vc->vc_npar++] = (c > '9' ? (c & 0xDF) - 'A' + 10 : c - '0'); | 1810 | vc->vc_par[vc->vc_npar++] = hex_to_bin(c); |
1801 | if (vc->vc_npar == 7) { | 1811 | if (vc->vc_npar == 7) { |
1802 | int i = vc->vc_par[0] * 3, j = 1; | 1812 | int i = vc->vc_par[0] * 3, j = 1; |
1803 | vc->vc_palette[i] = 16 * vc->vc_par[j++]; | 1813 | vc->vc_palette[i] = 16 * vc->vc_par[j++]; |
@@ -2505,7 +2515,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2505 | goto quit; | 2515 | goto quit; |
2506 | } | 2516 | } |
2507 | 2517 | ||
2508 | if (vc->vc_mode != KD_TEXT) | 2518 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) |
2509 | goto quit; | 2519 | goto quit; |
2510 | 2520 | ||
2511 | /* undraw cursor first */ | 2521 | /* undraw cursor first */ |
@@ -2611,8 +2621,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2611 | return -EFAULT; | 2621 | return -EFAULT; |
2612 | ret = 0; | 2622 | ret = 0; |
2613 | 2623 | ||
2614 | lock_kernel(); | ||
2615 | |||
2616 | switch (type) | 2624 | switch (type) |
2617 | { | 2625 | { |
2618 | case TIOCL_SETSEL: | 2626 | case TIOCL_SETSEL: |
@@ -2687,7 +2695,6 @@ int tioclinux(struct tty_struct *tty, unsigned long arg) | |||
2687 | ret = -EINVAL; | 2695 | ret = -EINVAL; |
2688 | break; | 2696 | break; |
2689 | } | 2697 | } |
2690 | unlock_kernel(); | ||
2691 | return ret; | 2698 | return ret; |
2692 | } | 2699 | } |
2693 | 2700 | ||
@@ -2800,12 +2807,12 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2800 | struct vc_data *vc = vc_cons[currcons].d; | 2807 | struct vc_data *vc = vc_cons[currcons].d; |
2801 | 2808 | ||
2802 | /* Still being freed */ | 2809 | /* Still being freed */ |
2803 | if (vc->vc_tty) { | 2810 | if (vc->port.tty) { |
2804 | release_console_sem(); | 2811 | release_console_sem(); |
2805 | return -ERESTARTSYS; | 2812 | return -ERESTARTSYS; |
2806 | } | 2813 | } |
2807 | tty->driver_data = vc; | 2814 | tty->driver_data = vc; |
2808 | vc->vc_tty = tty; | 2815 | vc->port.tty = tty; |
2809 | 2816 | ||
2810 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { | 2817 | if (!tty->winsize.ws_row && !tty->winsize.ws_col) { |
2811 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; | 2818 | tty->winsize.ws_row = vc_cons[currcons].d->vc_rows; |
@@ -2833,7 +2840,7 @@ static void con_shutdown(struct tty_struct *tty) | |||
2833 | struct vc_data *vc = tty->driver_data; | 2840 | struct vc_data *vc = tty->driver_data; |
2834 | BUG_ON(vc == NULL); | 2841 | BUG_ON(vc == NULL); |
2835 | acquire_console_sem(); | 2842 | acquire_console_sem(); |
2836 | vc->vc_tty = NULL; | 2843 | vc->port.tty = NULL; |
2837 | release_console_sem(); | 2844 | release_console_sem(); |
2838 | tty_shutdown(tty); | 2845 | tty_shutdown(tty); |
2839 | } | 2846 | } |
@@ -2915,6 +2922,7 @@ static int __init con_init(void) | |||
2915 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { | 2922 | for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) { |
2916 | vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); | 2923 | vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT); |
2917 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); | 2924 | INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); |
2925 | tty_port_init(&vc->port); | ||
2918 | visual_init(vc, currcons, 1); | 2926 | visual_init(vc, currcons, 1); |
2919 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); | 2927 | vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT); |
2920 | vc_init(vc, vc->vc_rows, vc->vc_cols, | 2928 | vc_init(vc, vc->vc_rows, vc->vc_cols, |
@@ -3783,7 +3791,8 @@ void do_unblank_screen(int leaving_gfx) | |||
3783 | return; | 3791 | return; |
3784 | } | 3792 | } |
3785 | vc = vc_cons[fg_console].d; | 3793 | vc = vc_cons[fg_console].d; |
3786 | if (vc->vc_mode != KD_TEXT) | 3794 | /* Try to unblank in oops case too */ |
3795 | if (vc->vc_mode != KD_TEXT && !vt_force_oops_output(vc)) | ||
3787 | return; /* but leave console_blanked != 0 */ | 3796 | return; /* but leave console_blanked != 0 */ |
3788 | 3797 | ||
3789 | if (blankinterval) { | 3798 | if (blankinterval) { |
@@ -3792,7 +3801,7 @@ void do_unblank_screen(int leaving_gfx) | |||
3792 | } | 3801 | } |
3793 | 3802 | ||
3794 | console_blanked = 0; | 3803 | console_blanked = 0; |
3795 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx)) | 3804 | if (vc->vc_sw->con_blank(vc, 0, leaving_gfx) || vt_force_oops_output(vc)) |
3796 | /* Low-level driver cannot restore -> do it ourselves */ | 3805 | /* Low-level driver cannot restore -> do it ourselves */ |
3797 | update_screen(vc); | 3806 | update_screen(vc); |
3798 | if (console_blank_hook) | 3807 | if (console_blank_hook) |