Skip to contentSkip to conversation

vgacon: Workaround for resize bug in some chipsets

PATCH In review Antonino A. Daplas 3 participants 6 messages Nov 12, 2005 – Nov 13, 2005

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 vgacon: Workaround for resize bug in some chipsets

Reported from Redhat Bugzilla Bug 170450

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

I have a Silicon Graphics 1600sw LCD panel with a Number Nine Revolution 4 video card."

This bug seems to be a glitch in the VGA core of this chipset. Resizing the screen triggers the mentioned bug.

The workaround is to make vgacon avoid calling vgacon_doresize() if the display parameters did not change. It also has a nice side effect of faster console switches, but that will be barely noticeable.

Note that this bug may be triggered if the user changes the screen height with stty, or using another font with different dimensions.

A definitive fix will need to be provided by someone who knows and has the hardware.

This patch also converted hard-coded constants to a named constant (VGACON_FONTWIDTH).

---
 vgacon.c |   28 +++++++++++++++++++++-------
 1 files changed, 21 insertions(+), 7 deletions(-)
drivers/video/console/vgacon.c +21 -7
index 274f905..5ce8348 100644
@@ -56,6 +56,8 @@
 static DEFINE_SPINLOCK(vga_lock);
 static int cursor_size_lastfrom;
 static int cursor_size_lastto;
+static u32 vgacon_xres;
+static u32 vgacon_yres;
 static struct vgastate state;
 
 #define BLANK 0x0020
@@ -69,7 +71,7 @@ static struct vgastate state;
  * appear.
  */
 #undef TRIDENT_GLITCH
-
+#define VGA_FONTWIDTH       8   /* VGA does not support fontwidths != 8 */
 /*
  *  Interface used by the world
  */
@@ -325,6 +327,10 @@ static const char __init *vgacon_startup
 		vga_scan_lines =
 		    vga_video_font_height * vga_video_num_lines;
 	}
+
+	vgacon_xres = ORIG_VIDEO_COLS * VGA_FONTWIDTH;
+	vgacon_yres = vga_scan_lines;
+
 	return display_desc;
 }
 
