
From: "Antonino A. Daplas" <adaplas@hotpop.com>

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 <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 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)
_
