| From 50145474f6ef4a9c19205b173da6264a644c7489 Mon Sep 17 00:00:00 2001 |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| Date: Mon, 7 Sep 2020 11:45:27 -0700 |
| Subject: fbcon: remove soft scrollback code |
| |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| commit 50145474f6ef4a9c19205b173da6264a644c7489 upstream. |
| |
| This (and the VGA soft scrollback) turns out to have various nasty small |
| special cases that nobody really is willing to fight. The soft |
| scrollback code was really useful a few decades ago when you typically |
| used the console interactively as the main way to interact with the |
| machine, but that just isn't the case any more. |
| |
| So it's not worth dragging along. |
| |
| Tested-by: Yuan Ming <yuanmingbuaa@gmail.com> |
| Tested-by: Willy Tarreau <w@1wt.eu> |
| Acked-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> |
| Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/video/console/fbcon.c | 336 ------------------------------------------ |
| 1 file changed, 4 insertions(+), 332 deletions(-) |
| |
| --- a/drivers/video/console/fbcon.c |
| +++ b/drivers/video/console/fbcon.c |
| @@ -101,12 +101,6 @@ static int logo_lines; |
| /* logo_shown is an index to vc_cons when >= 0; otherwise follows FBCON_LOGO |
| enums. */ |
| static int logo_shown = FBCON_LOGO_CANSHOW; |
| -/* Software scrollback */ |
| -static int fbcon_softback_size = 32768; |
| -static unsigned long softback_buf, softback_curr; |
| -static unsigned long softback_in; |
| -static unsigned long softback_top, softback_end; |
| -static int softback_lines; |
| /* console mappings */ |
| static int first_fb_vc; |
| static int last_fb_vc = MAX_NR_CONSOLES - 1; |
| @@ -140,8 +134,6 @@ static int fbcon_has_sysfs; |
| |
| static const struct consw fb_con; |
| |
| -#define CM_SOFTBACK (8) |
| - |
| #define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row) |
| |
| static int fbcon_set_origin(struct vc_data *); |
| @@ -171,7 +163,6 @@ static void fbcon_bmove(struct vc_data * |
| static int fbcon_switch(struct vc_data *vc); |
| static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch); |
| static int fbcon_set_palette(struct vc_data *vc, unsigned char *table); |
| -static int fbcon_scrolldelta(struct vc_data *vc, int lines); |
| |
| /* |
| * Internal routines |
| @@ -350,18 +341,6 @@ static int get_color(struct vc_data *vc, |
| return color; |
| } |
| |
| -static void fbcon_update_softback(struct vc_data *vc) |
| -{ |
| - int l = fbcon_softback_size / vc->vc_size_row; |
| - |
| - if (l > 5) |
| - softback_end = softback_buf + l * vc->vc_size_row; |
| - else |
| - /* Smaller scrollback makes no sense, and 0 would screw |
| - the operation totally */ |
| - softback_top = 0; |
| -} |
| - |
| static void fb_flashcursor(struct work_struct *work) |
| { |
| struct fb_info *info = container_of(work, struct fb_info, queue); |
| @@ -391,7 +370,7 @@ static void fb_flashcursor(struct work_s |
| c = scr_readw((u16 *) vc->vc_pos); |
| mode = (!ops->cursor_flash || ops->cursor_state.enable) ? |
| CM_ERASE : CM_DRAW; |
| - ops->cursor(vc, info, mode, softback_lines, get_color(vc, info, c, 1), |
| + ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1), |
| get_color(vc, info, c, 0)); |
| console_unlock(); |
| } |
| @@ -451,13 +430,7 @@ static int __init fb_console_setup(char |
| } |
| |
| if (!strncmp(options, "scrollback:", 11)) { |
| - options += 11; |
| - if (*options) { |
| - fbcon_softback_size = simple_strtoul(options, &options, 0); |
| - if (*options == 'k' || *options == 'K') { |
| - fbcon_softback_size *= 1024; |
| - } |
| - } |
| + pr_warn("Ignoring scrollback size option\n"); |
| continue; |
| } |
| |
| @@ -962,31 +935,6 @@ static const char *fbcon_startup(void) |
| p->con_rotate = initial_rotation; |
| set_blitting_type(vc, info); |
| |
| - if (info->fix.type != FB_TYPE_TEXT) { |
| - if (fbcon_softback_size) { |
| - if (!softback_buf) { |
| - softback_buf = |
| - (unsigned long) |
| - kmalloc(fbcon_softback_size, |
| - GFP_KERNEL); |
| - if (!softback_buf) { |
| - fbcon_softback_size = 0; |
| - softback_top = 0; |
| - } |
| - } |
| - } else { |
| - if (softback_buf) { |
| - kfree((void *) softback_buf); |
| - softback_buf = 0; |
| - softback_top = 0; |
| - } |
| - } |
| - if (softback_buf) |
| - softback_in = softback_top = softback_curr = |
| - softback_buf; |
| - softback_lines = 0; |
| - } |
| - |
| /* Setup default font */ |
| if (!p->fontdata && !vc->vc_font.data) { |
| if (!fontname[0] || !(font = find_font(fontname))) |
| @@ -1149,9 +1097,6 @@ static void fbcon_init(struct vc_data *v |
| if (logo) |
| fbcon_prepare_logo(vc, info, cols, rows, new_cols, new_rows); |
| |
| - if (vc == svc && softback_buf) |
| - fbcon_update_softback(vc); |
| - |
| if (ops->rotate_font && ops->rotate_font(info, vc)) { |
| ops->rotate = FB_ROTATE_UR; |
| set_blitting_type(vc, info); |
| @@ -1311,7 +1256,6 @@ static void fbcon_cursor(struct vc_data |
| { |
| struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
| struct fbcon_ops *ops = info->fbcon_par; |
| - int y; |
| int c = scr_readw((u16 *) vc->vc_pos); |
| |
| ops->cur_blink_jiffies = msecs_to_jiffies(vc->vc_cur_blink_ms); |
| @@ -1325,16 +1269,8 @@ static void fbcon_cursor(struct vc_data |
| fbcon_add_cursor_timer(info); |
| |
| ops->cursor_flash = (mode == CM_ERASE) ? 0 : 1; |
| - if (mode & CM_SOFTBACK) { |
| - mode &= ~CM_SOFTBACK; |
| - y = softback_lines; |
| - } else { |
| - if (softback_lines) |
| - fbcon_set_origin(vc); |
| - y = 0; |
| - } |
| |
| - ops->cursor(vc, info, mode, y, get_color(vc, info, c, 1), |
| + ops->cursor(vc, info, mode, 0, get_color(vc, info, c, 1), |
| get_color(vc, info, c, 0)); |
| } |
| |
| @@ -1405,8 +1341,6 @@ static void fbcon_set_disp(struct fb_inf |
| |
| if (CON_IS_VISIBLE(vc)) { |
| update_screen(vc); |
| - if (softback_buf) |
| - fbcon_update_softback(vc); |
| } |
| } |
| |
| @@ -1544,99 +1478,6 @@ static __inline__ void ypan_down_redraw( |
| scrollback_current = 0; |
| } |
| |
| -static void fbcon_redraw_softback(struct vc_data *vc, struct display *p, |
| - long delta) |
| -{ |
| - int count = vc->vc_rows; |
| - unsigned short *d, *s; |
| - unsigned long n; |
| - int line = 0; |
| - |
| - d = (u16 *) softback_curr; |
| - if (d == (u16 *) softback_in) |
| - d = (u16 *) vc->vc_origin; |
| - n = softback_curr + delta * vc->vc_size_row; |
| - softback_lines -= delta; |
| - if (delta < 0) { |
| - if (softback_curr < softback_top && n < softback_buf) { |
| - n += softback_end - softback_buf; |
| - if (n < softback_top) { |
| - softback_lines -= |
| - (softback_top - n) / vc->vc_size_row; |
| - n = softback_top; |
| - } |
| - } else if (softback_curr >= softback_top |
| - && n < softback_top) { |
| - softback_lines -= |
| - (softback_top - n) / vc->vc_size_row; |
| - n = softback_top; |
| - } |
| - } else { |
| - if (softback_curr > softback_in && n >= softback_end) { |
| - n += softback_buf - softback_end; |
| - if (n > softback_in) { |
| - n = softback_in; |
| - softback_lines = 0; |
| - } |
| - } else if (softback_curr <= softback_in && n > softback_in) { |
| - n = softback_in; |
| - softback_lines = 0; |
| - } |
| - } |
| - if (n == softback_curr) |
| - return; |
| - softback_curr = n; |
| - s = (u16 *) softback_curr; |
| - if (s == (u16 *) softback_in) |
| - s = (u16 *) vc->vc_origin; |
| - while (count--) { |
| - unsigned short *start; |
| - unsigned short *le; |
| - unsigned short c; |
| - int x = 0; |
| - unsigned short attr = 1; |
| - |
| - start = s; |
| - le = advance_row(s, 1); |
| - do { |
| - c = scr_readw(s); |
| - if (attr != (c & 0xff00)) { |
| - attr = c & 0xff00; |
| - if (s > start) { |
| - fbcon_putcs(vc, start, s - start, |
| - line, x); |
| - x += s - start; |
| - start = s; |
| - } |
| - } |
| - if (c == scr_readw(d)) { |
| - if (s > start) { |
| - fbcon_putcs(vc, start, s - start, |
| - line, x); |
| - x += s - start + 1; |
| - start = s + 1; |
| - } else { |
| - x++; |
| - start++; |
| - } |
| - } |
| - s++; |
| - d++; |
| - } while (s < le); |
| - if (s > start) |
| - fbcon_putcs(vc, start, s - start, line, x); |
| - line++; |
| - if (d == (u16 *) softback_end) |
| - d = (u16 *) softback_buf; |
| - if (d == (u16 *) softback_in) |
| - d = (u16 *) vc->vc_origin; |
| - if (s == (u16 *) softback_end) |
| - s = (u16 *) softback_buf; |
| - if (s == (u16 *) softback_in) |
| - s = (u16 *) vc->vc_origin; |
| - } |
| -} |
| - |
| static void fbcon_redraw_move(struct vc_data *vc, struct display *p, |
| int line, int count, int dy) |
| { |
| @@ -1776,31 +1617,6 @@ static void fbcon_redraw(struct vc_data |
| } |
| } |
| |
| -static inline void fbcon_softback_note(struct vc_data *vc, int t, |
| - int count) |
| -{ |
| - unsigned short *p; |
| - |
| - if (vc->vc_num != fg_console) |
| - return; |
| - p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row); |
| - |
| - while (count) { |
| - scr_memcpyw((u16 *) softback_in, p, vc->vc_size_row); |
| - count--; |
| - p = advance_row(p, 1); |
| - softback_in += vc->vc_size_row; |
| - if (softback_in == softback_end) |
| - softback_in = softback_buf; |
| - if (softback_in == softback_top) { |
| - softback_top += vc->vc_size_row; |
| - if (softback_top == softback_end) |
| - softback_top = softback_buf; |
| - } |
| - } |
| - softback_curr = softback_in; |
| -} |
| - |
| static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, |
| int count) |
| { |
| @@ -1823,8 +1639,6 @@ static int fbcon_scroll(struct vc_data * |
| case SM_UP: |
| if (count > vc->vc_rows) /* Maximum realistic size */ |
| count = vc->vc_rows; |
| - if (softback_top) |
| - fbcon_softback_note(vc, t, count); |
| if (logo_shown >= 0) |
| goto redraw_up; |
| switch (p->scrollmode) { |
| @@ -2195,14 +2009,6 @@ static int fbcon_switch(struct vc_data * |
| info = registered_fb[con2fb_map[vc->vc_num]]; |
| ops = info->fbcon_par; |
| |
| - if (softback_top) { |
| - if (softback_lines) |
| - fbcon_set_origin(vc); |
| - softback_top = softback_curr = softback_in = softback_buf; |
| - softback_lines = 0; |
| - fbcon_update_softback(vc); |
| - } |
| - |
| if (logo_shown >= 0) { |
| struct vc_data *conp2 = vc_cons[logo_shown].d; |
| |
| @@ -2536,9 +2342,6 @@ static int fbcon_do_set_font(struct vc_d |
| int cnt; |
| char *old_data = NULL; |
| |
| - if (CON_IS_VISIBLE(vc) && softback_lines) |
| - fbcon_set_origin(vc); |
| - |
| resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); |
| if (p->userfont) |
| old_data = vc->vc_font.data; |
| @@ -2564,8 +2367,6 @@ static int fbcon_do_set_font(struct vc_d |
| cols /= w; |
| rows /= h; |
| vc_resize(vc, cols, rows); |
| - if (CON_IS_VISIBLE(vc) && softback_buf) |
| - fbcon_update_softback(vc); |
| } else if (CON_IS_VISIBLE(vc) |
| && vc->vc_mode == KD_TEXT) { |
| fbcon_clear_margins(vc, 0); |
| @@ -2723,19 +2524,7 @@ static int fbcon_set_palette(struct vc_d |
| |
| static u16 *fbcon_screen_pos(struct vc_data *vc, int offset) |
| { |
| - unsigned long p; |
| - int line; |
| - |
| - if (vc->vc_num != fg_console || !softback_lines) |
| - return (u16 *) (vc->vc_origin + offset); |
| - line = offset / vc->vc_size_row; |
| - if (line >= softback_lines) |
| - return (u16 *) (vc->vc_origin + offset - |
| - softback_lines * vc->vc_size_row); |
| - p = softback_curr + offset; |
| - if (p >= softback_end) |
| - p += softback_buf - softback_end; |
| - return (u16 *) p; |
| + return (u16 *) (vc->vc_origin + offset); |
| } |
| |
| static unsigned long fbcon_getxy(struct vc_data *vc, unsigned long pos, |
| @@ -2749,22 +2538,7 @@ static unsigned long fbcon_getxy(struct |
| |
| x = offset % vc->vc_cols; |
| y = offset / vc->vc_cols; |
| - if (vc->vc_num == fg_console) |
| - y += softback_lines; |
| ret = pos + (vc->vc_cols - x) * 2; |
| - } else if (vc->vc_num == fg_console && softback_lines) { |
| - unsigned long offset = pos - softback_curr; |
| - |
| - if (pos < softback_curr) |
| - offset += softback_end - softback_buf; |
| - offset /= 2; |
| - x = offset % vc->vc_cols; |
| - y = offset / vc->vc_cols; |
| - ret = pos + (vc->vc_cols - x) * 2; |
| - if (ret == softback_end) |
| - ret = softback_buf; |
| - if (ret == softback_in) |
| - ret = vc->vc_origin; |
| } else { |
| /* Should not happen */ |
| x = y = 0; |
| @@ -2792,107 +2566,11 @@ static void fbcon_invert_region(struct v |
| a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | |
| (((a) & 0x0700) << 4); |
| scr_writew(a, p++); |
| - if (p == (u16 *) softback_end) |
| - p = (u16 *) softback_buf; |
| - if (p == (u16 *) softback_in) |
| - p = (u16 *) vc->vc_origin; |
| } |
| } |
| |
| -static int fbcon_scrolldelta(struct vc_data *vc, int lines) |
| -{ |
| - struct fb_info *info = registered_fb[con2fb_map[fg_console]]; |
| - struct fbcon_ops *ops = info->fbcon_par; |
| - struct display *disp = &fb_display[fg_console]; |
| - int offset, limit, scrollback_old; |
| - |
| - if (softback_top) { |
| - if (vc->vc_num != fg_console) |
| - return 0; |
| - if (vc->vc_mode != KD_TEXT || !lines) |
| - return 0; |
| - if (logo_shown >= 0) { |
| - struct vc_data *conp2 = vc_cons[logo_shown].d; |
| - |
| - if (conp2->vc_top == logo_lines |
| - && conp2->vc_bottom == conp2->vc_rows) |
| - conp2->vc_top = 0; |
| - if (logo_shown == vc->vc_num) { |
| - unsigned long p, q; |
| - int i; |
| - |
| - p = softback_in; |
| - q = vc->vc_origin + |
| - logo_lines * vc->vc_size_row; |
| - for (i = 0; i < logo_lines; i++) { |
| - if (p == softback_top) |
| - break; |
| - if (p == softback_buf) |
| - p = softback_end; |
| - p -= vc->vc_size_row; |
| - q -= vc->vc_size_row; |
| - scr_memcpyw((u16 *) q, (u16 *) p, |
| - vc->vc_size_row); |
| - } |
| - softback_in = softback_curr = p; |
| - update_region(vc, vc->vc_origin, |
| - logo_lines * vc->vc_cols); |
| - } |
| - logo_shown = FBCON_LOGO_CANSHOW; |
| - } |
| - fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); |
| - fbcon_redraw_softback(vc, disp, lines); |
| - fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); |
| - return 0; |
| - } |
| - |
| - if (!scrollback_phys_max) |
| - return -ENOSYS; |
| - |
| - scrollback_old = scrollback_current; |
| - scrollback_current -= lines; |
| - if (scrollback_current < 0) |
| - scrollback_current = 0; |
| - else if (scrollback_current > scrollback_max) |
| - scrollback_current = scrollback_max; |
| - if (scrollback_current == scrollback_old) |
| - return 0; |
| - |
| - if (fbcon_is_inactive(vc, info)) |
| - return 0; |
| - |
| - fbcon_cursor(vc, CM_ERASE); |
| - |
| - offset = disp->yscroll - scrollback_current; |
| - limit = disp->vrows; |
| - switch (disp->scrollmode) { |
| - case SCROLL_WRAP_MOVE: |
| - info->var.vmode |= FB_VMODE_YWRAP; |
| - break; |
| - case SCROLL_PAN_MOVE: |
| - case SCROLL_PAN_REDRAW: |
| - limit -= vc->vc_rows; |
| - info->var.vmode &= ~FB_VMODE_YWRAP; |
| - break; |
| - } |
| - if (offset < 0) |
| - offset += limit; |
| - else if (offset >= limit) |
| - offset -= limit; |
| - |
| - ops->var.xoffset = 0; |
| - ops->var.yoffset = offset * vc->vc_font.height; |
| - ops->update_start(info); |
| - |
| - if (!scrollback_current) |
| - fbcon_cursor(vc, CM_DRAW); |
| - return 0; |
| -} |
| - |
| static int fbcon_set_origin(struct vc_data *vc) |
| { |
| - if (softback_lines) |
| - fbcon_scrolldelta(vc, softback_lines); |
| return 0; |
| } |
| |
| @@ -2956,8 +2634,6 @@ static void fbcon_modechanged(struct fb_ |
| |
| fbcon_set_palette(vc, color_table); |
| update_screen(vc); |
| - if (softback_buf) |
| - fbcon_update_softback(vc); |
| } |
| } |
| |
| @@ -3378,7 +3054,6 @@ static const struct consw fb_con = { |
| .con_font_default = fbcon_set_def_font, |
| .con_font_copy = fbcon_copy_font, |
| .con_set_palette = fbcon_set_palette, |
| - .con_scrolldelta = fbcon_scrolldelta, |
| .con_set_origin = fbcon_set_origin, |
| .con_invert_region = fbcon_invert_region, |
| .con_screen_pos = fbcon_screen_pos, |
| @@ -3587,9 +3262,6 @@ static void fbcon_exit(void) |
| if (fbcon_has_exited) |
| return; |
| |
| - kfree((void *)softback_buf); |
| - softback_buf = 0UL; |
| - |
| for (i = 0; i < FB_MAX; i++) { |
| int pending = 0; |
| |