From: "Antonino A. Daplas" The frambuffer console is still writing to the graphics hardware even if the hardware is not owned anymore by the console. This can lead to crashes with some hardware. A trace of the source indicates that it comes from almost anywhere, anytime. The fix is to return immediately if vc_mode != KD_TEXT. The test is placed in the following functions if not already present. fbcon_cursor() fbcon_putcs() fbcon_clear() fbcon_bmove() fbcon_blank() Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton --- 25-akpm/drivers/video/console/fbcon.c | 29 +++++++++++++++++++---------- 1 files changed, 19 insertions(+), 10 deletions(-) diff -puN drivers/video/console/fbcon.c~fbcon-do-not-touch-hardware-if-vc_mode-=-kd_text drivers/video/console/fbcon.c --- 25/drivers/video/console/fbcon.c~fbcon-do-not-touch-hardware-if-vc_mode-=-kd_text Wed Nov 3 15:18:42 2004 +++ 25-akpm/drivers/video/console/fbcon.c Wed Nov 3 15:18:42 2004 @@ -983,6 +983,9 @@ static void fbcon_clear(struct vc_data * if (info->state != FBINFO_STATE_RUNNING) return; + if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) + return; + if (!height || !width) return; @@ -1007,6 +1010,7 @@ static void fbcon_putcs(struct vc_data * if (!info->fbops->fb_blank && console_blanked) return; + if (info->state != FBINFO_STATE_RUNNING) return; @@ -1042,6 +1046,9 @@ static void fbcon_cursor(struct vc_data int y = real_y(p, vc->vc_y); int c = scr_readw((u16 *) vc->vc_pos); + if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) + return; + ops->cursor_flash = 1; if (mode & CM_SOFTBACK) { mode &= ~CM_SOFTBACK; @@ -1690,6 +1697,9 @@ static void fbcon_bmove(struct vc_data * if (!info->fbops->fb_blank && console_blanked) return; + if (vt_cons[vc->vc_num]->vc_mode != KD_TEXT) + return; + if (!width || !height) return; @@ -1952,6 +1962,7 @@ static int fbcon_blank(struct vc_data *v struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct fbcon_ops *ops = (struct fbcon_ops *) info->fbcon_par; struct display *p = &fb_display[vc->vc_num]; + int retval = 0; if (mode_switch) { struct fb_var_screeninfo var = info->var; @@ -1968,19 +1979,16 @@ static int fbcon_blank(struct vc_data *v if (info->flags & FBINFO_MISC_MODESWITCHLATE) info->flags |= FBINFO_MISC_MODESWITCH; - if (blank) { - fbcon_cursor(vc, CM_ERASE); - return 0; - } - - if (!(info->flags & FBINFO_MISC_MODESWITCHLATE)) { + if (!blank && !(info->flags & FBINFO_MISC_MODESWITCHLATE)) { var.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE; fb_set_var(info, &var); } + + return 0; } - fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); ops->cursor_flash = (!blank); + fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW); if (!info->fbops->fb_blank) { if (blank) { @@ -2001,9 +2009,10 @@ static int fbcon_blank(struct vc_data *v vc->vc_video_erase_char = oldc; } else update_screen(vc->vc_num); - return 0; - } else - return fb_blank(info, blank); + } else if (vt_cons[vc->vc_num]->vc_mode == KD_TEXT) + retval = fb_blank(info, blank); + + return retval; } static void fbcon_free_font(struct display *p) _