@@ -507,6 +513,8 @@ static int vgacon_doresize(struct vc_dat
 
 	spin_lock_irqsave(&vga_lock, flags);
 
+	vgacon_xres = width * VGA_FONTWIDTH;
+	vgacon_yres = height * c->vc_font.height;
 	outb_p(VGA_CRTC_MODE, vga_video_port_reg);
 	mode = inb_p(vga_video_port_val);
 
@@ -551,6 +559,10 @@ static int vgacon_doresize(struct vc_dat
 
 static int vgacon_switch(struct vc_data *c)
 {
+	int x = c->vc_cols * VGA_FONTWIDTH;
+	int y = c->vc_rows * c->vc_font.height;
+	int rows = ORIG_VIDEO_LINES * vga_default_font_height/
+		c->vc_font.height;
 	/*
 	 * We need to save screen size here as it's the only way
 	 * we can spot the screen has been resized and we need to
@@ -566,10 +578,11 @@ static int vgacon_switch(struct vc_data 
 		scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf,
 			    c->vc_screenbuf_size > vga_vram_size ?
 				vga_vram_size : c->vc_screenbuf_size);
-		if (!(vga_video_num_columns % 2) &&
-		    vga_video_num_columns <= ORIG_VIDEO_COLS &&
-		    vga_video_num_lines <= (ORIG_VIDEO_LINES *
-			vga_default_font_height) / c->vc_font.height)
+
+		if ((vgacon_xres != x || vgacon_yres != y) &&
+		    (!(vga_video_num_columns % 2) &&
+		     vga_video_num_columns <= ORIG_VIDEO_COLS &&
+		     vga_video_num_lines <= rows))
 			vgacon_doresize(c, c->vc_cols, c->vc_rows);
 	}
 
@@ -992,7 +1005,8 @@ static int vgacon_font_set(struct vc_dat
 	if (vga_video_type < VIDEO_TYPE_EGAM)
 		return -EINVAL;
 
-	if (font->width != 8 || (charcount != 256 && charcount != 512))
+	if (font->width != VGA_FONTWIDTH ||
+	    (charcount != 256 && charcount != 512))
 		return -EINVAL;
 
 	rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512);
@@ -1009,7 +1023,7 @@ static int vgacon_font_get(struct vc_dat
 	if (vga_video_type < VIDEO_TYPE_EGAM)
 		return -EINVAL;
 
-	font->width = 8;
+	font->width = VGA_FONTWIDTH;
 	font->height = c->vc_font.height;
 	font->charcount = vga_512_chars ? 512 : 256;
 	if (!font->data)
#1 lore raw

Hello!

Quoted 18 lines

Reported from Redhat Bugzilla Bug 170450

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

I have a Silicon Graphics 1600sw LCD panel with a Number Nine Revolution 4 video card."

Quoted 6 lines

This bug seems to be a glitch in the VGA core of this chipset. Resizing the screen triggers the mentioned bug.

The workaround is to make vgacon avoid calling vgacon_doresize() if the display parameters did not change. It also has a nice side effect of faster console switches, but that will be barely noticeable.

This patch really deserves a comment in the code that such a broken hardware exists.

Also, I don't see much reasons for introducing VGA_FONTWIDTH, it seems to only complicate the code.

Have a nice fortnight

Signature · 3 lines
Martin `MJ' Mares   <[email protected]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
For every complex problem, there's a solution that is simple, neat and wrong.
#2 lore raw
In reply to Antonino A. Daplas
Quoted 4 lines · Antonino A. Daplas, le Sun 13 Nov 2005 06:20:53 +0800, a écrit :

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

Quoted 8 lines
| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

Are you missing some left and right part too? What are the dimensions of the text screen at bootup? What bootloader are you using? (It could be a bug in the boot up text screen dimension discovery).

Quoted 2 lines

I have a Silicon Graphics 1600sw LCD panel with a Number Nine Revolution 4 video card."

Does vgacon.c properly discovers that it is a VGA board?

Quoted 2 lines

This bug seems to be a glitch in the VGA core of this chipset. Resizing the screen triggers the mentioned bug.

Do vga-only games (like old DOS-mode games) work with it?

Quoted 2 lines

The workaround is to make vgacon avoid calling vgacon_doresize() if the display parameters did not change.

I.e. never call it, actually.

Quoted 2 lines

A definitive fix will need to be provided by someone who knows and has the hardware.

I'm not sure it is hardware-specific. Maybe you have a combination of vga bios/bootloader/vga=ask/... that prevents vgacon.c from properly discovering the dimensions of the text screen.

Well, else it looks like a "safe side" patch: people now hit by such bug won't be hit any more unless using stty or such.

Regards,
Samuel

#3 lore raw
Quoted 14 lines · Samuel Thibault
Quoted 4 lines · Antonino A. Daplas, le Sun 13 Nov 2005 06:20:53 +0800, a écrit :

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

Quoted 8 lines
| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

Quoted 3 lines

Are you missing some left and right part too? What are the dimensions of the text screen at bootup? What bootloader are you using? (It could be a bug in the boot up text screen dimension discovery).

It was just the height. All numbers (done with printk's) look okay from bootup. He gets 80 and 25 for ORIG_VIDEO_NUM_COLS and ORIG_VIDEO_NUM_LINES respectively.

Quoted 5 lines
Quoted 3 lines

I have a Silicon Graphics 1600sw LCD panel with a Number Nine Revolution 4 video card."

Does vgacon.c properly discovers that it is a VGA board?

Yes.

Quoted 9 lines
Quoted 3 lines

This bug seems to be a glitch in the VGA core of this chipset. Resizing the screen triggers the mentioned bug.

Do vga-only games (like old DOS-mode games) work with it?

Quoted 2 lines

The workaround is to make vgacon avoid calling vgacon_doresize() if the display parameters did not change.

Quoted 8 lines

I.e. never call it, actually.

Quoted 2 lines

A definitive fix will need to be provided by someone who knows and has the hardware.

I'm not sure it is hardware-specific. Maybe you have a combination of vga bios/bootloader/vga=ask/... that prevents vgacon.c from properly discovering the dimensions of the text screen.

His console worked before linux-2.6.14-rc2.

Tony

#4 lore raw
Quoted 15 lines · Antonino A. Daplas, le Sun 13 Nov 2005 22:33:18 +0800, a écrit :
Quoted 14 lines · Samuel Thibault
Quoted 12 lines · Antonino A. Daplas, le Sun 13 Nov 2005 06:20:53 +0800, a écrit :

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

Quoted 7 lines
Quoted 3 lines

Are you missing some left and right part too? What are the dimensions of the text screen at bootup? What bootloader are you using? (It could be a bug in the boot up text screen dimension discovery).

It was just the height. All numbers (done with printk's) look okay from bootup. He gets 80 and 25 for ORIG_VIDEO_NUM_COLS and ORIG_VIDEO_NUM_LINES respectively.

And you got less than 25 lines? How many exactly?

Regards,
Samuel

#5 lore raw
Quoted 15 lines · Samuel Thibault
Quoted 14 lines · Antonino A. Daplas, le Sun 13 Nov 2005 22:33:18 +0800, a écrit :
Quoted 13 lines · Samuel Thibault
Quoted 12 lines · Antonino A. Daplas, le Sun 13 Nov 2005 06:20:53 +0800, a écrit :

"I updated to the development kernel and now during boot only the top of the text is visable. For example the monitor screen the is the lines and I can only see text in the asterik area.
---------------------

| ****************  |
| *              *  |
| *              *  |
| ****************  |
|                   |
|                   |
|                   |

---------------------

Quoted 8 lines
Quoted 6 lines
Quoted 3 lines

Are you missing some left and right part too? What are the dimensions of the text screen at bootup? What bootloader are you using? (It could be a bug in the boot up text screen dimension discovery).

It was just the height. All numbers (done with printk's) look okay from bootup. He gets 80 and 25 for ORIG_VIDEO_NUM_COLS and ORIG_VIDEO_NUM_LINES respectively.

And you got less than 25 lines? How many exactly?

If the original size was at 80x25, and vgacon_doresize() was called, the the resulting screen is only 80x12.5. The 13th line has its bottom half chopped off, and the rest of the lines (14-25) is invisible.

If he sets it at < 25, he gets a window much smaller than 12.5, but he did not specify. So my guess is his chipset programs the screen height by 1/2 of the value of the requested rows.

Tony