linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 01/38] vc: separate state
@ 2020-06-15  7:48 Jiri Slaby
  2020-06-15  7:48 ` [PATCH 02/38] vt: introduce enum vc_intensity for intensity Jiri Slaby
                   ` (36 more replies)
  0 siblings, 37 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

There are two copies of some members of struct vc_data. This is because
we need to save them and restore later. Move these memebers to a
separate structure called vc_state. So now instead of members like:
  vc_x, vc_y and vc_saved_x, vc_saved_y
we have
  state and saved_state (of type: struct vc_state)
containing
  state.x, state.y and saved_state.x, saved_state.y

This change:
* makes clear what is saved & restored
* eases save & restore by using memcpy (see save_cur and restore_cur)

Finally, we document the newly added struct vc_state using kernel-doc.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 .../accessibility/braille/braille_console.c   |  10 +-
 drivers/staging/speakup/main.c                |  28 +-
 drivers/tty/vt/vt.c                           | 327 +++++++++---------
 drivers/video/console/mdacon.c                |   2 +-
 drivers/video/console/sticon.c                |   6 +-
 drivers/video/console/vgacon.c                |  22 +-
 drivers/video/fbdev/core/bitblit.c            |   6 +-
 drivers/video/fbdev/core/fbcon.c              |   8 +-
 drivers/video/fbdev/core/fbcon_ccw.c          |   4 +-
 drivers/video/fbdev/core/fbcon_cw.c           |   4 +-
 drivers/video/fbdev/core/fbcon_ud.c           |   4 +-
 drivers/video/fbdev/core/tileblit.c           |   4 +-
 include/linux/console_struct.h                |  54 +--
 13 files changed, 239 insertions(+), 240 deletions(-)

diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
index a8f7c278b691..c2b452af6806 100644
--- a/drivers/accessibility/braille/braille_console.c
+++ b/drivers/accessibility/braille/braille_console.c
@@ -109,16 +109,16 @@ static void braille_write(u16 *buf)
 /* Follow the VC cursor*/
 static void vc_follow_cursor(struct vc_data *vc)
 {
-	vc_x = vc->vc_x - (vc->vc_x % WIDTH);
-	vc_y = vc->vc_y;
-	lastvc_x = vc->vc_x;
-	lastvc_y = vc->vc_y;
+	vc_x = vc->state.x - (vc->state.x % WIDTH);
+	vc_y = vc->state.y;
+	lastvc_x = vc->state.x;
+	lastvc_y = vc->state.y;
 }
 
 /* Maybe the VC cursor moved, if so follow it */
 static void vc_maybe_cursor_moved(struct vc_data *vc)
 {
-	if (vc->vc_x != lastvc_x || vc->vc_y != lastvc_y)
+	if (vc->state.x != lastvc_x || vc->state.y != lastvc_y)
 		vc_follow_cursor(vc);
 }
 
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index 02471d932d71..ddfd12afe3b9 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -263,8 +263,8 @@ static unsigned char get_attributes(struct vc_data *vc, u16 *pos)
 
 static void speakup_date(struct vc_data *vc)
 {
-	spk_x = spk_cx = vc->vc_x;
-	spk_y = spk_cy = vc->vc_y;
+	spk_x = spk_cx = vc->state.x;
+	spk_y = spk_cy = vc->state.y;
 	spk_pos = spk_cp = vc->vc_pos;
 	spk_old_attr = spk_attr;
 	spk_attr = get_attributes(vc, (u_short *)spk_pos);
@@ -1551,9 +1551,9 @@ static void do_handle_cursor(struct vc_data *vc, u_char value, char up_flag)
  */
 	is_cursor = value + 1;
 	old_cursor_pos = vc->vc_pos;
-	old_cursor_x = vc->vc_x;
-	old_cursor_y = vc->vc_y;
-	speakup_console[vc->vc_num]->ht.cy = vc->vc_y;
+	old_cursor_x = vc->state.x;
+	old_cursor_y = vc->state.y;
+	speakup_console[vc->vc_num]->ht.cy = vc->state.y;
 	cursor_con = vc->vc_num;
 	if (cursor_track == CT_Highlight)
 		reset_highlight_buffers(vc);
@@ -1574,8 +1574,8 @@ static void update_color_buffer(struct vc_data *vc, const u16 *ic, int len)
 	i = 0;
 	if (speakup_console[vc_num]->ht.highsize[bi] == 0) {
 		speakup_console[vc_num]->ht.rpos[bi] = vc->vc_pos;
-		speakup_console[vc_num]->ht.rx[bi] = vc->vc_x;
-		speakup_console[vc_num]->ht.ry[bi] = vc->vc_y;
+		speakup_console[vc_num]->ht.rx[bi] = vc->state.x;
+		speakup_console[vc_num]->ht.ry[bi] = vc->state.y;
 	}
 	while ((hi < COLOR_BUFFER_SIZE) && (i < len)) {
 		if (ic[i] > 32) {
@@ -1664,9 +1664,9 @@ static int speak_highlight(struct vc_data *vc)
 		return 0;
 	hc = get_highlight_color(vc);
 	if (hc != -1) {
-		d = vc->vc_y - speakup_console[vc_num]->ht.cy;
+		d = vc->state.y - speakup_console[vc_num]->ht.cy;
 		if ((d == 1) || (d == -1))
-			if (speakup_console[vc_num]->ht.ry[hc] != vc->vc_y)
+			if (speakup_console[vc_num]->ht.ry[hc] != vc->state.y)
 				return 0;
 		spk_parked |= 0x01;
 		spk_do_flush();
@@ -1693,8 +1693,8 @@ static void cursor_done(struct timer_list *unused)
 	}
 	speakup_date(vc);
 	if (win_enabled) {
-		if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
-		    vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
+		if (vc->state.x >= win_left && vc->state.x <= win_right &&
+		    vc->state.y >= win_top && vc->state.y <= win_bottom) {
 			spk_keydown = 0;
 			is_cursor = 0;
 			goto out;
@@ -1757,7 +1757,7 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
 	if (!spin_trylock_irqsave(&speakup_info.spinlock, flags))
 		/* Speakup output, discard */
 		return;
-	if (spk_bell_pos && spk_keydown && (vc->vc_x == spk_bell_pos - 1))
+	if (spk_bell_pos && spk_keydown && (vc->state.x == spk_bell_pos - 1))
 		bleep(3);
 	if ((is_cursor) || (cursor_track == read_all_mode)) {
 		if (cursor_track == CT_Highlight)
@@ -1766,8 +1766,8 @@ static void speakup_con_write(struct vc_data *vc, u16 *str, int len)
 		return;
 	}
 	if (win_enabled) {
-		if (vc->vc_x >= win_left && vc->vc_x <= win_right &&
-		    vc->vc_y >= win_top && vc->vc_y <= win_bottom) {
+		if (vc->state.x >= win_left && vc->state.x <= win_right &&
+		    vc->state.y >= win_top && vc->state.y <= win_bottom) {
 			spin_unlock_irqrestore(&speakup_info.spinlock, flags);
 			return;
 		}
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 48a8199f7845..76f52935e0c8 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -381,7 +381,7 @@ static void vc_uniscr_putc(struct vc_data *vc, char32_t uc)
 	struct uni_screen *uniscr = get_vc_uniscr(vc);
 
 	if (uniscr)
-		uniscr->lines[vc->vc_y][vc->vc_x] = uc;
+		uniscr->lines[vc->state.y][vc->state.x] = uc;
 }
 
 static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
@@ -389,8 +389,8 @@ static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
 	struct uni_screen *uniscr = get_vc_uniscr(vc);
 
 	if (uniscr) {
-		char32_t *ln = uniscr->lines[vc->vc_y];
-		unsigned int x = vc->vc_x, cols = vc->vc_cols;
+		char32_t *ln = uniscr->lines[vc->state.y];
+		unsigned int x = vc->state.x, cols = vc->vc_cols;
 
 		memmove(&ln[x + nr], &ln[x], (cols - x - nr) * sizeof(*ln));
 		memset32(&ln[x], ' ', nr);
@@ -402,8 +402,8 @@ static void vc_uniscr_delete(struct vc_data *vc, unsigned int nr)
 	struct uni_screen *uniscr = get_vc_uniscr(vc);
 
 	if (uniscr) {
-		char32_t *ln = uniscr->lines[vc->vc_y];
-		unsigned int x = vc->vc_x, cols = vc->vc_cols;
+		char32_t *ln = uniscr->lines[vc->state.y];
+		unsigned int x = vc->state.x, cols = vc->vc_cols;
 
 		memcpy(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
 		memset32(&ln[cols - nr], ' ', nr);
@@ -416,7 +416,7 @@ static void vc_uniscr_clear_line(struct vc_data *vc, unsigned int x,
 	struct uni_screen *uniscr = get_vc_uniscr(vc);
 
 	if (uniscr) {
-		char32_t *ln = uniscr->lines[vc->vc_y];
+		char32_t *ln = uniscr->lines[vc->state.y];
 
 		memset32(&ln[x], ' ', nr);
 	}
@@ -750,10 +750,11 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
 
 static void update_attr(struct vc_data *vc)
 {
-	vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
-	              vc->vc_blink, vc->vc_underline,
-	              vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
-	vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
+	vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity,
+	              vc->state.blink, vc->state.underline,
+	              vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
+	vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color, 1,
+				vc->state.blink, 0, vc->vc_decscnm, 0) << 8);
 }
 
 /* Note: inverting the screen twice should revert to the original state */
@@ -842,12 +843,12 @@ static void insert_char(struct vc_data *vc, unsigned int nr)
 	unsigned short *p = (unsigned short *) vc->vc_pos;
 
 	vc_uniscr_insert(vc, nr);
-	scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2);
+	scr_memmovew(p + nr, p, (vc->vc_cols - vc->state.x - nr) * 2);
 	scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
 	vc->vc_need_wrap = 0;
 	if (con_should_update(vc))
 		do_update_region(vc, (unsigned long) p,
-			vc->vc_cols - vc->vc_x);
+			vc->vc_cols - vc->state.x);
 }
 
 static void delete_char(struct vc_data *vc, unsigned int nr)
@@ -855,13 +856,13 @@ static void delete_char(struct vc_data *vc, unsigned int nr)
 	unsigned short *p = (unsigned short *) vc->vc_pos;
 
 	vc_uniscr_delete(vc, nr);
-	scr_memcpyw(p, p + nr, (vc->vc_cols - vc->vc_x - nr) * 2);
-	scr_memsetw(p + vc->vc_cols - vc->vc_x - nr, vc->vc_video_erase_char,
+	scr_memcpyw(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2);
+	scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char,
 			nr * 2);
 	vc->vc_need_wrap = 0;
 	if (con_should_update(vc))
 		do_update_region(vc, (unsigned long) p,
-			vc->vc_cols - vc->vc_x);
+			vc->vc_cols - vc->state.x);
 }
 
 static int softcursor_original = -1;
@@ -880,7 +881,7 @@ static void add_softcursor(struct vc_data *vc)
 	if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
 	scr_writew(i, (u16 *) vc->vc_pos);
 	if (con_should_update(vc))
-		vc->vc_sw->con_putc(vc, i, vc->vc_y, vc->vc_x);
+		vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
 }
 
 static void hide_softcursor(struct vc_data *vc)
@@ -889,7 +890,7 @@ static void hide_softcursor(struct vc_data *vc)
 		scr_writew(softcursor_original, (u16 *)vc->vc_pos);
 		if (con_should_update(vc))
 			vc->vc_sw->con_putc(vc, softcursor_original,
-					vc->vc_y, vc->vc_x);
+					vc->state.y, vc->state.x);
 		softcursor_original = -1;
 	}
 }
@@ -927,7 +928,8 @@ static void set_origin(struct vc_data *vc)
 		vc->vc_origin = (unsigned long)vc->vc_screenbuf;
 	vc->vc_visible_origin = vc->vc_origin;
 	vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
-	vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x;
+	vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->state.y +
+		2 * vc->state.x;
 }
 
 static void save_screen(struct vc_data *vc)
@@ -1250,8 +1252,8 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
 	new_origin = (long) newscreen;
 	new_scr_end = new_origin + new_screen_size;
 
-	if (vc->vc_y > new_rows) {
-		if (old_rows - vc->vc_y < new_rows) {
+	if (vc->state.y > new_rows) {
+		if (old_rows - vc->state.y < new_rows) {
 			/*
 			 * Cursor near the bottom, copy contents from the
 			 * bottom of buffer
@@ -1262,7 +1264,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
 			 * Cursor is in no man's land, copy 1/2 screenful
 			 * from the top and bottom of cursor position
 			 */
-			first_copied_row = (vc->vc_y - new_rows/2);
+			first_copied_row = (vc->state.y - new_rows/2);
 		}
 		old_origin += first_copied_row * old_row_size;
 	} else
@@ -1296,7 +1298,7 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
 	/* do part of a reset_terminal() */
 	vc->vc_top = 0;
 	vc->vc_bottom = vc->vc_rows;
-	gotoxy(vc, vc->vc_x, vc->vc_y);
+	gotoxy(vc, vc->state.x, vc->state.y);
 	save_cur(vc);
 
 	if (tty) {
@@ -1431,12 +1433,12 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y)
 	int min_y, max_y;
 
 	if (new_x < 0)
-		vc->vc_x = 0;
+		vc->state.x = 0;
 	else {
 		if (new_x >= vc->vc_cols)
-			vc->vc_x = vc->vc_cols - 1;
+			vc->state.x = vc->vc_cols - 1;
 		else
-			vc->vc_x = new_x;
+			vc->state.x = new_x;
 	}
 
  	if (vc->vc_decom) {
@@ -1447,12 +1449,13 @@ static void gotoxy(struct vc_data *vc, int new_x, int new_y)
 		max_y = vc->vc_rows;
 	}
 	if (new_y < min_y)
-		vc->vc_y = min_y;
+		vc->state.y = min_y;
 	else if (new_y >= max_y)
-		vc->vc_y = max_y - 1;
+		vc->state.y = max_y - 1;
 	else
-		vc->vc_y = new_y;
-	vc->vc_pos = vc->vc_origin + vc->vc_y * vc->vc_size_row + (vc->vc_x<<1);
+		vc->state.y = new_y;
+	vc->vc_pos = vc->vc_origin + vc->state.y * vc->vc_size_row +
+		(vc->state.x << 1);
 	vc->vc_need_wrap = 0;
 }
 
@@ -1479,10 +1482,10 @@ static void lf(struct vc_data *vc)
     	/* don't scroll if above bottom of scrolling region, or
 	 * if below scrolling region
 	 */
-    	if (vc->vc_y + 1 == vc->vc_bottom)
+	if (vc->state.y + 1 == vc->vc_bottom)
 		con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_UP, 1);
-	else if (vc->vc_y < vc->vc_rows - 1) {
-	    	vc->vc_y++;
+	else if (vc->state.y < vc->vc_rows - 1) {
+		vc->state.y++;
 		vc->vc_pos += vc->vc_size_row;
 	}
 	vc->vc_need_wrap = 0;
@@ -1494,10 +1497,10 @@ static void ri(struct vc_data *vc)
     	/* don't scroll if below top of scrolling region, or
 	 * if above scrolling region
 	 */
-	if (vc->vc_y == vc->vc_top)
+	if (vc->state.y == vc->vc_top)
 		con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_DOWN, 1);
-	else if (vc->vc_y > 0) {
-		vc->vc_y--;
+	else if (vc->state.y > 0) {
+		vc->state.y--;
 		vc->vc_pos -= vc->vc_size_row;
 	}
 	vc->vc_need_wrap = 0;
@@ -1505,16 +1508,16 @@ static void ri(struct vc_data *vc)
 
 static inline void cr(struct vc_data *vc)
 {
-	vc->vc_pos -= vc->vc_x << 1;
-	vc->vc_need_wrap = vc->vc_x = 0;
+	vc->vc_pos -= vc->state.x << 1;
+	vc->vc_need_wrap = vc->state.x = 0;
 	notify_write(vc, '\r');
 }
 
 static inline void bs(struct vc_data *vc)
 {
-	if (vc->vc_x) {
+	if (vc->state.x) {
 		vc->vc_pos -= 2;
-		vc->vc_x--;
+		vc->state.x--;
 		vc->vc_need_wrap = 0;
 		notify_write(vc, '\b');
 	}
@@ -1532,16 +1535,16 @@ static void csi_J(struct vc_data *vc, int vpar)
 
 	switch (vpar) {
 		case 0:	/* erase from cursor to end of display */
-			vc_uniscr_clear_line(vc, vc->vc_x,
-					     vc->vc_cols - vc->vc_x);
-			vc_uniscr_clear_lines(vc, vc->vc_y + 1,
-					      vc->vc_rows - vc->vc_y - 1);
+			vc_uniscr_clear_line(vc, vc->state.x,
+					     vc->vc_cols - vc->state.x);
+			vc_uniscr_clear_lines(vc, vc->state.y + 1,
+					      vc->vc_rows - vc->state.y - 1);
 			count = (vc->vc_scr_end - vc->vc_pos) >> 1;
 			start = (unsigned short *)vc->vc_pos;
 			break;
 		case 1:	/* erase from start to cursor */
-			vc_uniscr_clear_line(vc, 0, vc->vc_x + 1);
-			vc_uniscr_clear_lines(vc, 0, vc->vc_y);
+			vc_uniscr_clear_line(vc, 0, vc->state.x + 1);
+			vc_uniscr_clear_lines(vc, 0, vc->state.y);
 			count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
 			start = (unsigned short *)vc->vc_origin;
 			break;
@@ -1571,20 +1574,20 @@ static void csi_K(struct vc_data *vc, int vpar)
 	switch (vpar) {
 		case 0:	/* erase from cursor to end of line */
 			offset = 0;
-			count = vc->vc_cols - vc->vc_x;
+			count = vc->vc_cols - vc->state.x;
 			break;
 		case 1:	/* erase from start of line to cursor */
-			offset = -vc->vc_x;
-			count = vc->vc_x + 1;
+			offset = -vc->state.x;
+			count = vc->state.x + 1;
 			break;
 		case 2: /* erase whole line */
-			offset = -vc->vc_x;
+			offset = -vc->state.x;
 			count = vc->vc_cols;
 			break;
 		default:
 			return;
 	}
-	vc_uniscr_clear_line(vc, vc->vc_x + offset, count);
+	vc_uniscr_clear_line(vc, vc->state.x + offset, count);
 	scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
 	vc->vc_need_wrap = 0;
 	if (con_should_update(vc))
@@ -1597,23 +1600,23 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
 
 	if (!vpar)
 		vpar++;
-	count = (vpar > vc->vc_cols - vc->vc_x) ? (vc->vc_cols - vc->vc_x) : vpar;
+	count = (vpar > vc->vc_cols - vc->state.x) ? (vc->vc_cols - vc->state.x) : vpar;
 
-	vc_uniscr_clear_line(vc, vc->vc_x, count);
+	vc_uniscr_clear_line(vc, vc->state.x, count);
 	scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
 	if (con_should_update(vc))
-		vc->vc_sw->con_clear(vc, vc->vc_y, vc->vc_x, 1, count);
+		vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, 1, count);
 	vc->vc_need_wrap = 0;
 }
 
 static void default_attr(struct vc_data *vc)
 {
-	vc->vc_intensity = 1;
-	vc->vc_italic = 0;
-	vc->vc_underline = 0;
-	vc->vc_reverse = 0;
-	vc->vc_blink = 0;
-	vc->vc_color = vc->vc_def_color;
+	vc->state.intensity = 1;
+	vc->state.italic = 0;
+	vc->state.underline = 0;
+	vc->state.reverse = 0;
+	vc->state.blink = 0;
+	vc->state.color = vc->vc_def_color;
 }
 
 struct rgb { u8 r; u8 g; u8 b; };
@@ -1649,19 +1652,19 @@ static void rgb_foreground(struct vc_data *vc, const struct rgb *c)
 
 	if (hue == 7 && max <= 0x55) {
 		hue = 0;
-		vc->vc_intensity = 2;
+		vc->state.intensity = 2;
 	} else if (max > 0xaa)
-		vc->vc_intensity = 2;
+		vc->state.intensity = 2;
 	else
-		vc->vc_intensity = 1;
+		vc->state.intensity = 1;
 
-	vc->vc_color = (vc->vc_color & 0xf0) | hue;
+	vc->state.color = (vc->state.color & 0xf0) | hue;
 }
 
 static void rgb_background(struct vc_data *vc, const struct rgb *c)
 {
 	/* For backgrounds, err on the dark side. */
-	vc->vc_color = (vc->vc_color & 0x0f)
+	vc->state.color = (vc->state.color & 0x0f)
 		| (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3;
 }
 
@@ -1712,13 +1715,13 @@ static void csi_m(struct vc_data *vc)
 			default_attr(vc);
 			break;
 		case 1:
-			vc->vc_intensity = 2;
+			vc->state.intensity = 2;
 			break;
 		case 2:
-			vc->vc_intensity = 0;
+			vc->state.intensity = 0;
 			break;
 		case 3:
-			vc->vc_italic = 1;
+			vc->state.italic = 1;
 			break;
 		case 21:
 			/*
@@ -1726,21 +1729,21 @@ static void csi_m(struct vc_data *vc)
 			 * convert it to a single underline.
 			 */
 		case 4:
-			vc->vc_underline = 1;
+			vc->state.underline = 1;
 			break;
 		case 5:
-			vc->vc_blink = 1;
+			vc->state.blink = 1;
 			break;
 		case 7:
-			vc->vc_reverse = 1;
+			vc->state.reverse = 1;
 			break;
 		case 10: /* ANSI X3.64-1979 (SCO-ish?)
 			  * Select primary font, don't display control chars if
 			  * defined, don't set bit 8 on output.
 			  */
-			vc->vc_translate = set_translate(vc->vc_charset == 0
-					? vc->vc_G0_charset
-					: vc->vc_G1_charset, vc);
+			vc->vc_translate = set_translate(vc->state.charset == 0
+					? vc->state.G0_charset
+					: vc->state.G1_charset, vc);
 			vc->vc_disp_ctrl = 0;
 			vc->vc_toggle_meta = 0;
 			break;
@@ -1761,19 +1764,19 @@ static void csi_m(struct vc_data *vc)
 			vc->vc_toggle_meta = 1;
 			break;
 		case 22:
-			vc->vc_intensity = 1;
+			vc->state.intensity = 1;
 			break;
 		case 23:
-			vc->vc_italic = 0;
+			vc->state.italic = 0;
 			break;
 		case 24:
-			vc->vc_underline = 0;
+			vc->state.underline = 0;
 			break;
 		case 25:
-			vc->vc_blink = 0;
+			vc->state.blink = 0;
 			break;
 		case 27:
-			vc->vc_reverse = 0;
+			vc->state.reverse = 0;
 			break;
 		case 38:
 			i = vc_t416_color(vc, i, rgb_foreground);
@@ -1782,25 +1785,25 @@ static void csi_m(struct vc_data *vc)
 			i = vc_t416_color(vc, i, rgb_background);
 			break;
 		case 39:
-			vc->vc_color = (vc->vc_def_color & 0x0f) |
-				(vc->vc_color & 0xf0);
+			vc->state.color = (vc->vc_def_color & 0x0f) |
+				(vc->state.color & 0xf0);
 			break;
 		case 49:
-			vc->vc_color = (vc->vc_def_color & 0xf0) |
-				(vc->vc_color & 0x0f);
+			vc->state.color = (vc->vc_def_color & 0xf0) |
+				(vc->state.color & 0x0f);
 			break;
 		default:
 			if (vc->vc_par[i] >= 90 && vc->vc_par[i] <= 107) {
 				if (vc->vc_par[i] < 100)
-					vc->vc_intensity = 2;
+					vc->state.intensity = 2;
 				vc->vc_par[i] -= 60;
 			}
 			if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
-				vc->vc_color = color_table[vc->vc_par[i] - 30]
-					| (vc->vc_color & 0xf0);
+				vc->state.color = color_table[vc->vc_par[i] - 30]
+					| (vc->state.color & 0xf0);
 			else if (vc->vc_par[i] >= 40 && vc->vc_par[i] <= 47)
-				vc->vc_color = (color_table[vc->vc_par[i] - 40] << 4)
-					| (vc->vc_color & 0x0f);
+				vc->state.color = (color_table[vc->vc_par[i] - 40] << 4)
+					| (vc->state.color & 0x0f);
 			break;
 		}
 	update_attr(vc);
@@ -1819,7 +1822,7 @@ static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
 {
 	char buf[40];
 
-	sprintf(buf, "\033[%d;%dR", vc->vc_y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->vc_x + 1);
+	sprintf(buf, "\033[%d;%dR", vc->state.y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->state.x + 1);
 	respond_string(buf, tty->port);
 }
 
@@ -1924,14 +1927,14 @@ static void setterm_command(struct vc_data *vc)
 	case 1:	/* set color for underline mode */
 		if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
 			vc->vc_ulcolor = color_table[vc->vc_par[1]];
-			if (vc->vc_underline)
+			if (vc->state.underline)
 				update_attr(vc);
 		}
 		break;
 	case 2:	/* set color for half intensity mode */
 		if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
 			vc->vc_halfcolor = color_table[vc->vc_par[1]];
-			if (vc->vc_intensity == 0)
+			if (vc->state.intensity == 0)
 				update_attr(vc);
 		}
 		break;
