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.c37
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.. */
289static inline void scrolldelta(int lines) 291static 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
969int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows) 979int 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)