提交 d1baa4ff 编写于 作者: A Antonino A. Daplas 提交者: Linus Torvalds

fbcon: set_con2fb_map fixes

set_con2fb_map() has regressed for some time.  Using fbcon=map:01, for
example, works only if there is only 1 working framebuffer. Trying to do a
set_con2fb_map() on a non-allocated vc will freeze the system.

- ensure that succeeding drivers after the first gets mapped to the console
- remove fbcon_preset_display() and modify fbcon_set_display() to include the
  former's functionality
- ensure that binding and unbinding succeeds if multiple drivers are mapped to
  the console
Signed-off-by: NAntonino Daplas <adaplas@gmail.com>
Signed-off-by: NAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: NLinus Torvalds <torvalds@linux-foundation.org>
上级 2f7bb99f
...@@ -192,9 +192,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count); ...@@ -192,9 +192,7 @@ static __inline__ void ypan_down(struct vc_data *vc, int count);
static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx, static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int sx,
int dy, int dx, int height, int width, u_int y_break); int dy, int dx, int height, int width, u_int y_break);
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
struct vc_data *vc); int unit);
static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
int unit);
static void fbcon_redraw_move(struct vc_data *vc, struct display *p, static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
int line, int count, int dy); int line, int count, int dy);
static void fbcon_modechanged(struct fb_info *info); static void fbcon_modechanged(struct fb_info *info);
...@@ -745,7 +743,9 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info, ...@@ -745,7 +743,9 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
if (!err) { if (!err) {
info->fbcon_par = ops; info->fbcon_par = ops;
set_blitting_type(vc, info);
if (vc)
set_blitting_type(vc, info);
} }
if (err) { if (err) {
...@@ -807,11 +807,7 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info, ...@@ -807,11 +807,7 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
ops->flags |= FBCON_FLAGS_INIT; ops->flags |= FBCON_FLAGS_INIT;
ops->graphics = 0; ops->graphics = 0;
fbcon_set_disp(info, &info->var, unit);
if (vc)
fbcon_set_disp(info, &info->var, vc);
else
fbcon_preset_disp(info, &info->var, unit);
if (show_logo) { if (show_logo) {
struct vc_data *fg_vc = vc_cons[fg_console].d; struct vc_data *fg_vc = vc_cons[fg_console].d;
...@@ -1116,6 +1112,9 @@ static void fbcon_init(struct vc_data *vc, int init) ...@@ -1116,6 +1112,9 @@ static void fbcon_init(struct vc_data *vc, int init)
if (var_to_display(p, &info->var, info)) if (var_to_display(p, &info->var, info))
return; return;
if (!info->fbcon_par)
con2fb_acquire_newinfo(vc, info, vc->vc_num, -1);
/* If we are not the first console on this /* If we are not the first console on this
fb, copy the font from that console */ fb, copy the font from that console */
t = &fb_display[fg_console]; t = &fb_display[fg_console];
...@@ -1382,36 +1381,29 @@ static int scrollback_phys_max = 0; ...@@ -1382,36 +1381,29 @@ static int scrollback_phys_max = 0;
static int scrollback_max = 0; static int scrollback_max = 0;
static int scrollback_current = 0; static int scrollback_current = 0;
/*
* If no vc is existent yet, just set struct display
*/
static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
int unit)
{
struct display *p = &fb_display[unit];
struct display *t = &fb_display[fg_console];
if (var_to_display(p, var, info))
return;
p->fontdata = t->fontdata;
p->userfont = t->userfont;
if (p->userfont)
REFCOUNT(p->fontdata)++;
}
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var, static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
struct vc_data *vc) int unit)
{ {
struct display *p = &fb_display[vc->vc_num], *t; struct display *p, *t;
struct vc_data **default_mode = vc->vc_display_fg; struct vc_data **default_mode, *vc;
struct vc_data *svc = *default_mode; struct vc_data *svc;
struct fbcon_ops *ops = info->fbcon_par; struct fbcon_ops *ops = info->fbcon_par;
int rows, cols, charcnt = 256; int rows, cols, charcnt = 256;
p = &fb_display[unit];
if (var_to_display(p, var, info)) if (var_to_display(p, var, info))
return; return;
vc = vc_cons[unit].d;
if (!vc)
return;
default_mode = vc->vc_display_fg;
svc = *default_mode;
t = &fb_display[svc->vc_num]; t = &fb_display[svc->vc_num];
if (!vc->vc_font.data) { if (!vc->vc_font.data) {
vc->vc_font.data = (void *)(p->fontdata = t->fontdata); vc->vc_font.data = (void *)(p->fontdata = t->fontdata);
vc->vc_font.width = (*default_mode)->vc_font.width; vc->vc_font.width = (*default_mode)->vc_font.width;
...@@ -3118,8 +3110,7 @@ static int fbcon_fb_registered(struct fb_info *info) ...@@ -3118,8 +3110,7 @@ static int fbcon_fb_registered(struct fb_info *info)
ret = fbcon_takeover(1); ret = fbcon_takeover(1);
} else { } else {
for (i = first_fb_vc; i <= last_fb_vc; i++) { for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map_boot[i] == idx && if (con2fb_map_boot[i] == idx)
con2fb_map[i] == -1)
set_con2fb_map(i, idx, 0); set_con2fb_map(i, idx, 0);
} }
} }
...@@ -3167,12 +3158,7 @@ static void fbcon_new_modelist(struct fb_info *info) ...@@ -3167,12 +3158,7 @@ static void fbcon_new_modelist(struct fb_info *info)
mode = fb_find_nearest_mode(fb_display[i].mode, mode = fb_find_nearest_mode(fb_display[i].mode,
&info->modelist); &info->modelist);
fb_videomode_to_var(&var, mode); fb_videomode_to_var(&var, mode);
fbcon_set_disp(info, &var, vc->vc_num);
if (vc)
fbcon_set_disp(info, &var, vc);
else
fbcon_preset_disp(info, &var, i);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册