@@ -1985,8 +1988,8 @@ static void setterm_command(struct vc_data *vc)
 /* console_lock is held */
 static void csi_at(struct vc_data *vc, unsigned int nr)
 {
-	if (nr > vc->vc_cols - vc->vc_x)
-		nr = vc->vc_cols - vc->vc_x;
+	if (nr > vc->vc_cols - vc->state.x)
+		nr = vc->vc_cols - vc->state.x;
 	else if (!nr)
 		nr = 1;
 	insert_char(vc, nr);
@@ -1995,19 +1998,19 @@ static void csi_at(struct vc_data *vc, unsigned int nr)
 /* console_lock is held */
 static void csi_L(struct vc_data *vc, unsigned int nr)
 {
-	if (nr > vc->vc_rows - vc->vc_y)
-		nr = vc->vc_rows - vc->vc_y;
+	if (nr > vc->vc_rows - vc->state.y)
+		nr = vc->vc_rows - vc->state.y;
 	else if (!nr)
 		nr = 1;
-	con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_DOWN, nr);
+	con_scroll(vc, vc->state.y, vc->vc_bottom, SM_DOWN, nr);
 	vc->vc_need_wrap = 0;
 }
 
 /* console_lock is held */
 static void csi_P(struct vc_data *vc, unsigned int nr)
 {
-	if (nr > vc->vc_cols - vc->vc_x)
-		nr = vc->vc_cols - vc->vc_x;
+	if (nr > vc->vc_cols - vc->state.x)
+		nr = vc->vc_cols - vc->state.x;
 	else if (!nr)
 		nr = 1;
 	delete_char(vc, nr);
@@ -2016,44 +2019,28 @@ static void csi_P(struct vc_data *vc, unsigned int nr)
 /* console_lock is held */
 static void csi_M(struct vc_data *vc, unsigned int nr)
 {
-	if (nr > vc->vc_rows - vc->vc_y)
-		nr = vc->vc_rows - vc->vc_y;
+	if (nr > vc->vc_rows - vc->state.y)
+		nr = vc->vc_rows - vc->state.y;
 	else if (!nr)
 		nr=1;
-	con_scroll(vc, vc->vc_y, vc->vc_bottom, SM_UP, nr);
+	con_scroll(vc, vc->state.y, vc->vc_bottom, SM_UP, nr);
 	vc->vc_need_wrap = 0;
 }
 
 /* console_lock is held (except via vc_init->reset_terminal */
 static void save_cur(struct vc_data *vc)
 {
-	vc->vc_saved_x		= vc->vc_x;
-	vc->vc_saved_y		= vc->vc_y;
-	vc->vc_s_intensity	= vc->vc_intensity;
-	vc->vc_s_italic         = vc->vc_italic;
-	vc->vc_s_underline	= vc->vc_underline;
-	vc->vc_s_blink		= vc->vc_blink;
-	vc->vc_s_reverse	= vc->vc_reverse;
-	vc->vc_s_charset	= vc->vc_charset;
-	vc->vc_s_color		= vc->vc_color;
-	vc->vc_saved_G0		= vc->vc_G0_charset;
-	vc->vc_saved_G1		= vc->vc_G1_charset;
+	memcpy(&vc->saved_state, &vc->state, sizeof(vc->state));
 }
 
 /* console_lock is held */
 static void restore_cur(struct vc_data *vc)
 {
-	gotoxy(vc, vc->vc_saved_x, vc->vc_saved_y);
-	vc->vc_intensity	= vc->vc_s_intensity;
-	vc->vc_italic		= vc->vc_s_italic;
-	vc->vc_underline	= vc->vc_s_underline;
-	vc->vc_blink		= vc->vc_s_blink;
-	vc->vc_reverse		= vc->vc_s_reverse;
-	vc->vc_charset		= vc->vc_s_charset;
-	vc->vc_color		= vc->vc_s_color;
-	vc->vc_G0_charset	= vc->vc_saved_G0;
-	vc->vc_G1_charset	= vc->vc_saved_G1;
-	vc->vc_translate	= set_translate(vc->vc_charset ? vc->vc_G1_charset : vc->vc_G0_charset, vc);
+	memcpy(&vc->state, &vc->saved_state, sizeof(vc->state));
+
+	gotoxy(vc, vc->state.x, vc->state.y);
+	vc->vc_translate = set_translate(vc->state.charset ? vc->state.G1_charset :
+			vc->state.G0_charset, vc);
 	update_attr(vc);
 	vc->vc_need_wrap = 0;
 }
@@ -2070,9 +2057,9 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 	vc->vc_state		= ESnormal;
 	vc->vc_priv		= EPecma;
 	vc->vc_translate	= set_translate(LAT1_MAP, vc);
-	vc->vc_G0_charset	= LAT1_MAP;
-	vc->vc_G1_charset	= GRAF_MAP;
-	vc->vc_charset		= 0;
+	vc->state.G0_charset	= LAT1_MAP;
+	vc->state.G1_charset	= GRAF_MAP;
+	vc->state.charset	= 0;
 	vc->vc_need_wrap	= 0;
 	vc->vc_report_mouse	= 0;
 	vc->vc_utf              = default_utf8;
@@ -2136,13 +2123,13 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		bs(vc);
 		return;
 	case 9:
-		vc->vc_pos -= (vc->vc_x << 1);
-		while (vc->vc_x < vc->vc_cols - 1) {
-			vc->vc_x++;
-			if (vc->vc_tab_stop[7 & (vc->vc_x >> 5)] & (1 << (vc->vc_x & 31)))
+		vc->vc_pos -= (vc->state.x << 1);
+		while (vc->state.x < vc->vc_cols - 1) {
+			vc->state.x++;
+			if (vc->vc_tab_stop[7 & (vc->state.x >> 5)] & (1 << (vc->state.x & 31)))
 				break;
 		}
-		vc->vc_pos += (vc->vc_x << 1);
+		vc->vc_pos += (vc->state.x << 1);
 		notify_write(vc, '\t');
 		return;
 	case 10: case 11: case 12:
@@ -2154,13 +2141,13 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		cr(vc);
 		return;
 	case 14:
-		vc->vc_charset = 1;
-		vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
+		vc->state.charset = 1;
+		vc->vc_translate = set_translate(vc->state.G1_charset, vc);
 		vc->vc_disp_ctrl = 1;
 		return;
 	case 15:
-		vc->vc_charset = 0;
-		vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
+		vc->state.charset = 0;
+		vc->vc_translate = set_translate(vc->state.G0_charset, vc);
 		vc->vc_disp_ctrl = 0;
 		return;
 	case 24: case 26:
@@ -2200,7 +2187,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			lf(vc);
 			return;
 		case 'H':
-			vc->vc_tab_stop[7 & (vc->vc_x >> 5)] |= (1 << (vc->vc_x & 31));
+			vc->vc_tab_stop[7 & (vc->state.x >> 5)] |= (1 << (vc->state.x & 31));
 			return;
 		case 'Z':
 			respond_ID(tty);
@@ -2347,42 +2334,42 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case 'G': case '`':
 			if (vc->vc_par[0])
 				vc->vc_par[0]--;
-			gotoxy(vc, vc->vc_par[0], vc->vc_y);
+			gotoxy(vc, vc->vc_par[0], vc->state.y);
 			return;
 		case 'A':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, vc->vc_x, vc->vc_y - vc->vc_par[0]);
+			gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
 			return;
 		case 'B': case 'e':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, vc->vc_x, vc->vc_y + vc->vc_par[0]);
+			gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
 			return;
 		case 'C': case 'a':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, vc->vc_x + vc->vc_par[0], vc->vc_y);
+			gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
 			return;
 		case 'D':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, vc->vc_x - vc->vc_par[0], vc->vc_y);
+			gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
 			return;
 		case 'E':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, 0, vc->vc_y + vc->vc_par[0]);
+			gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
 			return;
 		case 'F':
 			if (!vc->vc_par[0])
 				vc->vc_par[0]++;
-			gotoxy(vc, 0, vc->vc_y - vc->vc_par[0]);
+			gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
 			return;
 		case 'd':
 			if (vc->vc_par[0])
 				vc->vc_par[0]--;
-			gotoxay(vc, vc->vc_x ,vc->vc_par[0]);
+			gotoxay(vc, vc->state.x ,vc->vc_par[0]);
 			return;
 		case 'H': case 'f':
 			if (vc->vc_par[0])
@@ -2412,7 +2399,7 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			return;
 		case 'g':
 			if (!vc->vc_par[0])
-				vc->vc_tab_stop[7 & (vc->vc_x >> 5)] &= ~(1 << (vc->vc_x & 31));
+				vc->vc_tab_stop[7 & (vc->state.x >> 5)] &= ~(1 << (vc->state.x & 31));
 			else if (vc->vc_par[0] == 3) {
 				vc->vc_tab_stop[0] =
 					vc->vc_tab_stop[1] =
@@ -2497,28 +2484,28 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		return;
 	case ESsetG0:
 		if (c == '0')
-			vc->vc_G0_charset = GRAF_MAP;
+			vc->state.G0_charset = GRAF_MAP;
 		else if (c == 'B')
-			vc->vc_G0_charset = LAT1_MAP;
+			vc->state.G0_charset = LAT1_MAP;
 		else if (c == 'U')
-			vc->vc_G0_charset = IBMPC_MAP;
+			vc->state.G0_charset = IBMPC_MAP;
 		else if (c == 'K')
-			vc->vc_G0_charset = USER_MAP;
-		if (vc->vc_charset == 0)
-			vc->vc_translate = set_translate(vc->vc_G0_charset, vc);
+			vc->state.G0_charset = USER_MAP;
+		if (vc->state.charset == 0)
+			vc->vc_translate = set_translate(vc->state.G0_charset, vc);
 		vc->vc_state = ESnormal;
 		return;
 	case ESsetG1:
 		if (c == '0')
-			vc->vc_G1_charset = GRAF_MAP;
+			vc->state.G1_charset = GRAF_MAP;
 		else if (c == 'B')
-			vc->vc_G1_charset = LAT1_MAP;
+			vc->state.G1_charset = LAT1_MAP;
 		else if (c == 'U')
-			vc->vc_G1_charset = IBMPC_MAP;
+			vc->state.G1_charset = IBMPC_MAP;
 		else if (c == 'K')
-			vc->vc_G1_charset = USER_MAP;
-		if (vc->vc_charset == 1)
-			vc->vc_translate = set_translate(vc->vc_G1_charset, vc);
+			vc->state.G1_charset = USER_MAP;
+		if (vc->state.charset == 1)
+			vc->vc_translate = set_translate(vc->state.G1_charset, vc);
 		vc->vc_state = ESnormal;
 		return;
 	case ESosc:
@@ -2572,7 +2559,7 @@ static void con_flush(struct vc_data *vc, unsigned long draw_from,
 		return;
 
 	vc->vc_sw->con_putcs(vc, (u16 *)draw_from,
-			(u16 *)draw_to - (u16 *)draw_from, vc->vc_y, *draw_x);
+			(u16 *)draw_to - (u16 *)draw_from, vc->state.y, *draw_x);
 	*draw_x = -1;
 }
 
@@ -2788,14 +2775,14 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 					     (vc_attr << 8) + tc,
 					   (u16 *) vc->vc_pos);
 				if (con_should_update(vc) && draw_x < 0) {
-					draw_x = vc->vc_x;
+					draw_x = vc->state.x;
 					draw_from = vc->vc_pos;
 				}
