Skip to content

Commit

Permalink
[PATCH] vgacon: no vertical resizing on EGA
Browse files Browse the repository at this point in the history
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]>
Cc: "Antonino A. Daplas" <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
sthibaul authored and Linus Torvalds committed Feb 24, 2006
1 parent fe1db50 commit d152126
Showing 1 changed file with 35 additions and 32 deletions.
67 changes: 35 additions & 32 deletions drivers/video/console/vgacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,57 +509,60 @@ static int vgacon_doresize(struct vc_data *c,
{
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 (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 (mode & 0x04)
scanlines >>= 1;
if (max_scan & 0x80)
scanlines <<= 1;

scanlines -= 1;
scanlines_lo = scanlines & 0xff;
outb_p(VGA_CRTC_MODE, vga_video_port_reg);
mode = inb_p(vga_video_port_val);

outb_p(VGA_CRTC_OVERFLOW, vga_video_port_reg);
r7 = inb_p(vga_video_port_val) & ~0x42;
if (mode & 0x04)
scanlines >>= 1;

if (scanlines & 0x100)
r7 |= 0x02;
if (scanlines & 0x200)
r7 |= 0x40;
scanlines -= 1;
scanlines_lo = scanlines & 0xff;

/* 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_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);
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);
/* 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;
}

Expand Down

0 comments on commit d152126

Please sign in to comment.