Hi,
Here is a fixup (vgacon-no-vertical-resize-on-ega):
EGA boards suck: they mostly have write-only registers. This is
particularly problematic for the overflow register: for being able to
write to it, we would have to handle vertical sync & such too, which
(I'd say) would potentially break a lot of configurations. Instead, just
disabling vertical resize for EGA boards is just nice enough (horizontal
resize still works).
Signed-off-by: Samuel Thibault <[email protected]>
--- drivers/video/console/vgacon.c.2.6.15.4 2006-02-22 01:35:49.000000000 +0100
+++ drivers/video/console/vgacon.c 2006-02-22 01:43:41.000000000 +0100
@@ -503,52 +503,56 @@ static int vgacon_doresize(struct vc_dat
{
unsigned long flags;
unsigned int scanlines = height * c->vc_font.height;
- u8 scanlines_lo, r7, vsync_end, mode, max_scan;
+ u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;
spin_lock_irqsave(&vga_lock, flags);
- outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
- max_scan = inb_p(vga_video_port_val);
-
- if (max_scan & 0x80)
- scanlines <<= 1;
-
- outb_p(VGA_CRTC_MODE, vga_video_port_reg);
- mode = inb_p(vga_video_port_val);
-
- if (mode & 0x04)
- scanlines >>= 1;
-
- scanlines -= 1;
- scanlines_lo = scanlines & 0xff;
-
- outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
- r7 = inb_p(vga_video_port_val) & ~0x42;
-
- if (scanlines & 0x100)
- r7 |= 0x02;
- if (scanlines & 0x200)
- r7 |= 0x40;
-
- /* deprotect registers */
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- vsync_end = inb_p(vga_video_port_val);
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- outb_p(vsync_end & ~0x80, vga_video_port_val);
+ if (vga_video_type >= VIDEO_TYPE_VGAC) {
+ outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
+ max_scan = inb_p(vga_video_port_val);
+
+ if (max_scan & 0x80)
+ scanlines <<= 1;
+
+ outb_p(VGA_CRTC_MODE, vga_video_port_reg);
+ mode = inb_p(vga_video_port_val);
+
+ if (mode & 0x04)
+ scanlines >>= 1;
+
+ scanlines -= 1;
+ scanlines_lo = scanlines & 0xff;
+
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ r7 = inb_p(vga_video_port_val) & ~0x42;
+
+ if (scanlines & 0x100)
+ r7 |= 0x02;
+ if (scanlines & 0x200)
+ r7 |= 0x40;
+
+ /* deprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ vsync_end = inb_p(vga_video_port_val);
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end & ~0x80, vga_video_port_val);
+ }
outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
outb_p(width - 1, vga_video_port_val);
outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
outb_p(width >> 1, vga_video_port_val);
- outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
- outb_p(scanlines_lo, vga_video_port_val);
- outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
- outb_p(r7,vga_video_port_val);
-
- /* reprotect registers */
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- outb_p(vsync_end, vga_video_port_val);
+ if (vga_video_type >= VIDEO_TYPE_VGAC) {
+ outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
+ outb_p(scanlines_lo, vga_video_port_val);
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ outb_p(r7,vga_video_port_val);
+
+ /* reprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end, vga_video_port_val);
+ }
spin_unlock_irqrestore(&vga_lock, flags);
Samuel Thibault <[email protected]> wrote:
>
> Here is a fixup (vgacon-no-vertical-resize-on-ega):
Thanks. I'm 51% inclined to hold this off for 2.6.17 - vgacon seems to be
a bit accident-prone lately.
Your patch was against some prehistoric kernel which didn't have the
vgacon_xres and vgacon_yres initialisations in vgacon_doresize().
Please confirm that this is correct:
From: Samuel Thibault <[email protected]>
EGA boards suck: they mostly have write-only registers. This is
particularly problematic for the overflow register: for being able to write
to it, we would have to handle vertical sync & such too, which (I'd say)
would potentially break a lot of configurations. Instead, just disabling
vertical resize for EGA boards is just nice enough (horizontal resize still
works).
Fixes http://bugzilla.kernel.org/show_bug.cgi?id=6106
Signed-off-by: Samuel Thibault <[email protected]>
Cc: Rafal Olearski <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
---
drivers/video/console/vgacon.c | 79 ++++++++++++++++---------------
1 files changed, 41 insertions(+), 38 deletions(-)
diff -puN drivers/video/console/vgacon.c~vgacon-no-vertical-resizing-on-ega drivers/video/console/vgacon.c
--- devel/drivers/video/console/vgacon.c~vgacon-no-vertical-resizing-on-ega 2006-02-21 17:49:40.000000000 -0800
+++ devel-akpm/drivers/video/console/vgacon.c 2006-02-21 17:52:27.000000000 -0800
@@ -509,57 +509,60 @@ static int vgacon_doresize(struct vc_dat
{
unsigned long flags;
unsigned int scanlines = height * c->vc_font.height;
- u8 scanlines_lo, r7, vsync_end, mode, max_scan;
+ u8 scanlines_lo = 0, r7 = 0, vsync_end = 0, mode, max_scan;
spin_lock_irqsave(&vga_lock, flags);
- outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
- max_scan = inb_p(vga_video_port_val);
-
- if (max_scan & 0x80)
- scanlines <<= 1;
-
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);
-
- if (mode & 0x04)
- scanlines >>= 1;
-
- scanlines -= 1;
- scanlines_lo = scanlines & 0xff;
-
- outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
- r7 = inb_p(vga_video_port_val) & ~0x42;
-
- if (scanlines & 0x100)
- r7 |= 0x02;
- if (scanlines & 0x200)
- r7 |= 0x40;
-
- /* deprotect registers */
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- vsync_end = inb_p(vga_video_port_val);
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- outb_p(vsync_end & ~0x80, vga_video_port_val);
+ if (vga_video_type >= VIDEO_TYPE_VGAC) {
+ outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg);
+ max_scan = inb_p(vga_video_port_val);
+
+ if (max_scan & 0x80)
+ scanlines <<= 1;
+
+ outb_p(VGA_CRTC_MODE, vga_video_port_reg);
+ mode = inb_p(vga_video_port_val);
+
+ if (mode & 0x04)
+ scanlines >>= 1;
+
+ scanlines -= 1;
+ scanlines_lo = scanlines & 0xff;
+
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ r7 = inb_p(vga_video_port_val) & ~0x42;
+
+ if (scanlines & 0x100)
+ r7 |= 0x02;
+ if (scanlines & 0x200)
+ r7 |= 0x40;
+
+ /* deprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ vsync_end = inb_p(vga_video_port_val);
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end & ~0x80, vga_video_port_val);
+ }
outb_p(VGA_CRTC_H_DISP, vga_video_port_reg);
outb_p(width - 1, vga_video_port_val);
outb_p(VGA_CRTC_OFFSET, vga_video_port_reg);
outb_p(width >> 1, vga_video_port_val);
- outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
- outb_p(scanlines_lo, vga_video_port_val);
- outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
- outb_p(r7,vga_video_port_val);
-
- /* reprotect registers */
- outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
- outb_p(vsync_end, vga_video_port_val);
+ if (vga_video_type >= VIDEO_TYPE_VGAC) {
+ outb_p(VGA_CRTC_V_DISP_END, vga_video_port_reg);
+ outb_p(scanlines_lo, vga_video_port_val);
+ outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
+ outb_p(r7,vga_video_port_val);
+
+ /* reprotect registers */
+ outb_p(VGA_CRTC_V_SYNC_END, vga_video_port_reg);
+ outb_p(vsync_end, vga_video_port_val);
+ }
spin_unlock_irqrestore(&vga_lock, flags);
-
return 0;
}
_
Hi,
Andrew Morton, le Tue 21 Feb 2006 17:57:10 -0800, a ?crit :
> Your patch was against some prehistoric kernel which didn't have the
> vgacon_xres and vgacon_yres initialisations in vgacon_doresize().
Ah, yes, sorry.
> Please confirm that this is correct:
This is indeed.
Regards,
Samuel
Hi,
Here is another fixup for EGA cursor resize function.
This corrects cursor resize on ega boards: registers are write-only, so
we shouldn't even try to read them. And on ega, 31/30 produces a flat
cursor. Using 31/31 is better: except with 32 pixels high fonts, it
shouldn't show up.
Signed-off-by: Samuel Thibault <[email protected]>
--- drivers/video/console/vgacon.c.git 2006-02-24 10:43:25.000000000 +0100
+++ drivers/video/console/vgacon.c 2006-02-25 01:17:17.000000000 +0100
@@ -433,17 +433,22 @@ static void vgacon_set_cursor_size(int x
cursor_size_lastto = to;
spin_lock_irqsave(&vga_lock, flags);
- outb_p(0x0a, vga_video_port_reg); /* Cursor start */
- curs = inb_p(vga_video_port_val);
- outb_p(0x0b, vga_video_port_reg); /* Cursor end */
- cure = inb_p(vga_video_port_val);
+ if (vga_video_type >= VIDEO_TYPE_VGAC) {
+ outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
+ curs = inb_p(vga_video_port_val);
+ outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
+ cure = inb_p(vga_video_port_val);
+ } else {
+ curs = 0;
+ cure = 0;
+ }
curs = (curs & 0xc0) | from;
cure = (cure & 0xe0) | to;
- outb_p(0x0a, vga_video_port_reg); /* Cursor start */
+ outb_p(VGA_CRTC_CURSOR_START, vga_video_port_reg);
outb_p(curs, vga_video_port_val);
- outb_p(0x0b, vga_video_port_reg); /* Cursor end */
+ outb_p(VGA_CRTC_CURSOR_END, vga_video_port_reg);
outb_p(cure, vga_video_port_val);
spin_unlock_irqrestore(&vga_lock, flags);
}
@@ -455,7 +460,10 @@ static void vgacon_cursor(struct vc_data
switch (mode) {
case CM_ERASE:
write_vga(14, (c->vc_pos - vga_vram_base) / 2);
- vgacon_set_cursor_size(c->vc_x, 31, 30);
+ if (vga_video_type >= VIDEO_TYPE_VGAC)
+ vgacon_set_cursor_size(c->vc_x, 31, 30);
+ else
+ vgacon_set_cursor_size(c->vc_x, 31, 31);
break;
case CM_MOVE:
@@ -493,7 +501,10 @@ static void vgacon_cursor(struct vc_data
10 ? 1 : 2));
break;
case CUR_NONE:
- vgacon_set_cursor_size(c->vc_x, 31, 30);
+ if (vga_video_type >= VIDEO_TYPE_VGAC)
+ vgacon_set_cursor_size(c->vc_x, 31, 30);
+ else
+ vgacon_set_cursor_size(c->vc_x, 31, 31);
break;
default:
vgacon_set_cursor_size(c->vc_x, 1,