-				if (vc->vc_x == vc->vc_cols - 1) {
+				if (vc->state.x == vc->vc_cols - 1) {
 					vc->vc_need_wrap = vc->vc_decawm;
 					draw_to = vc->vc_pos + 2;
 				} else {
-					vc->vc_x++;
+					vc->state.x++;
 					draw_to = (vc->vc_pos += 2);
 				}
 
@@ -2972,25 +2959,25 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 		hide_cursor(vc);
 
 	start = (ushort *)vc->vc_pos;
-	start_x = vc->vc_x;
+	start_x = vc->state.x;
 	cnt = 0;
 	while (count--) {
 		c = *b++;
 		if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
 			if (cnt && con_is_visible(vc))
-				vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
+				vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
 			cnt = 0;
 			if (c == 8) {		/* backspace */
 				bs(vc);
 				start = (ushort *)vc->vc_pos;
-				start_x = vc->vc_x;
+				start_x = vc->state.x;
 				continue;
 			}
 			if (c != 13)
 				lf(vc);
 			cr(vc);
 			start = (ushort *)vc->vc_pos;
-			start_x = vc->vc_x;
+			start_x = vc->state.x;
 			if (c == 10 || c == 13)
 				continue;
 		}
@@ -2998,15 +2985,15 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
 		scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
 		notify_write(vc, c);
 		cnt++;
-		if (vc->vc_x == vc->vc_cols - 1) {
+		if (vc->state.x == vc->vc_cols - 1) {
 			vc->vc_need_wrap = 1;
 		} else {
 			vc->vc_pos += 2;
-			vc->vc_x++;
+			vc->state.x++;
 		}
 	}
 	if (cnt && con_is_visible(vc))
-		vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
+		vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
 	set_cursor(vc);
 	notify_update(vc);
 
@@ -3401,7 +3388,7 @@ static int __init con_init(void)
 	master_display_fg = vc = vc_cons[currcons].d;
 	set_origin(vc);
 	save_screen(vc);
-	gotoxy(vc, vc->vc_x, vc->vc_y);
+	gotoxy(vc, vc->state.x, vc->state.y);
 	csi_J(vc, 0);
 	update_screen(vc);
 	pr_info("Console: %s %s %dx%d\n",
@@ -4680,8 +4667,8 @@ EXPORT_SYMBOL_GPL(screen_pos);
 void getconsxy(struct vc_data *vc, unsigned char *p)
 {
 	/* clamp values if they don't fit */
-	p[0] = min(vc->vc_x, 0xFFu);
-	p[1] = min(vc->vc_y, 0xFFu);
+	p[0] = min(vc->state.x, 0xFFu);
+	p[1] = min(vc->state.y, 0xFFu);
 }
 
 void putconsxy(struct vc_data *vc, unsigned char *p)
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index d0d427a2f1a3..d64c5ce84125 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -488,7 +488,7 @@ static void mdacon_cursor(struct vc_data *c, int mode)
 		return;
 	}
 
-	mda_set_cursor(c->vc_y*mda_num_columns*2 + c->vc_x*2);
+	mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2);
 
 	switch (c->vc_cursor_type & 0x0f) {
 
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 79c9bd8d3025..90083eb80515 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -132,10 +132,10 @@ static void sticon_cursor(struct vc_data *conp, int mode)
 {
     unsigned short car1;
 
-    car1 = conp->vc_screenbuf[conp->vc_x + conp->vc_y * conp->vc_cols];
+    car1 = conp->vc_screenbuf[conp->state.x + conp->state.y * conp->vc_cols];
     switch (mode) {
     case CM_ERASE:
-	sti_putc(sticon_sti, car1, conp->vc_y, conp->vc_x);
+	sti_putc(sticon_sti, car1, conp->state.y, conp->state.x);
 	break;
     case CM_MOVE:
     case CM_DRAW:
@@ -146,7 +146,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
 	case CUR_TWO_THIRDS:
 	case CUR_BLOCK:
 	    sti_putc(sticon_sti, (car1 & 255) + (0 << 8) + (7 << 11),
-		     conp->vc_y, conp->vc_x);
+		     conp->state.y, conp->state.x);
 	    break;
 	}
 	break;
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 998b0de1812f..d073fa167e87 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -718,9 +718,9 @@ static void vgacon_cursor(struct vc_data *c, int mode)
 	case CM_ERASE:
 		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
 	        if (vga_video_type >= VIDEO_TYPE_VGAC)
-			vgacon_set_cursor_size(c->vc_x, 31, 30);
+			vgacon_set_cursor_size(c->state.x, 31, 30);
 		else
-			vgacon_set_cursor_size(c->vc_x, 31, 31);
+			vgacon_set_cursor_size(c->state.x, 31, 31);
 		break;
 
 	case CM_MOVE:
@@ -728,7 +728,7 @@ static void vgacon_cursor(struct vc_data *c, int mode)
 		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
 		switch (c->vc_cursor_type & 0x0f) {
 		case CUR_UNDERLINE:
-			vgacon_set_cursor_size(c->vc_x,
+			vgacon_set_cursor_size(c->state.x,
 					       c->vc_font.height -
 					       (c->vc_font.height <
 						10 ? 2 : 3),
@@ -737,21 +737,21 @@ static void vgacon_cursor(struct vc_data *c, int mode)
 						10 ? 1 : 2));
 			break;
 		case CUR_TWO_THIRDS:
-			vgacon_set_cursor_size(c->vc_x,
+			vgacon_set_cursor_size(c->state.x,
 					       c->vc_font.height / 3,
 					       c->vc_font.height -
 					       (c->vc_font.height <
 						10 ? 1 : 2));
 			break;
 		case CUR_LOWER_THIRD:
-			vgacon_set_cursor_size(c->vc_x,
+			vgacon_set_cursor_size(c->state.x,
 					       (c->vc_font.height * 2) / 3,
 					       c->vc_font.height -
 					       (c->vc_font.height <
 						10 ? 1 : 2));
 			break;
 		case CUR_LOWER_HALF:
-			vgacon_set_cursor_size(c->vc_x,
+			vgacon_set_cursor_size(c->state.x,
 					       c->vc_font.height / 2,
 					       c->vc_font.height -
 					       (c->vc_font.height <
@@ -759,12 +759,12 @@ static void vgacon_cursor(struct vc_data *c, int mode)
 			break;
 		case CUR_NONE:
 			if (vga_video_type >= VIDEO_TYPE_VGAC)
-				vgacon_set_cursor_size(c->vc_x, 31, 30);
+				vgacon_set_cursor_size(c->state.x, 31, 30);
 			else
-				vgacon_set_cursor_size(c->vc_x, 31, 31);
+				vgacon_set_cursor_size(c->state.x, 31, 31);
 			break;
 		default:
-			vgacon_set_cursor_size(c->vc_x, 1,
+			vgacon_set_cursor_size(c->state.x, 1,
 					       c->vc_font.height);
 			break;
 		}
@@ -1352,8 +1352,8 @@ static void vgacon_save_screen(struct vc_data *c)
 		 * console initialization routines.
 		 */
 		vga_bootup_console = 1;
-		c->vc_x = screen_info.orig_x;
-		c->vc_y = screen_info.orig_y;
+		c->state.x = screen_info.orig_x;
+		c->state.y = screen_info.orig_y;
 	}
 
 	/* We can't copy in more than the size of the video buffer,
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index ca935c09a261..c750470a31ec 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -240,7 +240,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	struct fbcon_ops *ops = info->fbcon_par;
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
-	int y = real_y(ops->p, vc->vc_y);
+	int y = real_y(ops->p, vc->state.y);
 	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
 	int err = 1;
 	char *src;
@@ -286,10 +286,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 		cursor.set |= FB_CUR_SETCMAP;
 	}
 
-	if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->vc_x)) ||
+	if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) ||
 	    (ops->cursor_state.image.dy != (vc->vc_font.height * y)) ||
 	    ops->cursor_reset) {
-		ops->cursor_state.image.dx = vc->vc_font.width * vc->vc_x;
+		ops->cursor_state.image.dx = vc->vc_font.width * vc->state.x;
 		ops->cursor_state.image.dy = vc->vc_font.height * y;
 		cursor.set |= FB_CUR_SETPOS;
 	}
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 9d28a8e3328f..38d2a00b0ccf 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -655,11 +655,11 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
 		}
 		if (!save) {
 			int lines;
-			if (vc->vc_y + logo_lines >= rows)
-				lines = rows - vc->vc_y - 1;
+			if (vc->state.y + logo_lines >= rows)
+				lines = rows - vc->state.y - 1;
 			else
 				lines = logo_lines;
-			vc->vc_y += lines;
+			vc->state.y += lines;
 			vc->vc_pos += lines * vc->vc_size_row;
 		}
 	}
@@ -677,7 +677,7 @@ static void fbcon_prepare_logo(struct vc_data *vc, struct fb_info *info,
 					vc->vc_size_row *
 					rows);
 		scr_memcpyw(q, save, logo_lines * new_cols * 2);
-		vc->vc_y += logo_lines;
+		vc->state.y += logo_lines;
 		vc->vc_pos += logo_lines * vc->vc_size_row;
 		kfree(save);
 	}
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index dfa9a8aa4509..9d06446a1a3b 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -225,7 +225,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	struct fbcon_ops *ops = info->fbcon_par;
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.height + 7) >> 3, c;
-	int y = real_y(ops->p, vc->vc_y);
+	int y = real_y(ops->p, vc->state.y);
 	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
 	int err = 1, dx, dy;
 	char *src;
@@ -284,7 +284,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	}
 
 	dx = y * vc->vc_font.height;
-	dy = vyres - ((vc->vc_x + 1) * vc->vc_font.width);
+	dy = vyres - ((vc->state.x + 1) * vc->vc_font.width);
 
 	if (ops->cursor_state.image.dx != dx ||
 	    ops->cursor_state.image.dy != dy ||
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index ce08251bfd38..4b5f76bb01e5 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -208,7 +208,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	struct fbcon_ops *ops = info->fbcon_par;
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.height + 7) >> 3, c;
-	int y = real_y(ops->p, vc->vc_y);
+	int y = real_y(ops->p, vc->state.y);
 	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
 	int err = 1, dx, dy;
 	char *src;
@@ -267,7 +267,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	}
 
 	dx = vxres - ((y * vc->vc_font.height) + vc->vc_font.height);
-	dy = vc->vc_x * vc->vc_font.width;
+	dy = vc->state.x * vc->vc_font.width;
 
 	if (ops->cursor_state.image.dx != dx ||
 	    ops->cursor_state.image.dy != dy ||
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 1936afc78fec..7e0ae3549dc7 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -255,7 +255,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	struct fbcon_ops *ops = info->fbcon_par;
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.width + 7) >> 3, c;
-	int y = real_y(ops->p, vc->vc_y);
+	int y = real_y(ops->p, vc->state.y);
 	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
 	int err = 1, dx, dy;
 	char *src;
@@ -315,7 +315,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	}
 
 	dy = vyres - ((y * vc->vc_font.height) + vc->vc_font.height);
-	dx = vxres - ((vc->vc_x * vc->vc_font.width) + vc->vc_font.width);
+	dx = vxres - ((vc->state.x * vc->vc_font.width) + vc->vc_font.width);
 
 	if (ops->cursor_state.image.dx != dx ||
 	    ops->cursor_state.image.dy != dy ||
diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c
index 93390312957f..ac51425687e4 100644
--- a/drivers/video/fbdev/core/tileblit.c
+++ b/drivers/video/fbdev/core/tileblit.c
@@ -85,8 +85,8 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	struct fb_tilecursor cursor;
 	int use_sw = (vc->vc_cursor_type & 0x10);
 
-	cursor.sx = vc->vc_x;
-	cursor.sy = vc->vc_y;
+	cursor.sx = vc->state.x;
+	cursor.sy = vc->state.y;
 	cursor.mode = (mode == CM_ERASE || use_sw) ? 0 : 1;
 	cursor.fg = fg;
 	cursor.bg = bg;
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 24d4c16e3ae0..162f4337c767 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -22,6 +22,37 @@ struct uni_screen;
 
 #define NPAR 16
 
+/**
+ * struct vc_state -- state of a VC
+ * @x: cursor's x-position
+ * @y: cursor's y-position
+ * @color: foreground & background colors
+ * @G0_charset: what's G0 slot set to (like GRAF_MAP, LAT1_MAP)
+ * @G1_charset: what's G1 slot set to (like GRAF_MAP, LAT1_MAP)
+ * @charset: what character set to use (0=G0 or 1=G1)
+ * @intensity: 0=half-bright, 1=normal, 2=bold
+ * @reverse: reversed foreground/background colors
+ *
+ * These members are defined separately from struct vc_data as we save &
+ * restore them at times.
+ */
+struct vc_state {
+	unsigned int	x, y;
+
+	unsigned char	color;
+
+	unsigned char	G0_charset;
+	unsigned char	G1_charset;
+	unsigned int	charset		: 1;
+
+	/* attribute flags */
+	unsigned int	intensity	: 2;
+	unsigned int	italic		: 1;
+	unsigned int	underline	: 1;
+	unsigned int	blink		: 1;
+	unsigned int	reverse		: 1;
+};
+
 /*
  * Example: vc_data of a console that was scrolled 3 lines down.
  *
@@ -57,6 +88,8 @@ struct uni_screen;
 struct vc_data {
 	struct tty_port port;			/* Upper level data */
 
+	struct vc_state state, saved_state;
+
 	unsigned short	vc_num;			/* Console number */
 	unsigned int	vc_cols;		/* [#] Console size */
 	unsigned int	vc_rows;
@@ -73,8 +106,6 @@ struct vc_data {
 	/* attributes for all characters on screen */
 	unsigned char	vc_attr;		/* Current attributes */
 	unsigned char	vc_def_color;		/* Default colors */
-	unsigned char	vc_color;		/* Foreground & background */
-	unsigned char	vc_s_color;		/* Saved foreground & background */
 	unsigned char	vc_ulcolor;		/* Color for underline mode */
 	unsigned char   vc_itcolor;
 	unsigned char	vc_halfcolor;		/* Color for half intensity mode */
@@ -82,8 +113,6 @@ struct vc_data {
 	unsigned int	vc_cursor_type;
 	unsigned short	vc_complement_mask;	/* [#] Xor mask for mouse pointer */
 	unsigned short	vc_s_complement_mask;	/* Saved mouse pointer mask */
-	unsigned int	vc_x, vc_y;		/* Cursor position */
-	unsigned int	vc_saved_x, vc_saved_y;
 	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 */
@@ -98,8 +127,6 @@ struct vc_data {
 	int		vt_newvt;
 	wait_queue_head_t paste_wait;
 	/* mode flags */
-	unsigned int	vc_charset	: 1;	/* Character set G0 / G1 */
-	unsigned int	vc_s_charset	: 1;	/* Saved character set */
 	unsigned int	vc_disp_ctrl	: 1;	/* Display chars < 32? */
 	unsigned int	vc_toggle_meta	: 1;	/* Toggle high bit? */
 	unsigned int	vc_decscnm	: 1;	/* Screen Mode */
@@ -107,17 +134,6 @@ struct vc_data {
 	unsigned int	vc_decawm	: 1;	/* Autowrap Mode */
 	unsigned int	vc_deccm	: 1;	/* Cursor Visible */
 	unsigned int	vc_decim	: 1;	/* Insert Mode */
-	/* attribute flags */
-	unsigned int	vc_intensity	: 2;	/* 0=half-bright, 1=normal, 2=bold */
-	unsigned int    vc_italic:1;
-	unsigned int	vc_underline	: 1;
-	unsigned int	vc_blink	: 1;
-	unsigned int	vc_reverse	: 1;
-	unsigned int	vc_s_intensity	: 2;	/* saved rendition */
-	unsigned int    vc_s_italic:1;
-	unsigned int	vc_s_underline	: 1;
-	unsigned int	vc_s_blink	: 1;
-	unsigned int	vc_s_reverse	: 1;
 	/* misc */
 	unsigned int	vc_priv		: 3;
 	unsigned int	vc_need_wrap	: 1;
@@ -129,10 +145,6 @@ struct vc_data {
 	unsigned int	vc_tab_stop[8];		/* Tab stops. 256 columns. */
 	unsigned char   vc_palette[16*3];       /* Colour palette for VGA+ */
 	unsigned short * vc_translate;
-	unsigned char 	vc_G0_charset;
-	unsigned char 	vc_G1_charset;
-	unsigned char 	vc_saved_G0;
-	unsigned char 	vc_saved_G1;
 	unsigned int    vc_resize_user;         /* resize request from user */
 	unsigned int	vc_bell_pitch;		/* Console bell pitch */
 	unsigned int	vc_bell_duration;	/* Console bell duration */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 02/38] vt: introduce enum vc_intensity for intensity
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 03/38] vc: switch state to bool Jiri Slaby
                   ` (35 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Introduce names (en enum) for 0, 1, and 2 constants. We now have
VCI_HALF_BRIGHT, VCI_NORMAL, and VCI_BOLD instead.

Apart from the cleanup,
1) the enum allows for better type checking, and
2) this saves some code. No more fiddling with bits is needed in
   assembly now. (OTOH, the structure is larger.)

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c                     | 32 +++++++++++++------------
 drivers/usb/misc/sisusbvga/sisusb_con.c |  6 ++---
 drivers/video/console/mdacon.c          |  5 ++--
 drivers/video/console/sticon.c          |  3 ++-
 drivers/video/console/vgacon.c          |  9 +++----
 include/linux/console.h                 |  5 +++-
 include/linux/console_struct.h          | 11 +++++++--
 7 files changed, 43 insertions(+), 28 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 76f52935e0c8..71bf483e5640 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -705,8 +705,9 @@ void update_region(struct vc_data *vc, unsigned long start, int count)
 
 /* Structure of attributes is hardware-dependent */
 
-static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
-    u8 _underline, u8 _reverse, u8 _italic)
+static u8 build_attr(struct vc_data *vc, u8 _color,
+		enum vc_intensity _intensity, u8 _blink, u8 _underline,
+		u8 _reverse, u8 _italic)
 {
 	if (vc->vc_sw->con_build_attr)
 		return vc->vc_sw->con_build_attr(vc, _color, _intensity,
@@ -734,13 +735,13 @@ static u8 build_attr(struct vc_data *vc, u8 _color, u8 _intensity, u8 _blink,
 		a = (a & 0xF0) | vc->vc_itcolor;
 	else if (_underline)
 		a = (a & 0xf0) | vc->vc_ulcolor;
-	else if (_intensity == 0)
+	else if (_intensity == VCI_HALF_BRIGHT)
 		a = (a & 0xf0) | vc->vc_halfcolor;
 	if (_reverse)
 		a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
 	if (_blink)
 		a ^= 0x80;
-	if (_intensity == 2)
+	if (_intensity == VCI_BOLD)
 		a ^= 0x08;
 	if (vc->vc_hi_font_mask == 0x100)
 		a <<= 1;
@@ -753,8 +754,9 @@ static void update_attr(struct vc_data *vc)
 	vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity,
 	              vc->state.blink, vc->state.underline,
 	              vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
-	vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color, 1,
-				vc->state.blink, 0, vc->vc_decscnm, 0) << 8);
+	vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
+				VCI_NORMAL, vc->state.blink, 0, vc->vc_decscnm,
+				0) << 8);
 }
 
 /* Note: inverting the screen twice should revert to the original state */
@@ -1611,7 +1613,7 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
 
 static void default_attr(struct vc_data *vc)
 {
-	vc->state.intensity = 1;
+	vc->state.intensity = VCI_NORMAL;
 	vc->state.italic = 0;
 	vc->state.underline = 0;
 	vc->state.reverse = 0;
@@ -1652,11 +1654,11 @@ static void rgb_foreground(struct vc_data *vc, const struct rgb *c)
 
 	if (hue == 7 && max <= 0x55) {
 		hue = 0;
-		vc->state.intensity = 2;
+		vc->state.intensity = VCI_BOLD;
 	} else if (max > 0xaa)
-		vc->state.intensity = 2;
+		vc->state.intensity = VCI_BOLD;
 	else
-		vc->state.intensity = 1;
+		vc->state.intensity = VCI_NORMAL;
 
 	vc->state.color = (vc->state.color & 0xf0) | hue;
 }
@@ -1715,10 +1717,10 @@ static void csi_m(struct vc_data *vc)
 			default_attr(vc);
 			break;
 		case 1:
-			vc->state.intensity = 2;
+			vc->state.intensity = VCI_BOLD;
 			break;
 		case 2:
-			vc->state.intensity = 0;
+			vc->state.intensity = VCI_HALF_BRIGHT;
 			break;
 		case 3:
 			vc->state.italic = 1;
@@ -1764,7 +1766,7 @@ static void csi_m(struct vc_data *vc)
 			vc->vc_toggle_meta = 1;
 			break;
 		case 22:
-			vc->state.intensity = 1;
+			vc->state.intensity = VCI_NORMAL;
 			break;
 		case 23:
 			vc->state.italic = 0;
@@ -1795,7 +1797,7 @@ static void csi_m(struct vc_data *vc)
 		default:
 			if (vc->vc_par[i] >= 90 && vc->vc_par[i] <= 107) {
 				if (vc->vc_par[i] < 100)
-					vc->state.intensity = 2;
+					vc->state.intensity = VCI_BOLD;
 				vc->vc_par[i] -= 60;
 			}
 			if (vc->vc_par[i] >= 30 && vc->vc_par[i] <= 37)
@@ -1934,7 +1936,7 @@ static void setterm_command(struct vc_data *vc)
 	case 2:	/* set color for half intensity mode */
 		if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
 			vc->vc_halfcolor = color_table[vc->vc_par[1]];
-			if (vc->state.intensity == 0)
+			if (vc->state.intensity == VCI_HALF_BRIGHT)
 				update_attr(vc);
 		}
 		break;
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index cd0155310fea..c59fe641b8b5 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -302,14 +302,14 @@ sisusbcon_deinit(struct vc_data *c)
 
 /* interface routine */
 static u8
-sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
+sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity,
 			    u8 blink, u8 underline, u8 reverse, u8 unused)
 {
 	u8 attr = color;
 
 	if (underline)
 		attr = (attr & 0xf0) | c->vc_ulcolor;
-	else if (intensity == 0)
+	else if (intensity == VCI_HALF_BRIGHT)
 		attr = (attr & 0xf0) | c->vc_halfcolor;
 
 	if (reverse)
@@ -320,7 +320,7 @@ sisusbcon_build_attr(struct vc_data *c, u8 color, u8 intensity,
 	if (blink)
 		attr ^= 0x80;
 
-	if (intensity == 2)
+	if (intensity == VCI_BOLD)
 		attr ^= 0x08;
 
 	return attr;
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index d64c5ce84125..e3da664df16c 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -394,7 +394,8 @@ static inline u16 mda_convert_attr(u16 ch)
 		(ch & 0x00ff) | attr;
 }
 
-static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity, 
+static u8 mdacon_build_attr(struct vc_data *c, u8 color,
+			    enum vc_intensity intensity,
 			    u8 blink, u8 underline, u8 reverse, u8 italic)
 {
 	/* The attribute is just a bit vector:
@@ -405,7 +406,7 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
 	 *	Bit 7    : blink
 	 */
 
-	return (intensity & 3) |
+	return (intensity & VCI_MASK) |
 		((underline & 1) << 2) |
 		((reverse   & 1) << 3) |
 		(!!italic << 4) |
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 90083eb80515..a847067abbe5 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -288,7 +288,8 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
     return ret;
 }
 
-static u8 sticon_build_attr(struct vc_data *conp, u8 color, u8 intens,
+static u8 sticon_build_attr(struct vc_data *conp, u8 color,
+			    enum vc_intensity intens,
 			    u8 blink, u8 underline, u8 reverse, u8 italic)
 {
     u8 attr = ((color & 0x70) >> 1) | ((color & 7));
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d073fa167e87..d0b26e2318d3 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -629,7 +629,8 @@ static void vgacon_deinit(struct vc_data *c)
 	con_set_default_unimap(c);
 }
 
-static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
+static u8 vgacon_build_attr(struct vc_data *c, u8 color,
+			    enum vc_intensity intensity,
 			    u8 blink, u8 underline, u8 reverse, u8 italic)
 {
 	u8 attr = color;
@@ -639,7 +640,7 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
 			attr = (attr & 0xF0) | c->vc_itcolor;
 		else if (underline)
 			attr = (attr & 0xf0) | c->vc_ulcolor;
-		else if (intensity == 0)
+		else if (intensity == VCI_HALF_BRIGHT)
 			attr = (attr & 0xf0) | c->vc_halfcolor;
 	}
 	if (reverse)
@@ -648,14 +649,14 @@ static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity,
 				       0x77);
 	if (blink)
 		attr ^= 0x80;
-	if (intensity == 2)
+	if (intensity == VCI_BOLD)
 		attr ^= 0x08;
 	if (!vga_can_do_color) {
 		if (italic)
 			attr = (attr & 0xF8) | 0x02;
 		else if (underline)
 			attr = (attr & 0xf8) | 0x01;
-		else if (intensity == 0)
+		else if (intensity == VCI_HALF_BRIGHT)
 			attr = (attr & 0xf0) | 0x08;
 	}
 	return attr;
diff --git a/include/linux/console.h b/include/linux/console.h
index 75dd20650fbe..10c04779ae49 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -35,6 +35,8 @@ enum con_scroll {
 	SM_DOWN,
 };
 
+enum vc_intensity;
+
 /**
  * struct consw - callbacks for consoles
  *
@@ -74,7 +76,8 @@ struct consw {
 	void	(*con_scrolldelta)(struct vc_data *vc, int lines);
 	int	(*con_set_origin)(struct vc_data *vc);
 	void	(*con_save_screen)(struct vc_data *vc);
-	u8	(*con_build_attr)(struct vc_data *vc, u8 color, u8 intensity,
+	u8	(*con_build_attr)(struct vc_data *vc, u8 color,
+			enum vc_intensity intensity,
 			u8 blink, u8 underline, u8 reverse, u8 italic);
 	void	(*con_invert_region)(struct vc_data *vc, u16 *p, int count);
 	u16    *(*con_screen_pos)(struct vc_data *vc, int offset);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 162f4337c767..e901d98790bf 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -22,6 +22,13 @@ struct uni_screen;
 
 #define NPAR 16
 
+enum vc_intensity {
+	VCI_HALF_BRIGHT,
+	VCI_NORMAL,
+	VCI_BOLD,
+	VCI_MASK = 0x3,
+};
+
 /**
  * struct vc_state -- state of a VC
  * @x: cursor's x-position
@@ -30,7 +37,7 @@ struct uni_screen;
  * @G0_charset: what's G0 slot set to (like GRAF_MAP, LAT1_MAP)
  * @G1_charset: what's G1 slot set to (like GRAF_MAP, LAT1_MAP)
  * @charset: what character set to use (0=G0 or 1=G1)
- * @intensity: 0=half-bright, 1=normal, 2=bold
+ * @intensity: see enum vc_intensity for values
  * @reverse: reversed foreground/background colors
  *
  * These members are defined separately from struct vc_data as we save &
@@ -46,7 +53,7 @@ struct vc_state {
 	unsigned int	charset		: 1;
 
 	/* attribute flags */
-	unsigned int	intensity	: 2;
+	enum vc_intensity intensity;
 	unsigned int	italic		: 1;
 	unsigned int	underline	: 1;
 	unsigned int	blink		: 1;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 03/38] vc: switch state to bool
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
  2020-06-15  7:48 ` [PATCH 02/38] vt: introduce enum vc_intensity for intensity Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 04/38] vt: deduplicate setGx code Jiri Slaby
                   ` (34 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

The code currently uses bitfields to store true-false values. Switch all
of that to bools. Apart from the cleanup, it saves 20B of code as many
shifts, ANDs, and ORs became simple movzb's.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c                     | 32 ++++++++++++-------------
 drivers/usb/misc/sisusbvga/sisusb_con.c |  3 ++-
 drivers/video/console/mdacon.c          | 11 +++++----
 drivers/video/console/sticon.c          |  3 ++-
 drivers/video/console/vgacon.c          |  3 ++-
 include/linux/console.h                 |  2 +-
 include/linux/console_struct.h          |  8 +++----
 7 files changed, 33 insertions(+), 29 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 71bf483e5640..26cb1fc48b27 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -706,8 +706,8 @@ void update_region(struct vc_data *vc, unsigned long start, int count)
 /* Structure of attributes is hardware-dependent */
 
 static u8 build_attr(struct vc_data *vc, u8 _color,
-		enum vc_intensity _intensity, u8 _blink, u8 _underline,
-		u8 _reverse, u8 _italic)
+		enum vc_intensity _intensity, bool _blink, bool _underline,
+		bool _reverse, bool _italic)
 {
 	if (vc->vc_sw->con_build_attr)
 		return vc->vc_sw->con_build_attr(vc, _color, _intensity,
@@ -755,8 +755,8 @@ static void update_attr(struct vc_data *vc)
 	              vc->state.blink, vc->state.underline,
 	              vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
 	vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
-				VCI_NORMAL, vc->state.blink, 0, vc->vc_decscnm,
-				0) << 8);
+				VCI_NORMAL, vc->state.blink, false,
+				vc->vc_decscnm, false) << 8);
 }
 
 /* Note: inverting the screen twice should revert to the original state */
@@ -1614,10 +1614,10 @@ static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar posi
 static void default_attr(struct vc_data *vc)
 {
 	vc->state.intensity = VCI_NORMAL;
-	vc->state.italic = 0;
-	vc->state.underline = 0;
-	vc->state.reverse = 0;
-	vc->state.blink = 0;
+	vc->state.italic = false;
+	vc->state.underline = false;
+	vc->state.reverse = false;
+	vc->state.blink = false;
 	vc->state.color = vc->vc_def_color;
 }
 
@@ -1723,7 +1723,7 @@ static void csi_m(struct vc_data *vc)
 			vc->state.intensity = VCI_HALF_BRIGHT;
 			break;
 		case 3:
-			vc->state.italic = 1;
+			vc->state.italic = true;
 			break;
 		case 21:
 			/*
@@ -1731,13 +1731,13 @@ static void csi_m(struct vc_data *vc)
 			 * convert it to a single underline.
 			 */
 		case 4:
-			vc->state.underline = 1;
+			vc->state.underline = true;
 			break;
 		case 5:
-			vc->state.blink = 1;
+			vc->state.blink = true;
 			break;
 		case 7:
-			vc->state.reverse = 1;
+			vc->state.reverse = true;
 			break;
 		case 10: /* ANSI X3.64-1979 (SCO-ish?)
 			  * Select primary font, don't display control chars if
@@ -1769,16 +1769,16 @@ static void csi_m(struct vc_data *vc)
 			vc->state.intensity = VCI_NORMAL;
 			break;
 		case 23:
-			vc->state.italic = 0;
+			vc->state.italic = false;
 			break;
 		case 24:
-			vc->state.underline = 0;
+			vc->state.underline = false;
 			break;
 		case 25:
-			vc->state.blink = 0;
+			vc->state.blink = false;
 			break;
 		case 27:
-			vc->state.reverse = 0;
+			vc->state.reverse = false;
 			break;
 		case 38:
 			i = vc_t416_color(vc, i, rgb_foreground);
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index c59fe641b8b5..80657c49310a 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -303,7 +303,8 @@ sisusbcon_deinit(struct vc_data *c)
 /* interface routine */
 static u8
 sisusbcon_build_attr(struct vc_data *c, u8 color, enum vc_intensity intensity,
-			    u8 blink, u8 underline, u8 reverse, u8 unused)
+			    bool blink, bool underline, bool reverse,
+			    bool unused)
 {
 	u8 attr = color;
 
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index e3da664df16c..00cb6245fbef 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -396,7 +396,8 @@ static inline u16 mda_convert_attr(u16 ch)
 
 static u8 mdacon_build_attr(struct vc_data *c, u8 color,
 			    enum vc_intensity intensity,
-			    u8 blink, u8 underline, u8 reverse, u8 italic)
+			    bool blink, bool underline, bool reverse,
+			    bool italic)
 {
 	/* The attribute is just a bit vector:
 	 *
@@ -407,10 +408,10 @@ static u8 mdacon_build_attr(struct vc_data *c, u8 color,
 	 */
 
 	return (intensity & VCI_MASK) |
-		((underline & 1) << 2) |
-		((reverse   & 1) << 3) |
-		(!!italic << 4) |
-		((blink     & 1) << 7);
+		(underline << 2) |
+		(reverse << 3) |
+		(italic << 4) |
+		(blink << 7);
 }
 
 static void mdacon_invert_region(struct vc_data *c, u16 *p, int count)
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index a847067abbe5..bbcdfd312c36 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -290,7 +290,8 @@ static unsigned long sticon_getxy(struct vc_data *conp, unsigned long pos,
 
 static u8 sticon_build_attr(struct vc_data *conp, u8 color,
 			    enum vc_intensity intens,
-			    u8 blink, u8 underline, u8 reverse, u8 italic)
+			    bool blink, bool underline, bool reverse,
+			    bool italic)
 {
     u8 attr = ((color & 0x70) >> 1) | ((color & 7));
 
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d0b26e2318d3..c1c4ce28ac5e 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -631,7 +631,8 @@ static void vgacon_deinit(struct vc_data *c)
 
 static u8 vgacon_build_attr(struct vc_data *c, u8 color,
 			    enum vc_intensity intensity,
-			    u8 blink, u8 underline, u8 reverse, u8 italic)
+			    bool blink, bool underline, bool reverse,
+			    bool italic)
 {
 	u8 attr = color;
 
diff --git a/include/linux/console.h b/include/linux/console.h
index 10c04779ae49..964b67912b04 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -78,7 +78,7 @@ struct consw {
 	void	(*con_save_screen)(struct vc_data *vc);
 	u8	(*con_build_attr)(struct vc_data *vc, u8 color,
 			enum vc_intensity intensity,
-			u8 blink, u8 underline, u8 reverse, u8 italic);
+			bool blink, bool underline, bool reverse, bool italic);
 	void	(*con_invert_region)(struct vc_data *vc, u16 *p, int count);
 	u16    *(*con_screen_pos)(struct vc_data *vc, int offset);
 	unsigned long (*con_getxy)(struct vc_data *vc, unsigned long position,
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index e901d98790bf..fa1abffe64be 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -54,10 +54,10 @@ struct vc_state {
 
 	/* attribute flags */
 	enum vc_intensity intensity;
-	unsigned int	italic		: 1;
-	unsigned int	underline	: 1;
-	unsigned int	blink		: 1;
-	unsigned int	reverse		: 1;
+	bool		italic;
+	bool		underline;
+	bool		blink;
+	bool		reverse;
 };
 
 /*
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 04/38] vt: deduplicate setGx code
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
  2020-06-15  7:48 ` [PATCH 02/38] vt: introduce enum vc_intensity for intensity Jiri Slaby
  2020-06-15  7:48 ` [PATCH 03/38] vc: switch state to bool Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 05/38] vt: switch G0/1_charset to an array Jiri Slaby
                   ` (33 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

The code for setting G0 and G1 is duplicated -- for each of them. Move
the code to a separate function (vc_setGx) and distinguish the two cases
by a parameter.

Change if-else-if to switch which allows for slightly better
optimization (decision tree).

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 46 +++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 26cb1fc48b27..729c7c8c682b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2103,6 +2103,30 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 	    csi_J(vc, 2);
 }
 
+static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
+{
+	unsigned char *charset = which == 0 ? &vc->state.G0_charset :
+		&vc->state.G1_charset;
+
+	switch (c) {
+	case '0':
+		*charset = GRAF_MAP;
+		break;
+	case 'B':
+		*charset = LAT1_MAP;
+		break;
+	case 'U':
+		*charset = IBMPC_MAP;
+		break;
+	case 'K':
+		*charset = USER_MAP;
+		break;
+	}
+
+	if (vc->state.charset == which)
+		vc->vc_translate = set_translate(*charset, vc);
+}
+
 /* console_lock is held */
 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 {
@@ -2485,29 +2509,11 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		}
 		return;
 	case ESsetG0:
-		if (c == '0')
-			vc->state.G0_charset = GRAF_MAP;
-		else if (c == 'B')
-			vc->state.G0_charset = LAT1_MAP;
-		else if (c == 'U')
-			vc->state.G0_charset = IBMPC_MAP;
-		else if (c == 'K')
-			vc->state.G0_charset = USER_MAP;
-		if (vc->state.charset == 0)
-			vc->vc_translate = set_translate(vc->state.G0_charset, vc);
+		vc_setGx(vc, 0, c);
 		vc->vc_state = ESnormal;
 		return;
 	case ESsetG1:
-		if (c == '0')
-			vc->state.G1_charset = GRAF_MAP;
-		else if (c == 'B')
-			vc->state.G1_charset = LAT1_MAP;
-		else if (c == 'U')
-			vc->state.G1_charset = IBMPC_MAP;
-		else if (c == 'K')
-			vc->state.G1_charset = USER_MAP;
-		if (vc->state.charset == 1)
-			vc->vc_translate = set_translate(vc->state.G1_charset, vc);
+		vc_setGx(vc, 1, c);
 		vc->vc_state = ESnormal;
 		return;
 	case ESosc:
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 05/38] vt: switch G0/1_charset to an array
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (2 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 04/38] vt: deduplicate setGx code Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 06/38] vt: convert vc_tab_stop to bitmap Jiri Slaby
                   ` (32 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Declare Gx_charset[2] instead of G0_charset and G1_charset. It makes
the code simpler (without ternary operators).

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c            | 19 ++++++++-----------
 include/linux/console_struct.h |  6 ++----
 2 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 729c7c8c682b..4e79cda0c2be 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1743,9 +1743,7 @@ static void csi_m(struct vc_data *vc)
 			  * Select primary font, don't display control chars if
 			  * defined, don't set bit 8 on output.
 			  */
-			vc->vc_translate = set_translate(vc->state.charset == 0
-					? vc->state.G0_charset
-					: vc->state.G1_charset, vc);
+			vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], vc);
 			vc->vc_disp_ctrl = 0;
 			vc->vc_toggle_meta = 0;
 			break;
@@ -2041,8 +2039,8 @@ static void restore_cur(struct vc_data *vc)
 	memcpy(&vc->state, &vc->saved_state, sizeof(vc->state));
 
 	gotoxy(vc, vc->state.x, vc->state.y);
-	vc->vc_translate = set_translate(vc->state.charset ? vc->state.G1_charset :
-			vc->state.G0_charset, vc);
+	vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset],
+			vc);
 	update_attr(vc);
 	vc->vc_need_wrap = 0;
 }
@@ -2059,8 +2057,8 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 	vc->vc_state		= ESnormal;
 	vc->vc_priv		= EPecma;
 	vc->vc_translate	= set_translate(LAT1_MAP, vc);
-	vc->state.G0_charset	= LAT1_MAP;
-	vc->state.G1_charset	= GRAF_MAP;
+	vc->state.Gx_charset[0]	= LAT1_MAP;
+	vc->state.Gx_charset[1]	= GRAF_MAP;
 	vc->state.charset	= 0;
 	vc->vc_need_wrap	= 0;
 	vc->vc_report_mouse	= 0;
@@ -2105,8 +2103,7 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 
 static void vc_setGx(struct vc_data *vc, unsigned int which, int c)
 {
-	unsigned char *charset = which == 0 ? &vc->state.G0_charset :
-		&vc->state.G1_charset;
+	unsigned char *charset = &vc->state.Gx_charset[which];
 
 	switch (c) {
 	case '0':
@@ -2168,12 +2165,12 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		return;
 	case 14:
 		vc->state.charset = 1;
-		vc->vc_translate = set_translate(vc->state.G1_charset, vc);
+		vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc);
 		vc->vc_disp_ctrl = 1;
 		return;
 	case 15:
 		vc->state.charset = 0;
-		vc->vc_translate = set_translate(vc->state.G0_charset, vc);
+		vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc);
 		vc->vc_disp_ctrl = 0;
 		return;
 	case 24: case 26:
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index fa1abffe64be..623e86689c3a 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -34,8 +34,7 @@ enum vc_intensity {
  * @x: cursor's x-position
  * @y: cursor's y-position
  * @color: foreground & background colors
- * @G0_charset: what's G0 slot set to (like GRAF_MAP, LAT1_MAP)
- * @G1_charset: what's G1 slot set to (like GRAF_MAP, LAT1_MAP)
+ * @Gx_charset: what's G0/G1 slot set to (like GRAF_MAP, LAT1_MAP)
  * @charset: what character set to use (0=G0 or 1=G1)
  * @intensity: see enum vc_intensity for values
  * @reverse: reversed foreground/background colors
@@ -48,8 +47,7 @@ struct vc_state {
 
 	unsigned char	color;
 
-	unsigned char	G0_charset;
-	unsigned char	G1_charset;
+	unsigned char	Gx_charset[2];
 	unsigned int	charset		: 1;
 
 	/* attribute flags */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 06/38] vt: convert vc_tab_stop to bitmap
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (3 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 05/38] vt: switch G0/1_charset to an array Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 07/38] vt: remove 25 years stale comment Jiri Slaby
                   ` (31 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

vc_tab_stop is used as a bitmap, but defined as an unsigned int array.
Switch it to bitmap and convert all users to the bitmap interface.

Note the difference in behavior! We no longer mask the top 24 bits away
from x, hence we do not wrap tabs at 256th column. Instead, we silently
drop attempts to set a tab behind 256 columns. And we will also seek by
'\t' to the rightmost column, when behind that boundary. I do not think
the original behavior was desired and that someone relies on that. If
this turns out to be the case, we can change the added 'if's back to
masks here and there instead...

(Or we can increase the limit as fb consoles now have 240 chars here.
And they could have more with higher than my resolution, of course.)

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c            | 44 ++++++++++++++--------------------
 include/linux/console_struct.h |  3 ++-
 2 files changed, 20 insertions(+), 27 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4e79cda0c2be..3adb7f409524 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2052,6 +2052,8 @@ enum { ESnormal, ESesc, ESsquare, ESgetpars, ESfunckey,
 /* console_lock is held (except via vc_init()) */
 static void reset_terminal(struct vc_data *vc, int do_clear)
 {
+	unsigned int i;
+
 	vc->vc_top		= 0;
 	vc->vc_bottom		= vc->vc_rows;
 	vc->vc_state		= ESnormal;
@@ -2082,14 +2084,9 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
 	default_attr(vc);
 	update_attr(vc);
 
-	vc->vc_tab_stop[0]	=
-	vc->vc_tab_stop[1]	=
-	vc->vc_tab_stop[2]	=
-	vc->vc_tab_stop[3]	=
-	vc->vc_tab_stop[4]	=
-	vc->vc_tab_stop[5]	=
-	vc->vc_tab_stop[6]	=
-	vc->vc_tab_stop[7]	= 0x01010101;
+	bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
+	for (i = 0; i < VC_TABSTOPS_COUNT; i += 8)
+		set_bit(i, vc->vc_tab_stop);
 
 	vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
 	vc->vc_bell_duration = DEFAULT_BELL_DURATION;
@@ -2147,11 +2144,13 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		return;
 	case 9:
 		vc->vc_pos -= (vc->state.x << 1);
-		while (vc->state.x < vc->vc_cols - 1) {
-			vc->state.x++;
-			if (vc->vc_tab_stop[7 & (vc->state.x >> 5)] & (1 << (vc->state.x & 31)))
-				break;
-		}
+
+		vc->state.x = find_next_bit(vc->vc_tab_stop,
+				min(vc->vc_cols - 1, VC_TABSTOPS_COUNT),
+				vc->state.x + 1);
+		if (vc->state.x >= VC_TABSTOPS_COUNT)
+			vc->state.x = vc->vc_cols - 1;
+
 		vc->vc_pos += (vc->state.x << 1);
 		notify_write(vc, '\t');
 		return;
@@ -2210,7 +2209,8 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 			lf(vc);
 			return;
 		case 'H':
-			vc->vc_tab_stop[7 & (vc->state.x >> 5)] |= (1 << (vc->state.x & 31));
+			if (vc->state.x < VC_TABSTOPS_COUNT)
+				set_bit(vc->state.x, vc->vc_tab_stop);
 			return;
 		case 'Z':
 			respond_ID(tty);
@@ -2421,18 +2421,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 				respond_ID(tty);
 			return;
 		case 'g':
-			if (!vc->vc_par[0])
-				vc->vc_tab_stop[7 & (vc->state.x >> 5)] &= ~(1 << (vc->state.x & 31));
-			else if (vc->vc_par[0] == 3) {
-				vc->vc_tab_stop[0] =
-					vc->vc_tab_stop[1] =
-					vc->vc_tab_stop[2] =
-					vc->vc_tab_stop[3] =
-					vc->vc_tab_stop[4] =
-					vc->vc_tab_stop[5] =
-					vc->vc_tab_stop[6] =
-					vc->vc_tab_stop[7] = 0;
-			}
+			if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
+				set_bit(vc->state.x, vc->vc_tab_stop);
+			else if (vc->vc_par[0] == 3)
+				bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
 			return;
 		case 'm':
 			csi_m(vc);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 623e86689c3a..81f7afcd061a 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -21,6 +21,7 @@ struct uni_pagedir;
 struct uni_screen;
 
 #define NPAR 16
+#define VC_TABSTOPS_COUNT	256U
 
 enum vc_intensity {
 	VCI_HALF_BRIGHT,
@@ -147,7 +148,7 @@ struct vc_data {
 	unsigned char	vc_utf		: 1;	/* Unicode UTF-8 encoding */
 	unsigned char	vc_utf_count;
 		 int	vc_utf_char;
-	unsigned int	vc_tab_stop[8];		/* Tab stops. 256 columns. */
+	DECLARE_BITMAP(vc_tab_stop, VC_TABSTOPS_COUNT);	/* Tab stops. 256 columns. */
 	unsigned char   vc_palette[16*3];       /* Colour palette for VGA+ */
 	unsigned short * vc_translate;
 	unsigned int    vc_resize_user;         /* resize request from user */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 07/38] vt: remove 25 years stale comment
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (4 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 06/38] vt: convert vc_tab_stop to bitmap Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 08/38] vt: use tty_insert_flip_string in respond_string Jiri Slaby
                   ` (30 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

vc_cons was made global (non-static) in 1.3.38, almost 25 years ago.
Remove a comment which says that it would be a disadvantage to do so :P.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 include/linux/console_struct.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 81f7afcd061a..40ed52f67bc5 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -167,8 +167,7 @@ struct vc {
 	struct work_struct SAK_work;
 
 	/* might add  scrmem, kbd  at some time,
-	   to have everything in one place - the disadvantage
-	   would be that vc_cons etc can no longer be static */
+	   to have everything in one place */
 };
 
 extern struct vc vc_cons [MAX_NR_CONSOLES];
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 08/38] vt: use tty_insert_flip_string in respond_string
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (5 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 07/38] vt: remove 25 years stale comment Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 09/38] vt: get rid of VT10.ID macros Jiri Slaby
                   ` (29 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Pass the length of a string to respond_string and use
tty_insert_flip_string instead of a loop with tty_insert_flip_char. This
simplifies the processing on the tty side.

The added strlens are optimized during constant folding and propagation
and the result are proper constants in assembly.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3adb7f409524..49c9d1e4067c 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1809,40 +1809,43 @@ static void csi_m(struct vc_data *vc)
 	update_attr(vc);
 }
 
-static void respond_string(const char *p, struct tty_port *port)
+static void respond_string(const char *p, size_t len, struct tty_port *port)
 {
-	while (*p) {
-		tty_insert_flip_char(port, *p, 0);
-		p++;
-	}
+	tty_insert_flip_string(port, p, len);
 	tty_schedule_flip(port);
 }
 
 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
 {
 	char buf[40];
+	int len;
 
-	sprintf(buf, "\033[%d;%dR", vc->state.y + (vc->vc_decom ? vc->vc_top + 1 : 1), vc->state.x + 1);
-	respond_string(buf, tty->port);
+	len = sprintf(buf, "\033[%d;%dR", vc->state.y +
+			(vc->vc_decom ? vc->vc_top + 1 : 1),
+			vc->state.x + 1);
+	respond_string(buf, len, tty->port);
 }
 
 static inline void status_report(struct tty_struct *tty)
 {
-	respond_string("\033[0n", tty->port);	/* Terminal ok */
+	static const char teminal_ok[] = "\033[0n";
+
+	respond_string(teminal_ok, strlen(teminal_ok), tty->port);
 }
 
 static inline void respond_ID(struct tty_struct *tty)
 {
-	respond_string(VT102ID, tty->port);
+	respond_string(VT102ID, strlen(VT102ID), tty->port);
 }
 
 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
 {
 	char buf[8];
+	int len;
 
-	sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt), (char)('!' + mrx),
-		(char)('!' + mry));
-	respond_string(buf, tty->port);
+	len = sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt),
+			(char)('!' + mrx), (char)('!' + mry));
+	respond_string(buf, len, tty->port);
 }
 
 /* invoked via ioctl(TIOCLINUX) and through set_selection_user */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 09/38] vt: get rid of VT10.ID macros
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (6 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 08/38] vt: use tty_insert_flip_string in respond_string Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 10/38] vt: move vc_translate to vt.c and rename it Jiri Slaby
                   ` (28 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

VT100ID is unused, but defined twice. Kill it.

VT102ID is used only in respond_ID. Define there a variable with proper
type and use that instead. Then drop both defines of VT102ID too.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c     | 11 ++++-------
 include/linux/console.h |  6 ------
 2 files changed, 4 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 49c9d1e4067c..8d9e532f050a 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1397,12 +1397,6 @@ enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt};
 #define kbdapplic	VC_APPLIC
 #define lnm		VC_CRLF
 
-/*
- * this is what the terminal answers to a ESC-Z or csi0c query.
- */
-#define VT100ID "\033[?1;2c"
-#define VT102ID "\033[?6c"
-
 const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
 				       8,12,10,14, 9,13,11,15 };
 
@@ -1835,7 +1829,10 @@ static inline void status_report(struct tty_struct *tty)
 
 static inline void respond_ID(struct tty_struct *tty)
 {
-	respond_string(VT102ID, strlen(VT102ID), tty->port);
+	/* terminal answer to an ESC-Z or csi0c query. */
+	static const char vt102_id[] = "\033[?6c";
+
+	respond_string(vt102_id, strlen(vt102_id), tty->port);
 }
 
 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
diff --git a/include/linux/console.h b/include/linux/console.h
index 964b67912b04..0670d3491e0e 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -24,12 +24,6 @@ struct module;
 struct tty_struct;
 struct notifier_block;
 
-/*
- * this is what the terminal answers to a ESC-Z or csi0c query.
- */
-#define VT100ID "\033[?1;2c"
-#define VT102ID "\033[?6c"
-
 enum con_scroll {
 	SM_UP,
 	SM_DOWN,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 10/38] vt: move vc_translate to vt.c and rename it
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (7 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 09/38] vt: get rid of VT10.ID macros Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 11/38] vt: use modern types in do_con_write Jiri Slaby
                   ` (27 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

vc_translate is used only in vt.c, so move the definition from a header
there. Also, it used to be a macro, so be modern and make a static
inline from it. This makes the code actually readable.

And as a preparation for next patches, rename it to vc_translate_ascii.
vc_translate will be a wrapper for both unicode and this one.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c     | 14 +++++++++++++-
 include/linux/vt_kern.h |  3 ---
 2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8d9e532f050a..b86639351dd2 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2560,6 +2560,18 @@ static void con_flush(struct vc_data *vc, unsigned long draw_from,
 	*draw_x = -1;
 }
 
+static inline int vc_translate_ascii(const struct vc_data *vc, int c)
+{
+	if (IS_ENABLED(CONFIG_CONSOLE_TRANSLATIONS)) {
+		if (vc->vc_toggle_meta)
+			c |= 0x80;
+
+		return vc->vc_translate[c];
+	}
+
+	return c;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
@@ -2687,7 +2699,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 			c = 0xfffd;
 		    tc = c;
 		} else {	/* no utf or alternate charset mode */
-		    tc = vc_translate(vc, c);
+			tc = vc_translate_ascii(vc, c);
 		}
 
 		param.c = tc;
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index abf5bccf906a..349e39c3ab60 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -74,8 +74,6 @@ int con_set_default_unimap(struct vc_data *vc);
 void con_free_unimap(struct vc_data *vc);
 int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc);
 
-#define vc_translate(vc, c) ((vc)->vc_translate[(c) |			\
-					((vc)->vc_toggle_meta ? 0x80 : 0)])
 #else
 static inline int con_set_trans_old(unsigned char __user *table)
 {
@@ -124,7 +122,6 @@ int con_copy_unimap(struct vc_data *dst_vc, struct vc_data *src_vc)
 	return 0;
 }
 
-#define vc_translate(vc, c) (c)
 #endif
 
 /* vt.c */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 11/38] vt: use modern types in do_con_write
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (8 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 10/38] vt: move vc_translate to vt.c and rename it Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 12/38] vt: separate unicode handling into vc_translate_unicode Jiri Slaby
                   ` (26 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Use bools for rescan and inverse. And true/false accordingly.

Use u8 for width instead of uint8_t.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b86639351dd2..a9e4924fa675 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2581,10 +2581,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 	struct vc_data *vc;
 	unsigned char vc_attr;
 	struct vt_notifier_param param;
-	uint8_t rescan;
-	uint8_t inverse;
-	uint8_t width;
 	u16 himask, charmask;
+	u8 width;
+	bool rescan;
+	bool inverse;
 
 	if (in_interrupt())
 		return count;
@@ -2620,8 +2620,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		buf++;
 		n++;
 		count--;
-		rescan = 0;
-		inverse = 0;
+		rescan = false;
+		inverse = false;
 		width = 1;
 
 		/* Do no translation at all in control states */
@@ -2660,7 +2660,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 			/* Single ASCII byte or first byte of a sequence received */
 			if (vc->vc_utf_count) {
 			    /* Continuation byte expected */
-			    rescan = 1;
+			    rescan = true;
 			    vc->vc_utf_count = 0;
 			    c = 0xfffd;
 			} else if (c > 0x7f) {
@@ -2746,7 +2746,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 				    /* Display U+FFFD. If it's not found, display an inverse question mark. */
 				    tc = conv_uni_to_pc(vc, 0xfffd);
 				    if (tc < 0) {
-					inverse = 1;
+					inverse = true;
 					tc = conv_uni_to_pc(vc, '?');
 					if (tc < 0) tc = '?';
 				    }
@@ -2807,8 +2807,8 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 				con_flush(vc, draw_from, draw_to, &draw_x);
 
 			if (rescan) {
-				rescan = 0;
-				inverse = 0;
+				rescan = false;
+				inverse = false;
 				width = 1;
 				c = orig;
 				goto rescan_last_byte;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 12/38] vt: separate unicode handling into vc_translate_unicode
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (9 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 11/38] vt: use modern types in do_con_write Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 13/38] vt: rearrange vc_translate_unicode Jiri Slaby
                   ` (25 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

do_con_write is complicated enough. Extract unicode handling to a
separate function. For do_con_write, 249 LOCs lowered to 183 lines.

Use diff -w -b to see the difference is neligible -- mostly whitespace
and use of 'return's instead of 'continue's.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 149 ++++++++++++++++++++++++--------------------
 1 file changed, 81 insertions(+), 68 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index a9e4924fa675..caaad820413a 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2572,6 +2572,85 @@ static inline int vc_translate_ascii(const struct vc_data *vc, int c)
 	return c;
 }
 
