From owner-svn-src-all@FreeBSD.ORG Fri Sep 25 18:08:38 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 71F8D1065676; Fri, 25 Sep 2009 18:08:38 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 617548FC18; Fri, 25 Sep 2009 18:08:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n8PI8cRk036123; Fri, 25 Sep 2009 18:08:38 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n8PI8cOf036121; Fri, 25 Sep 2009 18:08:38 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <200909251808.n8PI8cOf036121@svn.freebsd.org> From: Jung-uk Kim Date: Fri, 25 Sep 2009 18:08:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r197496 - head/sys/dev/fb X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Sep 2009 18:08:38 -0000 Author: jkim Date: Fri Sep 25 18:08:38 2009 New Revision: 197496 URL: http://svn.freebsd.org/changeset/base/197496 Log: Reject some VESA graphics modes if the controller does not have enough memory to support them. Some adapters have expansible memory slots but video mode table is static. In this case, unusable modes may be reported. Submitted by: paradox (ddkprog yahoo com) (initial patch) Modified: head/sys/dev/fb/vesa.c Modified: head/sys/dev/fb/vesa.c ============================================================================== --- head/sys/dev/fb/vesa.c Fri Sep 25 18:07:23 2009 (r197495) +++ head/sys/dev/fb/vesa.c Fri Sep 25 18:08:38 2009 (r197496) @@ -194,6 +194,7 @@ static int vesa_bios_set_start(int x, in static int vesa_map_gen_mode_num(int type, int color, int mode); static int vesa_translate_flags(u_int16_t vflags); static int vesa_translate_mmodel(u_int8_t vmodel); +static int vesa_get_line_width(video_info_t *info); static int vesa_bios_init(void); static void vesa_clear_modes(video_info_t *info, int color); static vm_offset_t vesa_map_buffer(u_int paddr, size_t size); @@ -654,12 +655,44 @@ vesa_translate_mmodel(u_int8_t vmodel) } static int +vesa_get_line_width(video_info_t *info) +{ + int len; + int width; + + width = info->vi_width; + + if (info->vi_flags & V_INFO_GRAPHICS) + switch (info->vi_depth / info->vi_planes) { + case 1: + return (width / 8); + case 2: + return (width / 4); + case 4: + return (width / 2); + case 8: + return (width); + case 15: + case 16: + return (width * 2); + case 24: + case 32: + return (width * 4); + } + + len = vesa_bios_get_line_length(); + + return (len > 0 ? len : width); +} + +static int vesa_bios_init(void) { static struct vesa_info buf; struct vesa_mode vmode; video_info_t *p; x86regs_t regs; + size_t bsize; int offs; u_char *vmbuf; int is_via_cle266; @@ -837,6 +870,20 @@ vesa_bios_init(void) vesa_vmode[modes].vi_flags = vesa_translate_flags(vmode.v_modeattr) | V_INFO_VESA; + + /* Does it have enough memory to support this mode? */ + bsize = vesa_get_line_width(&vesa_vmode[modes]); + bsize *= vesa_vmode[modes].vi_height; + if (bsize > vesa_vmode[modes].vi_buffer_size) { +#if VESA_DEBUG > 1 + printf( + "Rejecting VESA %s mode: %d x %d x %d bpp attr = %x, not enough memory\n", + (vmode.v_modeattr & V_MODEGRAPHICS) != 0 ? "graphics" : "text", + vmode.v_width, vmode.v_height, vmode.v_bpp, vmode.v_modeattr); +#endif + continue; + } + ++modes; } vesa_vmode[modes].vi_mode = EOT; @@ -1049,7 +1096,6 @@ static int vesa_set_mode(video_adapter_t *adp, int mode) { video_info_t info; - int len = 0; if (adp != vesa_adp) return (*prevvidsw->set_mode)(adp, mode); @@ -1132,42 +1178,12 @@ vesa_set_mode(video_adapter_t *adp, int vesa_adp->va_window_gran = info.vi_window_gran; } vesa_adp->va_window_orig = 0; - - if (info.vi_flags & V_INFO_GRAPHICS) { - switch (info.vi_depth/info.vi_planes) { - case 1: - vesa_adp->va_line_width = info.vi_width/8; - break; - case 2: - vesa_adp->va_line_width = info.vi_width/4; - break; - case 4: - vesa_adp->va_line_width = info.vi_width/2; - break; - case 8: - default: /* shouldn't happen */ - vesa_adp->va_line_width = info.vi_width; - break; - case 15: - case 16: - vesa_adp->va_line_width = info.vi_width*2; - break; - case 24: - case 32: - vesa_adp->va_line_width = info.vi_width*4; - break; - } - } else { - vesa_adp->va_line_width = info.vi_width; - len = vesa_bios_get_line_length(); - if (len > 0) - vesa_adp->va_line_width = len; - } + vesa_adp->va_line_width = vesa_get_line_width(&info); vesa_adp->va_disp_start.x = 0; vesa_adp->va_disp_start.y = 0; #if VESA_DEBUG > 0 - printf("vesa_set_mode(): vi_width:%d, len:%d, line_width:%d\n", - info.vi_width, len, vesa_adp->va_line_width); + printf("vesa_set_mode(): vi_width:%d, line_width:%d\n", + info.vi_width, vesa_adp->va_line_width); #endif bcopy(&info, &vesa_adp->va_info, sizeof(vesa_adp->va_info));