diff options
Diffstat (limited to 'drivers/video/fbdev/core/fbcon.c')
-rw-r--r-- | drivers/video/fbdev/core/fbcon.c | 83 |
1 files changed, 38 insertions, 45 deletions
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 14a7d404062c..0a2c47df01f4 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -26,7 +26,7 @@ * * Hardware cursor support added by Emmanuel Marty (core@ggi-project.org) * Smart redraw scrolling, arbitrary font width support, 512char font support - * and software scrollback added by + * and software scrollback added by * Jakub Jelinek (jj@ultra.linux.cz) * * Random hacking by Martin Mares <mj@ucw.cz> @@ -127,7 +127,7 @@ static int logo_shown = FBCON_LOGO_CANSHOW; /* console mappings */ static unsigned int first_fb_vc; static unsigned int last_fb_vc = MAX_NR_CONSOLES - 1; -static int fbcon_is_default = 1; +static int fbcon_is_default = 1; static int primary_device = -1; static int fbcon_has_console_bind; @@ -415,12 +415,12 @@ static int __init fb_console_setup(char *this_opt) strscpy(fontname, options + 5, sizeof(fontname)); continue; } - + if (!strncmp(options, "scrollback:", 11)) { pr_warn("Ignoring scrollback size option\n"); continue; } - + if (!strncmp(options, "map:", 4)) { options += 4; if (*options) { @@ -446,7 +446,7 @@ static int __init fb_console_setup(char *this_opt) last_fb_vc = simple_strtoul(options, &options, 10) - 1; if (last_fb_vc < first_fb_vc || last_fb_vc >= MAX_NR_CONSOLES) last_fb_vc = MAX_NR_CONSOLES - 1; - fbcon_is_default = 0; + fbcon_is_default = 0; continue; } @@ -940,7 +940,7 @@ static const char *fbcon_startup(void) info = fbcon_registered_fb[info_idx]; if (!info) return NULL; - + if (fbcon_open(info)) return NULL; @@ -958,7 +958,7 @@ static const char *fbcon_startup(void) set_blitting_type(vc, info); /* Setup default font */ - if (!p->fontdata && !vc->vc_font.data) { + if (!p->fontdata) { if (!fontname[0] || !(font = find_font(fontname))) font = get_default_font(info->var.xres, info->var.yres, @@ -968,8 +968,6 @@ static const char *fbcon_startup(void) vc->vc_font.height = font->height; vc->vc_font.data = (void *)(p->fontdata = font->data); vc->vc_font.charcount = font->charcount; - } else { - p->fontdata = vc->vc_font.data; } cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres); @@ -1135,9 +1133,9 @@ static void fbcon_init(struct vc_data *vc, int init) ops->p = &fb_display[fg_console]; } -static void fbcon_free_font(struct fbcon_display *p, bool freefont) +static void fbcon_free_font(struct fbcon_display *p) { - if (freefont && p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) + if (p->userfont && p->fontdata && (--REFCOUNT(p->fontdata) == 0)) kfree(p->fontdata - FONT_EXTRA_WORDS * sizeof(int)); p->fontdata = NULL; p->userfont = 0; @@ -1172,8 +1170,8 @@ static void fbcon_deinit(struct vc_data *vc) struct fb_info *info; struct fbcon_ops *ops; int idx; - bool free_font = true; + fbcon_free_font(p); idx = con2fb_map[vc->vc_num]; if (idx == -1) @@ -1184,8 +1182,6 @@ static void fbcon_deinit(struct vc_data *vc) if (!info) goto finished; - if (info->flags & FBINFO_MISC_FIRMWARE) - free_font = false; ops = info->fbcon_par; if (!ops) @@ -1197,9 +1193,8 @@ static void fbcon_deinit(struct vc_data *vc) ops->initialized = false; finished: - fbcon_free_font(p, free_font); - if (free_font) - vc->vc_font.data = NULL; + fbcon_free_font(p); + vc->vc_font.data = NULL; if (vc->vc_hi_font_mask && vc->vc_screenbuf) set_vc_hi_font(vc, false); @@ -1999,7 +1994,7 @@ static void updatescrollmode(struct fbcon_display *p, #define PITCH(w) (((w) + 7) >> 3) #define CALC_FONTSZ(h, p, c) ((h) * (p) * (c)) /* size = height * pitch * charcount */ -static int fbcon_resize(struct vc_data *vc, unsigned int width, +static int fbcon_resize(struct vc_data *vc, unsigned int width, unsigned int height, unsigned int user) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); @@ -2174,7 +2169,7 @@ static int fbcon_switch(struct vc_data *vc) ops->update_start(info); } - fbcon_set_palette(vc, color_table); + fbcon_set_palette(vc, color_table); fbcon_clear_margins(vc, 0); if (logo_shown == FBCON_LOGO_DRAW) { @@ -2271,7 +2266,7 @@ static int fbcon_debug_leave(struct vc_data *vc) return 0; } -static int fbcon_get_font(struct vc_data *vc, struct console_font *font) +static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch) { u8 *fontdata = vc->vc_font.data; u8 *data = font->data; @@ -2279,6 +2274,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) font->width = vc->vc_font.width; font->height = vc->vc_font.height; + if (font->height > vpitch) + return -ENOSPC; font->charcount = vc->vc_hi_font_mask ? 512 : 256; if (!font->data) return 0; @@ -2290,8 +2287,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 32 - j); - data += 32; + memset(data + j, 0, vpitch - j); + data += vpitch; fontdata += j; } } else if (font->width <= 16) { @@ -2301,8 +2298,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 64 - j); - data += 64; + memset(data + j, 0, 2*vpitch - j); + data += 2*vpitch; fontdata += j; } } else if (font->width <= 24) { @@ -2316,8 +2313,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) *data++ = fontdata[2]; fontdata += sizeof(u32); } - memset(data, 0, 3 * (32 - j)); - data += 3 * (32 - j); + memset(data, 0, 3 * (vpitch - j)); + data += 3 * (vpitch - j); } } else { j = vc->vc_font.height * 4; @@ -2326,8 +2323,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font) for (i = 0; i < font->charcount; i++) { memcpy(data, fontdata, j); - memset(data + j, 0, 128 - j); - data += 128; + memset(data + j, 0, 4 * vpitch - j); + data += 4 * vpitch; fontdata += j; } } @@ -2343,7 +2340,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set) vc->vc_complement_mask >>= 1; vc->vc_s_complement_mask >>= 1; } - + /* ++Edmund: reorder the attribute bits */ if (vc->vc_can_do_color) { unsigned short *cp = @@ -2366,7 +2363,7 @@ static void set_vc_hi_font(struct vc_data *vc, bool set) vc->vc_complement_mask <<= 1; vc->vc_s_complement_mask <<= 1; } - + /* ++Edmund: reorder the attribute bits */ { unsigned short *cp = @@ -2462,19 +2459,12 @@ err_out: } /* - * User asked to set font; we are guaranteed that - * a) width and height are in range 1..32 - * b) charcount does not exceed 512 - * but lets not assume that, since someone might someday want to use larger - * fonts. And charcount of 512 is small for unicode support. - * - * However, user space gives the font in 32 rows , regardless of - * actual font height. So a new API is needed if support for larger fonts - * is ever implemented. + * User asked to set font; we are guaranteed that charcount does not exceed 512 + * but lets not assume that, since charcount of 512 is small for unicode support. */ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, - unsigned int flags) + unsigned int vpitch, unsigned int flags) { struct fb_info *info = fbcon_info_from_console(vc->vc_num); unsigned charcount = font->charcount; @@ -2495,9 +2485,12 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres)) return -EINVAL; + if (font->width > 32 || font->height > 32) + return -EINVAL; + /* Make sure drawing engine can handle the font */ - if (!(info->pixmap.blit_x & (1 << (font->width - 1))) || - !(info->pixmap.blit_y & (1 << (font->height - 1)))) + if (!(info->pixmap.blit_x & BIT(font->width - 1)) || + !(info->pixmap.blit_y & BIT(font->height - 1))) return -EINVAL; /* Make sure driver can handle the font length */ @@ -2517,7 +2510,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, FNTSIZE(new_data) = size; REFCOUNT(new_data) = 0; /* usage counter */ for (i=0; i< charcount; i++) { - memcpy(new_data + i*h*pitch, data + i*32*pitch, h*pitch); + memcpy(new_data + i*h*pitch, data + i*vpitch*pitch, h*pitch); } /* Since linux has a nice crc32 function use it for counting font @@ -2528,7 +2521,7 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font, /* Check if the same font is on some other console already */ for (i = first_fb_vc; i <= last_fb_vc; i++) { struct vc_data *tmp = vc_cons[i].d; - + if (fb_display[i].userfont && fb_display[i].fontdata && FNTSUM(fb_display[i].fontdata) == csum && @@ -3436,5 +3429,5 @@ void __exit fb_console_exit(void) do_unregister_con_driver(&fb_con); console_unlock(); -} +} #endif |