+/**
+ * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char
+ *
+ * @vc_utf_char is the being-constructed unicode character.
+ * @vc_utf_count is the number of continuation bytes still expected to arrive.
+ * @vc_npar is the number of continuation bytes arrived so far.
+ */
+static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
+{
+	static const u32 utf8_length_changes[] = {
+		0x0000007f, 0x000007ff, 0x0000ffff,
+		0x001fffff, 0x03ffffff, 0x7fffffff
+	};
+
+	if ((c & 0xc0) == 0x80) {
+		/* Continuation byte received */
+		if (vc->vc_utf_count) {
+			vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+			vc->vc_npar++;
+			if (--vc->vc_utf_count) {
+				/* Still need some bytes */
+				return -1;
+			}
+			/* Got a whole character */
+			c = vc->vc_utf_char;
+			/* Reject overlong sequences */
+			if (c <= utf8_length_changes[vc->vc_npar - 1] ||
+					c > utf8_length_changes[vc->vc_npar])
+				return 0xfffd;
+		} else {
+			/* Unexpected continuation byte */
+			vc->vc_utf_count = 0;
+			return 0xfffd;
+		}
+	} else {
+		/* Single ASCII byte or first byte of a sequence received */
+		if (vc->vc_utf_count) {
+			/* Continuation byte expected */
+			*rescan = true;
+			vc->vc_utf_count = 0;
+			return 0xfffd;
+		} else if (c > 0x7f) {
+			/* First byte of a multibyte sequence received */
+			vc->vc_npar = 0;
+			if ((c & 0xe0) == 0xc0) {
+				vc->vc_utf_count = 1;
+				vc->vc_utf_char = (c & 0x1f);
+			} else if ((c & 0xf0) == 0xe0) {
+				vc->vc_utf_count = 2;
+				vc->vc_utf_char = (c & 0x0f);
+			} else if ((c & 0xf8) == 0xf0) {
+				vc->vc_utf_count = 3;
+				vc->vc_utf_char = (c & 0x07);
+			} else if ((c & 0xfc) == 0xf8) {
+				vc->vc_utf_count = 4;
+				vc->vc_utf_char = (c & 0x03);
+			} else if ((c & 0xfe) == 0xfc) {
+				vc->vc_utf_count = 5;
+				vc->vc_utf_char = (c & 0x01);
+			} else {
+				/* 254 and 255 are invalid */
+				return 0xfffd;
+			}
+			if (vc->vc_utf_count) {
+				/* Still need some bytes */
+				return -1;
+			}
+		}
+		/* Nothing to do if an ASCII byte was received */
+	}
+	/* End of UTF-8 decoding. */
+	/* c is the received character, or U+FFFD for invalid sequences. */
+	/* Replace invalid Unicode code points with U+FFFD too */
+	if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+		return 0xfffd;
+
+	return c;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
@@ -2628,76 +2707,10 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		if (vc->vc_state != ESnormal) {
 			tc = c;
 		} else if (vc->vc_utf && !vc->vc_disp_ctrl) {
-		    /* Combine UTF-8 into Unicode in vc_utf_char.
-		     * vc_utf_count is the number of continuation bytes still
-		     * expected to arrive.
-		     * vc_npar is the number of continuation bytes arrived so
-		     * far
-		     */
 rescan_last_byte:
-		    if ((c & 0xc0) == 0x80) {
-			/* Continuation byte received */
-			static const uint32_t utf8_length_changes[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff };
-			if (vc->vc_utf_count) {
-			    vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
-			    vc->vc_npar++;
-			    if (--vc->vc_utf_count) {
-				/* Still need some bytes */
-				continue;
-			    }
-			    /* Got a whole character */
-			    c = vc->vc_utf_char;
-			    /* Reject overlong sequences */
-			    if (c <= utf8_length_changes[vc->vc_npar - 1] ||
-					c > utf8_length_changes[vc->vc_npar])
-				c = 0xfffd;
-			} else {
-			    /* Unexpected continuation byte */
-			    vc->vc_utf_count = 0;
-			    c = 0xfffd;
-			}
-		    } else {
-			/* Single ASCII byte or first byte of a sequence received */
-			if (vc->vc_utf_count) {
-			    /* Continuation byte expected */
-			    rescan = true;
-			    vc->vc_utf_count = 0;
-			    c = 0xfffd;
-			} else if (c > 0x7f) {
-			    /* First byte of a multibyte sequence received */
-			    vc->vc_npar = 0;
-			    if ((c & 0xe0) == 0xc0) {
-				vc->vc_utf_count = 1;
-				vc->vc_utf_char = (c & 0x1f);
-			    } else if ((c & 0xf0) == 0xe0) {
-				vc->vc_utf_count = 2;
-				vc->vc_utf_char = (c & 0x0f);
-			    } else if ((c & 0xf8) == 0xf0) {
-				vc->vc_utf_count = 3;
-				vc->vc_utf_char = (c & 0x07);
-			    } else if ((c & 0xfc) == 0xf8) {
-				vc->vc_utf_count = 4;
-				vc->vc_utf_char = (c & 0x03);
-			    } else if ((c & 0xfe) == 0xfc) {
-				vc->vc_utf_count = 5;
-				vc->vc_utf_char = (c & 0x01);
-			    } else {
-				/* 254 and 255 are invalid */
-				c = 0xfffd;
-			    }
-			    if (vc->vc_utf_count) {
-				/* Still need some bytes */
+			tc = c = vc_translate_unicode(vc, c, &rescan);
+			if (tc == -1)
 				continue;
-			    }
-			}
-			/* Nothing to do if an ASCII byte was received */
-		    }
-		    /* End of UTF-8 decoding. */
-		    /* c is the received character, or U+FFFD for invalid sequences. */
-		    /* Replace invalid Unicode code points with U+FFFD too */
-		    if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
-			c = 0xfffd;
-		    tc = c;
 		} else {	/* no utf or alternate charset mode */
 			tc = vc_translate_ascii(vc, c);
 		}
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 13/38] vt: rearrange vc_translate_unicode
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (10 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 12/38] vt: separate unicode handling into vc_translate_unicode Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 14/38] vt: extract attribute inversion to vc_invert_attr Jiri Slaby
                   ` (24 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

The code was too overcomplicated. Extract vc_sanitize_unicode to a
separate function and flatten the code. I believe the code is
straightforward now.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 121 +++++++++++++++++++++++---------------------
 1 file changed, 64 insertions(+), 57 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index caaad820413a..5004242d601b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2572,6 +2572,19 @@ static inline int vc_translate_ascii(const struct vc_data *vc, int c)
 	return c;
 }
 
+
+/**
+ * vc_sanitize_unicode -- Replace invalid Unicode code points with U+FFFD
+ * @c: the received character, or U+FFFD for invalid sequences.
+ */
+static inline int vc_sanitize_unicode(const int c)
+{
+	if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+		return 0xfffd;
+
+	return c;
+}
+
 /**
  * vc_translate_unicode -- Combine UTF-8 into Unicode in @vc_utf_char
  *
@@ -2586,69 +2599,63 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
 		0x001fffff, 0x03ffffff, 0x7fffffff
 	};
 
+	/* Continuation byte received */
 	if ((c & 0xc0) == 0x80) {
-		/* Continuation byte received */
-		if (vc->vc_utf_count) {
-			vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
-			vc->vc_npar++;
-			if (--vc->vc_utf_count) {
-				/* Still need some bytes */
-				return -1;
-			}
-			/* Got a whole character */
-			c = vc->vc_utf_char;
-			/* Reject overlong sequences */
-			if (c <= utf8_length_changes[vc->vc_npar - 1] ||
-					c > utf8_length_changes[vc->vc_npar])
-				return 0xfffd;
-		} else {
-			/* Unexpected continuation byte */
-			vc->vc_utf_count = 0;
+		/* Unexpected continuation byte? */
+		if (!vc->vc_utf_count)
 			return 0xfffd;
-		}
-	} else {
-		/* Single ASCII byte or first byte of a sequence received */
-		if (vc->vc_utf_count) {
-			/* Continuation byte expected */
-			*rescan = true;
-			vc->vc_utf_count = 0;
+
+		vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
+		vc->vc_npar++;
+		if (--vc->vc_utf_count)
+			goto need_more_bytes;
+
+		/* Got a whole character */
+		c = vc->vc_utf_char;
+		/* Reject overlong sequences */
+		if (c <= utf8_length_changes[vc->vc_npar - 1] ||
+				c > utf8_length_changes[vc->vc_npar])
 			return 0xfffd;
-		} else if (c > 0x7f) {
-			/* First byte of a multibyte sequence received */
-			vc->vc_npar = 0;
-			if ((c & 0xe0) == 0xc0) {
-				vc->vc_utf_count = 1;
-				vc->vc_utf_char = (c & 0x1f);
-			} else if ((c & 0xf0) == 0xe0) {
-				vc->vc_utf_count = 2;
-				vc->vc_utf_char = (c & 0x0f);
-			} else if ((c & 0xf8) == 0xf0) {
-				vc->vc_utf_count = 3;
-				vc->vc_utf_char = (c & 0x07);
-			} else if ((c & 0xfc) == 0xf8) {
-				vc->vc_utf_count = 4;
-				vc->vc_utf_char = (c & 0x03);
-			} else if ((c & 0xfe) == 0xfc) {
-				vc->vc_utf_count = 5;
-				vc->vc_utf_char = (c & 0x01);
-			} else {
-				/* 254 and 255 are invalid */
-				return 0xfffd;
-			}
-			if (vc->vc_utf_count) {
-				/* Still need some bytes */
-				return -1;
-			}
-		}
-		/* Nothing to do if an ASCII byte was received */
+
+		return vc_sanitize_unicode(c);
 	}
-	/* End of UTF-8 decoding. */
-	/* c is the received character, or U+FFFD for invalid sequences. */
-	/* Replace invalid Unicode code points with U+FFFD too */
-	if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff)
+
+	/* Single ASCII byte or first byte of a sequence received */
+	if (vc->vc_utf_count) {
+		/* Continuation byte expected */
+		*rescan = true;
+		vc->vc_utf_count = 0;
 		return 0xfffd;
+	}
 
-	return c;
+	/* Nothing to do if an ASCII byte was received */
+	if (c <= 0x7f)
+		return c;
+
+	/* First byte of a multibyte sequence received */
+	vc->vc_npar = 0;
+	if ((c & 0xe0) == 0xc0) {
+		vc->vc_utf_count = 1;
+		vc->vc_utf_char = (c & 0x1f);
+	} else if ((c & 0xf0) == 0xe0) {
+		vc->vc_utf_count = 2;
+		vc->vc_utf_char = (c & 0x0f);
+	} else if ((c & 0xf8) == 0xf0) {
+		vc->vc_utf_count = 3;
+		vc->vc_utf_char = (c & 0x07);
+	} else if ((c & 0xfc) == 0xf8) {
+		vc->vc_utf_count = 4;
+		vc->vc_utf_char = (c & 0x03);
+	} else if ((c & 0xfe) == 0xfc) {
+		vc->vc_utf_count = 5;
+		vc->vc_utf_char = (c & 0x01);
+	} else {
+		/* 254 and 255 are invalid */
+		return 0xfffd;
+	}
+
+need_more_bytes:
+	return -1;
 }
 
 /* acquires console_lock */
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 14/38] vt: extract attribute inversion to vc_invert_attr
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (11 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 13/38] vt: rearrange vc_translate_unicode Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 15/38] vt: move rescan_last_byte label earlier Jiri Slaby
                   ` (23 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

We continue cleaning up do_con_write. This (hopefully) makes the
inversion code obvious.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 5004242d601b..bf171bb1d2fd 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2658,6 +2658,21 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
 	return -1;
 }
 
+static inline unsigned char vc_invert_attr(const struct vc_data *vc)
+{
+	if (!vc->vc_can_do_color)
+		return vc->vc_attr ^ 0x08;
+
+	if (vc->vc_hi_font_mask == 0x100)
+		return   (vc->vc_attr & 0x11) |
+			((vc->vc_attr & 0xe0) >> 4) |
+			((vc->vc_attr & 0x0e) << 4);
+
+	return   (vc->vc_attr & 0x88) |
+		((vc->vc_attr & 0x70) >> 4) |
+		((vc->vc_attr & 0x07) << 4);
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
@@ -2776,14 +2791,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 			if (!inverse) {
 				vc_attr = vc->vc_attr;
 			} else {
-				/* invert vc_attr */
-				if (!vc->vc_can_do_color) {
-					vc_attr = (vc->vc_attr) ^ 0x08;
-				} else if (vc->vc_hi_font_mask == 0x100) {
-					vc_attr = ((vc->vc_attr) & 0x11) | (((vc->vc_attr) & 0xe0) >> 4) | (((vc->vc_attr) & 0x0e) << 4);
-				} else {
-					vc_attr = ((vc->vc_attr) & 0x88) | (((vc->vc_attr) & 0x70) >> 4) | (((vc->vc_attr) & 0x07) << 4);
-				}
+				vc_attr = vc_invert_attr(vc);
 				con_flush(vc, draw_from, draw_to, &draw_x);
 			}
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 15/38] vt: move rescan_last_byte label earlier
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (12 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 14/38] vt: extract attribute inversion to vc_invert_attr Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 16/38] vc: move translation out of do_con_write Jiri Slaby
                   ` (22 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

This removes duplicated initialization of variables (after reordering
'c' initialization).

It will also allow for eliminating whole translation into a separate
function in the next patch.

Note that vc_state, vc_utf etc. are checked with every rescan now. But
they are immutable for non-control characters where rescan might be
only necessary.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index bf171bb1d2fd..93ad7e004900 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2717,10 +2717,11 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 
 	while (!tty->stopped && count) {
 		int orig = *buf;
-		c = orig;
 		buf++;
 		n++;
 		count--;
+rescan_last_byte:
+		c = orig;
 		rescan = false;
 		inverse = false;
 		width = 1;
@@ -2729,7 +2730,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		if (vc->vc_state != ESnormal) {
 			tc = c;
 		} else if (vc->vc_utf && !vc->vc_disp_ctrl) {
-rescan_last_byte:
 			tc = c = vc_translate_unicode(vc, c, &rescan);
 			if (tc == -1)
 				continue;
@@ -2834,13 +2834,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 			if (inverse)
 				con_flush(vc, draw_from, draw_to, &draw_x);
 
-			if (rescan) {
-				rescan = false;
-				inverse = false;
-				width = 1;
-				c = orig;
+			if (rescan)
 				goto rescan_last_byte;
-			}
+
 			continue;
 		}
 		con_flush(vc, draw_from, draw_to, &draw_x);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 16/38] vc: move translation out of do_con_write
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (13 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 15/38] vt: move rescan_last_byte label earlier Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 17/38] vc: introduce struct vc_draw_region Jiri Slaby
                   ` (21 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Now that we reordered the code and the label, we can eliminate the
translation into a separate function. We call it vc_translate here.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 93ad7e004900..0f61dc360067 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2658,6 +2658,19 @@ static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
 	return -1;
 }
 
