Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1baa4ff authored by Antonino A. Daplas's avatar Antonino A. Daplas Committed by Linus Torvalds
Browse files

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: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 2f7bb99f
Loading
Loading
Loading
Loading
+25 −39
Original line number Original line Diff line number Diff line
@@ -192,8 +192,6 @@ 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);
static void fbcon_preset_disp(struct fb_info *info, struct fb_var_screeninfo *var,
			   int unit);
			   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);
@@ -745,6 +743,8 @@ 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;

		if (vc)
			set_blitting_type(vc, info);
			set_blitting_type(vc, 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)
	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;
static int scrollback_max = 0;
static int scrollback_max = 0;
static int scrollback_current = 0;
static int scrollback_current = 0;


/*
static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
 * 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)
			   int unit)
{
{
	struct display *p = &fb_display[unit];
	struct display *p, *t;
	struct display *t = &fb_display[fg_console];
	struct vc_data **default_mode, *vc;
	struct vc_data *svc;
	struct fbcon_ops *ops = info->fbcon_par;
	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;


	p->fontdata = t->fontdata;
	vc = vc_cons[unit].d;
	p->userfont = t->userfont;
	if (p->userfont)
		REFCOUNT(p->fontdata)++;
}

static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
			   struct vc_data *vc)
{
	struct display *p = &fb_display[vc->vc_num], *t;
	struct vc_data **default_mode = vc->vc_display_fg;
	struct vc_data *svc = *default_mode;
	struct fbcon_ops *ops = info->fbcon_par;
	int rows, cols, charcnt = 256;


	if (var_to_display(p, var, info))
	if (!vc)
		return;
		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)
			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)
		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);

	}
	}
}
}