Replace struct console_font with struct vc_font for the type of the vc_font field of struct vc_data. Struct console_font is UAPI, which prevents further changes. Hence a new data type is required.
Struct console_font has a documented vertical pitch of 32 bytes. This is not the case after the font data has been loaded into the kernel. Changing the type of vc_font addresses this inconsistency. The font data is now declared as constant, as it might come from the kernel's read-only section. There's some fallout throughout the console code where non-const variables refer to it. Fix them. A later update will declare the font data to a dedicated data type. Signed-off-by: Thomas Zimmermann <[email protected]> --- drivers/video/fbdev/core/bitblit.c | 11 +++++------ drivers/video/fbdev/core/fbcon.c | 4 ++-- drivers/video/fbdev/core/fbcon.h | 4 ++-- include/linux/console_struct.h | 29 +++++++++++++++++++++++++++-- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c index 085ffb44c51a..7478accea8ec 100644 --- a/drivers/video/fbdev/core/bitblit.c +++ b/drivers/video/fbdev/core/bitblit.c @@ -22,8 +22,7 @@ /* * Accelerated handlers. */ -static void update_attr(u8 *dst, u8 *src, int attribute, - struct vc_data *vc) +static void update_attr(u8 *dst, const u8 *src, int attribute, struct vc_data *vc) { int i, offset = (vc->vc_font.height < 10) ? 1 : 2; int width = DIV_ROUND_UP(vc->vc_font.width, 8); @@ -81,7 +80,7 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info, u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff; unsigned int charcnt = vc->vc_font.charcount; u32 idx = vc->vc_font.width >> 3; - u8 *src; + const u8 *src; while (cnt--) { u16 ch = scr_readw(s++) & charmask; @@ -120,7 +119,7 @@ static inline void bit_putcs_unaligned(struct vc_data *vc, u32 shift_low = 0, mod = vc->vc_font.width % 8; u32 shift_high = 8; u32 idx = vc->vc_font.width >> 3; - u8 *src; + const u8 *src; while (cnt--) { u16 ch = scr_readw(s++) & charmask; @@ -267,7 +266,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, int y = real_y(par->p, vc->state.y); int attribute, use_sw = vc->vc_cursor_type & CUR_SW; int err = 1; - char *src; + const u8 *src; cursor.set = 0; @@ -278,7 +277,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, attribute = get_attribute(info, c); src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); - if (par->cursor_state.image.data != src || + if (par->cursor_state.image.data != (const char *)src || par->cursor_reset) { par->cursor_state.image.data = src; cursor.set |= FB_CUR_SETIMAGE; diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 34ea14412ace..5467b37b1441 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -2291,7 +2291,7 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank, static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch) { - u8 *fontdata = vc->vc_font.data; + const u8 *fontdata = vc->vc_font.data; u8 *data = font->data; int i, j; @@ -2422,7 +2422,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount, struct fbcon_par *par = info->fbcon_par; struct fbcon_display *p = &fb_display[vc->vc_num]; int resize, ret, old_userfont, old_width, old_height, old_charcount; - u8 *old_data = vc->vc_font.data; + const u8 *old_data = vc->vc_font.data; resize = (w != vc->vc_font.width) || (h != vc->vc_font.height); vc->vc_font.data = (void *)(p->fontdata = data); diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h index fca14e9b729b..3f4386a40237 100644 --- a/drivers/video/fbdev/core/fbcon.h +++ b/drivers/video/fbdev/core/fbcon.h @@ -82,8 +82,8 @@ struct fbcon_par { int rotate; int cur_rotate; char *cursor_data; - u8 *fontbuffer; - u8 *fontdata; + u8 *fontbuffer; + const u8 *fontdata; u8 *cursor_src; u32 cursor_size; u32 fd_size; diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h index ebdb9750d348..7fdcae6ed49c 100644 --- a/include/linux/console_struct.h +++ b/include/linux/console_struct.h @@ -13,8 +13,9 @@ #ifndef _LINUX_CONSOLE_STRUCT_H #define _LINUX_CONSOLE_STRUCT_H -#include <linux/wait.h> +#include <linux/math.h> #include <linux/vt.h> +#include <linux/wait.h> #include <linux/workqueue.h> struct uni_pagedict; @@ -58,6 +59,30 @@ struct vc_state { bool reverse; }; +/** + * struct vc_font - Describes a font + * @width: The width of a single glyph in bits + * @height: The height of a single glyph in scanlines + * @charcount: The number of glyphs in the font + * @data: The raw font data + * + * Font data is organized as an array of glyphs. Each glyph is a bitmap with + * set bits indicating the foreground color. Unset bits indicate background + * color. The fields @width and @height store a single glyph's number of + * horizontal bits and vertical scanlines. If width is not a multiple of 8, + * there are trailing bits to fill up the byte. These bits should not be drawn. + * + * The field @data points to the first glphy's first byte. The value @charcount + * gives the number of glyphs in the font. There are no empty scanlines between + * two adjacent glyphs. + */ +struct vc_font { + unsigned int width; + unsigned int height; + unsigned int charcount; + const unsigned char *data; +}; + /* * Example: vc_data of a console that was scrolled 3 lines down. * @@ -122,7 +147,7 @@ struct vc_data { unsigned long vc_pos; /* Cursor address */ /* fonts */ unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */ - struct console_font vc_font; /* Current VC font set */ + struct vc_font vc_font; /* Current VC font set */ unsigned short vc_video_erase_char; /* Background erase character */ /* VT terminal data */ unsigned int vc_state; /* Escape sequence parser state */ -- 2.52.0