+static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
+{
+	/* Do no translation at all in control states */
+	if (vc->vc_state != ESnormal)
+		return *c;
+
+	if (vc->vc_utf && !vc->vc_disp_ctrl)
+		return *c = vc_translate_unicode(vc, *c, rescan);
+
+	/* no utf or alternate charset mode */
+	return vc_translate_ascii(vc, *c);
+}
+
 static inline unsigned char vc_invert_attr(const struct vc_data *vc)
 {
 	if (!vc->vc_can_do_color)
@@ -2726,16 +2739,9 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		inverse = false;
 		width = 1;
 
-		/* Do no translation at all in control states */
-		if (vc->vc_state != ESnormal) {
-			tc = c;
-		} else if (vc->vc_utf && !vc->vc_disp_ctrl) {
-			tc = c = vc_translate_unicode(vc, c, &rescan);
-			if (tc == -1)
-				continue;
-		} else {	/* no utf or alternate charset mode */
-			tc = vc_translate_ascii(vc, c);
-		}
+		tc = vc_translate(vc, &c, &rescan);
+		if (tc == -1)
+			continue;
 
 		param.c = tc;
 		if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 17/38] vc: introduce struct vc_draw_region
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (14 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 16/38] vc: move translation out of do_con_write Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 18/38] vc: extract detecting control characters from do_con_write Jiri Slaby
                   ` (20 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

For passing of draw area among functions. This makes next patches
simpler.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 44 +++++++++++++++++++++++++-------------------
 1 file changed, 25 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 0f61dc360067..0c663054ab79 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2549,15 +2549,20 @@ static int is_double_width(uint32_t ucs)
 			sizeof(struct interval), ucs_cmp) != NULL;
 }
 
-static void con_flush(struct vc_data *vc, unsigned long draw_from,
-		unsigned long draw_to, int *draw_x)
+struct vc_draw_region {
+	unsigned long from, to;
+	int x;
+};
+
+static void con_flush(struct vc_data *vc, struct vc_draw_region *draw)
 {
-	if (*draw_x < 0)
+	if (draw->x < 0)
 		return;
 
-	vc->vc_sw->con_putcs(vc, (u16 *)draw_from,
-			(u16 *)draw_to - (u16 *)draw_from, vc->state.y, *draw_x);
-	*draw_x = -1;
+	vc->vc_sw->con_putcs(vc, (u16 *)draw->from,
+			(u16 *)draw->to - (u16 *)draw->from, vc->state.y,
+			draw->x);
+	draw->x = -1;
 }
 
 static inline int vc_translate_ascii(const struct vc_data *vc, int c)
@@ -2689,9 +2694,11 @@ static inline unsigned char vc_invert_attr(const struct vc_data *vc)
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
-	int c, next_c, tc, ok, n = 0, draw_x = -1;
+	struct vc_draw_region draw = {
+		.x = -1,
+	};
+	int c, next_c, tc, ok, n = 0;
 	unsigned int currcons;
-	unsigned long draw_from = 0, draw_to = 0;
 	struct vc_data *vc;
 	unsigned char vc_attr;
 	struct vt_notifier_param param;
@@ -2798,14 +2805,13 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 				vc_attr = vc->vc_attr;
 			} else {
 				vc_attr = vc_invert_attr(vc);
-				con_flush(vc, draw_from, draw_to, &draw_x);
+				con_flush(vc, &draw);
 			}
 
 			next_c = c;
 			while (1) {
 				if (vc->vc_need_wrap || vc->vc_decim)
-					con_flush(vc, draw_from, draw_to,
-							&draw_x);
+					con_flush(vc, &draw);
 				if (vc->vc_need_wrap) {
 					cr(vc);
 					lf(vc);
@@ -2817,16 +2823,16 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 					     ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
 					     (vc_attr << 8) + tc,
 					   (u16 *) vc->vc_pos);
-				if (con_should_update(vc) && draw_x < 0) {
-					draw_x = vc->state.x;
-					draw_from = vc->vc_pos;
+				if (con_should_update(vc) && draw.x < 0) {
+					draw.x = vc->state.x;
+					draw.from = vc->vc_pos;
 				}
 				if (vc->state.x == vc->vc_cols - 1) {
 					vc->vc_need_wrap = vc->vc_decawm;
-					draw_to = vc->vc_pos + 2;
+					draw.to = vc->vc_pos + 2;
 				} else {
 					vc->state.x++;
-					draw_to = (vc->vc_pos += 2);
+					draw.to = (vc->vc_pos += 2);
 				}
 
 				if (!--width) break;
@@ -2838,17 +2844,17 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 			notify_write(vc, c);
 
 			if (inverse)
-				con_flush(vc, draw_from, draw_to, &draw_x);
+				con_flush(vc, &draw);
 
 			if (rescan)
 				goto rescan_last_byte;
 
 			continue;
 		}
-		con_flush(vc, draw_from, draw_to, &draw_x);
+		con_flush(vc, &draw);
 		do_con_trol(tty, vc, orig);
 	}
-	con_flush(vc, draw_from, draw_to, &draw_x);
+	con_flush(vc, &draw);
 	vc_uniscr_debug_check(vc);
 	console_conditional_schedule();
 	notify_update(vc);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 18/38] vc: extract detecting control characters from do_con_write
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (15 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 17/38] vc: introduce struct vc_draw_region Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 19/38] vc: move normal char processing " Jiri Slaby
                   ` (19 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Move the control characters detection to a separate function dubbed
vc_is_control. It makes the 14 subexpressions a "bit" more readable. And
also simplifies next patches.

It moves also CTRL_ACTION and CTRL_ALWAYS to this new function, as they
are used exclusively here. While at it, these are converted to static
const variables.

And we use "& BIT()" instead of ">>" and "& 1".

Checked using symbolic execution (klee), that the old and new
behaviors are the same.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 71 ++++++++++++++++++++++++++++-----------------
 1 file changed, 45 insertions(+), 26 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 0c663054ab79..45d32844e61b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -127,14 +127,6 @@ struct con_driver {
 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
 const struct consw *conswitchp;
 
-/* A bitmap for codes <32. A bit of 1 indicates that the code
- * corresponding to that bit number invokes some special action
- * (such as cursor movement) and should not be displayed as a
- * glyph unless the disp_ctrl mode is explicitly enabled.
- */
-#define CTRL_ACTION 0x0d00ff81
-#define CTRL_ALWAYS 0x0800f501	/* Cannot be overridden by disp_ctrl */
-
 /*
  * Here is the default bell parameters: 750HZ, 1/8th of a second
  */
@@ -2691,13 +2683,56 @@ static inline unsigned char vc_invert_attr(const struct vc_data *vc)
 		((vc->vc_attr & 0x07) << 4);
 }
 
+static bool vc_is_control(struct vc_data *vc, int tc, int c)
+{
+	/*
+	 * A bitmap for codes <32. A bit of 1 indicates that the code
+	 * corresponding to that bit number invokes some special action (such
+	 * as cursor movement) and should not be displayed as a glyph unless
+	 * the disp_ctrl mode is explicitly enabled.
+	 */
+	static const u32 CTRL_ACTION = 0x0d00ff81;
+	/* Cannot be overridden by disp_ctrl */
+	static const u32 CTRL_ALWAYS = 0x0800f501;
+
+	if (vc->vc_state != ESnormal)
+		return true;
+
+	if (!tc)
+		return true;
+
+	/*
+	 * If the original code was a control character we only allow a glyph
+	 * to be displayed if the code is not normally used (such as for cursor
+	 * movement) or if the disp_ctrl mode has been explicitly enabled.
+	 * Certain characters (as given by the CTRL_ALWAYS bitmap) are always
+	 * displayed as control characters, as the console would be pretty
+	 * useless without them; to display an arbitrary font position use the
+	 * direct-to-font zone in UTF-8 mode.
+	 */
+	if (c < 32) {
+		if (vc->vc_disp_ctrl)
+			return CTRL_ALWAYS & BIT(c);
+		else
+			return vc->vc_utf || (CTRL_ACTION & BIT(c));
+	}
+
+	if (c == 127 && !vc->vc_disp_ctrl)
+		return true;
+
+	if (c == 128 + 27)
+		return true;
+
+	return false;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
 	struct vc_draw_region draw = {
 		.x = -1,
 	};
-	int c, next_c, tc, ok, n = 0;
+	int c, next_c, tc, n = 0;
 	unsigned int currcons;
 	struct vc_data *vc;
 	unsigned char vc_attr;
@@ -2755,23 +2790,7 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 					&param) == NOTIFY_STOP)
 			continue;
 
-                /* If the original code was a control character we
-                 * only allow a glyph to be displayed if the code is
-                 * not normally used (such as for cursor movement) or
-                 * if the disp_ctrl mode has been explicitly enabled.
-                 * Certain characters (as given by the CTRL_ALWAYS
-                 * bitmap) are always displayed as control characters,
-                 * as the console would be pretty useless without
-                 * them; to display an arbitrary font position use the
-                 * direct-to-font zone in UTF-8 mode.
-                 */
-                ok = tc && (c >= 32 ||
-			    !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
-				  vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
-			&& (c != 127 || vc->vc_disp_ctrl)
-			&& (c != 128+27);
-
-		if (vc->vc_state == ESnormal && ok) {
+		if (!vc_is_control(vc, tc, c)) {
 			if (vc->vc_utf && !vc->vc_disp_ctrl) {
 				if (is_double_width(c))
 					width = 2;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 19/38] vc: move normal char processing from do_con_write
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (16 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 18/38] vc: extract detecting control characters from do_con_write Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 20/38] vc: simplify condition in vc_con_write_normal Jiri Slaby
                   ` (18 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

vc_con_write_normal now handles the complex normal characters
processing. It is no longer a part of do_con_write. So this patch makes
do_con_write pretty clean and obvious.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 198 ++++++++++++++++++++++++--------------------
 1 file changed, 109 insertions(+), 89 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 45d32844e61b..893f72dc812c 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2726,21 +2726,116 @@ static bool vc_is_control(struct vc_data *vc, int tc, int c)
 	return false;
 }
 
+static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
+		struct vc_draw_region *draw)
+{
+	int next_c;
+	unsigned char vc_attr;
+	u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
+	u8 width = 1;
+	bool inverse = false;
+
+	if (vc->vc_utf && !vc->vc_disp_ctrl) {
+		if (is_double_width(c))
+			width = 2;
+	}
+
+	/* Now try to find out how to display it */
+	tc = conv_uni_to_pc(vc, tc);
+	if (tc & ~charmask) {
+		if (tc == -1 || tc == -2)
+			return -1; /* nothing to display */
+
+		/* Glyph not found */
+		if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) &&
+				!(c & ~charmask)) {
+			/*
+			 * In legacy mode use the glyph we get by a 1:1
+			 * mapping.
+			 * This would make absolutely no sense with Unicode in
+			 * mind, but do this for ASCII characters since a font
+			 * may lack Unicode mapping info and we don't want to
+			 * end up with having question marks only.
+			 */
+			tc = c;
+		} else {
+			/*
+			 * Display U+FFFD. If it's not found, display an inverse
+			 * question mark.
+			 */
+			tc = conv_uni_to_pc(vc, 0xfffd);
+			if (tc < 0) {
+				inverse = true;
+				tc = conv_uni_to_pc(vc, '?');
+				if (tc < 0)
+					tc = '?';
+			}
+		}
+	}
+
+	if (!inverse) {
+		vc_attr = vc->vc_attr;
+	} else {
+		vc_attr = vc_invert_attr(vc);
+		con_flush(vc, draw);
+	}
+
+	next_c = c;
+	while (1) {
+		if (vc->vc_need_wrap || vc->vc_decim)
+			con_flush(vc, draw);
+		if (vc->vc_need_wrap) {
+			cr(vc);
+			lf(vc);
+		}
+		if (vc->vc_decim)
+			insert_char(vc, 1);
+		vc_uniscr_putc(vc, next_c);
+		scr_writew(himask ?
+			     ((vc_attr << 8) & ~himask) +
+			     ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
+			     (vc_attr << 8) + tc,
+			   (u16 *)vc->vc_pos);
+		if (con_should_update(vc) && draw->x < 0) {
+			draw->x = vc->state.x;
+			draw->from = vc->vc_pos;
+		}
+		if (vc->state.x == vc->vc_cols - 1) {
+			vc->vc_need_wrap = vc->vc_decawm;
+			draw->to = vc->vc_pos + 2;
+		} else {
+			vc->state.x++;
+			draw->to = (vc->vc_pos += 2);
+		}
+
+		if (!--width)
+			break;
+
+		/* A space is printed in the second column */
+		tc = conv_uni_to_pc(vc, ' ');
+		if (tc < 0)
+			tc = ' ';
+		next_c = ' ';
+	}
+	notify_write(vc, c);
+
+	if (inverse)
+		con_flush(vc, draw);
+
+	return 0;
+}
+
 /* acquires console_lock */
 static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int count)
 {
 	struct vc_draw_region draw = {
 		.x = -1,
 	};
-	int c, next_c, tc, n = 0;
+	int c, tc, n = 0;
 	unsigned int currcons;
 	struct vc_data *vc;
-	unsigned char vc_attr;
 	struct vt_notifier_param param;
-	u16 himask, charmask;
-	u8 width;
 	bool rescan;
-	bool inverse;
 
 	if (in_interrupt())
 		return count;
@@ -2761,8 +2856,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 		return 0;
 	}
 
-	himask = vc->vc_hi_font_mask;
-	charmask = himask ? 0x1ff : 0xff;
 
 	/* undraw cursor first */
 	if (con_is_fg(vc))
@@ -2778,8 +2871,6 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 rescan_last_byte:
 		c = orig;
 		rescan = false;
-		inverse = false;
-		width = 1;
 
 		tc = vc_translate(vc, &c, &rescan);
 		if (tc == -1)
@@ -2790,88 +2881,17 @@ static int do_con_write(struct tty_struct *tty, const unsigned char *buf, int co
 					&param) == NOTIFY_STOP)
 			continue;
 
-		if (!vc_is_control(vc, tc, c)) {
-			if (vc->vc_utf && !vc->vc_disp_ctrl) {
-				if (is_double_width(c))
-					width = 2;
-			}
-			/* Now try to find out how to display it */
-			tc = conv_uni_to_pc(vc, tc);
-			if (tc & ~charmask) {
-				if (tc == -1 || tc == -2) {
-				    continue; /* nothing to display */
-				}
-				/* Glyph not found */
-				if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) {
-				    /* In legacy mode use the glyph we get by a 1:1 mapping.
-				       This would make absolutely no sense with Unicode in mind,
-				       but do this for ASCII characters since a font may lack
-				       Unicode mapping info and we don't want to end up with
-				       having question marks only. */
-				    tc = c;
-				} else {
-				    /* Display U+FFFD. If it's not found, display an inverse question mark. */
-				    tc = conv_uni_to_pc(vc, 0xfffd);
-				    if (tc < 0) {
-					inverse = true;
-					tc = conv_uni_to_pc(vc, '?');
-					if (tc < 0) tc = '?';
-				    }
-				}
-			}
-
-			if (!inverse) {
-				vc_attr = vc->vc_attr;
-			} else {
-				vc_attr = vc_invert_attr(vc);
-				con_flush(vc, &draw);
-			}
-
-			next_c = c;
-			while (1) {
-				if (vc->vc_need_wrap || vc->vc_decim)
-					con_flush(vc, &draw);
-				if (vc->vc_need_wrap) {
-					cr(vc);
-					lf(vc);
-				}
-				if (vc->vc_decim)
-					insert_char(vc, 1);
-				vc_uniscr_putc(vc, next_c);
-				scr_writew(himask ?
-					     ((vc_attr << 8) & ~himask) + ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
-					     (vc_attr << 8) + tc,
-					   (u16 *) vc->vc_pos);
-				if (con_should_update(vc) && draw.x < 0) {
-					draw.x = vc->state.x;
-					draw.from = vc->vc_pos;
-				}
-				if (vc->state.x == vc->vc_cols - 1) {
-					vc->vc_need_wrap = vc->vc_decawm;
-					draw.to = vc->vc_pos + 2;
-				} else {
-					vc->state.x++;
-					draw.to = (vc->vc_pos += 2);
-				}
-
-				if (!--width) break;
-
-				tc = conv_uni_to_pc(vc, ' '); /* A space is printed in the second column */
-				if (tc < 0) tc = ' ';
-				next_c = ' ';
-			}
-			notify_write(vc, c);
-
-			if (inverse)
-				con_flush(vc, &draw);
-
-			if (rescan)
-				goto rescan_last_byte;
-
+		if (vc_is_control(vc, tc, c)) {
+			con_flush(vc, &draw);
+			do_con_trol(tty, vc, orig);
 			continue;
 		}
-		con_flush(vc, &draw);
-		do_con_trol(tty, vc, orig);
+
+		if (vc_con_write_normal(vc, tc, c, &draw) < 0)
+			continue;
+
+		if (rescan)
+			goto rescan_last_byte;
 	}
 	con_flush(vc, &draw);
 	vc_uniscr_debug_check(vc);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 20/38] vc: simplify condition in vc_con_write_normal
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (17 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 19/38] vc: move normal char processing " Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 21/38] vt: simplify vc_attr handling " Jiri Slaby
                   ` (17 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Convert (!(A && !B) || C) into (!A || B || C) to improve readability.

No functional changes, as was just proven by objdump.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 893f72dc812c..d3cd256ba0fa 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2747,7 +2747,7 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
 			return -1; /* nothing to display */
 
 		/* Glyph not found */
-		if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) &&
+		if ((!vc->vc_utf || vc->vc_disp_ctrl || c < 128) &&
 				!(c & ~charmask)) {
 			/*
 			 * In legacy mode use the glyph we get by a 1:1
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 21/38] vt: simplify vc_attr handling in vc_con_write_normal
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (18 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 20/38] vc: simplify condition in vc_con_write_normal Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 22/38] vt: make tc write more obvious " Jiri Slaby
                   ` (16 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Invert the attribute on the only place, without the need of checking
'inverse'.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 12 ++++--------
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index d3cd256ba0fa..72ae8ede1ac9 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2730,7 +2730,7 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
 		struct vc_draw_region *draw)
 {
 	int next_c;
-	unsigned char vc_attr;
+	unsigned char vc_attr = vc->vc_attr;
 	u16 himask = vc->vc_hi_font_mask, charmask = himask ? 0x1ff : 0xff;
 	u8 width = 1;
 	bool inverse = false;
@@ -2769,17 +2769,13 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
 				tc = conv_uni_to_pc(vc, '?');
 				if (tc < 0)
 					tc = '?';
+
+				vc_attr = vc_invert_attr(vc);
+				con_flush(vc, draw);
 			}
 		}
 	}
 
-	if (!inverse) {
-		vc_attr = vc->vc_attr;
-	} else {
-		vc_attr = vc_invert_attr(vc);
-		con_flush(vc, draw);
-	}
-
 	next_c = c;
 	while (1) {
 		if (vc->vc_need_wrap || vc->vc_decim)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 22/38] vt: make tc write more obvious in vc_con_write_normal
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (19 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 21/38] vt: simplify vc_attr handling " Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 23/38] vt: synchronize types and use min in csi_X Jiri Slaby
                   ` (15 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Nested ternary operators spread over 4 lines are really evil for
reading. Turn the outer one to proper 'if'. Now, we see, there is a
common path, so the code can be simplified. This way, the code is
understandable now.

Checked using symbolic execution (klee), that the old and new behaviors
are the same.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 72ae8ede1ac9..4686f8b9251d 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -2787,11 +2787,14 @@ static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
 		if (vc->vc_decim)
 			insert_char(vc, 1);
 		vc_uniscr_putc(vc, next_c);
-		scr_writew(himask ?
-			     ((vc_attr << 8) & ~himask) +
-			     ((tc & 0x100) ? himask : 0) + (tc & 0xff) :
-			     (vc_attr << 8) + tc,
-			   (u16 *)vc->vc_pos);
+
+		if (himask)
+			tc = ((tc & 0x100) ? himask : 0) |
+			      (tc &  0xff);
+		tc |= (vc_attr << 8) & ~himask;
+
+		scr_writew(tc, (u16 *)vc->vc_pos);
+
 		if (con_should_update(vc) && draw->x < 0) {
 			draw->x = vc->state.x;
 			draw->from = vc->vc_pos;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 23/38] vt: synchronize types and use min in csi_X
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (20 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 22/38] vt: make tc write more obvious " Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 24/38] vt: whitespace and paren cleanup in add_softcursor Jiri Slaby
                   ` (14 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

All the types are unsinged ints -- even the vpar passed to the function.
So unify them and use min() to compute count instead of explicit
comparison.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 4686f8b9251d..b1fdbf119755 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -1582,13 +1582,15 @@ static void csi_K(struct vc_data *vc, int vpar)
 		do_update_region(vc, (unsigned long)(start + offset), count);
 }
 
-static void csi_X(struct vc_data *vc, int vpar) /* erase the following vpar positions */
+/* erase the following vpar positions */
+static void csi_X(struct vc_data *vc, unsigned int vpar)
 {					  /* not vt100? */
-	int count;
+	unsigned int count;
 
 	if (!vpar)
 		vpar++;
-	count = (vpar > vc->vc_cols - vc->state.x) ? (vc->vc_cols - vc->state.x) : vpar;
+
+	count = min(vpar, vc->vc_cols - vc->state.x);
 
 	vc_uniscr_clear_line(vc, vc->state.x, count);
 	scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 24/38] vt: whitespace and paren cleanup in add_softcursor
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (21 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 23/38] vt: synchronize types and use min in csi_X Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 25/38] vt: redefine world of cursor macros Jiri Slaby
                   ` (13 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Format add_softcursor according to CodingStyle. Until now, it was a mess
of letters.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index b1fdbf119755..f7d5a3c3845f 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -866,14 +866,18 @@ static void add_softcursor(struct vc_data *vc)
 	int i = scr_readw((u16 *) vc->vc_pos);
 	u32 type = vc->vc_cursor_type;
 
-	if (! (type & 0x10)) return;
-	if (softcursor_original != -1) return;
+	if (!(type & 0x10))
+		return;
+	if (softcursor_original != -1)
+		return;
 	softcursor_original = i;
-	i |= ((type >> 8) & 0xff00 );
-	i ^= ((type) & 0xff00 );
-	if ((type & 0x20) && ((softcursor_original & 0x7000) == (i & 0x7000))) i ^= 0x7000;
-	if ((type & 0x40) && ((i & 0x700) == ((i & 0x7000) >> 4))) i ^= 0x0700;
-	scr_writew(i, (u16 *) vc->vc_pos);
+	i |= (type >> 8) & 0xff00;
+	i ^= type & 0xff00;
+	if ((type & 0x20) && (softcursor_original & 0x7000) == (i & 0x7000))
+		i ^= 0x7000;
+	if ((type & 0x40) && (i & 0x700) == ((i & 0x7000) >> 4))
+		i ^= 0x0700;
+	scr_writew(i, (u16 *)vc->vc_pos);
 	if (con_should_update(vc))
 		vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
 }
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 25/38] vt: redefine world of cursor macros
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (22 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 24/38] vt: whitespace and paren cleanup in add_softcursor Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:48 ` [PATCH 26/38] vt: use newly defined CUR_* macros Jiri Slaby
                   ` (12 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-kernel, Jiri Slaby,
	Bartlomiej Zolnierkiewicz, dri-devel, linux-fbdev

The cursor code used to use magic constants, ANDs, ORs, and some macros.
Redefine all this to make some sense.

In particular:
* Drop CUR_DEFAULT, which is CUR_UNDERLINE. CUR_DEFAULT was used only
  for cur_default variable initialization, so use CUR_UNDERLINE there to
  make obvious what's the default.
* Drop CUR_HWMASK. Instead, define CUR_SIZE() which explains it more.
  And use it all over the places.
* Define few more masks and bits which will be used in next patches
  instead of magic constants.
* Define CUR_MAKE to build up cursor value.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: dri-devel@lists.freedesktop.org
Cc: linux-fbdev@vger.kernel.org
---
 drivers/tty/vt/vt.c                  |  2 +-
 drivers/video/fbdev/core/bitblit.c   |  2 +-
 drivers/video/fbdev/core/fbcon_ccw.c |  2 +-
 drivers/video/fbdev/core/fbcon_cw.c  |  2 +-
 drivers/video/fbdev/core/fbcon_ud.c  |  2 +-
 include/linux/console_struct.h       | 28 +++++++++++++++++-----------
 6 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index f7d5a3c3845f..af1ef717f416 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -163,7 +163,7 @@ module_param(default_utf8, int, S_IRUGO | S_IWUSR);
 int global_cursor_default = -1;
 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
 
-static int cur_default = CUR_DEFAULT;
+static int cur_default = CUR_UNDERLINE;
 module_param(cur_default, int, S_IRUGO | S_IWUSR);
 
 /*
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index c750470a31ec..3b002b365a5a 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -325,7 +325,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 		ops->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
 
-		switch (ops->p->cursor_shape & CUR_HWMASK) {
+		switch (CUR_SIZE(ops->p->cursor_shape)) {
 		case CUR_NONE:
 			cur_height = 0;
 			break;
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 9d06446a1a3b..5b67bcebe34c 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -325,7 +325,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 		ops->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
 
-		switch (ops->p->cursor_shape & CUR_HWMASK) {
+		switch (CUR_SIZE(ops->p->cursor_shape)) {
 		case CUR_NONE:
 			cur_height = 0;
 			break;
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index 4b5f76bb01e5..f1aab3ae3bc9 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -308,7 +308,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 		ops->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
 
-		switch (ops->p->cursor_shape & CUR_HWMASK) {
+		switch (CUR_SIZE(ops->p->cursor_shape)) {
 		case CUR_NONE:
 			cur_height = 0;
 			break;
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 7e0ae3549dc7..81ed6f6bed67 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -348,7 +348,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 		ops->p->cursor_shape = vc->vc_cursor_type;
 		cursor.set |= FB_CUR_SETSHAPE;
 
-		switch (ops->p->cursor_shape & CUR_HWMASK) {
+		switch (CUR_SIZE(ops->p->cursor_shape)) {
 		case CUR_NONE:
 			cur_height = 0;
 			break;
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index 40ed52f67bc5..153734816b49 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -173,17 +173,23 @@ struct vc {
 extern struct vc vc_cons [MAX_NR_CONSOLES];
 extern void vc_SAK(struct work_struct *work);
 
-#define CUR_DEF		0
-#define CUR_NONE	1
-#define CUR_UNDERLINE	2
-#define CUR_LOWER_THIRD	3
-#define CUR_LOWER_HALF	4
-#define CUR_TWO_THIRDS	5
-#define CUR_BLOCK	6
-#define CUR_HWMASK	0x0f
-#define CUR_SWMASK	0xfff0
-
-#define CUR_DEFAULT CUR_UNDERLINE
+#define CUR_MAKE(size, change, set)	((size) | ((change) << 8) |	\
+		((set) << 16))
+#define CUR_SIZE(c)		 ((c) & 0x00000f)
+# define CUR_DEF			       0
+# define CUR_NONE			       1
+# define CUR_UNDERLINE			       2
+# define CUR_LOWER_THIRD		       3
+# define CUR_LOWER_HALF			       4
+# define CUR_TWO_THIRDS			       5
+# define CUR_BLOCK			       6
+#define CUR_SW				0x000010
+#define CUR_ALWAYS_BG			0x000020
+#define CUR_INVERT_FG_BG		0x000040
+#define CUR_FG				0x000700
+#define CUR_BG				0x007000
+#define CUR_CHANGE(c)		 ((c) & 0x00ff00)
+#define CUR_SET(c)		(((c) & 0xff0000) >> 8)
 
 bool con_is_visible(const struct vc_data *vc);
 
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 26/38] vt: use newly defined CUR_* macros
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (23 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 25/38] vt: redefine world of cursor macros Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15 20:31   ` Helge Deller
  2020-06-15  7:48 ` [PATCH 27/38] vt: remove superfluous parens in invert_screen and build_attr Jiri Slaby
                   ` (11 subsequent siblings)
  36 siblings, 1 reply; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh
  Cc: linux-serial, linux-kernel, Jiri Slaby, Thomas Winischhofer,
	Bartlomiej Zolnierkiewicz, James E.J. Bottomley, Helge Deller,
	linux-usb, dri-devel, linux-fbdev, linux-parisc

We defined macros for all the magic constants in the previous patch. So
let us use the macro in the code now.

No functional change intended.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Cc: Thomas Winischhofer <thomas@winischhofer.net>
Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: Helge Deller <deller@gmx.de>
Cc: linux-usb@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-fbdev@vger.kernel.org
Cc: linux-parisc@vger.kernel.org
---
 drivers/tty/vt/vt.c                     | 22 +++++++++++++---------
 drivers/usb/misc/sisusbvga/sisusb_con.c |  2 +-
 drivers/video/console/mdacon.c          |  2 +-
 drivers/video/console/sticon.c          |  2 +-
 drivers/video/console/vgacon.c          |  2 +-
 drivers/video/fbdev/core/bitblit.c      |  2 +-
 drivers/video/fbdev/core/fbcon.c        |  2 +-
 drivers/video/fbdev/core/fbcon_ccw.c    |  2 +-
 drivers/video/fbdev/core/fbcon_cw.c     |  2 +-
 drivers/video/fbdev/core/fbcon_ud.c     |  2 +-
 drivers/video/fbdev/core/tileblit.c     |  2 +-
 11 files changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index af1ef717f416..2b9fc628f05b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -866,17 +866,18 @@ static void add_softcursor(struct vc_data *vc)
 	int i = scr_readw((u16 *) vc->vc_pos);
 	u32 type = vc->vc_cursor_type;
 
-	if (!(type & 0x10))
+	if (!(type & CUR_SW))
 		return;
 	if (softcursor_original != -1)
 		return;
 	softcursor_original = i;
-	i |= (type >> 8) & 0xff00;
-	i ^= type & 0xff00;
-	if ((type & 0x20) && (softcursor_original & 0x7000) == (i & 0x7000))
-		i ^= 0x7000;
-	if ((type & 0x40) && (i & 0x700) == ((i & 0x7000) >> 4))
-		i ^= 0x0700;
+	i |= CUR_SET(type);
+	i ^= CUR_CHANGE(type);
+	if ((type & CUR_ALWAYS_BG) &&
+			(softcursor_original & CUR_BG) == (i & CUR_BG))
+		i ^= CUR_BG;
+	if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4))
+		i ^= CUR_FG;
 	scr_writew(i, (u16 *)vc->vc_pos);
 	if (con_should_update(vc))
 		vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
@@ -910,7 +911,7 @@ static void set_cursor(struct vc_data *vc)
 		if (vc_is_sel(vc))
 			clear_selection();
 		add_softcursor(vc);
-		if ((vc->vc_cursor_type & 0x0f) != 1)
+		if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE)
 			vc->vc_sw->con_cursor(vc, CM_DRAW);
 	} else
 		hide_cursor(vc);
@@ -2322,7 +2323,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
 		case 'c':
 			if (vc->vc_priv == EPdec) {
 				if (vc->vc_par[0])
-					vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
+					vc->vc_cursor_type =
+						CUR_MAKE(vc->vc_par[0],
+							 vc->vc_par[1],
+							 vc->vc_par[2]);
 				else
 					vc->vc_cursor_type = cur_default;
 				return;
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 80657c49310a..1058eaba3084 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -727,7 +727,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
 
 	baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);
 
-	switch (c->vc_cursor_type & 0x0f) {
+	switch (CUR_SIZE(c->vc_cursor_type)) {
 		case CUR_BLOCK:		from = 1;
 					to   = c->vc_font.height;
 					break;
diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
index 00cb6245fbef..ef29b321967f 100644
--- a/drivers/video/console/mdacon.c
+++ b/drivers/video/console/mdacon.c
@@ -492,7 +492,7 @@ static void mdacon_cursor(struct vc_data *c, int mode)
 
 	mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2);
 
-	switch (c->vc_cursor_type & 0x0f) {
+	switch (CUR_SIZE(c->vc_cursor_type)) {
 
 		case CUR_LOWER_THIRD:	mda_set_cursor_size(10, 13); break;
 		case CUR_LOWER_HALF:	mda_set_cursor_size(7,  13); break;
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index bbcdfd312c36..21a5c280c8c9 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -139,7 +139,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
 	break;
     case CM_MOVE:
     case CM_DRAW:
-	switch (conp->vc_cursor_type & 0x0f) {
+	switch (CUR_SIZE(conp->vc_cursor_type)) {
 	case CUR_UNDERLINE:
 	case CUR_LOWER_THIRD:
 	case CUR_LOWER_HALF:
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index c1c4ce28ac5e..f0f3d573f848 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -728,7 +728,7 @@ static void vgacon_cursor(struct vc_data *c, int mode)
 	case CM_MOVE:
 	case CM_DRAW:
 		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
-		switch (c->vc_cursor_type & 0x0f) {
+		switch (CUR_SIZE(c->vc_cursor_type)) {
 		case CUR_UNDERLINE:
 			vgacon_set_cursor_size(c->state.x,
 					       c->vc_font.height -
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 3b002b365a5a..dde8004d8610 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -241,7 +241,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
 	int y = real_y(ops->p, vc->state.y);
-	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
 	int err = 1;
 	char *src;
 
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 38d2a00b0ccf..86fe41b1deb8 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -1393,7 +1393,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
 	if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
 		return;
 
-	if (vc->vc_cursor_type & 0x10)
+	if (vc->vc_cursor_type & CUR_SW)
 		fbcon_del_cursor_timer(info);
 	else
 		fbcon_add_cursor_timer(info);
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 5b67bcebe34c..b5dd8317086d 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -226,7 +226,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.height + 7) >> 3, c;
 	int y = real_y(ops->p, vc->state.y);
-	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
 	int err = 1, dx, dy;
 	char *src;
 	u32 vyres = GETVYRES(ops->p->scrollmode, info);
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index f1aab3ae3bc9..dbb5dbf3dd01 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -209,7 +209,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.height + 7) >> 3, c;
 	int y = real_y(ops->p, vc->state.y);
-	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
 	int err = 1, dx, dy;
 	char *src;
 	u32 vxres = GETVXRES(ops->p->scrollmode, info);
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index 81ed6f6bed67..b2c9cdbcc9e4 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -256,7 +256,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
 	int w = (vc->vc_font.width + 7) >> 3, c;
 	int y = real_y(ops->p, vc->state.y);
-	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
+	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
 	int err = 1, dx, dy;
 	char *src;
 	u32 vyres = GETVYRES(ops->p->scrollmode, info);
diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c
index ac51425687e4..1dfaff0881fb 100644
--- a/drivers/video/fbdev/core/tileblit.c
+++ b/drivers/video/fbdev/core/tileblit.c
@@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
 			int softback_lines, int fg, int bg)
 {
 	struct fb_tilecursor cursor;
-	int use_sw = (vc->vc_cursor_type & 0x10);
+	int use_sw = vc->vc_cursor_type & CUR_SW;
 
 	cursor.sx = vc->state.x;
 	cursor.sy = vc->state.y;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 27/38] vt: remove superfluous parens in invert_screen and build_attr
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (24 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 26/38] vt: use newly defined CUR_* macros Jiri Slaby
@ 2020-06-15  7:48 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 28/38] vt: simplify noncolor attributes in build_attr Jiri Slaby
                   ` (10 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:48 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

There were too many parentheses in invert_screen, remove them and align
the code in invert_screen a bit.

No functional change intended.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 2b9fc628f05b..3aff2e3cf5a6 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -730,7 +730,7 @@ static u8 build_attr(struct vc_data *vc, u8 _color,
 	else if (_intensity == VCI_HALF_BRIGHT)
 		a = (a & 0xf0) | vc->vc_halfcolor;
 	if (_reverse)
-		a = ((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77);
+		a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77);
 	if (_blink)
 		a ^= 0x80;
 	if (_intensity == VCI_BOLD)
@@ -777,14 +777,18 @@ void invert_screen(struct vc_data *vc, int offset, int count, int viewed)
 		} else if (vc->vc_hi_font_mask == 0x100) {
 			while (cnt--) {
 				a = scr_readw(q);
-				a = ((a) & 0x11ff) | (((a) & 0xe000) >> 4) | (((a) & 0x0e00) << 4);
+				a = (a & 0x11ff) |
+				   ((a & 0xe000) >> 4) |
+				   ((a & 0x0e00) << 4);
 				scr_writew(a, q);
 				q++;
 			}
 		} else {
 			while (cnt--) {
 				a = scr_readw(q);
-				a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+				a = (a & 0x88ff) |
+				   ((a & 0x7000) >> 4) |
+				   ((a & 0x0700) << 4);
 				scr_writew(a, q);
 				q++;
 			}
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 28/38] vt: simplify noncolor attributes in build_attr
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (25 preceding siblings ...)
  2020-06-15  7:48 ` [PATCH 27/38] vt: remove superfluous parens in invert_screen and build_attr Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 29/38] vt_ioctl: eliminate ret & breaks in vt_ioctl Jiri Slaby
                   ` (9 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

All the attributes are bools, so do a simple shift instead of tests and
constants as bool is either 0 or 1.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3aff2e3cf5a6..673177d4e859 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -719,10 +719,10 @@ static u8 build_attr(struct vc_data *vc, u8 _color,
 	u8 a = _color;
 	if (!vc->vc_can_do_color)
 		return _intensity |
-		       (_italic ? 2 : 0) |
-		       (_underline ? 4 : 0) |
-		       (_reverse ? 8 : 0) |
-		       (_blink ? 0x80 : 0);
+		       (_italic    << 1) |
+		       (_underline << 2) |
+		       (_reverse   << 3) |
+		       (_blink     << 7);
 	if (_italic)
 		a = (a & 0xF0) | vc->vc_itcolor;
 	else if (_underline)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 29/38] vt_ioctl: eliminate ret & breaks in vt_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (26 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 28/38] vt: simplify noncolor attributes in build_attr Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 30/38] vt_ioctl: eliminate use of uival and ucval Jiri Slaby
                   ` (8 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

This is still a leftover from BKL, when we locked it around vt_ioctl's
code. We can return instead of breaks in the switch loop. And we can
return in case of errors too. This allows for sifting of the code to the
left in some cases.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 318 ++++++++++++++++----------------------
 1 file changed, 133 insertions(+), 185 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index daf61c28ba76..87fe088c3eb4 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -357,7 +357,7 @@ int vt_ioctl(struct tty_struct *tty,
 	unsigned int uival;
 	void __user *up = (void __user *)arg;
 	int i, perm;
-	int ret = 0;
+	int ret;
 
 	/*
 	 * To have permissions to do most of the vt ioctls, we either have
@@ -369,8 +369,7 @@ int vt_ioctl(struct tty_struct *tty,
  
 	switch (cmd) {
 	case TIOCLINUX:
-		ret = tioclinux(tty, arg);
-		break;
+		return tioclinux(tty, arg);
 	case KIOCSOUND:
 		if (!perm)
 			return -EPERM;
@@ -408,8 +407,7 @@ int vt_ioctl(struct tty_struct *tty,
 		 * this is naïve.
 		 */
 		ucval = KB_101;
-		ret = put_user(ucval, (char __user *)arg);
-		break;
+		return put_user(ucval, (char __user *)arg);
 
 		/*
 		 * These cannot be implemented on any machine that implements
@@ -426,18 +424,15 @@ int vt_ioctl(struct tty_struct *tty,
 		 *
 		 * These are locked internally via sys_ioperm
 		 */
-		if (arg < GPFIRST || arg > GPLAST) {
-			ret = -EINVAL;
-			break;
-		}
-		ret = ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
-		break;
+		if (arg < GPFIRST || arg > GPLAST)
+			return -EINVAL;
+
+		return ksys_ioperm(arg, 1, (cmd == KDADDIO)) ? -ENXIO : 0;
 
 	case KDENABIO:
 	case KDDISABIO:
-		ret = ksys_ioperm(GPFIRST, GPNUM,
+		return ksys_ioperm(GPFIRST, GPNUM,
 				  (cmd == KDENABIO)) ? -ENXIO : 0;
-		break;
 #endif
 
 	/* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
@@ -449,15 +444,14 @@ int vt_ioctl(struct tty_struct *tty,
 		if (!capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
 
-		if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat))) {
-			ret =  -EFAULT;
-			break;
-		}
+		if (copy_from_user(&kbrep, up, sizeof(struct kbd_repeat)))
+			return -EFAULT;
+
 		ret = kbd_rate(&kbrep);
 		if (ret)
-			break;
+			return ret;
 		if (copy_to_user(up, &kbrep, sizeof(struct kbd_repeat)))
-			ret = -EFAULT;
+			return -EFAULT;
 		break;
 	}
 
@@ -481,8 +475,7 @@ int vt_ioctl(struct tty_struct *tty,
 		case KD_TEXT:
 			break;
 		default:
-			ret = -EINVAL;
-			goto out;
+			return -EINVAL;
 		}
 		/* FIXME: this needs the console lock extending */
 		if (vc->vc_mode == (unsigned char) arg)
@@ -511,51 +504,45 @@ int vt_ioctl(struct tty_struct *tty,
 		 * these work like a combination of mmap and KDENABIO.
 		 * this could be easily finished.
 		 */
-		ret = -EINVAL;
-		break;
+		return -EINVAL;
 
 	case KDSKBMODE:
 		if (!perm)
 			return -EPERM;
 		ret = vt_do_kdskbmode(console, arg);
-		if (ret == 0)
-			tty_ldisc_flush(tty);
+		if (ret)
+			return ret;
+		tty_ldisc_flush(tty);
 		break;
 
 	case KDGKBMODE:
 		uival = vt_do_kdgkbmode(console);
-		ret = put_user(uival, (int __user *)arg);
-		break;
+		return put_user(uival, (int __user *)arg);
 
 	/* this could be folded into KDSKBMODE, but for compatibility
 	   reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
 	case KDSKBMETA:
-		ret = vt_do_kdskbmeta(console, arg);
-		break;
+		return vt_do_kdskbmeta(console, arg);
 
 	case KDGKBMETA:
 		/* FIXME: should review whether this is worth locking */
 		uival = vt_do_kdgkbmeta(console);
 	setint:
-		ret = put_user(uival, (int __user *)arg);
-		break;
+		return put_user(uival, (int __user *)arg);
 
 	case KDGETKEYCODE:
 	case KDSETKEYCODE:
 		if(!capable(CAP_SYS_TTY_CONFIG))
 			perm = 0;
-		ret = vt_do_kbkeycode_ioctl(cmd, up, perm);
-		break;
+		return vt_do_kbkeycode_ioctl(cmd, up, perm);
 
 	case KDGKBENT:
 	case KDSKBENT:
-		ret = vt_do_kdsk_ioctl(cmd, up, perm, console);
-		break;
+		return vt_do_kdsk_ioctl(cmd, up, perm, console);
 
 	case KDGKBSENT:
 	case KDSKBSENT:
-		ret = vt_do_kdgkb_ioctl(cmd, up, perm);
-		break;
+		return vt_do_kdgkb_ioctl(cmd, up, perm);
 
 	/* Diacritical processing. Handled in keyboard.c as it has
 	   to operate on the keyboard locks and structures */
@@ -563,8 +550,7 @@ int vt_ioctl(struct tty_struct *tty,
 	case KDGKBDIACRUC:
 	case KDSKBDIACR:
 	case KDSKBDIACRUC:
-		ret = vt_do_diacrit(cmd, up, perm);
-		break;
+		return vt_do_diacrit(cmd, up, perm);
 
 	/* the ioctls below read/set the flags usually shown in the leds */
 	/* don't use them - they will go away without warning */
@@ -572,8 +558,7 @@ int vt_ioctl(struct tty_struct *tty,
 	case KDSKBLED:
 	case KDGETLED:
 	case KDSETLED:
-		ret = vt_do_kdskled(console, cmd, arg, perm);
-		break;
+		return vt_do_kdskled(console, cmd, arg, perm);
 
 	/*
 	 * A process can indicate its willingness to accept signals
@@ -583,20 +568,17 @@ int vt_ioctl(struct tty_struct *tty,
 	 * See also the kbrequest field of inittab(5).
 	 */
 	case KDSIGACCEPT:
-	{
 		if (!perm || !capable(CAP_KILL))
 			return -EPERM;
 		if (!valid_signal(arg) || arg < 1 || arg == SIGKILL)
-			ret = -EINVAL;
-		else {
-			spin_lock_irq(&vt_spawn_con.lock);
-			put_pid(vt_spawn_con.pid);
-			vt_spawn_con.pid = get_pid(task_pid(current));
-			vt_spawn_con.sig = arg;
-			spin_unlock_irq(&vt_spawn_con.lock);
-		}
+			return -EINVAL;
+
+		spin_lock_irq(&vt_spawn_con.lock);
+		put_pid(vt_spawn_con.pid);
+		vt_spawn_con.pid = get_pid(task_pid(current));
+		vt_spawn_con.sig = arg;
+		spin_unlock_irq(&vt_spawn_con.lock);
 		break;
-	}
 
 	case VT_SETMODE:
 	{
@@ -604,14 +586,11 @@ int vt_ioctl(struct tty_struct *tty,
 
 		if (!perm)
 			return -EPERM;
-		if (copy_from_user(&tmp, up, sizeof(struct vt_mode))) {
-			ret = -EFAULT;
-			goto out;
-		}
-		if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS) {
-			ret = -EINVAL;
-			goto out;
-		}
+		if (copy_from_user(&tmp, up, sizeof(struct vt_mode)))
+			return -EFAULT;
+		if (tmp.mode != VT_AUTO && tmp.mode != VT_PROCESS)
+			return -EINVAL;
+
 		console_lock();
 		vc->vt_mode = tmp;
 		/* the frsig is ignored, so we set it to 0 */
@@ -635,7 +614,7 @@ int vt_ioctl(struct tty_struct *tty,
 
 		rc = copy_to_user(up, &tmp, sizeof(struct vt_mode));
 		if (rc)
-			ret = -EFAULT;
+			return -EFAULT;
 		break;
 	}
 
@@ -650,18 +629,16 @@ int vt_ioctl(struct tty_struct *tty,
 		unsigned short state, mask;
 
 		if (put_user(fg_console + 1, &vtstat->v_active))
-			ret = -EFAULT;
-		else {
-			state = 1;	/* /dev/tty0 is always open */
-			console_lock(); /* required by vt_in_use() */
-			for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
-							++i, mask <<= 1)
-				if (vt_in_use(i))
-					state |= mask;
-			console_unlock();
-			ret = put_user(state, &vtstat->v_state);
-		}
-		break;
+			return -EFAULT;
+
+		state = 1;	/* /dev/tty0 is always open */
+		console_lock(); /* required by vt_in_use() */
+		for (i = 0, mask = 2; i < MAX_NR_CONSOLES && mask;
+				++i, mask <<= 1)
+			if (vt_in_use(i))
+				state |= mask;
+		console_unlock();
+		return put_user(state, &vtstat->v_state);
 	}
 
 	/*
@@ -685,56 +662,54 @@ int vt_ioctl(struct tty_struct *tty,
 		if (!perm)
 			return -EPERM;
 		if (arg == 0 || arg > MAX_NR_CONSOLES)
-			ret =  -ENXIO;
-		else {
-			arg--;
-			console_lock();
-			ret = vc_allocate(arg);
-			console_unlock();
-			if (ret)
-				break;
-			set_console(arg);
-		}
+			return -ENXIO;
+
+		arg--;
+		console_lock();
+		ret = vc_allocate(arg);
+		console_unlock();
+		if (ret)
+			return ret;
+		set_console(arg);
 		break;
 
 	case VT_SETACTIVATE:
 	{
 		struct vt_setactivate vsa;
+		struct vc_data *nvc;
 
 		if (!perm)
 			return -EPERM;
 
 		if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
-					sizeof(struct vt_setactivate))) {
-			ret = -EFAULT;
-			goto out;
-		}
+					sizeof(struct vt_setactivate)))
+			return -EFAULT;
 		if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
-			ret = -ENXIO;
-		else {
-			vsa.console = array_index_nospec(vsa.console,
-							 MAX_NR_CONSOLES + 1);
-			vsa.console--;
-			console_lock();
-			ret = vc_allocate(vsa.console);
-			if (ret == 0) {
-				struct vc_data *nvc;
-				/* This is safe providing we don't drop the
-				   console sem between vc_allocate and
-				   finishing referencing nvc */
-				nvc = vc_cons[vsa.console].d;
-				nvc->vt_mode = vsa.mode;
-				nvc->vt_mode.frsig = 0;
-				put_pid(nvc->vt_pid);
-				nvc->vt_pid = get_pid(task_pid(current));
-			}
+			return -ENXIO;
+
+		vsa.console = array_index_nospec(vsa.console,
+						 MAX_NR_CONSOLES + 1);
+		vsa.console--;
+		console_lock();
+		ret = vc_allocate(vsa.console);
+		if (ret) {
 			console_unlock();
-			if (ret)
-				break;
-			/* Commence switch and lock */
-			/* Review set_console locks */
-			set_console(vsa.console);
+			return ret;
 		}
+
+		/* This is safe providing we don't drop the
+		   console sem between vc_allocate and
+		   finishing referencing nvc */
+		nvc = vc_cons[vsa.console].d;
+		nvc->vt_mode = vsa.mode;
+		nvc->vt_mode.frsig = 0;
+		put_pid(nvc->vt_pid);
+		nvc->vt_pid = get_pid(task_pid(current));
+		console_unlock();
+
+		/* Commence switch and lock */
+		/* Review set_console locks */
+		set_console(vsa.console);
 		break;
 	}
 
@@ -745,10 +720,8 @@ int vt_ioctl(struct tty_struct *tty,
 		if (!perm)
 			return -EPERM;
 		if (arg == 0 || arg > MAX_NR_CONSOLES)
-			ret = -ENXIO;
-		else
-			ret = vt_waitactive(arg);
-		break;
+			return -ENXIO;
+		return vt_waitactive(arg);
 
 	/*
 	 * If a vt is under process control, the kernel will not switch to it
@@ -767,8 +740,7 @@ int vt_ioctl(struct tty_struct *tty,
 		console_lock();
 		if (vc->vt_mode.mode != VT_PROCESS) {
 			console_unlock();
-			ret = -EINVAL;
-			break;
+			return -EINVAL;
 		}
 		/*
 		 * Switching-from response
@@ -792,7 +764,7 @@ int vt_ioctl(struct tty_struct *tty,
 				ret = vc_allocate(newvt);
 				if (ret) {
 					console_unlock();
-					break;
+					return ret;
 				}
 				/*
 				 * When we actually do the console switch,
@@ -808,8 +780,10 @@ int vt_ioctl(struct tty_struct *tty,
 			/*
 			 * If it's just an ACK, ignore it
 			 */
-			if (arg != VT_ACKACQ)
-				ret = -EINVAL;
+			if (arg != VT_ACKACQ) {
+				console_unlock();
+				return -EINVAL;
+			}
 		}
 		console_unlock();
 		break;
@@ -818,40 +792,38 @@ int vt_ioctl(struct tty_struct *tty,
 	  * Disallocate memory associated to VT (but leave VT1)
 	  */
 	 case VT_DISALLOCATE:
-		if (arg > MAX_NR_CONSOLES) {
-			ret = -ENXIO;
-			break;
-		}
+		if (arg > MAX_NR_CONSOLES)
+			return -ENXIO;
+
 		if (arg == 0)
 			vt_disallocate_all();
 		else
-			ret = vt_disallocate(--arg);
+			return vt_disallocate(--arg);
 		break;
 
 	case VT_RESIZE:
 	{
 		struct vt_sizes __user *vtsizes = up;
 		struct vc_data *vc;
-
 		ushort ll,cc;
+
 		if (!perm)
 			return -EPERM;
 		if (get_user(ll, &vtsizes->v_rows) ||
 		    get_user(cc, &vtsizes->v_cols))
-			ret = -EFAULT;
-		else {
-			console_lock();
-			for (i = 0; i < MAX_NR_CONSOLES; i++) {
-				vc = vc_cons[i].d;
+			return -EFAULT;
 
-				if (vc) {
-					vc->vc_resize_user = 1;
-					/* FIXME: review v tty lock */
-					vc_resize(vc_cons[i].d, cc, ll);
-				}
+		console_lock();
+		for (i = 0; i < MAX_NR_CONSOLES; i++) {
+			vc = vc_cons[i].d;
+
+			if (vc) {
+				vc->vc_resize_user = 1;
+				/* FIXME: review v tty lock */
+				vc_resize(vc_cons[i].d, cc, ll);
 			}
-			console_unlock();
 		}
+		console_unlock();
 		break;
 	}
 
@@ -905,7 +877,7 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 	}
 
-	case PIO_FONT: {
+	case PIO_FONT:
 		if (!perm)
 			return -EPERM;
 		op.op = KD_FONT_OP_SET;
@@ -914,98 +886,77 @@ int vt_ioctl(struct tty_struct *tty,
 		op.height = 0;
 		op.charcount = 256;
 		op.data = up;
-		ret = con_font_op(vc_cons[fg_console].d, &op);
-		break;
-	}
+		return con_font_op(vc_cons[fg_console].d, &op);
 
-	case GIO_FONT: {
+	case GIO_FONT:
 		op.op = KD_FONT_OP_GET;
 		op.flags = KD_FONT_FLAG_OLD;
 		op.width = 8;
 		op.height = 32;
 		op.charcount = 256;
 		op.data = up;
-		ret = con_font_op(vc_cons[fg_console].d, &op);
-		break;
-	}
+		return con_font_op(vc_cons[fg_console].d, &op);
 
 	case PIO_CMAP:
                 if (!perm)
-			ret = -EPERM;
-		else
-	                ret = con_set_cmap(up);
-		break;
+			return -EPERM;
+		return con_set_cmap(up);
 
 	case GIO_CMAP:
-                ret = con_get_cmap(up);
-		break;
+                return con_get_cmap(up);
 
 	case PIO_FONTX:
 	case GIO_FONTX:
-		ret = do_fontx_ioctl(cmd, up, perm, &op);
-		break;
+		return do_fontx_ioctl(cmd, up, perm, &op);
 
 	case PIO_FONTRESET:
-	{
 		if (!perm)
 			return -EPERM;
 
 #ifdef BROKEN_GRAPHICS_PROGRAMS
 		/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
 		   font is not saved. */
-		ret = -ENOSYS;
-		break;
+		return -ENOSYS;
 #else
-		{
 		op.op = KD_FONT_OP_SET_DEFAULT;
 		op.data = NULL;
 		ret = con_font_op(vc_cons[fg_console].d, &op);
 		if (ret)
-			break;
+			return ret;
 		console_lock();
 		con_set_default_unimap(vc_cons[fg_console].d);
 		console_unlock();
 		break;
-		}
 #endif
-	}
 
 	case KDFONTOP: {
-		if (copy_from_user(&op, up, sizeof(op))) {
-			ret = -EFAULT;
-			break;
-		}
+		if (copy_from_user(&op, up, sizeof(op)))
+			return -EFAULT;
 		if (!perm && op.op != KD_FONT_OP_GET)
 			return -EPERM;
 		ret = con_font_op(vc, &op);
 		if (ret)
-			break;
+			return ret;
 		if (copy_to_user(up, &op, sizeof(op)))
-			ret = -EFAULT;
+			return -EFAULT;
 		break;
 	}
 
 	case PIO_SCRNMAP:
 		if (!perm)
-			ret = -EPERM;
-		else
-			ret = con_set_trans_old(up);
-		break;
+			return -EPERM;
+		return con_set_trans_old(up);
 
 	case GIO_SCRNMAP:
-		ret = con_get_trans_old(up);
-		break;
+		return con_get_trans_old(up);
 
 	case PIO_UNISCRNMAP:
 		if (!perm)
-			ret = -EPERM;
-		else
-			ret = con_set_trans_new(up);
-		break;
+			return -EPERM;
+		return con_set_trans_new(up);
 
 	case GIO_UNISCRNMAP:
-		ret = con_get_trans_new(up);
-		break;
+		return con_get_trans_new(up);
 
 	case PIO_UNIMAPCLR:
 		if (!perm)
@@ -1015,8 +966,7 @@ int vt_ioctl(struct tty_struct *tty,
 
 	case PIO_UNIMAP:
 	case GIO_UNIMAP:
-		ret = do_unimap_ioctl(cmd, up, perm, vc);
-		break;
+		return do_unimap_ioctl(cmd, up, perm, vc);
 
 	case VT_LOCKSWITCH:
 		if (!capable(CAP_SYS_TTY_CONFIG))
@@ -1029,17 +979,15 @@ int vt_ioctl(struct tty_struct *tty,
 		vt_dont_switch = false;
 		break;
 	case VT_GETHIFONTMASK:
-		ret = put_user(vc->vc_hi_font_mask,
+		return put_user(vc->vc_hi_font_mask,
 					(unsigned short __user *)arg);
-		break;
 	case VT_WAITEVENT:
-		ret = vt_event_wait_ioctl((struct vt_event __user *)arg);
-		break;
+		return vt_event_wait_ioctl((struct vt_event __user *)arg);
 	default:
-		ret = -ENOIOCTLCMD;
+		return -ENOIOCTLCMD;
 	}
-out:
-	return ret;
+
+	return 0;
 }
 
 void reset_vc(struct vc_data *vc)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 30/38] vt_ioctl: eliminate use of uival and ucval
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (27 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 29/38] vt_ioctl: eliminate ret & breaks in vt_ioctl Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 31/38] vt_ioctl: move K* ioctls to a separate function Jiri Slaby
                   ` (7 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

They were used for the first parameter of put_user. But put_user accepts
constants in the parameter and also determines the type only by the
second parameter. So we can safely drop these helpers and simplify the
code a bit.

Including the removal of set_int label.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 87fe088c3eb4..911edd8d1272 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -353,8 +353,6 @@ int vt_ioctl(struct tty_struct *tty,
 	struct vc_data *vc = tty->driver_data;
 	struct console_font_op op;	/* used in multiple places here */
 	unsigned int console = vc->vc_num;
-	unsigned char ucval;
-	unsigned int uival;
 	void __user *up = (void __user *)arg;
 	int i, perm;
 	int ret;
@@ -406,8 +404,7 @@ int vt_ioctl(struct tty_struct *tty,
 		/*
 		 * this is naïve.
 		 */
-		ucval = KB_101;
-		return put_user(ucval, (char __user *)arg);
+		return put_user(KB_101, (char __user *)arg);
 
 		/*
 		 * These cannot be implemented on any machine that implements
@@ -495,8 +492,7 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 
 	case KDGETMODE:
-		uival = vc->vc_mode;
-		goto setint;
+		return put_user(vc->vc_mode, (int __user *)arg);
 
 	case KDMAPDISP:
 	case KDUNMAPDISP:
@@ -516,8 +512,7 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 
 	case KDGKBMODE:
-		uival = vt_do_kdgkbmode(console);
-		return put_user(uival, (int __user *)arg);
+		return put_user(vt_do_kdgkbmode(console), (int __user *)arg);
 
 	/* this could be folded into KDSKBMODE, but for compatibility
 	   reasons it is not so easy to fold KDGKBMETA into KDGKBMODE */
@@ -526,9 +521,7 @@ int vt_ioctl(struct tty_struct *tty,
 
 	case KDGKBMETA:
 		/* FIXME: should review whether this is worth locking */
-		uival = vt_do_kdgkbmeta(console);
-	setint:
-		return put_user(uival, (int __user *)arg);
+		return put_user(vt_do_kdgkbmeta(console), (int __user *)arg);
 
 	case KDGETKEYCODE:
 	case KDSETKEYCODE:
@@ -650,8 +643,8 @@ int vt_ioctl(struct tty_struct *tty,
 			if (!vt_in_use(i))
 				break;
 		console_unlock();
-		uival = i < MAX_NR_CONSOLES ? (i+1) : -1;
-		goto setint;		 
+		i = i < MAX_NR_CONSOLES ? (i+1) : -1;
+		return put_user(i, (int __user *)arg);
 
 	/*
 	 * ioctl(fd, VT_ACTIVATE, num) will cause us to switch to vt # num,
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 31/38] vt_ioctl: move K* ioctls to a separate function
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (28 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 30/38] vt_ioctl: eliminate use of uival and ucval Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 32/38] vt_ioctl: move io " Jiri Slaby
                   ` (6 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

We create a new vt_k_ioctl here and move there all the K* ioctls.  This
makes vt_ioctl significantly smaller.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 294 ++++++++++++++++++++------------------
 1 file changed, 157 insertions(+), 137 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 911edd8d1272..1b423bdc488e 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -241,133 +241,15 @@ int vt_waitactive(int n)
 #define GPLAST 0x3df
 #define GPNUM (GPLAST - GPFIRST + 1)
 
-
-
-static inline int 
-do_fontx_ioctl(int cmd, struct consolefontdesc __user *user_cfd, int perm, struct console_font_op *op)
-{
-	struct consolefontdesc cfdarg;
-	int i;
-
-	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc))) 
-		return -EFAULT;
- 	
-	switch (cmd) {
-	case PIO_FONTX:
-		if (!perm)
-			return -EPERM;
-		op->op = KD_FONT_OP_SET;
-		op->flags = KD_FONT_FLAG_OLD;
-		op->width = 8;
-		op->height = cfdarg.charheight;
-		op->charcount = cfdarg.charcount;
-		op->data = cfdarg.chardata;
-		return con_font_op(vc_cons[fg_console].d, op);
-	case GIO_FONTX: {
-		op->op = KD_FONT_OP_GET;
-		op->flags = KD_FONT_FLAG_OLD;
-		op->width = 8;
-		op->height = cfdarg.charheight;
-		op->charcount = cfdarg.charcount;
-		op->data = cfdarg.chardata;
-		i = con_font_op(vc_cons[fg_console].d, op);
-		if (i)
-			return i;
-		cfdarg.charheight = op->height;
-		cfdarg.charcount = op->charcount;
-		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
-			return -EFAULT;
-		return 0;
-		}
-	}
-	return -EINVAL;
-}
-
-static inline int 
-do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud, int perm, struct vc_data *vc)
-{
-	struct unimapdesc tmp;
-
-	if (copy_from_user(&tmp, user_ud, sizeof tmp))
-		return -EFAULT;
-	switch (cmd) {
-	case PIO_UNIMAP:
-		if (!perm)
-			return -EPERM;
-		return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
-	case GIO_UNIMAP:
-		if (!perm && fg_console != vc->vc_num)
-			return -EPERM;
-		return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct), tmp.entries);
-	}
-	return 0;
-}
-
-/* deallocate a single console, if possible (leave 0) */
-static int vt_disallocate(unsigned int vc_num)
-{
-	struct vc_data *vc = NULL;
-	int ret = 0;
-
-	console_lock();
-	if (vt_busy(vc_num))
-		ret = -EBUSY;
-	else if (vc_num)
-		vc = vc_deallocate(vc_num);
-	console_unlock();
-
-	if (vc && vc_num >= MIN_NR_CONSOLES)
-		tty_port_put(&vc->port);
-
-	return ret;
-}
-
-/* deallocate all unused consoles, but leave 0 */
-static void vt_disallocate_all(void)
-{
-	struct vc_data *vc[MAX_NR_CONSOLES];
-	int i;
-
-	console_lock();
-	for (i = 1; i < MAX_NR_CONSOLES; i++)
-		if (!vt_busy(i))
-			vc[i] = vc_deallocate(i);
-		else
-			vc[i] = NULL;
-	console_unlock();
-
-	for (i = 1; i < MAX_NR_CONSOLES; i++) {
-		if (vc[i] && i >= MIN_NR_CONSOLES)
-			tty_port_put(&vc[i]->port);
-	}
-}
-
-
-/*
- * We handle the console-specific ioctl's here.  We allow the
- * capability to modify any console, not just the fg_console. 
- */
-int vt_ioctl(struct tty_struct *tty,
-	     unsigned int cmd, unsigned long arg)
+static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
+		unsigned long arg, bool perm)
 {
 	struct vc_data *vc = tty->driver_data;
-	struct console_font_op op;	/* used in multiple places here */
-	unsigned int console = vc->vc_num;
 	void __user *up = (void __user *)arg;
-	int i, perm;
+	unsigned int console = vc->vc_num;
 	int ret;
 
-	/*
-	 * To have permissions to do most of the vt ioctls, we either have
-	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
-	 */
-	perm = 0;
-	if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
-		perm = 1;
- 
 	switch (cmd) {
-	case TIOCLINUX:
-		return tioclinux(tty, arg);
 	case KIOCSOUND:
 		if (!perm)
 			return -EPERM;
@@ -387,7 +269,7 @@ int vt_ioctl(struct tty_struct *tty,
 			return -EPERM;
 	{
 		unsigned int ticks, count;
-		
+
 		/*
 		 * Generate the tone for the appropriate number of ticks.
 		 * If the time is zero, turn off sound ourselves.
@@ -433,11 +315,11 @@ int vt_ioctl(struct tty_struct *tty,
 #endif
 
 	/* Linux m68k/i386 interface for setting the keyboard delay/repeat rate */
-		
+
 	case KDKBDREP:
 	{
 		struct kbd_repeat kbrep;
-		
+
 		if (!capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
 
@@ -573,6 +455,157 @@ int vt_ioctl(struct tty_struct *tty,
 		spin_unlock_irq(&vt_spawn_con.lock);
 		break;
 
+	case KDFONTOP: {
+		struct console_font_op op;
+
+		if (copy_from_user(&op, up, sizeof(op)))
+			return -EFAULT;
+		if (!perm && op.op != KD_FONT_OP_GET)
+			return -EPERM;
+		ret = con_font_op(vc, &op);
+		if (ret)
+			return ret;
+		if (copy_to_user(up, &op, sizeof(op)))
+			return -EFAULT;
+		break;
+	}
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
+static inline int do_fontx_ioctl(int cmd,
+		struct consolefontdesc __user *user_cfd, int perm,
+		struct console_font_op *op)
+{
+	struct consolefontdesc cfdarg;
+	int i;
+
+	if (copy_from_user(&cfdarg, user_cfd, sizeof(struct consolefontdesc)))
+		return -EFAULT;
+
+	switch (cmd) {
+	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+		op->op = KD_FONT_OP_SET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = cfdarg.chardata;
+		return con_font_op(vc_cons[fg_console].d, op);
+	case GIO_FONTX: {
+		op->op = KD_FONT_OP_GET;
+		op->flags = KD_FONT_FLAG_OLD;
+		op->width = 8;
+		op->height = cfdarg.charheight;
+		op->charcount = cfdarg.charcount;
+		op->data = cfdarg.chardata;
+		i = con_font_op(vc_cons[fg_console].d, op);
+		if (i)
+			return i;
+		cfdarg.charheight = op->height;
+		cfdarg.charcount = op->charcount;
+		if (copy_to_user(user_cfd, &cfdarg, sizeof(struct consolefontdesc)))
+			return -EFAULT;
+		return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
+		int perm, struct vc_data *vc)
+{
+	struct unimapdesc tmp;
+
+	if (copy_from_user(&tmp, user_ud, sizeof tmp))
+		return -EFAULT;
+	switch (cmd) {
+	case PIO_UNIMAP:
+		if (!perm)
+			return -EPERM;
+		return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
+	case GIO_UNIMAP:
+		if (!perm && fg_console != vc->vc_num)
+			return -EPERM;
+		return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
+				tmp.entries);
+	}
+	return 0;
+}
+
+/* deallocate a single console, if possible (leave 0) */
+static int vt_disallocate(unsigned int vc_num)
+{
+	struct vc_data *vc = NULL;
+	int ret = 0;
+
+	console_lock();
+	if (vt_busy(vc_num))
+		ret = -EBUSY;
+	else if (vc_num)
+		vc = vc_deallocate(vc_num);
+	console_unlock();
+
+	if (vc && vc_num >= MIN_NR_CONSOLES)
+		tty_port_put(&vc->port);
+
+	return ret;
+}
+
+/* deallocate all unused consoles, but leave 0 */
+static void vt_disallocate_all(void)
+{
+	struct vc_data *vc[MAX_NR_CONSOLES];
+	int i;
+
+	console_lock();
+	for (i = 1; i < MAX_NR_CONSOLES; i++)
+		if (!vt_busy(i))
+			vc[i] = vc_deallocate(i);
+		else
+			vc[i] = NULL;
+	console_unlock();
+
+	for (i = 1; i < MAX_NR_CONSOLES; i++) {
+		if (vc[i] && i >= MIN_NR_CONSOLES)
+			tty_port_put(&vc[i]->port);
+	}
+}
+
+/*
+ * We handle the console-specific ioctl's here.  We allow the
+ * capability to modify any console, not just the fg_console.
+ */
+int vt_ioctl(struct tty_struct *tty,
+	     unsigned int cmd, unsigned long arg)
+{
+	struct vc_data *vc = tty->driver_data;
+	struct console_font_op op;	/* used in multiple places here */
+	void __user *up = (void __user *)arg;
+	int i, perm;
+	int ret;
+
+	/*
+	 * To have permissions to do most of the vt ioctls, we either have
+	 * to be the owner of the tty, or have CAP_SYS_TTY_CONFIG.
+	 */
+	perm = 0;
+	if (current->signal->tty == tty || capable(CAP_SYS_TTY_CONFIG))
+		perm = 1;
+
+	ret = vt_k_ioctl(tty, cmd, arg, perm);
+	if (ret != -ENOIOCTLCMD)
+		return ret;
+
+	switch (cmd) {
+	case TIOCLINUX:
+		return tioclinux(tty, arg);
 	case VT_SETMODE:
 	{
 		struct vt_mode tmp;
@@ -922,19 +955,6 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 #endif
 
-	case KDFONTOP: {
-		if (copy_from_user(&op, up, sizeof(op)))
-			return -EFAULT;
-		if (!perm && op.op != KD_FONT_OP_GET)
-			return -EPERM;
-		ret = con_font_op(vc, &op);
-		if (ret)
-			return ret;
-		if (copy_to_user(up, &op, sizeof(op)))
-			return -EFAULT;
-		break;
-	}
-
 	case PIO_SCRNMAP:
 		if (!perm)
 			return -EPERM;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 32/38] vt_ioctl: move io ioctls to a separate function
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (29 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 31/38] vt_ioctl: move K* ioctls to a separate function Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 33/38] vt_ioctl: move vt_setactivate out of vt_ioctl Jiri Slaby
                   ` (5 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

We create a new vt_io_ioctl here and move there all the IO ioctls.  This
makes vt_ioctl significantly smaller.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 177 +++++++++++++++++++++-----------------
 1 file changed, 98 insertions(+), 79 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 1b423bdc488e..978c33ad6619 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -539,6 +539,100 @@ static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
 	return 0;
 }
 
+static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
+		bool perm)
+{
+	struct console_font_op op;	/* used in multiple places here */
+
+	switch (cmd) {
+	case PIO_FONT:
+		if (!perm)
+			return -EPERM;
+		op.op = KD_FONT_OP_SET;
+		op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC;	/* Compatibility */
+		op.width = 8;
+		op.height = 0;
+		op.charcount = 256;
+		op.data = up;
+		return con_font_op(vc_cons[fg_console].d, &op);
+
+	case GIO_FONT:
+		op.op = KD_FONT_OP_GET;
+		op.flags = KD_FONT_FLAG_OLD;
+		op.width = 8;
+		op.height = 32;
+		op.charcount = 256;
+		op.data = up;
+		return con_font_op(vc_cons[fg_console].d, &op);
+
+	case PIO_CMAP:
+                if (!perm)
+			return -EPERM;
+		return con_set_cmap(up);
+
+	case GIO_CMAP:
+                return con_get_cmap(up);
+
+	case PIO_FONTX:
+	case GIO_FONTX:
+		return do_fontx_ioctl(cmd, up, perm, &op);
+
+	case PIO_FONTRESET:
+		if (!perm)
+			return -EPERM;
+
+#ifdef BROKEN_GRAPHICS_PROGRAMS
+		/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
+		   font is not saved. */
+		return -ENOSYS;
+#else
+		{
+		int ret;
+		op.op = KD_FONT_OP_SET_DEFAULT;
+		op.data = NULL;
+		ret = con_font_op(vc_cons[fg_console].d, &op);
+		if (ret)
+			return ret;
+		console_lock();
+		con_set_default_unimap(vc_cons[fg_console].d);
+		console_unlock();
+		break;
+		}
+#endif
+
+	case PIO_SCRNMAP:
+		if (!perm)
+			return -EPERM;
+		return con_set_trans_old(up);
+
+	case GIO_SCRNMAP:
+		return con_get_trans_old(up);
+
+	case PIO_UNISCRNMAP:
+		if (!perm)
+			return -EPERM;
+		return con_set_trans_new(up);
+
+	case GIO_UNISCRNMAP:
+		return con_get_trans_new(up);
+
+	case PIO_UNIMAPCLR:
+		if (!perm)
+			return -EPERM;
+		con_clear_unimap(vc);
+		break;
+
+	case PIO_UNIMAP:
+	case GIO_UNIMAP:
+		return do_unimap_ioctl(cmd, up, perm, vc);
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+
+	return 0;
+}
+
 /* deallocate a single console, if possible (leave 0) */
 static int vt_disallocate(unsigned int vc_num)
 {
@@ -586,7 +680,6 @@ int vt_ioctl(struct tty_struct *tty,
 	     unsigned int cmd, unsigned long arg)
 {
 	struct vc_data *vc = tty->driver_data;
-	struct console_font_op op;	/* used in multiple places here */
 	void __user *up = (void __user *)arg;
 	int i, perm;
 	int ret;
@@ -603,6 +696,10 @@ int vt_ioctl(struct tty_struct *tty,
 	if (ret != -ENOIOCTLCMD)
 		return ret;
 
+	ret = vt_io_ioctl(vc, cmd, up, perm);
+	if (ret != -ENOIOCTLCMD)
+		return ret;
+
 	switch (cmd) {
 	case TIOCLINUX:
 		return tioclinux(tty, arg);
@@ -903,84 +1000,6 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 	}
 
-	case PIO_FONT:
-		if (!perm)
-			return -EPERM;
-		op.op = KD_FONT_OP_SET;
-		op.flags = KD_FONT_FLAG_OLD | KD_FONT_FLAG_DONT_RECALC;	/* Compatibility */
-		op.width = 8;
-		op.height = 0;
-		op.charcount = 256;
-		op.data = up;
-		return con_font_op(vc_cons[fg_console].d, &op);
-
-	case GIO_FONT:
-		op.op = KD_FONT_OP_GET;
-		op.flags = KD_FONT_FLAG_OLD;
-		op.width = 8;
-		op.height = 32;
-		op.charcount = 256;
-		op.data = up;
-		return con_font_op(vc_cons[fg_console].d, &op);
-
-	case PIO_CMAP:
-                if (!perm)
-			return -EPERM;
-		return con_set_cmap(up);
-
-	case GIO_CMAP:
-                return con_get_cmap(up);
-
-	case PIO_FONTX:
-	case GIO_FONTX:
-		return do_fontx_ioctl(cmd, up, perm, &op);
-
-	case PIO_FONTRESET:
-		if (!perm)
-			return -EPERM;
-
-#ifdef BROKEN_GRAPHICS_PROGRAMS
-		/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
-		   font is not saved. */
-		return -ENOSYS;
-#else
-		op.op = KD_FONT_OP_SET_DEFAULT;
-		op.data = NULL;
-		ret = con_font_op(vc_cons[fg_console].d, &op);
-		if (ret)
-			return ret;
-		console_lock();
-		con_set_default_unimap(vc_cons[fg_console].d);
-		console_unlock();
-		break;
-#endif
-
-	case PIO_SCRNMAP:
-		if (!perm)
-			return -EPERM;
-		return con_set_trans_old(up);
-
-	case GIO_SCRNMAP:
-		return con_get_trans_old(up);
-
-	case PIO_UNISCRNMAP:
-		if (!perm)
-			return -EPERM;
-		return con_set_trans_new(up);
-
-	case GIO_UNISCRNMAP:
-		return con_get_trans_new(up);
-
-	case PIO_UNIMAPCLR:
-		if (!perm)
-			return -EPERM;
-		con_clear_unimap(vc);
-		break;
-
-	case PIO_UNIMAP:
-	case GIO_UNIMAP:
-		return do_unimap_ioctl(cmd, up, perm, vc);
-
 	case VT_LOCKSWITCH:
 		if (!capable(CAP_SYS_TTY_CONFIG))
 			return -EPERM;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 33/38] vt_ioctl: move vt_setactivate out of vt_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (30 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 32/38] vt_ioctl: move io " Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 34/38] vt_ioctl: move vt_reldisp " Jiri Slaby
                   ` (4 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

It's too long to be inlined.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 74 +++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 978c33ad6619..e8bcfcdbedbb 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -633,6 +633,44 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
 	return 0;
 }
 
+static int vt_setactivate(struct vt_setactivate __user *sa)
+{
+	struct vt_setactivate vsa;
+	struct vc_data *nvc;
+	int ret;
+
+	if (copy_from_user(&vsa, sa, sizeof(vsa)))
+		return -EFAULT;
+	if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
+		return -ENXIO;
+
+	vsa.console = array_index_nospec(vsa.console, MAX_NR_CONSOLES + 1);
+	vsa.console--;
+	console_lock();
+	ret = vc_allocate(vsa.console);
+	if (ret) {
+		console_unlock();
+		return ret;
+	}
+
+	/*
+	 * This is safe providing we don't drop the console sem between
+	 * vc_allocate and finishing referencing nvc.
+	 */
+	nvc = vc_cons[vsa.console].d;
+	nvc->vt_mode = vsa.mode;
+	nvc->vt_mode.frsig = 0;
+	put_pid(nvc->vt_pid);
+	nvc->vt_pid = get_pid(task_pid(current));
+	console_unlock();
+
+	/* Commence switch and lock */
+	/* Review set_console locks */
+	set_console(vsa.console);
+
+	return 0;
+}
+
 /* deallocate a single console, if possible (leave 0) */
 static int vt_disallocate(unsigned int vc_num)
 {
@@ -797,44 +835,10 @@ int vt_ioctl(struct tty_struct *tty,
 		break;
 
 	case VT_SETACTIVATE:
-	{
-		struct vt_setactivate vsa;
-		struct vc_data *nvc;
-
 		if (!perm)
 			return -EPERM;
 
-		if (copy_from_user(&vsa, (struct vt_setactivate __user *)arg,
-					sizeof(struct vt_setactivate)))
-			return -EFAULT;
-		if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
-			return -ENXIO;
-
-		vsa.console = array_index_nospec(vsa.console,
-						 MAX_NR_CONSOLES + 1);
-		vsa.console--;
-		console_lock();
-		ret = vc_allocate(vsa.console);
-		if (ret) {
-			console_unlock();
-			return ret;
-		}
-
-		/* This is safe providing we don't drop the
-		   console sem between vc_allocate and
-		   finishing referencing nvc */
-		nvc = vc_cons[vsa.console].d;
-		nvc->vt_mode = vsa.mode;
-		nvc->vt_mode.frsig = 0;
-		put_pid(nvc->vt_pid);
-		nvc->vt_pid = get_pid(task_pid(current));
-		console_unlock();
-
-		/* Commence switch and lock */
-		/* Review set_console locks */
-		set_console(vsa.console);
-		break;
-	}
+		return vt_setactivate(up);
 
 	/*
 	 * wait until the specified VT has been activated
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 34/38] vt_ioctl: move vt_reldisp out of vt_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (31 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 33/38] vt_ioctl: move vt_setactivate out of vt_ioctl Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 35/38] vt_ioctl: move vt_resizex " Jiri Slaby
                   ` (3 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

It's too long to be inlined.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 88 ++++++++++++++++++---------------------
 1 file changed, 40 insertions(+), 48 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index e8bcfcdbedbb..cdb7f0370ca9 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -633,6 +633,42 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
 	return 0;
 }
 
+static int vt_reldisp(struct vc_data *vc, unsigned int swtch)
+{
+	int newvt, ret;
+
+	if (vc->vt_mode.mode != VT_PROCESS)
+		return -EINVAL;
+
+	/* Switched-to response */
+	if (vc->vt_newvt < 0) {
+		 /* If it's just an ACK, ignore it */
+		return swtch == VT_ACKACQ ? 0 : -EINVAL;
+	}
+
+	/* Switching-from response */
+	if (swtch == 0) {
+		/* Switch disallowed, so forget we were trying to do it. */
+		vc->vt_newvt = -1;
+		return 0;
+	}
+
+	/* The current vt has been released, so complete the switch. */
+	newvt = vc->vt_newvt;
+	vc->vt_newvt = -1;
+	ret = vc_allocate(newvt);
+	if (ret)
+		return ret;
+
+	/*
+	 * When we actually do the console switch, make sure we are atomic with
+	 * respect to other console switches..
+	 */
+	complete_change_console(vc_cons[newvt].d);
+
+	return 0;
+}
+
 static int vt_setactivate(struct vt_setactivate __user *sa)
 {
 	struct vt_setactivate vsa;
@@ -865,55 +901,11 @@ int vt_ioctl(struct tty_struct *tty,
 			return -EPERM;
 
 		console_lock();
-		if (vc->vt_mode.mode != VT_PROCESS) {
-			console_unlock();
-			return -EINVAL;
-		}
-		/*
-		 * Switching-from response
-		 */
-		if (vc->vt_newvt >= 0) {
-			if (arg == 0)
-				/*
-				 * Switch disallowed, so forget we were trying
-				 * to do it.
-				 */
-				vc->vt_newvt = -1;
-
-			else {
-				/*
-				 * The current vt has been released, so
-				 * complete the switch.
-				 */
-				int newvt;
-				newvt = vc->vt_newvt;
-				vc->vt_newvt = -1;
-				ret = vc_allocate(newvt);
-				if (ret) {
-					console_unlock();
-					return ret;
-				}
-				/*
-				 * When we actually do the console switch,
-				 * make sure we are atomic with respect to
-				 * other console switches..
-				 */
-				complete_change_console(vc_cons[newvt].d);
-			}
-		} else {
-			/*
-			 * Switched-to response
-			 */
-			/*
-			 * If it's just an ACK, ignore it
-			 */
-			if (arg != VT_ACKACQ) {
-				console_unlock();
-				return -EINVAL;
-			}
-		}
+		ret = vt_reldisp(vc, arg);
 		console_unlock();
-		break;
+
+		return ret;
+
 
 	 /*
 	  * Disallocate memory associated to VT (but leave VT1)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 35/38] vt_ioctl: move vt_resizex out of vt_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (32 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 34/38] vt_ioctl: move vt_reldisp " Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 36/38] vt_ioctl: move vt_io_fontreset out of vt_io_ioctl Jiri Slaby
                   ` (2 subsequent siblings)
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

It's too long to be inlined.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 100 +++++++++++++++++++++-----------------
 1 file changed, 55 insertions(+), 45 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index cdb7f0370ca9..f671e94a94a9 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -746,6 +746,60 @@ static void vt_disallocate_all(void)
 	}
 }
 
+static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
+{
+	struct vt_consize v;
+	int i;
+
+	if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
+		return -EFAULT;
+
+	/* FIXME: Should check the copies properly */
+	if (!v.v_vlin)
+		v.v_vlin = vc->vc_scan_lines;
+
+	if (v.v_clin) {
+		int rows = v.v_vlin / v.v_clin;
+		if (v.v_rows != rows) {
+			if (v.v_rows) /* Parameters don't add up */
+				return -EINVAL;
+			v.v_rows = rows;
+		}
+	}
+
+	if (v.v_vcol && v.v_ccol) {
+		int cols = v.v_vcol / v.v_ccol;
+		if (v.v_cols != cols) {
+			if (v.v_cols)
+				return -EINVAL;
+			v.v_cols = cols;
+		}
+	}
+
+	if (v.v_clin > 32)
+		return -EINVAL;
+
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		struct vc_data *vcp;
+
+		if (!vc_cons[i].d)
+			continue;
+		console_lock();
+		vcp = vc_cons[i].d;
+		if (vcp) {
+			if (v.v_vlin)
+				vcp->vc_scan_lines = v.v_vlin;
+			if (v.v_clin)
+				vcp->vc_font.height = v.v_clin;
+			vcp->vc_resize_user = 1;
+			vc_resize(vcp, v.v_cols, v.v_rows);
+		}
+		console_unlock();
+	}
+
+	return 0;
+}
+
 /*
  * We handle the console-specific ioctl's here.  We allow the
  * capability to modify any console, not just the fg_console.
@@ -947,54 +1001,10 @@ int vt_ioctl(struct tty_struct *tty,
 	}
 
 	case VT_RESIZEX:
-	{
-		struct vt_consize v;
 		if (!perm)
 			return -EPERM;
-		if (copy_from_user(&v, up, sizeof(struct vt_consize)))
-			return -EFAULT;
-		/* FIXME: Should check the copies properly */
-		if (!v.v_vlin)
-			v.v_vlin = vc->vc_scan_lines;
-		if (v.v_clin) {
-			int rows = v.v_vlin/v.v_clin;
-			if (v.v_rows != rows) {
-				if (v.v_rows) /* Parameters don't add up */
-					return -EINVAL;
-				v.v_rows = rows;
-			}
-		}
-		if (v.v_vcol && v.v_ccol) {
-			int cols = v.v_vcol/v.v_ccol;
-			if (v.v_cols != cols) {
-				if (v.v_cols)
-					return -EINVAL;
-				v.v_cols = cols;
-			}
-		}
 
-		if (v.v_clin > 32)
-			return -EINVAL;
-
-		for (i = 0; i < MAX_NR_CONSOLES; i++) {
-			struct vc_data *vcp;
-
-			if (!vc_cons[i].d)
-				continue;
-			console_lock();
-			vcp = vc_cons[i].d;
-			if (vcp) {
-				if (v.v_vlin)
-					vcp->vc_scan_lines = v.v_vlin;
-				if (v.v_clin)
-					vcp->vc_font.height = v.v_clin;
-				vcp->vc_resize_user = 1;
-				vc_resize(vcp, v.v_cols, v.v_rows);
-			}
-			console_unlock();
-		}
-		break;
-	}
+		return vt_resizex(vc, up);
 
 	case VT_LOCKSWITCH:
 		if (!capable(CAP_SYS_TTY_CONFIG))
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 36/38] vt_ioctl: move vt_io_fontreset out of vt_io_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (33 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 35/38] vt_ioctl: move vt_resizex " Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 37/38] vt_ioctl: move vt_kdsetmode out of vt_k_ioctl Jiri Slaby
  2020-06-15  7:49 ` [PATCH 38/38] vt_ioctl: move perm checks level up Jiri Slaby
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

This also eliminates the ifdeffery by using if and __is_defined.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 44 +++++++++++++++++++++++----------------
 1 file changed, 26 insertions(+), 18 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index f671e94a94a9..ecf96f5e616d 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -518,6 +518,31 @@ static inline int do_fontx_ioctl(int cmd,
 	return -EINVAL;
 }
 
+static int vt_io_fontreset(struct console_font_op *op)
+{
+	int ret;
+
+	if (__is_defined(BROKEN_GRAPHICS_PROGRAMS)) {
+		/*
+		 * With BROKEN_GRAPHICS_PROGRAMS defined, the default font is
+		 * not saved.
+		 */
+		return -ENOSYS;
+	}
+
+	op->op = KD_FONT_OP_SET_DEFAULT;
+	op->data = NULL;
+	ret = con_font_op(vc_cons[fg_console].d, op);
+	if (ret)
+		return ret;
+
+	console_lock();
+	con_set_default_unimap(vc_cons[fg_console].d);
+	console_unlock();
+
+	return 0;
+}
+
 static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
 		int perm, struct vc_data *vc)
 {
@@ -581,24 +606,7 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
 		if (!perm)
 			return -EPERM;
 
-#ifdef BROKEN_GRAPHICS_PROGRAMS
-		/* With BROKEN_GRAPHICS_PROGRAMS defined, the default
-		   font is not saved. */
-		return -ENOSYS;
-#else
-		{
-		int ret;
-		op.op = KD_FONT_OP_SET_DEFAULT;
-		op.data = NULL;
-		ret = con_font_op(vc_cons[fg_console].d, &op);
-		if (ret)
-			return ret;
-		console_lock();
-		con_set_default_unimap(vc_cons[fg_console].d);
-		console_unlock();
-		break;
-		}
-#endif
+		return vt_io_fontreset(&op);
 
 	case PIO_SCRNMAP:
 		if (!perm)
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 37/38] vt_ioctl: move vt_kdsetmode out of vt_k_ioctl
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (34 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 36/38] vt_ioctl: move vt_io_fontreset out of vt_io_ioctl Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  2020-06-15  7:49 ` [PATCH 38/38] vt_ioctl: move perm checks level up Jiri Slaby
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

It's too long to be inlined.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 78 +++++++++++++++++++++------------------
 1 file changed, 43 insertions(+), 35 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index ecf96f5e616d..224f2a564e13 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -241,6 +241,47 @@ int vt_waitactive(int n)
 #define GPLAST 0x3df
 #define GPNUM (GPLAST - GPFIRST + 1)
 
+/*
+ * currently, setting the mode from KD_TEXT to KD_GRAPHICS doesn't do a whole
+ * lot. i'm not sure if it should do any restoration of modes or what...
+ *
+ * XXX It should at least call into the driver, fbdev's definitely need to
+ * restore their engine state. --BenH
+ */
+static int vt_kdsetmode(struct vc_data *vc, unsigned long mode)
+{
+	switch (mode) {
+	case KD_GRAPHICS:
+		break;
+	case KD_TEXT0:
+	case KD_TEXT1:
+		mode = KD_TEXT;
+		fallthrough;
+	case KD_TEXT:
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* FIXME: this needs the console lock extending */
+	if (vc->vc_mode == mode)
+		return 0;
+
+	vc->vc_mode = mode;
+	if (vc->vc_num != fg_console)
+		return 0;
+
+	/* explicitly blank/unblank the screen if switching modes */
+	console_lock();
+	if (mode == KD_TEXT)
+		do_unblank_screen(1);
+	else
+		do_blank_screen(1);
+	console_unlock();
+
+	return 0;
+}
+
 static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
 		unsigned long arg, bool perm)
 {
@@ -335,43 +376,10 @@ static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
 	}
 
 	case KDSETMODE:
-		/*
-		 * currently, setting the mode from KD_TEXT to KD_GRAPHICS
-		 * doesn't do a whole lot. i'm not sure if it should do any
-		 * restoration of modes or what...
-		 *
-		 * XXX It should at least call into the driver, fbdev's definitely
-		 * need to restore their engine state. --BenH
-		 */
 		if (!perm)
 			return -EPERM;
-		switch (arg) {
-		case KD_GRAPHICS:
-			break;
-		case KD_TEXT0:
-		case KD_TEXT1:
-			arg = KD_TEXT;
-		case KD_TEXT:
-			break;
-		default:
-			return -EINVAL;
-		}
-		/* FIXME: this needs the console lock extending */
-		if (vc->vc_mode == (unsigned char) arg)
-			break;
-		vc->vc_mode = (unsigned char) arg;
-		if (console != fg_console)
-			break;
-		/*
-		 * explicitly blank/unblank the screen if switching modes
-		 */
-		console_lock();
-		if (arg == KD_TEXT)
-			do_unblank_screen(1);
-		else
-			do_blank_screen(1);
-		console_unlock();
-		break;
+
+		return vt_kdsetmode(vc, arg);
 
 	case KDGETMODE:
 		return put_user(vc->vc_mode, (int __user *)arg);
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* [PATCH 38/38] vt_ioctl: move perm checks level up
  2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
                   ` (35 preceding siblings ...)
  2020-06-15  7:49 ` [PATCH 37/38] vt_ioctl: move vt_kdsetmode out of vt_k_ioctl Jiri Slaby
@ 2020-06-15  7:49 ` Jiri Slaby
  36 siblings, 0 replies; 39+ messages in thread
From: Jiri Slaby @ 2020-06-15  7:49 UTC (permalink / raw)
  To: gregkh; +Cc: linux-serial, linux-kernel, Jiri Slaby

Synchronize with others and check perm directly in vt_k_ioctl.
We do not need to pass perm to do_fontx_ioctl and do_unimap_ioctl then.

Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
 drivers/tty/vt/vt_ioctl.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 224f2a564e13..91c301775047 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -486,7 +486,7 @@ static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
 }
 
 static inline int do_fontx_ioctl(int cmd,
-		struct consolefontdesc __user *user_cfd, int perm,
+		struct consolefontdesc __user *user_cfd,
 		struct console_font_op *op)
 {
 	struct consolefontdesc cfdarg;
@@ -497,8 +497,6 @@ static inline int do_fontx_ioctl(int cmd,
 
 	switch (cmd) {
 	case PIO_FONTX:
-		if (!perm)
-			return -EPERM;
 		op->op = KD_FONT_OP_SET;
 		op->flags = KD_FONT_FLAG_OLD;
 		op->width = 8;
@@ -552,7 +550,7 @@ static int vt_io_fontreset(struct console_font_op *op)
 }
 
 static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
-		int perm, struct vc_data *vc)
+		struct vc_data *vc)
 {
 	struct unimapdesc tmp;
 
@@ -560,11 +558,9 @@ static inline int do_unimap_ioctl(int cmd, struct unimapdesc __user *user_ud,
 		return -EFAULT;
 	switch (cmd) {
 	case PIO_UNIMAP:
-		if (!perm)
-			return -EPERM;
 		return con_set_unimap(vc, tmp.entry_ct, tmp.entries);
 	case GIO_UNIMAP:
-		if (!perm && fg_console != vc->vc_num)
+		if (fg_console != vc->vc_num)
 			return -EPERM;
 		return con_get_unimap(vc, tmp.entry_ct, &(user_ud->entry_ct),
 				tmp.entries);
@@ -607,8 +603,12 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
                 return con_get_cmap(up);
 
 	case PIO_FONTX:
+		if (!perm)
+			return -EPERM;
+
+		fallthrough;
 	case GIO_FONTX:
-		return do_fontx_ioctl(cmd, up, perm, &op);
+		return do_fontx_ioctl(cmd, up, &op);
 
 	case PIO_FONTRESET:
 		if (!perm)
@@ -640,7 +640,10 @@ static int vt_io_ioctl(struct vc_data *vc, unsigned int cmd, void __user *up,
 
 	case PIO_UNIMAP:
 	case GIO_UNIMAP:
-		return do_unimap_ioctl(cmd, up, perm, vc);
+		if (!perm)
+			return -EPERM;
+
+		return do_unimap_ioctl(cmd, up, vc);
 
 	default:
 		return -ENOIOCTLCMD;
-- 
2.27.0


^ permalink raw reply	[flat|nested] 39+ messages in thread

* Re: [PATCH 26/38] vt: use newly defined CUR_* macros
  2020-06-15  7:48 ` [PATCH 26/38] vt: use newly defined CUR_* macros Jiri Slaby
@ 2020-06-15 20:31   ` Helge Deller
  0 siblings, 0 replies; 39+ messages in thread
From: Helge Deller @ 2020-06-15 20:31 UTC (permalink / raw)
  To: Jiri Slaby, gregkh
  Cc: linux-serial, linux-kernel, Thomas Winischhofer,
	Bartlomiej Zolnierkiewicz, James E.J. Bottomley, linux-usb,
	dri-devel, linux-fbdev, linux-parisc

On 15.06.20 09:48, Jiri Slaby wrote:
> We defined macros for all the magic constants in the previous patch. So
> let us use the macro in the code now.
>
> No functional change intended.
>
> Signed-off-by: Jiri Slaby <jslaby@suse.cz>
> Cc: Thomas Winischhofer <thomas@winischhofer.net>
> Cc: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: linux-usb@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: linux-fbdev@vger.kernel.org
> Cc: linux-parisc@vger.kernel.org


Acked-by: Helge Deller <deller@gmx.de>

Thanks!
Helge

> ---
>  drivers/tty/vt/vt.c                     | 22 +++++++++++++---------
>  drivers/usb/misc/sisusbvga/sisusb_con.c |  2 +-
>  drivers/video/console/mdacon.c          |  2 +-
>  drivers/video/console/sticon.c          |  2 +-
>  drivers/video/console/vgacon.c          |  2 +-
>  drivers/video/fbdev/core/bitblit.c      |  2 +-
>  drivers/video/fbdev/core/fbcon.c        |  2 +-
>  drivers/video/fbdev/core/fbcon_ccw.c    |  2 +-
>  drivers/video/fbdev/core/fbcon_cw.c     |  2 +-
>  drivers/video/fbdev/core/fbcon_ud.c     |  2 +-
>  drivers/video/fbdev/core/tileblit.c     |  2 +-
>  11 files changed, 23 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> index af1ef717f416..2b9fc628f05b 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -866,17 +866,18 @@ static void add_softcursor(struct vc_data *vc)
>  	int i = scr_readw((u16 *) vc->vc_pos);
>  	u32 type = vc->vc_cursor_type;
>
> -	if (!(type & 0x10))
> +	if (!(type & CUR_SW))
>  		return;
>  	if (softcursor_original != -1)
>  		return;
>  	softcursor_original = i;
> -	i |= (type >> 8) & 0xff00;
> -	i ^= type & 0xff00;
> -	if ((type & 0x20) && (softcursor_original & 0x7000) == (i & 0x7000))
> -		i ^= 0x7000;
> -	if ((type & 0x40) && (i & 0x700) == ((i & 0x7000) >> 4))
> -		i ^= 0x0700;
> +	i |= CUR_SET(type);
> +	i ^= CUR_CHANGE(type);
> +	if ((type & CUR_ALWAYS_BG) &&
> +			(softcursor_original & CUR_BG) == (i & CUR_BG))
> +		i ^= CUR_BG;
> +	if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4))
> +		i ^= CUR_FG;
>  	scr_writew(i, (u16 *)vc->vc_pos);
>  	if (con_should_update(vc))
>  		vc->vc_sw->con_putc(vc, i, vc->state.y, vc->state.x);
> @@ -910,7 +911,7 @@ static void set_cursor(struct vc_data *vc)
>  		if (vc_is_sel(vc))
>  			clear_selection();
>  		add_softcursor(vc);
> -		if ((vc->vc_cursor_type & 0x0f) != 1)
> +		if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE)
>  			vc->vc_sw->con_cursor(vc, CM_DRAW);
>  	} else
>  		hide_cursor(vc);
> @@ -2322,7 +2323,10 @@ static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, int c)
>  		case 'c':
>  			if (vc->vc_priv == EPdec) {
>  				if (vc->vc_par[0])
> -					vc->vc_cursor_type = vc->vc_par[0] | (vc->vc_par[1] << 8) | (vc->vc_par[2] << 16);
> +					vc->vc_cursor_type =
> +						CUR_MAKE(vc->vc_par[0],
> +							 vc->vc_par[1],
> +							 vc->vc_par[2]);
>  				else
>  					vc->vc_cursor_type = cur_default;
>  				return;
> diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
> index 80657c49310a..1058eaba3084 100644
> --- a/drivers/usb/misc/sisusbvga/sisusb_con.c
> +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
> @@ -727,7 +727,7 @@ sisusbcon_cursor(struct vc_data *c, int mode)
>
>  	baseline = c->vc_font.height - (c->vc_font.height < 10 ? 1 : 2);
>
> -	switch (c->vc_cursor_type & 0x0f) {
> +	switch (CUR_SIZE(c->vc_cursor_type)) {
>  		case CUR_BLOCK:		from = 1;
>  					to   = c->vc_font.height;
>  					break;
> diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c
> index 00cb6245fbef..ef29b321967f 100644
> --- a/drivers/video/console/mdacon.c
> +++ b/drivers/video/console/mdacon.c
> @@ -492,7 +492,7 @@ static void mdacon_cursor(struct vc_data *c, int mode)
>
>  	mda_set_cursor(c->state.y * mda_num_columns * 2 + c->state.x * 2);
>
> -	switch (c->vc_cursor_type & 0x0f) {
> +	switch (CUR_SIZE(c->vc_cursor_type)) {
>
>  		case CUR_LOWER_THIRD:	mda_set_cursor_size(10, 13); break;
>  		case CUR_LOWER_HALF:	mda_set_cursor_size(7,  13); break;
> diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
> index bbcdfd312c36..21a5c280c8c9 100644
> --- a/drivers/video/console/sticon.c
> +++ b/drivers/video/console/sticon.c
> @@ -139,7 +139,7 @@ static void sticon_cursor(struct vc_data *conp, int mode)
>  	break;
>      case CM_MOVE:
>      case CM_DRAW:
> -	switch (conp->vc_cursor_type & 0x0f) {
> +	switch (CUR_SIZE(conp->vc_cursor_type)) {
>  	case CUR_UNDERLINE:
>  	case CUR_LOWER_THIRD:
>  	case CUR_LOWER_HALF:
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index c1c4ce28ac5e..f0f3d573f848 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -728,7 +728,7 @@ static void vgacon_cursor(struct vc_data *c, int mode)
>  	case CM_MOVE:
>  	case CM_DRAW:
>  		write_vga(14, (c->vc_pos - vga_vram_base) / 2);
> -		switch (c->vc_cursor_type & 0x0f) {
> +		switch (CUR_SIZE(c->vc_cursor_type)) {
>  		case CUR_UNDERLINE:
>  			vgacon_set_cursor_size(c->state.x,
>  					       c->vc_font.height -
> diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
> index 3b002b365a5a..dde8004d8610 100644
> --- a/drivers/video/fbdev/core/bitblit.c
> +++ b/drivers/video/fbdev/core/bitblit.c
> @@ -241,7 +241,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
>  	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
>  	int w = DIV_ROUND_UP(vc->vc_font.width, 8), c;
>  	int y = real_y(ops->p, vc->state.y);
> -	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
> +	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
>  	int err = 1;
>  	char *src;
>
> diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
> index 38d2a00b0ccf..86fe41b1deb8 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -1393,7 +1393,7 @@ static void fbcon_cursor(struct vc_data *vc, int mode)
>  	if (fbcon_is_inactive(vc, info) || vc->vc_deccm != 1)
>  		return;
>
> -	if (vc->vc_cursor_type & 0x10)
> +	if (vc->vc_cursor_type & CUR_SW)
>  		fbcon_del_cursor_timer(info);
>  	else
>  		fbcon_add_cursor_timer(info);
> diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
> index 5b67bcebe34c..b5dd8317086d 100644
> --- a/drivers/video/fbdev/core/fbcon_ccw.c
> +++ b/drivers/video/fbdev/core/fbcon_ccw.c
> @@ -226,7 +226,7 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
>  	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
>  	int w = (vc->vc_font.height + 7) >> 3, c;
>  	int y = real_y(ops->p, vc->state.y);
> -	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
> +	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
>  	int err = 1, dx, dy;
>  	char *src;
>  	u32 vyres = GETVYRES(ops->p->scrollmode, info);
> diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
> index f1aab3ae3bc9..dbb5dbf3dd01 100644
> --- a/drivers/video/fbdev/core/fbcon_cw.c
> +++ b/drivers/video/fbdev/core/fbcon_cw.c
> @@ -209,7 +209,7 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, int mode,
>  	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
>  	int w = (vc->vc_font.height + 7) >> 3, c;
>  	int y = real_y(ops->p, vc->state.y);
> -	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
> +	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
>  	int err = 1, dx, dy;
>  	char *src;
>  	u32 vxres = GETVXRES(ops->p->scrollmode, info);
> diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
> index 81ed6f6bed67..b2c9cdbcc9e4 100644
> --- a/drivers/video/fbdev/core/fbcon_ud.c
> +++ b/drivers/video/fbdev/core/fbcon_ud.c
> @@ -256,7 +256,7 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, int mode,
>  	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
>  	int w = (vc->vc_font.width + 7) >> 3, c;
>  	int y = real_y(ops->p, vc->state.y);
> -	int attribute, use_sw = (vc->vc_cursor_type & 0x10);
> +	int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
>  	int err = 1, dx, dy;
>  	char *src;
>  	u32 vyres = GETVYRES(ops->p->scrollmode, info);
> diff --git a/drivers/video/fbdev/core/tileblit.c b/drivers/video/fbdev/core/tileblit.c
> index ac51425687e4..1dfaff0881fb 100644
> --- a/drivers/video/fbdev/core/tileblit.c
> +++ b/drivers/video/fbdev/core/tileblit.c
> @@ -83,7 +83,7 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, int mode,
>  			int softback_lines, int fg, int bg)
>  {
>  	struct fb_tilecursor cursor;
> -	int use_sw = (vc->vc_cursor_type & 0x10);
> +	int use_sw = vc->vc_cursor_type & CUR_SW;
>
>  	cursor.sx = vc->state.x;
>  	cursor.sy = vc->state.y;
>


^ permalink raw reply	[flat|nested] 39+ messages in thread

end of thread, other threads:[~2020-06-15 20:31 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-15  7:48 [PATCH 01/38] vc: separate state Jiri Slaby
2020-06-15  7:48 ` [PATCH 02/38] vt: introduce enum vc_intensity for intensity Jiri Slaby
2020-06-15  7:48 ` [PATCH 03/38] vc: switch state to bool Jiri Slaby
2020-06-15  7:48 ` [PATCH 04/38] vt: deduplicate setGx code Jiri Slaby
2020-06-15  7:48 ` [PATCH 05/38] vt: switch G0/1_charset to an array Jiri Slaby
2020-06-15  7:48 ` [PATCH 06/38] vt: convert vc_tab_stop to bitmap Jiri Slaby
2020-06-15  7:48 ` [PATCH 07/38] vt: remove 25 years stale comment Jiri Slaby
2020-06-15  7:48 ` [PATCH 08/38] vt: use tty_insert_flip_string in respond_string Jiri Slaby
2020-06-15  7:48 ` [PATCH 09/38] vt: get rid of VT10.ID macros Jiri Slaby
2020-06-15  7:48 ` [PATCH 10/38] vt: move vc_translate to vt.c and rename it Jiri Slaby
2020-06-15  7:48 ` [PATCH 11/38] vt: use modern types in do_con_write Jiri Slaby
2020-06-15  7:48 ` [PATCH 12/38] vt: separate unicode handling into vc_translate_unicode Jiri Slaby
2020-06-15  7:48 ` [PATCH 13/38] vt: rearrange vc_translate_unicode Jiri Slaby
2020-06-15  7:48 ` [PATCH 14/38] vt: extract attribute inversion to vc_invert_attr Jiri Slaby
2020-06-15  7:48 ` [PATCH 15/38] vt: move rescan_last_byte label earlier Jiri Slaby
2020-06-15  7:48 ` [PATCH 16/38] vc: move translation out of do_con_write Jiri Slaby
2020-06-15  7:48 ` [PATCH 17/38] vc: introduce struct vc_draw_region Jiri Slaby
2020-06-15  7:48 ` [PATCH 18/38] vc: extract detecting control characters from do_con_write Jiri Slaby
2020-06-15  7:48 ` [PATCH 19/38] vc: move normal char processing " Jiri Slaby
2020-06-15  7:48 ` [PATCH 20/38] vc: simplify condition in vc_con_write_normal Jiri Slaby
2020-06-15  7:48 ` [PATCH 21/38] vt: simplify vc_attr handling " Jiri Slaby
2020-06-15  7:48 ` [PATCH 22/38] vt: make tc write more obvious " Jiri Slaby
2020-06-15  7:48 ` [PATCH 23/38] vt: synchronize types and use min in csi_X Jiri Slaby
2020-06-15  7:48 ` [PATCH 24/38] vt: whitespace and paren cleanup in add_softcursor Jiri Slaby
2020-06-15  7:48 ` [PATCH 25/38] vt: redefine world of cursor macros Jiri Slaby
2020-06-15  7:48 ` [PATCH 26/38] vt: use newly defined CUR_* macros Jiri Slaby
2020-06-15 20:31   ` Helge Deller
2020-06-15  7:48 ` [PATCH 27/38] vt: remove superfluous parens in invert_screen and build_attr Jiri Slaby
2020-06-15  7:49 ` [PATCH 28/38] vt: simplify noncolor attributes in build_attr Jiri Slaby
2020-06-15  7:49 ` [PATCH 29/38] vt_ioctl: eliminate ret & breaks in vt_ioctl Jiri Slaby
2020-06-15  7:49 ` [PATCH 30/38] vt_ioctl: eliminate use of uival and ucval Jiri Slaby
2020-06-15  7:49 ` [PATCH 31/38] vt_ioctl: move K* ioctls to a separate function Jiri Slaby
2020-06-15  7:49 ` [PATCH 32/38] vt_ioctl: move io " Jiri Slaby
2020-06-15  7:49 ` [PATCH 33/38] vt_ioctl: move vt_setactivate out of vt_ioctl Jiri Slaby
2020-06-15  7:49 ` [PATCH 34/38] vt_ioctl: move vt_reldisp " Jiri Slaby
2020-06-15  7:49 ` [PATCH 35/38] vt_ioctl: move vt_resizex " Jiri Slaby
2020-06-15  7:49 ` [PATCH 36/38] vt_ioctl: move vt_io_fontreset out of vt_io_ioctl Jiri Slaby
2020-06-15  7:49 ` [PATCH 37/38] vt_ioctl: move vt_kdsetmode out of vt_k_ioctl Jiri Slaby
2020-06-15  7:49 ` [PATCH 38/38] vt_ioctl: move perm checks level up Jiri Slaby

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).