1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 1991, 1992 Linus Torvalds
4 */
5
6 /*
7 * Hopefully this will be a rather complete VT102 implementation.
8 *
9 * Beeping thanks to John T Kohl.
10 *
11 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
12 * Chars, and VT100 enhancements by Peter MacDonald.
13 *
14 * Copy and paste function by Andrew Haylett,
15 * some enhancements by Alessandro Rubini.
16 *
17 * Code to check for different video-cards mostly by Galen Hunt,
18 * <g-hunt@ee.utah.edu>
19 *
20 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
21 * Markus Kuhn, <mskuhn@immd4.informatik.uni-erlangen.de>.
22 *
23 * Dynamic allocation of consoles, aeb@cwi.nl, May 1994
24 * Resizing of consoles, aeb, 940926
25 *
26 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
27 * <poe@daimi.aau.dk>
28 *
29 * User-defined bell sound, new setterm control sequences and printk
30 * redirection by Martin Mares <mj@k332.feld.cvut.cz> 19-Nov-95
31 *
32 * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
33 *
34 * Merge with the abstract console driver by Geert Uytterhoeven
35 * <geert@linux-m68k.org>, Jan 1997.
36 *
37 * Original m68k console driver modifications by
38 *
39 * - Arno Griffioen <arno@usn.nl>
40 * - David Carter <carter@cs.bris.ac.uk>
41 *
42 * The abstract console driver provides a generic interface for a text
43 * console. It supports VGA text mode, frame buffer based graphical consoles
44 * and special graphics processors that are only accessible through some
45 * registers (e.g. a TMS340x0 GSP).
46 *
47 * The interface to the hardware is specified using a special structure
48 * (struct consw) which contains function pointers to console operations
49 * (see <linux/console.h> for more information).
50 *
51 * Support for changeable cursor shape
52 * by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>, August 1997
53 *
54 * Ported to i386 and con_scrolldelta fixed
55 * by Emmanuel Marty <core@ggi-project.org>, April 1998
56 *
57 * Resurrected character buffers in videoram plus lots of other trickery
58 * by Martin Mares <mj@atrey.karlin.mff.cuni.cz>, July 1998
59 *
60 * Removed old-style timers, introduced console_timer, made timer
61 * deletion SMP-safe. 17Jun00, Andrew Morton
62 *
63 * Removed console_lock, enabled interrupts across all console operations
64 * 13 March 2001, Andrew Morton
65 *
66 * Fixed UTF-8 mode so alternate charset modes always work according
67 * to control sequences interpreted in do_con_trol function
68 * preserving backward VT100 semigraphics compatibility,
69 * malformed UTF sequences represented as sequences of replacement glyphs,
70 * original codes or '?' as a last resort if replacement glyph is undefined
71 * by Adam Tla/lka <atlka@pg.gda.pl>, Aug 2006
72 */
73
74 #include <linux/module.h>
75 #include <linux/types.h>
76 #include <linux/sched/signal.h>
77 #include <linux/tty.h>
78 #include <linux/tty_flip.h>
79 #include <linux/kernel.h>
80 #include <linux/string.h>
81 #include <linux/errno.h>
82 #include <linux/kd.h>
83 #include <linux/slab.h>
84 #include <linux/vmalloc.h>
85 #include <linux/major.h>
86 #include <linux/mm.h>
87 #include <linux/console.h>
88 #include <linux/init.h>
89 #include <linux/mutex.h>
90 #include <linux/vt_kern.h>
91 #include <linux/selection.h>
92 #include <linux/tiocl.h>
93 #include <linux/kbd_kern.h>
94 #include <linux/consolemap.h>
95 #include <linux/timer.h>
96 #include <linux/interrupt.h>
97 #include <linux/workqueue.h>
98 #include <linux/pm.h>
99 #include <linux/font.h>
100 #include <linux/bitops.h>
101 #include <linux/notifier.h>
102 #include <linux/device.h>
103 #include <linux/io.h>
104 #include <linux/uaccess.h>
105 #include <linux/kdb.h>
106 #include <linux/ctype.h>
107 #include <linux/gcd.h>
108
109 #define MAX_NR_CON_DRIVER 16
110
111 #define CON_DRIVER_FLAG_MODULE 1
112 #define CON_DRIVER_FLAG_INIT 2
113 #define CON_DRIVER_FLAG_ATTR 4
114 #define CON_DRIVER_FLAG_ZOMBIE 8
115
116 struct con_driver {
117 const struct consw *con;
118 const char *desc;
119 struct device *dev;
120 int node;
121 int first;
122 int last;
123 int flag;
124 };
125
126 static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
127 const struct consw *conswitchp;
128
129 /*
130 * Here is the default bell parameters: 750HZ, 1/8th of a second
131 */
132 #define DEFAULT_BELL_PITCH 750
133 #define DEFAULT_BELL_DURATION (HZ/8)
134 #define DEFAULT_CURSOR_BLINK_MS 200
135
136 struct vc vc_cons [MAX_NR_CONSOLES];
137 EXPORT_SYMBOL(vc_cons);
138
139 static const struct consw *con_driver_map[MAX_NR_CONSOLES];
140
141 static int con_open(struct tty_struct *, struct file *);
142 static void vc_init(struct vc_data *vc, int do_clear);
143 static void gotoxy(struct vc_data *vc, int new_x, int new_y);
144 static void save_cur(struct vc_data *vc);
145 static void reset_terminal(struct vc_data *vc, int do_clear);
146 static void con_flush_chars(struct tty_struct *tty);
147 static int set_vesa_blanking(u8 __user *mode);
148 static void set_cursor(struct vc_data *vc);
149 static void hide_cursor(struct vc_data *vc);
150 static void console_callback(struct work_struct *ignored);
151 static void con_driver_unregister_callback(struct work_struct *ignored);
152 static void blank_screen_t(struct timer_list *unused);
153 static void set_palette(struct vc_data *vc);
154 static void unblank_screen(void);
155
156 #define vt_get_kmsg_redirect() vt_kmsg_redirect(-1)
157
158 int default_utf8 = true;
159 module_param(default_utf8, int, S_IRUGO | S_IWUSR);
160 int global_cursor_default = -1;
161 module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
162 EXPORT_SYMBOL(global_cursor_default);
163
164 static int cur_default = CUR_UNDERLINE;
165 module_param(cur_default, int, S_IRUGO | S_IWUSR);
166
167 /*
168 * ignore_poke: don't unblank the screen when things are typed. This is
169 * mainly for the privacy of braille terminal users.
170 */
171 static int ignore_poke;
172
173 int do_poke_blanked_console;
174 int console_blanked;
175 EXPORT_SYMBOL(console_blanked);
176
177 static enum vesa_blank_mode vesa_blank_mode;
178 static int vesa_off_interval;
179 static int blankinterval;
180 core_param(consoleblank, blankinterval, int, 0444);
181
182 static DECLARE_WORK(console_work, console_callback);
183 static DECLARE_WORK(con_driver_unregister_work, con_driver_unregister_callback);
184
185 /*
186 * fg_console is the current virtual console,
187 * last_console is the last used one,
188 * want_console is the console we want to switch to,
189 * saved_* variants are for save/restore around kernel debugger enter/leave
190 */
191 int fg_console;
192 EXPORT_SYMBOL(fg_console);
193 int last_console;
194 int want_console = -1;
195
196 static int saved_fg_console;
197 static int saved_last_console;
198 static int saved_want_console;
199 static int saved_vc_mode;
200 static int saved_console_blanked;
201
202 /*
203 * For each existing display, we have a pointer to console currently visible
204 * on that display, allowing consoles other than fg_console to be refreshed
205 * appropriately. Unless the low-level driver supplies its own display_fg
206 * variable, we use this one for the "master display".
207 */
208 static struct vc_data *master_display_fg;
209
210 /*
211 * Unfortunately, we need to delay tty echo when we're currently writing to the
212 * console since the code is (and always was) not re-entrant, so we schedule
213 * all flip requests to process context with schedule-task() and run it from
214 * console_callback().
215 */
216
217 /*
218 * For the same reason, we defer scrollback to the console callback.
219 */
220 static int scrollback_delta;
221
222 /*
223 * Hook so that the power management routines can (un)blank
224 * the console on our behalf.
225 */
226 int (*console_blank_hook)(int);
227 EXPORT_SYMBOL(console_blank_hook);
228
229 static DEFINE_TIMER(console_timer, blank_screen_t);
230 static int blank_state;
231 static int blank_timer_expired;
232 enum {
233 blank_off = 0,
234 blank_normal_wait,
235 blank_vesa_wait,
236 };
237
238 /*
239 * /sys/class/tty/tty0/
240 *
241 * the attribute 'active' contains the name of the current vc
242 * console and it supports poll() to detect vc switches
243 */
244 static struct device *tty0dev;
245
246 /*
247 * Notifier list for console events.
248 */
249 static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);
250
register_vt_notifier(struct notifier_block * nb)251 int register_vt_notifier(struct notifier_block *nb)
252 {
253 return atomic_notifier_chain_register(&vt_notifier_list, nb);
254 }
255 EXPORT_SYMBOL_GPL(register_vt_notifier);
256
unregister_vt_notifier(struct notifier_block * nb)257 int unregister_vt_notifier(struct notifier_block *nb)
258 {
259 return atomic_notifier_chain_unregister(&vt_notifier_list, nb);
260 }
261 EXPORT_SYMBOL_GPL(unregister_vt_notifier);
262
notify_write(struct vc_data * vc,unsigned int unicode)263 static void notify_write(struct vc_data *vc, unsigned int unicode)
264 {
265 struct vt_notifier_param param = { .vc = vc, .c = unicode };
266 atomic_notifier_call_chain(&vt_notifier_list, VT_WRITE, ¶m);
267 }
268
notify_update(struct vc_data * vc)269 static void notify_update(struct vc_data *vc)
270 {
271 struct vt_notifier_param param = { .vc = vc };
272 atomic_notifier_call_chain(&vt_notifier_list, VT_UPDATE, ¶m);
273 }
274 /*
275 * Low-Level Functions
276 */
277
con_is_fg(const struct vc_data * vc)278 static inline bool con_is_fg(const struct vc_data *vc)
279 {
280 return vc->vc_num == fg_console;
281 }
282
con_should_update(const struct vc_data * vc)283 static inline bool con_should_update(const struct vc_data *vc)
284 {
285 return con_is_visible(vc) && !console_blanked;
286 }
287
screenpos(const struct vc_data * vc,unsigned int offset,bool viewed)288 static inline u16 *screenpos(const struct vc_data *vc, unsigned int offset,
289 bool viewed)
290 {
291 unsigned long origin = viewed ? vc->vc_visible_origin : vc->vc_origin;
292
293 return (u16 *)(origin + offset);
294 }
295
con_putc(struct vc_data * vc,u16 ca,unsigned int y,unsigned int x)296 static void con_putc(struct vc_data *vc, u16 ca, unsigned int y, unsigned int x)
297 {
298 if (vc->vc_sw->con_putc)
299 vc->vc_sw->con_putc(vc, ca, y, x);
300 else
301 vc->vc_sw->con_putcs(vc, &ca, 1, y, x);
302 }
303
304 /* Called from the keyboard irq path.. */
scrolldelta(int lines)305 static inline void scrolldelta(int lines)
306 {
307 /* FIXME */
308 /* scrolldelta needs some kind of consistency lock, but the BKL was
309 and still is not protecting versus the scheduled back end */
310 scrollback_delta += lines;
311 schedule_console_callback();
312 }
313
schedule_console_callback(void)314 void schedule_console_callback(void)
315 {
316 schedule_work(&console_work);
317 }
318
319 /*
320 * Code to manage unicode-based screen buffers
321 */
322
323 /*
324 * Our screen buffer is preceded by an array of line pointers so that
325 * scrolling only implies some pointer shuffling.
326 */
327
vc_uniscr_alloc(unsigned int cols,unsigned int rows)328 static u32 **vc_uniscr_alloc(unsigned int cols, unsigned int rows)
329 {
330 u32 **uni_lines;
331 void *p;
332 unsigned int memsize, i, col_size = cols * sizeof(**uni_lines);
333
334 /* allocate everything in one go */
335 memsize = col_size * rows;
336 memsize += rows * sizeof(*uni_lines);
337 uni_lines = vzalloc(memsize);
338 if (!uni_lines)
339 return NULL;
340
341 /* initial line pointers */
342 p = uni_lines + rows;
343 for (i = 0; i < rows; i++) {
344 uni_lines[i] = p;
345 p += col_size;
346 }
347
348 return uni_lines;
349 }
350
vc_uniscr_free(u32 ** uni_lines)351 static void vc_uniscr_free(u32 **uni_lines)
352 {
353 vfree(uni_lines);
354 }
355
vc_uniscr_set(struct vc_data * vc,u32 ** new_uni_lines)356 static void vc_uniscr_set(struct vc_data *vc, u32 **new_uni_lines)
357 {
358 vc_uniscr_free(vc->vc_uni_lines);
359 vc->vc_uni_lines = new_uni_lines;
360 }
361
vc_uniscr_putc(struct vc_data * vc,u32 uc)362 static void vc_uniscr_putc(struct vc_data *vc, u32 uc)
363 {
364 if (vc->vc_uni_lines)
365 vc->vc_uni_lines[vc->state.y][vc->state.x] = uc;
366 }
367
vc_uniscr_insert(struct vc_data * vc,unsigned int nr)368 static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
369 {
370 if (vc->vc_uni_lines) {
371 u32 *ln = vc->vc_uni_lines[vc->state.y];
372 unsigned int x = vc->state.x, cols = vc->vc_cols;
373
374 memmove(&ln[x + nr], &ln[x], (cols - x - nr) * sizeof(*ln));
375 memset32(&ln[x], ' ', nr);
376 }
377 }
378
vc_uniscr_delete(struct vc_data * vc,unsigned int nr)379 static void vc_uniscr_delete(struct vc_data *vc, unsigned int nr)
380 {
381 if (vc->vc_uni_lines) {
382 u32 *ln = vc->vc_uni_lines[vc->state.y];
383 unsigned int x = vc->state.x, cols = vc->vc_cols;
384
385 memmove(&ln[x], &ln[x + nr], (cols - x - nr) * sizeof(*ln));
386 memset32(&ln[cols - nr], ' ', nr);
387 }
388 }
389
vc_uniscr_clear_line(struct vc_data * vc,unsigned int x,unsigned int nr)390 static void vc_uniscr_clear_line(struct vc_data *vc, unsigned int x,
391 unsigned int nr)
392 {
393 if (vc->vc_uni_lines)
394 memset32(&vc->vc_uni_lines[vc->state.y][x], ' ', nr);
395 }
396
vc_uniscr_clear_lines(struct vc_data * vc,unsigned int y,unsigned int nr)397 static void vc_uniscr_clear_lines(struct vc_data *vc, unsigned int y,
398 unsigned int nr)
399 {
400 if (vc->vc_uni_lines)
401 while (nr--)
402 memset32(vc->vc_uni_lines[y++], ' ', vc->vc_cols);
403 }
404
405 /* juggling array rotation algorithm (complexity O(N), size complexity O(1)) */
juggle_array(u32 ** array,unsigned int size,unsigned int nr)406 static void juggle_array(u32 **array, unsigned int size, unsigned int nr)
407 {
408 unsigned int gcd_idx;
409
410 for (gcd_idx = 0; gcd_idx < gcd(nr, size); gcd_idx++) {
411 u32 *gcd_idx_val = array[gcd_idx];
412 unsigned int dst_idx = gcd_idx;
413
414 while (1) {
415 unsigned int src_idx = (dst_idx + nr) % size;
416 if (src_idx == gcd_idx)
417 break;
418
419 array[dst_idx] = array[src_idx];
420 dst_idx = src_idx;
421 }
422
423 array[dst_idx] = gcd_idx_val;
424 }
425 }
426
vc_uniscr_scroll(struct vc_data * vc,unsigned int top,unsigned int bottom,enum con_scroll dir,unsigned int nr)427 static void vc_uniscr_scroll(struct vc_data *vc, unsigned int top,
428 unsigned int bottom, enum con_scroll dir,
429 unsigned int nr)
430 {
431 u32 **uni_lines = vc->vc_uni_lines;
432 unsigned int size = bottom - top;
433
434 if (!uni_lines)
435 return;
436
437 if (dir == SM_DOWN) {
438 juggle_array(&uni_lines[top], size, size - nr);
439 vc_uniscr_clear_lines(vc, top, nr);
440 } else {
441 juggle_array(&uni_lines[top], size, nr);
442 vc_uniscr_clear_lines(vc, bottom - nr, nr);
443 }
444 }
445
vc_uniscr_getc(struct vc_data * vc,int relative_pos)446 static u32 vc_uniscr_getc(struct vc_data *vc, int relative_pos)
447 {
448 int pos = vc->state.x + vc->vc_need_wrap + relative_pos;
449
450 if (vc->vc_uni_lines && in_range(pos, 0, vc->vc_cols))
451 return vc->vc_uni_lines[vc->state.y][pos];
452 return 0;
453 }
454
vc_uniscr_copy_area(u32 ** dst_lines,unsigned int dst_cols,unsigned int dst_rows,u32 ** src_lines,unsigned int src_cols,unsigned int src_top_row,unsigned int src_bot_row)455 static void vc_uniscr_copy_area(u32 **dst_lines,
456 unsigned int dst_cols,
457 unsigned int dst_rows,
458 u32 **src_lines,
459 unsigned int src_cols,
460 unsigned int src_top_row,
461 unsigned int src_bot_row)
462 {
463 unsigned int dst_row = 0;
464
465 if (!dst_lines)
466 return;
467
468 while (src_top_row < src_bot_row) {
469 u32 *src_line = src_lines[src_top_row];
470 u32 *dst_line = dst_lines[dst_row];
471
472 memcpy(dst_line, src_line, src_cols * sizeof(*src_line));
473 if (dst_cols - src_cols)
474 memset32(dst_line + src_cols, ' ', dst_cols - src_cols);
475 src_top_row++;
476 dst_row++;
477 }
478 while (dst_row < dst_rows) {
479 u32 *dst_line = dst_lines[dst_row];
480
481 memset32(dst_line, ' ', dst_cols);
482 dst_row++;
483 }
484 }
485
486 /*
487 * Called from vcs_read() to make sure unicode screen retrieval is possible.
488 * This will initialize the unicode screen buffer if not already done.
489 * This returns 0 if OK, or a negative error code otherwise.
490 * In particular, -ENODATA is returned if the console is not in UTF-8 mode.
491 */
vc_uniscr_check(struct vc_data * vc)492 int vc_uniscr_check(struct vc_data *vc)
493 {
494 u32 **uni_lines;
495 unsigned short *p;
496 int x, y, mask;
497
498 WARN_CONSOLE_UNLOCKED();
499
500 if (!vc->vc_utf)
501 return -ENODATA;
502
503 if (vc->vc_uni_lines)
504 return 0;
505
506 uni_lines = vc_uniscr_alloc(vc->vc_cols, vc->vc_rows);
507 if (!uni_lines)
508 return -ENOMEM;
509
510 /*
511 * Let's populate it initially with (imperfect) reverse translation.
512 * This is the next best thing we can do short of having it enabled
513 * from the start even when no users rely on this functionality. True
514 * unicode content will be available after a complete screen refresh.
515 */
516 p = (unsigned short *)vc->vc_origin;
517 mask = vc->vc_hi_font_mask | 0xff;
518 for (y = 0; y < vc->vc_rows; y++) {
519 u32 *line = uni_lines[y];
520 for (x = 0; x < vc->vc_cols; x++) {
521 u16 glyph = scr_readw(p++) & mask;
522 line[x] = inverse_translate(vc, glyph, true);
523 }
524 }
525
526 vc->vc_uni_lines = uni_lines;
527
528 return 0;
529 }
530
531 /*
532 * Called from vcs_read() to get the unicode data from the screen.
533 * This must be preceded by a successful call to vc_uniscr_check() once
534 * the console lock has been taken.
535 */
vc_uniscr_copy_line(const struct vc_data * vc,void * dest,bool viewed,unsigned int row,unsigned int col,unsigned int nr)536 void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, bool viewed,
537 unsigned int row, unsigned int col, unsigned int nr)
538 {
539 u32 **uni_lines = vc->vc_uni_lines;
540 int offset = row * vc->vc_size_row + col * 2;
541 unsigned long pos;
542
543 if (WARN_ON_ONCE(!uni_lines))
544 return;
545
546 pos = (unsigned long)screenpos(vc, offset, viewed);
547 if (pos >= vc->vc_origin && pos < vc->vc_scr_end) {
548 /*
549 * Desired position falls in the main screen buffer.
550 * However the actual row/col might be different if
551 * scrollback is active.
552 */
553 row = (pos - vc->vc_origin) / vc->vc_size_row;
554 col = ((pos - vc->vc_origin) % vc->vc_size_row) / 2;
555 memcpy(dest, &uni_lines[row][col], nr * sizeof(u32));
556 } else {
557 /*
558 * Scrollback is active. For now let's simply backtranslate
559 * the screen glyphs until the unicode screen buffer does
560 * synchronize with console display drivers for a scrollback
561 * buffer of its own.
562 */
563 u16 *p = (u16 *)pos;
564 int mask = vc->vc_hi_font_mask | 0xff;
565 u32 *uni_buf = dest;
566 while (nr--) {
567 u16 glyph = scr_readw(p++) & mask;
568 *uni_buf++ = inverse_translate(vc, glyph, true);
569 }
570 }
571 }
572
con_scroll(struct vc_data * vc,unsigned int top,unsigned int bottom,enum con_scroll dir,unsigned int nr)573 static void con_scroll(struct vc_data *vc, unsigned int top,
574 unsigned int bottom, enum con_scroll dir,
575 unsigned int nr)
576 {
577 unsigned int rows = bottom - top;
578 u16 *clear, *dst, *src;
579
580 if (top + nr >= bottom)
581 nr = rows - 1;
582 if (bottom > vc->vc_rows || top >= bottom || nr < 1)
583 return;
584
585 vc_uniscr_scroll(vc, top, bottom, dir, nr);
586 if (con_is_visible(vc) &&
587 vc->vc_sw->con_scroll(vc, top, bottom, dir, nr))
588 return;
589
590 src = clear = (u16 *)(vc->vc_origin + vc->vc_size_row * top);
591 dst = (u16 *)(vc->vc_origin + vc->vc_size_row * (top + nr));
592
593 if (dir == SM_UP) {
594 clear = src + (rows - nr) * vc->vc_cols;
595 swap(src, dst);
596 }
597 scr_memmovew(dst, src, (rows - nr) * vc->vc_size_row);
598 scr_memsetw(clear, vc->vc_video_erase_char, vc->vc_size_row * nr);
599 }
600
do_update_region(struct vc_data * vc,unsigned long start,int count)601 static void do_update_region(struct vc_data *vc, unsigned long start, int count)
602 {
603 unsigned int xx, yy, offset;
604 u16 *p = (u16 *)start;
605
606 offset = (start - vc->vc_origin) / 2;
607 xx = offset % vc->vc_cols;
608 yy = offset / vc->vc_cols;
609
610 for(;;) {
611 u16 attrib = scr_readw(p) & 0xff00;
612 int startx = xx;
613 u16 *q = p;
614 while (xx < vc->vc_cols && count) {
615 if (attrib != (scr_readw(p) & 0xff00)) {
616 if (p > q)
617 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
618 startx = xx;
619 q = p;
620 attrib = scr_readw(p) & 0xff00;
621 }
622 p++;
623 xx++;
624 count--;
625 }
626 if (p > q)
627 vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
628 if (!count)
629 break;
630 xx = 0;
631 yy++;
632 }
633 }
634
update_region(struct vc_data * vc,unsigned long start,int count)635 void update_region(struct vc_data *vc, unsigned long start, int count)
636 {
637 WARN_CONSOLE_UNLOCKED();
638
639 if (con_should_update(vc)) {
640 hide_cursor(vc);
641 do_update_region(vc, start, count);
642 set_cursor(vc);
643 }
644 }
645 EXPORT_SYMBOL(update_region);
646
647 /* Structure of attributes is hardware-dependent */
648
build_attr(struct vc_data * vc,u8 _color,enum vc_intensity _intensity,bool _blink,bool _underline,bool _reverse,bool _italic)649 static u8 build_attr(struct vc_data *vc, u8 _color,
650 enum vc_intensity _intensity, bool _blink, bool _underline,
651 bool _reverse, bool _italic)
652 {
653 if (vc->vc_sw->con_build_attr)
654 return vc->vc_sw->con_build_attr(vc, _color, _intensity,
655 _blink, _underline, _reverse, _italic);
656
657 /*
658 * ++roman: I completely changed the attribute format for monochrome
659 * mode (!can_do_color). The formerly used MDA (monochrome display
660 * adapter) format didn't allow the combination of certain effects.
661 * Now the attribute is just a bit vector:
662 * Bit 0..1: intensity (0..2)
663 * Bit 2 : underline
664 * Bit 3 : reverse
665 * Bit 7 : blink
666 */
667 {
668 u8 a = _color;
669 if (!vc->vc_can_do_color)
670 return _intensity |
671 (_italic << 1) |
672 (_underline << 2) |
673 (_reverse << 3) |
674 (_blink << 7);
675 if (_italic)
676 a = (a & 0xF0) | vc->vc_itcolor;
677 else if (_underline)
678 a = (a & 0xf0) | vc->vc_ulcolor;
679 else if (_intensity == VCI_HALF_BRIGHT)
680 a = (a & 0xf0) | vc->vc_halfcolor;
681 if (_reverse)
682 a = (a & 0x88) | (((a >> 4) | (a << 4)) & 0x77);
683 if (_blink)
684 a ^= 0x80;
685 if (_intensity == VCI_BOLD)
686 a ^= 0x08;
687 if (vc->vc_hi_font_mask == 0x100)
688 a <<= 1;
689 return a;
690 }
691 }
692
update_attr(struct vc_data * vc)693 static void update_attr(struct vc_data *vc)
694 {
695 vc->vc_attr = build_attr(vc, vc->state.color, vc->state.intensity,
696 vc->state.blink, vc->state.underline,
697 vc->state.reverse ^ vc->vc_decscnm, vc->state.italic);
698 vc->vc_video_erase_char = ' ' | (build_attr(vc, vc->state.color,
699 VCI_NORMAL, vc->state.blink, false,
700 vc->vc_decscnm, false) << 8);
701 }
702
703 /* Note: inverting the screen twice should revert to the original state */
invert_screen(struct vc_data * vc,int offset,int count,bool viewed)704 void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
705 {
706 u16 *p;
707
708 WARN_CONSOLE_UNLOCKED();
709
710 count /= 2;
711 p = screenpos(vc, offset, viewed);
712 if (vc->vc_sw->con_invert_region) {
713 vc->vc_sw->con_invert_region(vc, p, count);
714 } else {
715 u16 *q = p;
716 int cnt = count;
717 u16 a;
718
719 if (!vc->vc_can_do_color) {
720 while (cnt--) {
721 a = scr_readw(q);
722 a ^= 0x0800;
723 scr_writew(a, q);
724 q++;
725 }
726 } else if (vc->vc_hi_font_mask == 0x100) {
727 while (cnt--) {
728 a = scr_readw(q);
729 a = (a & 0x11ff) |
730 ((a & 0xe000) >> 4) |
731 ((a & 0x0e00) << 4);
732 scr_writew(a, q);
733 q++;
734 }
735 } else {
736 while (cnt--) {
737 a = scr_readw(q);
738 a = (a & 0x88ff) |
739 ((a & 0x7000) >> 4) |
740 ((a & 0x0700) << 4);
741 scr_writew(a, q);
742 q++;
743 }
744 }
745 }
746
747 if (con_should_update(vc))
748 do_update_region(vc, (unsigned long) p, count);
749 notify_update(vc);
750 }
751
752 /* used by selection: complement pointer position */
complement_pos(struct vc_data * vc,int offset)753 void complement_pos(struct vc_data *vc, int offset)
754 {
755 static int old_offset = -1;
756 static unsigned short old;
757 static unsigned short oldx, oldy;
758
759 WARN_CONSOLE_UNLOCKED();
760
761 if (old_offset != -1 && old_offset >= 0 &&
762 old_offset < vc->vc_screenbuf_size) {
763 scr_writew(old, screenpos(vc, old_offset, true));
764 if (con_should_update(vc))
765 con_putc(vc, old, oldy, oldx);
766 notify_update(vc);
767 }
768
769 old_offset = offset;
770
771 if (offset != -1 && offset >= 0 &&
772 offset < vc->vc_screenbuf_size) {
773 unsigned short new;
774 u16 *p = screenpos(vc, offset, true);
775 old = scr_readw(p);
776 new = old ^ vc->vc_complement_mask;
777 scr_writew(new, p);
778 if (con_should_update(vc)) {
779 oldx = (offset >> 1) % vc->vc_cols;
780 oldy = (offset >> 1) / vc->vc_cols;
781 con_putc(vc, new, oldy, oldx);
782 }
783 notify_update(vc);
784 }
785 }
786
insert_char(struct vc_data * vc,unsigned int nr)787 static void insert_char(struct vc_data *vc, unsigned int nr)
788 {
789 unsigned short *p = (unsigned short *) vc->vc_pos;
790
791 vc_uniscr_insert(vc, nr);
792 scr_memmovew(p + nr, p, (vc->vc_cols - vc->state.x - nr) * 2);
793 scr_memsetw(p, vc->vc_video_erase_char, nr * 2);
794 vc->vc_need_wrap = 0;
795 if (con_should_update(vc))
796 do_update_region(vc, (unsigned long) p,
797 vc->vc_cols - vc->state.x);
798 }
799
delete_char(struct vc_data * vc,unsigned int nr)800 static void delete_char(struct vc_data *vc, unsigned int nr)
801 {
802 unsigned short *p = (unsigned short *) vc->vc_pos;
803
804 vc_uniscr_delete(vc, nr);
805 scr_memmovew(p, p + nr, (vc->vc_cols - vc->state.x - nr) * 2);
806 scr_memsetw(p + vc->vc_cols - vc->state.x - nr, vc->vc_video_erase_char,
807 nr * 2);
808 vc->vc_need_wrap = 0;
809 if (con_should_update(vc))
810 do_update_region(vc, (unsigned long) p,
811 vc->vc_cols - vc->state.x);
812 }
813
814 static int softcursor_original = -1;
815
add_softcursor(struct vc_data * vc)816 static void add_softcursor(struct vc_data *vc)
817 {
818 int i = scr_readw((u16 *) vc->vc_pos);
819 u32 type = vc->vc_cursor_type;
820
821 if (!(type & CUR_SW))
822 return;
823 if (softcursor_original != -1)
824 return;
825 softcursor_original = i;
826 i |= CUR_SET(type);
827 i ^= CUR_CHANGE(type);
828 if ((type & CUR_ALWAYS_BG) &&
829 (softcursor_original & CUR_BG) == (i & CUR_BG))
830 i ^= CUR_BG;
831 if ((type & CUR_INVERT_FG_BG) && (i & CUR_FG) == ((i & CUR_BG) >> 4))
832 i ^= CUR_FG;
833 scr_writew(i, (u16 *)vc->vc_pos);
834 if (con_should_update(vc))
835 con_putc(vc, i, vc->state.y, vc->state.x);
836 }
837
hide_softcursor(struct vc_data * vc)838 static void hide_softcursor(struct vc_data *vc)
839 {
840 if (softcursor_original != -1) {
841 scr_writew(softcursor_original, (u16 *)vc->vc_pos);
842 if (con_should_update(vc))
843 con_putc(vc, softcursor_original, vc->state.y,
844 vc->state.x);
845 softcursor_original = -1;
846 }
847 }
848
hide_cursor(struct vc_data * vc)849 static void hide_cursor(struct vc_data *vc)
850 {
851 if (vc_is_sel(vc))
852 clear_selection();
853
854 vc->vc_sw->con_cursor(vc, false);
855 hide_softcursor(vc);
856 }
857
set_cursor(struct vc_data * vc)858 static void set_cursor(struct vc_data *vc)
859 {
860 if (!con_is_fg(vc) || console_blanked || vc->vc_mode == KD_GRAPHICS)
861 return;
862 if (vc->vc_deccm) {
863 if (vc_is_sel(vc))
864 clear_selection();
865 add_softcursor(vc);
866 if (CUR_SIZE(vc->vc_cursor_type) != CUR_NONE)
867 vc->vc_sw->con_cursor(vc, true);
868 } else
869 hide_cursor(vc);
870 }
871
set_origin(struct vc_data * vc)872 static void set_origin(struct vc_data *vc)
873 {
874 WARN_CONSOLE_UNLOCKED();
875
876 if (!con_is_visible(vc) ||
877 !vc->vc_sw->con_set_origin ||
878 !vc->vc_sw->con_set_origin(vc))
879 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
880 vc->vc_visible_origin = vc->vc_origin;
881 vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
882 vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->state.y +
883 2 * vc->state.x;
884 }
885
save_screen(struct vc_data * vc)886 static void save_screen(struct vc_data *vc)
887 {
888 WARN_CONSOLE_UNLOCKED();
889
890 if (vc->vc_sw->con_save_screen)
891 vc->vc_sw->con_save_screen(vc);
892 }
893
flush_scrollback(struct vc_data * vc)894 static void flush_scrollback(struct vc_data *vc)
895 {
896 WARN_CONSOLE_UNLOCKED();
897
898 set_origin(vc);
899 if (!con_is_visible(vc))
900 return;
901
902 /*
903 * The legacy way for flushing the scrollback buffer is to use a side
904 * effect of the con_switch method. We do it only on the foreground
905 * console as background consoles have no scrollback buffers in that
906 * case and we obviously don't want to switch to them.
907 */
908 hide_cursor(vc);
909 vc->vc_sw->con_switch(vc);
910 set_cursor(vc);
911 }
912
913 /*
914 * Redrawing of screen
915 */
916
clear_buffer_attributes(struct vc_data * vc)917 void clear_buffer_attributes(struct vc_data *vc)
918 {
919 unsigned short *p = (unsigned short *)vc->vc_origin;
920 int count = vc->vc_screenbuf_size / 2;
921 int mask = vc->vc_hi_font_mask | 0xff;
922
923 for (; count > 0; count--, p++) {
924 scr_writew((scr_readw(p)&mask) | (vc->vc_video_erase_char & ~mask), p);
925 }
926 }
927
redraw_screen(struct vc_data * vc,int is_switch)928 void redraw_screen(struct vc_data *vc, int is_switch)
929 {
930 int redraw = 0;
931
932 WARN_CONSOLE_UNLOCKED();
933
934 if (!vc) {
935 /* strange ... */
936 /* printk("redraw_screen: tty %d not allocated ??\n", new_console+1); */
937 return;
938 }
939
940 if (is_switch) {
941 struct vc_data *old_vc = vc_cons[fg_console].d;
942 if (old_vc == vc)
943 return;
944 if (!con_is_visible(vc))
945 redraw = 1;
946 *vc->vc_display_fg = vc;
947 fg_console = vc->vc_num;
948 hide_cursor(old_vc);
949 if (!con_is_visible(old_vc)) {
950 save_screen(old_vc);
951 set_origin(old_vc);
952 }
953 if (tty0dev)
954 sysfs_notify(&tty0dev->kobj, NULL, "active");
955 } else {
956 hide_cursor(vc);
957 redraw = 1;
958 }
959
960 if (redraw) {
961 bool update;
962 int old_was_color = vc->vc_can_do_color;
963
964 set_origin(vc);
965 update = vc->vc_sw->con_switch(vc);
966 set_palette(vc);
967 /*
968 * If console changed from mono<->color, the best we can do
969 * is to clear the buffer attributes. As it currently stands,
970 * rebuilding new attributes from the old buffer is not doable
971 * without overly complex code.
972 */
973 if (old_was_color != vc->vc_can_do_color) {
974 update_attr(vc);
975 clear_buffer_attributes(vc);
976 }
977
978 if (update && vc->vc_mode != KD_GRAPHICS)
979 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
980 }
981 set_cursor(vc);
982 if (is_switch) {
983 vt_set_leds_compute_shiftstate();
984 notify_update(vc);
985 }
986 }
987 EXPORT_SYMBOL(redraw_screen);
988
989 /*
990 * Allocation, freeing and resizing of VTs.
991 */
992
vc_cons_allocated(unsigned int i)993 int vc_cons_allocated(unsigned int i)
994 {
995 return (i < MAX_NR_CONSOLES && vc_cons[i].d);
996 }
997
visual_init(struct vc_data * vc,int num,bool init)998 static void visual_init(struct vc_data *vc, int num, bool init)
999 {
1000 /* ++Geert: vc->vc_sw->con_init determines console size */
1001 if (vc->vc_sw)
1002 module_put(vc->vc_sw->owner);
1003 vc->vc_sw = conswitchp;
1004
1005 if (con_driver_map[num])
1006 vc->vc_sw = con_driver_map[num];
1007
1008 __module_get(vc->vc_sw->owner);
1009 vc->vc_num = num;
1010 vc->vc_display_fg = &master_display_fg;
1011 if (vc->uni_pagedict_loc)
1012 con_free_unimap(vc);
1013 vc->uni_pagedict_loc = &vc->uni_pagedict;
1014 vc->uni_pagedict = NULL;
1015 vc->vc_hi_font_mask = 0;
1016 vc->vc_complement_mask = 0;
1017 vc->vc_can_do_color = 0;
1018 vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
1019 vc->vc_sw->con_init(vc, init);
1020 if (!vc->vc_complement_mask)
1021 vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
1022 vc->vc_s_complement_mask = vc->vc_complement_mask;
1023 vc->vc_size_row = vc->vc_cols << 1;
1024 vc->vc_screenbuf_size = vc->vc_rows * vc->vc_size_row;
1025 }
1026
1027
visual_deinit(struct vc_data * vc)1028 static void visual_deinit(struct vc_data *vc)
1029 {
1030 vc->vc_sw->con_deinit(vc);
1031 module_put(vc->vc_sw->owner);
1032 }
1033
vc_port_destruct(struct tty_port * port)1034 static void vc_port_destruct(struct tty_port *port)
1035 {
1036 struct vc_data *vc = container_of(port, struct vc_data, port);
1037
1038 kfree(vc);
1039 }
1040
1041 static const struct tty_port_operations vc_port_ops = {
1042 .destruct = vc_port_destruct,
1043 };
1044
1045 /*
1046 * Change # of rows and columns (0 means unchanged/the size of fg_console)
1047 * [this is to be used together with some user program
1048 * like resize that changes the hardware videomode]
1049 */
1050 #define VC_MAXCOL (32767)
1051 #define VC_MAXROW (32767)
1052
vc_allocate(unsigned int currcons)1053 int vc_allocate(unsigned int currcons) /* return 0 on success */
1054 {
1055 struct vt_notifier_param param;
1056 struct vc_data *vc;
1057 int err;
1058
1059 WARN_CONSOLE_UNLOCKED();
1060
1061 if (currcons >= MAX_NR_CONSOLES)
1062 return -ENXIO;
1063
1064 if (vc_cons[currcons].d)
1065 return 0;
1066
1067 /* due to the granularity of kmalloc, we waste some memory here */
1068 /* the alloc is done in two steps, to optimize the common situation
1069 of a 25x80 console (structsize=216, screenbuf_size=4000) */
1070 /* although the numbers above are not valid since long ago, the
1071 point is still up-to-date and the comment still has its value
1072 even if only as a historical artifact. --mj, July 1998 */
1073 param.vc = vc = kzalloc(sizeof(struct vc_data), GFP_KERNEL);
1074 if (!vc)
1075 return -ENOMEM;
1076
1077 vc_cons[currcons].d = vc;
1078 tty_port_init(&vc->port);
1079 vc->port.ops = &vc_port_ops;
1080 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
1081
1082 visual_init(vc, currcons, true);
1083
1084 if (!*vc->uni_pagedict_loc)
1085 con_set_default_unimap(vc);
1086
1087 err = -EINVAL;
1088 if (vc->vc_cols > VC_MAXCOL || vc->vc_rows > VC_MAXROW ||
1089 vc->vc_screenbuf_size > KMALLOC_MAX_SIZE || !vc->vc_screenbuf_size)
1090 goto err_free;
1091 err = -ENOMEM;
1092 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_KERNEL);
1093 if (!vc->vc_screenbuf)
1094 goto err_free;
1095
1096 /* If no drivers have overridden us and the user didn't pass a
1097 boot option, default to displaying the cursor */
1098 if (global_cursor_default == -1)
1099 global_cursor_default = 1;
1100
1101 vc_init(vc, 1);
1102 vcs_make_sysfs(currcons);
1103 atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m);
1104
1105 return 0;
1106 err_free:
1107 visual_deinit(vc);
1108 kfree(vc);
1109 vc_cons[currcons].d = NULL;
1110 return err;
1111 }
1112
resize_screen(struct vc_data * vc,int width,int height,bool from_user)1113 static inline int resize_screen(struct vc_data *vc, int width, int height,
1114 bool from_user)
1115 {
1116 /* Resizes the resolution of the display adapater */
1117 int err = 0;
1118
1119 if (vc->vc_sw->con_resize)
1120 err = vc->vc_sw->con_resize(vc, width, height, from_user);
1121
1122 return err;
1123 }
1124
1125 /**
1126 * vc_do_resize - resizing method for the tty
1127 * @tty: tty being resized
1128 * @vc: virtual console private data
1129 * @cols: columns
1130 * @lines: lines
1131 * @from_user: invoked by a user?
1132 *
1133 * Resize a virtual console, clipping according to the actual constraints. If
1134 * the caller passes a tty structure then update the termios winsize
1135 * information and perform any necessary signal handling.
1136 *
1137 * Locking: Caller must hold the console semaphore. Takes the termios rwsem and
1138 * ctrl.lock of the tty IFF a tty is passed.
1139 */
vc_do_resize(struct tty_struct * tty,struct vc_data * vc,unsigned int cols,unsigned int lines,bool from_user)1140 static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
1141 unsigned int cols, unsigned int lines, bool from_user)
1142 {
1143 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
1144 unsigned long end;
1145 unsigned int old_rows, old_row_size, first_copied_row;
1146 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
1147 unsigned short *oldscreen, *newscreen;
1148 u32 **new_uniscr = NULL;
1149
1150 WARN_CONSOLE_UNLOCKED();
1151
1152 if (cols > VC_MAXCOL || lines > VC_MAXROW)
1153 return -EINVAL;
1154
1155 new_cols = (cols ? cols : vc->vc_cols);
1156 new_rows = (lines ? lines : vc->vc_rows);
1157 new_row_size = new_cols << 1;
1158 new_screen_size = new_row_size * new_rows;
1159
1160 if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) {
1161 /*
1162 * This function is being called here to cover the case
1163 * where the userspace calls the FBIOPUT_VSCREENINFO twice,
1164 * passing the same fb_var_screeninfo containing the fields
1165 * yres/xres equal to a number non-multiple of vc_font.height
1166 * and yres_virtual/xres_virtual equal to number lesser than the
1167 * vc_font.height and yres/xres.
1168 * In the second call, the struct fb_var_screeninfo isn't
1169 * being modified by the underlying driver because of the
1170 * if above, and this causes the fbcon_display->vrows to become
1171 * negative and it eventually leads to out-of-bound
1172 * access by the imageblit function.
1173 * To give the correct values to the struct and to not have
1174 * to deal with possible errors from the code below, we call
1175 * the resize_screen here as well.
1176 */
1177 return resize_screen(vc, new_cols, new_rows, from_user);
1178 }
1179
1180 if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size)
1181 return -EINVAL;
1182 newscreen = kzalloc(new_screen_size, GFP_USER);
1183 if (!newscreen)
1184 return -ENOMEM;
1185
1186 if (vc->vc_uni_lines) {
1187 new_uniscr = vc_uniscr_alloc(new_cols, new_rows);
1188 if (!new_uniscr) {
1189 kfree(newscreen);
1190 return -ENOMEM;
1191 }
1192 }
1193
1194 if (vc_is_sel(vc))
1195 clear_selection();
1196
1197 old_rows = vc->vc_rows;
1198 old_row_size = vc->vc_size_row;
1199
1200 err = resize_screen(vc, new_cols, new_rows, from_user);
1201 if (err) {
1202 kfree(newscreen);
1203 vc_uniscr_free(new_uniscr);
1204 return err;
1205 }
1206
1207 vc->vc_rows = new_rows;
1208 vc->vc_cols = new_cols;
1209 vc->vc_size_row = new_row_size;
1210 vc->vc_screenbuf_size = new_screen_size;
1211
1212 rlth = min(old_row_size, new_row_size);
1213 rrem = new_row_size - rlth;
1214 old_origin = vc->vc_origin;
1215 new_origin = (long) newscreen;
1216 new_scr_end = new_origin + new_screen_size;
1217
1218 if (vc->state.y > new_rows) {
1219 if (old_rows - vc->state.y < new_rows) {
1220 /*
1221 * Cursor near the bottom, copy contents from the
1222 * bottom of buffer
1223 */
1224 first_copied_row = (old_rows - new_rows);
1225 } else {
1226 /*
1227 * Cursor is in no man's land, copy 1/2 screenful
1228 * from the top and bottom of cursor position
1229 */
1230 first_copied_row = (vc->state.y - new_rows/2);
1231 }
1232 old_origin += first_copied_row * old_row_size;
1233 } else
1234 first_copied_row = 0;
1235 end = old_origin + old_row_size * min(old_rows, new_rows);
1236
1237 vc_uniscr_copy_area(new_uniscr, new_cols, new_rows,
1238 vc->vc_uni_lines, rlth/2, first_copied_row,
1239 min(old_rows, new_rows));
1240 vc_uniscr_set(vc, new_uniscr);
1241
1242 update_attr(vc);
1243
1244 while (old_origin < end) {
1245 scr_memcpyw((unsigned short *) new_origin,
1246 (unsigned short *) old_origin, rlth);
1247 if (rrem)
1248 scr_memsetw((void *)(new_origin + rlth),
1249 vc->vc_video_erase_char, rrem);
1250 old_origin += old_row_size;
1251 new_origin += new_row_size;
1252 }
1253 if (new_scr_end > new_origin)
1254 scr_memsetw((void *)new_origin, vc->vc_video_erase_char,
1255 new_scr_end - new_origin);
1256 oldscreen = vc->vc_screenbuf;
1257 vc->vc_screenbuf = newscreen;
1258 vc->vc_screenbuf_size = new_screen_size;
1259 set_origin(vc);
1260 kfree(oldscreen);
1261
1262 /* do part of a reset_terminal() */
1263 vc->vc_top = 0;
1264 vc->vc_bottom = vc->vc_rows;
1265 gotoxy(vc, vc->state.x, vc->state.y);
1266 save_cur(vc);
1267
1268 if (tty) {
1269 /* Rewrite the requested winsize data with the actual
1270 resulting sizes */
1271 struct winsize ws;
1272 memset(&ws, 0, sizeof(ws));
1273 ws.ws_row = vc->vc_rows;
1274 ws.ws_col = vc->vc_cols;
1275 ws.ws_ypixel = vc->vc_scan_lines;
1276 tty_do_resize(tty, &ws);
1277 }
1278
1279 if (con_is_visible(vc))
1280 update_screen(vc);
1281 vt_event_post(VT_EVENT_RESIZE, vc->vc_num, vc->vc_num);
1282 notify_update(vc);
1283 return err;
1284 }
1285
1286 /**
1287 * __vc_resize - resize a VT
1288 * @vc: virtual console
1289 * @cols: columns
1290 * @rows: rows
1291 * @from_user: invoked by a user?
1292 *
1293 * Resize a virtual console as seen from the console end of things. We use the
1294 * common vc_do_resize() method to update the structures.
1295 *
1296 * Locking: The caller must hold the console sem to protect console internals
1297 * and @vc->port.tty.
1298 */
__vc_resize(struct vc_data * vc,unsigned int cols,unsigned int rows,bool from_user)1299 int __vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows,
1300 bool from_user)
1301 {
1302 return vc_do_resize(vc->port.tty, vc, cols, rows, from_user);
1303 }
1304 EXPORT_SYMBOL(__vc_resize);
1305
1306 /**
1307 * vt_resize - resize a VT
1308 * @tty: tty to resize
1309 * @ws: winsize attributes
1310 *
1311 * Resize a virtual terminal. This is called by the tty layer as we register
1312 * our own handler for resizing. The mutual helper does all the actual work.
1313 *
1314 * Locking: Takes the console sem and the called methods then take the tty
1315 * termios_rwsem and the tty ctrl.lock in that order.
1316 */
vt_resize(struct tty_struct * tty,struct winsize * ws)1317 static int vt_resize(struct tty_struct *tty, struct winsize *ws)
1318 {
1319 struct vc_data *vc = tty->driver_data;
1320 int ret;
1321
1322 console_lock();
1323 ret = vc_do_resize(tty, vc, ws->ws_col, ws->ws_row, false);
1324 console_unlock();
1325 return ret;
1326 }
1327
vc_deallocate(unsigned int currcons)1328 struct vc_data *vc_deallocate(unsigned int currcons)
1329 {
1330 struct vc_data *vc = NULL;
1331
1332 WARN_CONSOLE_UNLOCKED();
1333
1334 if (vc_cons_allocated(currcons)) {
1335 struct vt_notifier_param param;
1336
1337 param.vc = vc = vc_cons[currcons].d;
1338 atomic_notifier_call_chain(&vt_notifier_list, VT_DEALLOCATE, ¶m);
1339 vcs_remove_sysfs(currcons);
1340 visual_deinit(vc);
1341 con_free_unimap(vc);
1342 put_pid(vc->vt_pid);
1343 vc_uniscr_set(vc, NULL);
1344 kfree(vc->vc_screenbuf);
1345 vc_cons[currcons].d = NULL;
1346 }
1347 return vc;
1348 }
1349
1350 /*
1351 * VT102 emulator
1352 */
1353
1354 enum { EPecma = 0, EPdec, EPeq, EPgt, EPlt};
1355
1356 #define set_kbd(vc, x) vt_set_kbd_mode_bit((vc)->vc_num, (x))
1357 #define clr_kbd(vc, x) vt_clr_kbd_mode_bit((vc)->vc_num, (x))
1358 #define is_kbd(vc, x) vt_get_kbd_mode_bit((vc)->vc_num, (x))
1359
1360 #define decarm VC_REPEAT
1361 #define decckm VC_CKMODE
1362 #define kbdapplic VC_APPLIC
1363 #define lnm VC_CRLF
1364
1365 const unsigned char color_table[] = { 0, 4, 2, 6, 1, 5, 3, 7,
1366 8,12,10,14, 9,13,11,15 };
1367 EXPORT_SYMBOL(color_table);
1368
1369 /* the default colour table, for VGA+ colour systems */
1370 unsigned char default_red[] = {
1371 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
1372 0x55, 0xff, 0x55, 0xff, 0x55, 0xff, 0x55, 0xff
1373 };
1374 module_param_array(default_red, byte, NULL, S_IRUGO | S_IWUSR);
1375 EXPORT_SYMBOL(default_red);
1376
1377 unsigned char default_grn[] = {
1378 0x00, 0x00, 0xaa, 0x55, 0x00, 0x00, 0xaa, 0xaa,
1379 0x55, 0x55, 0xff, 0xff, 0x55, 0x55, 0xff, 0xff
1380 };
1381 module_param_array(default_grn, byte, NULL, S_IRUGO | S_IWUSR);
1382 EXPORT_SYMBOL(default_grn);
1383
1384 unsigned char default_blu[] = {
1385 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa,
1386 0x55, 0x55, 0x55, 0x55, 0xff, 0xff, 0xff, 0xff
1387 };
1388 module_param_array(default_blu, byte, NULL, S_IRUGO | S_IWUSR);
1389 EXPORT_SYMBOL(default_blu);
1390
1391 /*
1392 * gotoxy() must verify all boundaries, because the arguments
1393 * might also be negative. If the given position is out of
1394 * bounds, the cursor is placed at the nearest margin.
1395 */
gotoxy(struct vc_data * vc,int new_x,int new_y)1396 static void gotoxy(struct vc_data *vc, int new_x, int new_y)
1397 {
1398 int min_y, max_y;
1399
1400 if (new_x < 0)
1401 vc->state.x = 0;
1402 else {
1403 if (new_x >= vc->vc_cols)
1404 vc->state.x = vc->vc_cols - 1;
1405 else
1406 vc->state.x = new_x;
1407 }
1408
1409 if (vc->vc_decom) {
1410 min_y = vc->vc_top;
1411 max_y = vc->vc_bottom;
1412 } else {
1413 min_y = 0;
1414 max_y = vc->vc_rows;
1415 }
1416 if (new_y < min_y)
1417 vc->state.y = min_y;
1418 else if (new_y >= max_y)
1419 vc->state.y = max_y - 1;
1420 else
1421 vc->state.y = new_y;
1422 vc->vc_pos = vc->vc_origin + vc->state.y * vc->vc_size_row +
1423 (vc->state.x << 1);
1424 vc->vc_need_wrap = 0;
1425 }
1426
1427 /* for absolute user moves, when decom is set */
gotoxay(struct vc_data * vc,int new_x,int new_y)1428 static void gotoxay(struct vc_data *vc, int new_x, int new_y)
1429 {
1430 gotoxy(vc, new_x, vc->vc_decom ? (vc->vc_top + new_y) : new_y);
1431 }
1432
scrollback(struct vc_data * vc)1433 void scrollback(struct vc_data *vc)
1434 {
1435 scrolldelta(-(vc->vc_rows / 2));
1436 }
1437
scrollfront(struct vc_data * vc,int lines)1438 void scrollfront(struct vc_data *vc, int lines)
1439 {
1440 if (!lines)
1441 lines = vc->vc_rows / 2;
1442 scrolldelta(lines);
1443 }
1444
lf(struct vc_data * vc)1445 static void lf(struct vc_data *vc)
1446 {
1447 /* don't scroll if above bottom of scrolling region, or
1448 * if below scrolling region
1449 */
1450 if (vc->state.y + 1 == vc->vc_bottom)
1451 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_UP, 1);
1452 else if (vc->state.y < vc->vc_rows - 1) {
1453 vc->state.y++;
1454 vc->vc_pos += vc->vc_size_row;
1455 }
1456 vc->vc_need_wrap = 0;
1457 notify_write(vc, '\n');
1458 }
1459
ri(struct vc_data * vc)1460 static void ri(struct vc_data *vc)
1461 {
1462 /* don't scroll if below top of scrolling region, or
1463 * if above scrolling region
1464 */
1465 if (vc->state.y == vc->vc_top)
1466 con_scroll(vc, vc->vc_top, vc->vc_bottom, SM_DOWN, 1);
1467 else if (vc->state.y > 0) {
1468 vc->state.y--;
1469 vc->vc_pos -= vc->vc_size_row;
1470 }
1471 vc->vc_need_wrap = 0;
1472 }
1473
cr(struct vc_data * vc)1474 static inline void cr(struct vc_data *vc)
1475 {
1476 vc->vc_pos -= vc->state.x << 1;
1477 vc->vc_need_wrap = vc->state.x = 0;
1478 notify_write(vc, '\r');
1479 }
1480
bs(struct vc_data * vc)1481 static inline void bs(struct vc_data *vc)
1482 {
1483 if (vc->state.x) {
1484 vc->vc_pos -= 2;
1485 vc->state.x--;
1486 vc->vc_need_wrap = 0;
1487 notify_write(vc, '\b');
1488 }
1489 }
1490
del(struct vc_data * vc)1491 static inline void del(struct vc_data *vc)
1492 {
1493 /* ignored */
1494 }
1495
1496 enum CSI_J {
1497 CSI_J_CURSOR_TO_END = 0,
1498 CSI_J_START_TO_CURSOR = 1,
1499 CSI_J_VISIBLE = 2,
1500 CSI_J_FULL = 3,
1501 };
1502
csi_J(struct vc_data * vc,enum CSI_J vpar)1503 static void csi_J(struct vc_data *vc, enum CSI_J vpar)
1504 {
1505 unsigned short *start;
1506 unsigned int count;
1507
1508 switch (vpar) {
1509 case CSI_J_CURSOR_TO_END:
1510 vc_uniscr_clear_line(vc, vc->state.x,
1511 vc->vc_cols - vc->state.x);
1512 vc_uniscr_clear_lines(vc, vc->state.y + 1,
1513 vc->vc_rows - vc->state.y - 1);
1514 count = (vc->vc_scr_end - vc->vc_pos) >> 1;
1515 start = (unsigned short *)vc->vc_pos;
1516 break;
1517 case CSI_J_START_TO_CURSOR:
1518 vc_uniscr_clear_line(vc, 0, vc->state.x + 1);
1519 vc_uniscr_clear_lines(vc, 0, vc->state.y);
1520 count = ((vc->vc_pos - vc->vc_origin) >> 1) + 1;
1521 start = (unsigned short *)vc->vc_origin;
1522 break;
1523 case CSI_J_FULL:
1524 flush_scrollback(vc);
1525 fallthrough;
1526 case CSI_J_VISIBLE:
1527 vc_uniscr_clear_lines(vc, 0, vc->vc_rows);
1528 count = vc->vc_cols * vc->vc_rows;
1529 start = (unsigned short *)vc->vc_origin;
1530 break;
1531 default:
1532 return;
1533 }
1534 scr_memsetw(start, vc->vc_video_erase_char, 2 * count);
1535 if (con_should_update(vc))
1536 do_update_region(vc, (unsigned long) start, count);
1537 vc->vc_need_wrap = 0;
1538 }
1539
1540 enum {
1541 CSI_K_CURSOR_TO_LINEEND = 0,
1542 CSI_K_LINESTART_TO_CURSOR = 1,
1543 CSI_K_LINE = 2,
1544 };
1545
csi_K(struct vc_data * vc)1546 static void csi_K(struct vc_data *vc)
1547 {
1548 unsigned int count;
1549 unsigned short *start = (unsigned short *)vc->vc_pos;
1550 int offset;
1551
1552 switch (vc->vc_par[0]) {
1553 case CSI_K_CURSOR_TO_LINEEND:
1554 offset = 0;
1555 count = vc->vc_cols - vc->state.x;
1556 break;
1557 case CSI_K_LINESTART_TO_CURSOR:
1558 offset = -vc->state.x;
1559 count = vc->state.x + 1;
1560 break;
1561 case CSI_K_LINE:
1562 offset = -vc->state.x;
1563 count = vc->vc_cols;
1564 break;
1565 default:
1566 return;
1567 }
1568 vc_uniscr_clear_line(vc, vc->state.x + offset, count);
1569 scr_memsetw(start + offset, vc->vc_video_erase_char, 2 * count);
1570 vc->vc_need_wrap = 0;
1571 if (con_should_update(vc))
1572 do_update_region(vc, (unsigned long)(start + offset), count);
1573 }
1574
1575 /* erase the following count positions */
csi_X(struct vc_data * vc)1576 static void csi_X(struct vc_data *vc)
1577 { /* not vt100? */
1578 unsigned int count = clamp(vc->vc_par[0], 1, vc->vc_cols - vc->state.x);
1579
1580 vc_uniscr_clear_line(vc, vc->state.x, count);
1581 scr_memsetw((unsigned short *)vc->vc_pos, vc->vc_video_erase_char, 2 * count);
1582 if (con_should_update(vc))
1583 vc->vc_sw->con_clear(vc, vc->state.y, vc->state.x, count);
1584 vc->vc_need_wrap = 0;
1585 }
1586
default_attr(struct vc_data * vc)1587 static void default_attr(struct vc_data *vc)
1588 {
1589 vc->state.intensity = VCI_NORMAL;
1590 vc->state.italic = false;
1591 vc->state.underline = false;
1592 vc->state.reverse = false;
1593 vc->state.blink = false;
1594 vc->state.color = vc->vc_def_color;
1595 }
1596
1597 struct rgb { u8 r; u8 g; u8 b; };
1598
rgb_from_256(unsigned int i,struct rgb * c)1599 static void rgb_from_256(unsigned int i, struct rgb *c)
1600 {
1601 if (i < 8) { /* Standard colours. */
1602 c->r = i&1 ? 0xaa : 0x00;
1603 c->g = i&2 ? 0xaa : 0x00;
1604 c->b = i&4 ? 0xaa : 0x00;
1605 } else if (i < 16) {
1606 c->r = i&1 ? 0xff : 0x55;
1607 c->g = i&2 ? 0xff : 0x55;
1608 c->b = i&4 ? 0xff : 0x55;
1609 } else if (i < 232) { /* 6x6x6 colour cube. */
1610 i -= 16;
1611 c->b = i % 6 * 255 / 6;
1612 i /= 6;
1613 c->g = i % 6 * 255 / 6;
1614 i /= 6;
1615 c->r = i * 255 / 6;
1616 } else /* Grayscale ramp. */
1617 c->r = c->g = c->b = i * 10 - 2312;
1618 }
1619
rgb_foreground(struct vc_data * vc,const struct rgb * c)1620 static void rgb_foreground(struct vc_data *vc, const struct rgb *c)
1621 {
1622 u8 hue = 0, max = max3(c->r, c->g, c->b);
1623
1624 if (c->r > max / 2)
1625 hue |= 4;
1626 if (c->g > max / 2)
1627 hue |= 2;
1628 if (c->b > max / 2)
1629 hue |= 1;
1630
1631 if (hue == 7 && max <= 0x55) {
1632 hue = 0;
1633 vc->state.intensity = VCI_BOLD;
1634 } else if (max > 0xaa)
1635 vc->state.intensity = VCI_BOLD;
1636 else
1637 vc->state.intensity = VCI_NORMAL;
1638
1639 vc->state.color = (vc->state.color & 0xf0) | hue;
1640 }
1641
rgb_background(struct vc_data * vc,const struct rgb * c)1642 static void rgb_background(struct vc_data *vc, const struct rgb *c)
1643 {
1644 /* For backgrounds, err on the dark side. */
1645 vc->state.color = (vc->state.color & 0x0f)
1646 | (c->r&0x80) >> 1 | (c->g&0x80) >> 2 | (c->b&0x80) >> 3;
1647 }
1648
1649 /*
1650 * ITU T.416 Higher colour modes. They break the usual properties of SGR codes
1651 * and thus need to be detected and ignored by hand. That standard also
1652 * wants : rather than ; as separators but sequences containing : are currently
1653 * completely ignored by the parser.
1654 *
1655 * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
1656 * supporting them.
1657 */
vc_t416_color(struct vc_data * vc,int i,void (* set_color)(struct vc_data * vc,const struct rgb * c))1658 static int vc_t416_color(struct vc_data *vc, int i,
1659 void(*set_color)(struct vc_data *vc, const struct rgb *c))
1660 {
1661 struct rgb c;
1662
1663 i++;
1664 if (i > vc->vc_npar)
1665 return i;
1666
1667 if (vc->vc_par[i] == 5 && i + 1 <= vc->vc_npar) {
1668 /* 256 colours */
1669 i++;
1670 rgb_from_256(vc->vc_par[i], &c);
1671 } else if (vc->vc_par[i] == 2 && i + 3 <= vc->vc_npar) {
1672 /* 24 bit */
1673 c.r = vc->vc_par[i + 1];
1674 c.g = vc->vc_par[i + 2];
1675 c.b = vc->vc_par[i + 3];
1676 i += 3;
1677 } else
1678 return i;
1679
1680 set_color(vc, &c);
1681
1682 return i;
1683 }
1684
1685 enum {
1686 CSI_m_DEFAULT = 0,
1687 CSI_m_BOLD = 1,
1688 CSI_m_HALF_BRIGHT = 2,
1689 CSI_m_ITALIC = 3,
1690 CSI_m_UNDERLINE = 4,
1691 CSI_m_BLINK = 5,
1692 CSI_m_REVERSE = 7,
1693 CSI_m_PRI_FONT = 10,
1694 CSI_m_ALT_FONT1 = 11,
1695 CSI_m_ALT_FONT2 = 12,
1696 CSI_m_DOUBLE_UNDERLINE = 21,
1697 CSI_m_NORMAL_INTENSITY = 22,
1698 CSI_m_NO_ITALIC = 23,
1699 CSI_m_NO_UNDERLINE = 24,
1700 CSI_m_NO_BLINK = 25,
1701 CSI_m_NO_REVERSE = 27,
1702 CSI_m_FG_COLOR_BEG = 30,
1703 CSI_m_FG_COLOR_END = 37,
1704 CSI_m_FG_COLOR = 38,
1705 CSI_m_DEFAULT_FG_COLOR = 39,
1706 CSI_m_BG_COLOR_BEG = 40,
1707 CSI_m_BG_COLOR_END = 47,
1708 CSI_m_BG_COLOR = 48,
1709 CSI_m_DEFAULT_BG_COLOR = 49,
1710 CSI_m_BRIGHT_FG_COLOR_BEG = 90,
1711 CSI_m_BRIGHT_FG_COLOR_END = 97,
1712 CSI_m_BRIGHT_FG_COLOR_OFF = CSI_m_BRIGHT_FG_COLOR_BEG - CSI_m_FG_COLOR_BEG,
1713 CSI_m_BRIGHT_BG_COLOR_BEG = 100,
1714 CSI_m_BRIGHT_BG_COLOR_END = 107,
1715 CSI_m_BRIGHT_BG_COLOR_OFF = CSI_m_BRIGHT_BG_COLOR_BEG - CSI_m_BG_COLOR_BEG,
1716 };
1717
1718 /* console_lock is held */
csi_m(struct vc_data * vc)1719 static void csi_m(struct vc_data *vc)
1720 {
1721 int i;
1722
1723 for (i = 0; i <= vc->vc_npar; i++)
1724 switch (vc->vc_par[i]) {
1725 case CSI_m_DEFAULT: /* all attributes off */
1726 default_attr(vc);
1727 break;
1728 case CSI_m_BOLD:
1729 vc->state.intensity = VCI_BOLD;
1730 break;
1731 case CSI_m_HALF_BRIGHT:
1732 vc->state.intensity = VCI_HALF_BRIGHT;
1733 break;
1734 case CSI_m_ITALIC:
1735 vc->state.italic = true;
1736 break;
1737 case CSI_m_DOUBLE_UNDERLINE:
1738 /*
1739 * No console drivers support double underline, so
1740 * convert it to a single underline.
1741 */
1742 case CSI_m_UNDERLINE:
1743 vc->state.underline = true;
1744 break;
1745 case CSI_m_BLINK:
1746 vc->state.blink = true;
1747 break;
1748 case CSI_m_REVERSE:
1749 vc->state.reverse = true;
1750 break;
1751 case CSI_m_PRI_FONT: /* ANSI X3.64-1979 (SCO-ish?)
1752 * Select primary font, don't display control chars if
1753 * defined, don't set bit 8 on output.
1754 */
1755 vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset], vc);
1756 vc->vc_disp_ctrl = 0;
1757 vc->vc_toggle_meta = 0;
1758 break;
1759 case CSI_m_ALT_FONT1: /* ANSI X3.64-1979 (SCO-ish?)
1760 * Select first alternate font, lets chars < 32 be
1761 * displayed as ROM chars.
1762 */
1763 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1764 vc->vc_disp_ctrl = 1;
1765 vc->vc_toggle_meta = 0;
1766 break;
1767 case CSI_m_ALT_FONT2: /* ANSI X3.64-1979 (SCO-ish?)
1768 * Select second alternate font, toggle high bit
1769 * before displaying as ROM char.
1770 */
1771 vc->vc_translate = set_translate(IBMPC_MAP, vc);
1772 vc->vc_disp_ctrl = 1;
1773 vc->vc_toggle_meta = 1;
1774 break;
1775 case CSI_m_NORMAL_INTENSITY:
1776 vc->state.intensity = VCI_NORMAL;
1777 break;
1778 case CSI_m_NO_ITALIC:
1779 vc->state.italic = false;
1780 break;
1781 case CSI_m_NO_UNDERLINE:
1782 vc->state.underline = false;
1783 break;
1784 case CSI_m_NO_BLINK:
1785 vc->state.blink = false;
1786 break;
1787 case CSI_m_NO_REVERSE:
1788 vc->state.reverse = false;
1789 break;
1790 case CSI_m_FG_COLOR:
1791 i = vc_t416_color(vc, i, rgb_foreground);
1792 break;
1793 case CSI_m_BG_COLOR:
1794 i = vc_t416_color(vc, i, rgb_background);
1795 break;
1796 case CSI_m_DEFAULT_FG_COLOR:
1797 vc->state.color = (vc->vc_def_color & 0x0f) |
1798 (vc->state.color & 0xf0);
1799 break;
1800 case CSI_m_DEFAULT_BG_COLOR:
1801 vc->state.color = (vc->vc_def_color & 0xf0) |
1802 (vc->state.color & 0x0f);
1803 break;
1804 case CSI_m_BRIGHT_FG_COLOR_BEG ... CSI_m_BRIGHT_FG_COLOR_END:
1805 vc->state.intensity = VCI_BOLD;
1806 vc->vc_par[i] -= CSI_m_BRIGHT_FG_COLOR_OFF;
1807 fallthrough;
1808 case CSI_m_FG_COLOR_BEG ... CSI_m_FG_COLOR_END:
1809 vc->vc_par[i] -= CSI_m_FG_COLOR_BEG;
1810 vc->state.color = color_table[vc->vc_par[i]] |
1811 (vc->state.color & 0xf0);
1812 break;
1813 case CSI_m_BRIGHT_BG_COLOR_BEG ... CSI_m_BRIGHT_BG_COLOR_END:
1814 vc->vc_par[i] -= CSI_m_BRIGHT_BG_COLOR_OFF;
1815 fallthrough;
1816 case CSI_m_BG_COLOR_BEG ... CSI_m_BG_COLOR_END:
1817 vc->vc_par[i] -= CSI_m_BG_COLOR_BEG;
1818 vc->state.color = (color_table[vc->vc_par[i]] << 4) |
1819 (vc->state.color & 0x0f);
1820 break;
1821 }
1822 update_attr(vc);
1823 }
1824
respond_string(const char * p,size_t len,struct tty_port * port)1825 static void respond_string(const char *p, size_t len, struct tty_port *port)
1826 {
1827 tty_insert_flip_string(port, p, len);
1828 tty_flip_buffer_push(port);
1829 }
1830
cursor_report(struct vc_data * vc,struct tty_struct * tty)1831 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
1832 {
1833 char buf[40];
1834 int len;
1835
1836 len = sprintf(buf, "\033[%d;%dR", vc->state.y +
1837 (vc->vc_decom ? vc->vc_top + 1 : 1),
1838 vc->state.x + 1);
1839 respond_string(buf, len, tty->port);
1840 }
1841
status_report(struct tty_struct * tty)1842 static inline void status_report(struct tty_struct *tty)
1843 {
1844 static const char teminal_ok[] = "\033[0n";
1845
1846 respond_string(teminal_ok, strlen(teminal_ok), tty->port);
1847 }
1848
respond_ID(struct tty_struct * tty)1849 static inline void respond_ID(struct tty_struct *tty)
1850 {
1851 /* terminal answer to an ESC-Z or csi0c query. */
1852 static const char vt102_id[] = "\033[?6c";
1853
1854 respond_string(vt102_id, strlen(vt102_id), tty->port);
1855 }
1856
mouse_report(struct tty_struct * tty,int butt,int mrx,int mry)1857 void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
1858 {
1859 char buf[8];
1860 int len;
1861
1862 len = sprintf(buf, "\033[M%c%c%c", (char)(' ' + butt),
1863 (char)('!' + mrx), (char)('!' + mry));
1864 respond_string(buf, len, tty->port);
1865 }
1866
1867 /* invoked via ioctl(TIOCLINUX) and through set_selection_user */
mouse_reporting(void)1868 int mouse_reporting(void)
1869 {
1870 return vc_cons[fg_console].d->vc_report_mouse;
1871 }
1872
1873 /* invoked via ioctl(TIOCLINUX) */
get_bracketed_paste(struct tty_struct * tty)1874 static int get_bracketed_paste(struct tty_struct *tty)
1875 {
1876 struct vc_data *vc = tty->driver_data;
1877
1878 return vc->vc_bracketed_paste;
1879 }
1880
1881 enum {
1882 CSI_DEC_hl_CURSOR_KEYS = 1, /* CKM: cursor keys send ^[Ox/^[[x */
1883 CSI_DEC_hl_132_COLUMNS = 3, /* COLM: 80/132 mode switch */
1884 CSI_DEC_hl_REVERSE_VIDEO = 5, /* SCNM */
1885 CSI_DEC_hl_ORIGIN_MODE = 6, /* OM: origin relative/absolute */
1886 CSI_DEC_hl_AUTOWRAP = 7, /* AWM */
1887 CSI_DEC_hl_AUTOREPEAT = 8, /* ARM */
1888 CSI_DEC_hl_MOUSE_X10 = 9,
1889 CSI_DEC_hl_SHOW_CURSOR = 25, /* TCEM */
1890 CSI_DEC_hl_MOUSE_VT200 = 1000,
1891 CSI_DEC_hl_BRACKETED_PASTE = 2004,
1892 };
1893
1894 /* console_lock is held */
csi_DEC_hl(struct vc_data * vc,bool on_off)1895 static void csi_DEC_hl(struct vc_data *vc, bool on_off)
1896 {
1897 unsigned int i;
1898
1899 for (i = 0; i <= vc->vc_npar; i++)
1900 switch (vc->vc_par[i]) {
1901 case CSI_DEC_hl_CURSOR_KEYS:
1902 if (on_off)
1903 set_kbd(vc, decckm);
1904 else
1905 clr_kbd(vc, decckm);
1906 break;
1907 case CSI_DEC_hl_132_COLUMNS: /* unimplemented */
1908 #if 0
1909 vc_resize(deccolm ? 132 : 80, vc->vc_rows);
1910 /* this alone does not suffice; some user mode
1911 utility has to change the hardware regs */
1912 #endif
1913 break;
1914 case CSI_DEC_hl_REVERSE_VIDEO:
1915 if (vc->vc_decscnm != on_off) {
1916 vc->vc_decscnm = on_off;
1917 invert_screen(vc, 0, vc->vc_screenbuf_size,
1918 false);
1919 update_attr(vc);
1920 }
1921 break;
1922 case CSI_DEC_hl_ORIGIN_MODE:
1923 vc->vc_decom = on_off;
1924 gotoxay(vc, 0, 0);
1925 break;
1926 case CSI_DEC_hl_AUTOWRAP:
1927 vc->vc_decawm = on_off;
1928 break;
1929 case CSI_DEC_hl_AUTOREPEAT:
1930 if (on_off)
1931 set_kbd(vc, decarm);
1932 else
1933 clr_kbd(vc, decarm);
1934 break;
1935 case CSI_DEC_hl_MOUSE_X10:
1936 vc->vc_report_mouse = on_off ? 1 : 0;
1937 break;
1938 case CSI_DEC_hl_SHOW_CURSOR:
1939 vc->vc_deccm = on_off;
1940 break;
1941 case CSI_DEC_hl_MOUSE_VT200:
1942 vc->vc_report_mouse = on_off ? 2 : 0;
1943 break;
1944 case CSI_DEC_hl_BRACKETED_PASTE:
1945 vc->vc_bracketed_paste = on_off;
1946 break;
1947 }
1948 }
1949
1950 enum {
1951 CSI_hl_DISPLAY_CTRL = 3, /* handle ansi control chars */
1952 CSI_hl_INSERT = 4, /* IRM: insert/replace */
1953 CSI_hl_AUTO_NL = 20, /* LNM: Enter == CrLf/Lf */
1954 };
1955
1956 /* console_lock is held */
csi_hl(struct vc_data * vc,bool on_off)1957 static void csi_hl(struct vc_data *vc, bool on_off)
1958 {
1959 unsigned int i;
1960
1961 for (i = 0; i <= vc->vc_npar; i++)
1962 switch (vc->vc_par[i]) { /* ANSI modes set/reset */
1963 case CSI_hl_DISPLAY_CTRL:
1964 vc->vc_disp_ctrl = on_off;
1965 break;
1966 case CSI_hl_INSERT:
1967 vc->vc_decim = on_off;
1968 break;
1969 case CSI_hl_AUTO_NL:
1970 if (on_off)
1971 set_kbd(vc, lnm);
1972 else
1973 clr_kbd(vc, lnm);
1974 break;
1975 }
1976 }
1977
1978 enum CSI_right_square_bracket {
1979 CSI_RSB_COLOR_FOR_UNDERLINE = 1,
1980 CSI_RSB_COLOR_FOR_HALF_BRIGHT = 2,
1981 CSI_RSB_MAKE_CUR_COLOR_DEFAULT = 8,
1982 CSI_RSB_BLANKING_INTERVAL = 9,
1983 CSI_RSB_BELL_FREQUENCY = 10,
1984 CSI_RSB_BELL_DURATION = 11,
1985 CSI_RSB_BRING_CONSOLE_TO_FRONT = 12,
1986 CSI_RSB_UNBLANK = 13,
1987 CSI_RSB_VESA_OFF_INTERVAL = 14,
1988 CSI_RSB_BRING_PREV_CONSOLE_TO_FRONT = 15,
1989 CSI_RSB_CURSOR_BLINK_INTERVAL = 16,
1990 };
1991
1992 /*
1993 * csi_RSB - csi+] (Right Square Bracket) handler
1994 *
1995 * These are linux console private sequences.
1996 *
1997 * console_lock is held
1998 */
csi_RSB(struct vc_data * vc)1999 static void csi_RSB(struct vc_data *vc)
2000 {
2001 switch (vc->vc_par[0]) {
2002 case CSI_RSB_COLOR_FOR_UNDERLINE:
2003 if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
2004 vc->vc_ulcolor = color_table[vc->vc_par[1]];
2005 if (vc->state.underline)
2006 update_attr(vc);
2007 }
2008 break;
2009 case CSI_RSB_COLOR_FOR_HALF_BRIGHT:
2010 if (vc->vc_can_do_color && vc->vc_par[1] < 16) {
2011 vc->vc_halfcolor = color_table[vc->vc_par[1]];
2012 if (vc->state.intensity == VCI_HALF_BRIGHT)
2013 update_attr(vc);
2014 }
2015 break;
2016 case CSI_RSB_MAKE_CUR_COLOR_DEFAULT:
2017 vc->vc_def_color = vc->vc_attr;
2018 if (vc->vc_hi_font_mask == 0x100)
2019 vc->vc_def_color >>= 1;
2020 default_attr(vc);
2021 update_attr(vc);
2022 break;
2023 case CSI_RSB_BLANKING_INTERVAL:
2024 blankinterval = min(vc->vc_par[1], 60U) * 60;
2025 poke_blanked_console();
2026 break;
2027 case CSI_RSB_BELL_FREQUENCY:
2028 if (vc->vc_npar >= 1)
2029 vc->vc_bell_pitch = vc->vc_par[1];
2030 else
2031 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
2032 break;
2033 case CSI_RSB_BELL_DURATION:
2034 if (vc->vc_npar >= 1)
2035 vc->vc_bell_duration = (vc->vc_par[1] < 2000) ?
2036 msecs_to_jiffies(vc->vc_par[1]) : 0;
2037 else
2038 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
2039 break;
2040 case CSI_RSB_BRING_CONSOLE_TO_FRONT:
2041 if (vc->vc_par[1] >= 1 && vc_cons_allocated(vc->vc_par[1] - 1))
2042 set_console(vc->vc_par[1] - 1);
2043 break;
2044 case CSI_RSB_UNBLANK:
2045 poke_blanked_console();
2046 break;
2047 case CSI_RSB_VESA_OFF_INTERVAL:
2048 vesa_off_interval = min(vc->vc_par[1], 60U) * 60 * HZ;
2049 break;
2050 case CSI_RSB_BRING_PREV_CONSOLE_TO_FRONT:
2051 set_console(last_console);
2052 break;
2053 case CSI_RSB_CURSOR_BLINK_INTERVAL:
2054 if (vc->vc_npar >= 1 && vc->vc_par[1] >= 50 &&
2055 vc->vc_par[1] <= USHRT_MAX)
2056 vc->vc_cur_blink_ms = vc->vc_par[1];
2057 else
2058 vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
2059 break;
2060 }
2061 }
2062
2063 /* console_lock is held */
csi_at(struct vc_data * vc,unsigned int nr)2064 static void csi_at(struct vc_data *vc, unsigned int nr)
2065 {
2066 nr = clamp(nr, 1, vc->vc_cols - vc->state.x);
2067 insert_char(vc, nr);
2068 }
2069
2070 /* console_lock is held */
csi_L(struct vc_data * vc)2071 static void csi_L(struct vc_data *vc)
2072 {
2073 unsigned int nr = clamp(vc->vc_par[0], 1, vc->vc_rows - vc->state.y);
2074
2075 con_scroll(vc, vc->state.y, vc->vc_bottom, SM_DOWN, nr);
2076 vc->vc_need_wrap = 0;
2077 }
2078
2079 /* console_lock is held */
csi_P(struct vc_data * vc)2080 static void csi_P(struct vc_data *vc)
2081 {
2082 unsigned int nr = clamp(vc->vc_par[0], 1, vc->vc_cols - vc->state.x);
2083
2084 delete_char(vc, nr);
2085 }
2086
2087 /* console_lock is held */
csi_M(struct vc_data * vc)2088 static void csi_M(struct vc_data *vc)
2089 {
2090 unsigned int nr = clamp(vc->vc_par[0], 1, vc->vc_rows - vc->state.y);
2091
2092 con_scroll(vc, vc->state.y, vc->vc_bottom, SM_UP, nr);
2093 vc->vc_need_wrap = 0;
2094 }
2095
2096 /* console_lock is held (except via vc_init->reset_terminal */
save_cur(struct vc_data * vc)2097 static void save_cur(struct vc_data *vc)
2098 {
2099 memcpy(&vc->saved_state, &vc->state, sizeof(vc->state));
2100 }
2101
2102 /* console_lock is held */
restore_cur(struct vc_data * vc)2103 static void restore_cur(struct vc_data *vc)
2104 {
2105 memcpy(&vc->state, &vc->saved_state, sizeof(vc->state));
2106
2107 gotoxy(vc, vc->state.x, vc->state.y);
2108 vc->vc_translate = set_translate(vc->state.Gx_charset[vc->state.charset],
2109 vc);
2110 update_attr(vc);
2111 vc->vc_need_wrap = 0;
2112 }
2113
2114 /**
2115 * enum vc_ctl_state - control characters state of a vt
2116 *
2117 * @ESnormal: initial state, no control characters parsed
2118 * @ESesc: ESC parsed
2119 * @ESsquare: CSI parsed -- modifiers/parameters/ctrl chars expected
2120 * @ESgetpars: CSI parsed -- parameters/ctrl chars expected
2121 * @ESfunckey: CSI [ parsed
2122 * @EShash: ESC # parsed
2123 * @ESsetG0: ESC ( parsed
2124 * @ESsetG1: ESC ) parsed
2125 * @ESpercent: ESC % parsed
2126 * @EScsiignore: CSI [0x20-0x3f] parsed
2127 * @ESnonstd: OSC parsed
2128 * @ESpalette: OSC P parsed
2129 * @ESosc: OSC [0-9] parsed
2130 * @ESANSI_first: first state for ignoring ansi control sequences
2131 * @ESapc: ESC _ parsed
2132 * @ESpm: ESC ^ parsed
2133 * @ESdcs: ESC P parsed
2134 * @ESANSI_last: last state for ignoring ansi control sequences
2135 */
2136 enum vc_ctl_state {
2137 ESnormal,
2138 ESesc,
2139 ESsquare,
2140 ESgetpars,
2141 ESfunckey,
2142 EShash,
2143 ESsetG0,
2144 ESsetG1,
2145 ESpercent,
2146 EScsiignore,
2147 ESnonstd,
2148 ESpalette,
2149 ESosc,
2150 ESANSI_first = ESosc,
2151 ESapc,
2152 ESpm,
2153 ESdcs,
2154 ESANSI_last = ESdcs,
2155 };
2156
2157 /* console_lock is held (except via vc_init()) */
reset_terminal(struct vc_data * vc,int do_clear)2158 static void reset_terminal(struct vc_data *vc, int do_clear)
2159 {
2160 unsigned int i;
2161
2162 vc->vc_top = 0;
2163 vc->vc_bottom = vc->vc_rows;
2164 vc->vc_state = ESnormal;
2165 vc->vc_priv = EPecma;
2166 vc->vc_translate = set_translate(LAT1_MAP, vc);
2167 vc->state.Gx_charset[0] = LAT1_MAP;
2168 vc->state.Gx_charset[1] = GRAF_MAP;
2169 vc->state.charset = 0;
2170 vc->vc_need_wrap = 0;
2171 vc->vc_report_mouse = 0;
2172 vc->vc_bracketed_paste = 0;
2173 vc->vc_utf = default_utf8;
2174 vc->vc_utf_count = 0;
2175
2176 vc->vc_disp_ctrl = 0;
2177 vc->vc_toggle_meta = 0;
2178
2179 vc->vc_decscnm = 0;
2180 vc->vc_decom = 0;
2181 vc->vc_decawm = 1;
2182 vc->vc_deccm = global_cursor_default;
2183 vc->vc_decim = 0;
2184
2185 vt_reset_keyboard(vc->vc_num);
2186
2187 vc->vc_cursor_type = cur_default;
2188 vc->vc_complement_mask = vc->vc_s_complement_mask;
2189
2190 default_attr(vc);
2191 update_attr(vc);
2192
2193 bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
2194 for (i = 0; i < VC_TABSTOPS_COUNT; i += 8)
2195 set_bit(i, vc->vc_tab_stop);
2196
2197 vc->vc_bell_pitch = DEFAULT_BELL_PITCH;
2198 vc->vc_bell_duration = DEFAULT_BELL_DURATION;
2199 vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
2200
2201 gotoxy(vc, 0, 0);
2202 save_cur(vc);
2203 if (do_clear)
2204 csi_J(vc, CSI_J_VISIBLE);
2205 }
2206
vc_setGx(struct vc_data * vc,unsigned int which,u8 c)2207 static void vc_setGx(struct vc_data *vc, unsigned int which, u8 c)
2208 {
2209 unsigned char *charset = &vc->state.Gx_charset[which];
2210
2211 switch (c) {
2212 case '0':
2213 *charset = GRAF_MAP;
2214 break;
2215 case 'B':
2216 *charset = LAT1_MAP;
2217 break;
2218 case 'U':
2219 *charset = IBMPC_MAP;
2220 break;
2221 case 'K':
2222 *charset = USER_MAP;
2223 break;
2224 }
2225
2226 if (vc->state.charset == which)
2227 vc->vc_translate = set_translate(*charset, vc);
2228 }
2229
ansi_control_string(enum vc_ctl_state state)2230 static bool ansi_control_string(enum vc_ctl_state state)
2231 {
2232 return state >= ESANSI_first && state <= ESANSI_last;
2233 }
2234
2235 enum {
2236 ASCII_NULL = 0,
2237 ASCII_BELL = 7,
2238 ASCII_BACKSPACE = 8,
2239 ASCII_IGNORE_FIRST = ASCII_BACKSPACE,
2240 ASCII_HTAB = 9,
2241 ASCII_LINEFEED = 10,
2242 ASCII_VTAB = 11,
2243 ASCII_FORMFEED = 12,
2244 ASCII_CAR_RET = 13,
2245 ASCII_IGNORE_LAST = ASCII_CAR_RET,
2246 ASCII_SHIFTOUT = 14,
2247 ASCII_SHIFTIN = 15,
2248 ASCII_CANCEL = 24,
2249 ASCII_SUBSTITUTE = 26,
2250 ASCII_ESCAPE = 27,
2251 ASCII_CSI_IGNORE_FIRST = ' ', /* 0x2x, 0x3a and 0x3c - 0x3f */
2252 ASCII_CSI_IGNORE_LAST = '?',
2253 ASCII_DEL = 127,
2254 ASCII_EXT_CSI = 128 + ASCII_ESCAPE,
2255 };
2256
2257 /*
2258 * Handle ascii characters in control sequences and change states accordingly.
2259 * E.g. ESC sets the state of vc to ESesc.
2260 *
2261 * Returns: true if @c handled.
2262 */
handle_ascii(struct tty_struct * tty,struct vc_data * vc,u8 c)2263 static bool handle_ascii(struct tty_struct *tty, struct vc_data *vc, u8 c)
2264 {
2265 switch (c) {
2266 case ASCII_NULL:
2267 return true;
2268 case ASCII_BELL:
2269 if (ansi_control_string(vc->vc_state))
2270 vc->vc_state = ESnormal;
2271 else if (vc->vc_bell_duration)
2272 kd_mksound(vc->vc_bell_pitch, vc->vc_bell_duration);
2273 return true;
2274 case ASCII_BACKSPACE:
2275 bs(vc);
2276 return true;
2277 case ASCII_HTAB:
2278 vc->vc_pos -= (vc->state.x << 1);
2279
2280 vc->state.x = find_next_bit(vc->vc_tab_stop,
2281 min(vc->vc_cols - 1, VC_TABSTOPS_COUNT),
2282 vc->state.x + 1);
2283 if (vc->state.x >= VC_TABSTOPS_COUNT)
2284 vc->state.x = vc->vc_cols - 1;
2285
2286 vc->vc_pos += (vc->state.x << 1);
2287 notify_write(vc, '\t');
2288 return true;
2289 case ASCII_LINEFEED:
2290 case ASCII_VTAB:
2291 case ASCII_FORMFEED:
2292 lf(vc);
2293 if (!is_kbd(vc, lnm))
2294 return true;
2295 fallthrough;
2296 case ASCII_CAR_RET:
2297 cr(vc);
2298 return true;
2299 case ASCII_SHIFTOUT:
2300 vc->state.charset = 1;
2301 vc->vc_translate = set_translate(vc->state.Gx_charset[1], vc);
2302 vc->vc_disp_ctrl = 1;
2303 return true;
2304 case ASCII_SHIFTIN:
2305 vc->state.charset = 0;
2306 vc->vc_translate = set_translate(vc->state.Gx_charset[0], vc);
2307 vc->vc_disp_ctrl = 0;
2308 return true;
2309 case ASCII_CANCEL:
2310 case ASCII_SUBSTITUTE:
2311 vc->vc_state = ESnormal;
2312 return true;
2313 case ASCII_ESCAPE:
2314 vc->vc_state = ESesc;
2315 return true;
2316 case ASCII_DEL:
2317 del(vc);
2318 return true;
2319 case ASCII_EXT_CSI:
2320 vc->vc_state = ESsquare;
2321 return true;
2322 }
2323
2324 return false;
2325 }
2326
2327 /*
2328 * Handle a character (@c) following an ESC (when @vc is in the ESesc state).
2329 * E.g. previous ESC with @c == '[' here yields the ESsquare state (that is:
2330 * CSI).
2331 */
handle_esc(struct tty_struct * tty,struct vc_data * vc,u8 c)2332 static void handle_esc(struct tty_struct *tty, struct vc_data *vc, u8 c)
2333 {
2334 vc->vc_state = ESnormal;
2335 switch (c) {
2336 case '[':
2337 vc->vc_state = ESsquare;
2338 break;
2339 case ']':
2340 vc->vc_state = ESnonstd;
2341 break;
2342 case '_':
2343 vc->vc_state = ESapc;
2344 break;
2345 case '^':
2346 vc->vc_state = ESpm;
2347 break;
2348 case '%':
2349 vc->vc_state = ESpercent;
2350 break;
2351 case 'E':
2352 cr(vc);
2353 lf(vc);
2354 break;
2355 case 'M':
2356 ri(vc);
2357 break;
2358 case 'D':
2359 lf(vc);
2360 break;
2361 case 'H':
2362 if (vc->state.x < VC_TABSTOPS_COUNT)
2363 set_bit(vc->state.x, vc->vc_tab_stop);
2364 break;
2365 case 'P':
2366 vc->vc_state = ESdcs;
2367 break;
2368 case 'Z':
2369 respond_ID(tty);
2370 break;
2371 case '7':
2372 save_cur(vc);
2373 break;
2374 case '8':
2375 restore_cur(vc);
2376 break;
2377 case '(':
2378 vc->vc_state = ESsetG0;
2379 break;
2380 case ')':
2381 vc->vc_state = ESsetG1;
2382 break;
2383 case '#':
2384 vc->vc_state = EShash;
2385 break;
2386 case 'c':
2387 reset_terminal(vc, 1);
2388 break;
2389 case '>': /* Numeric keypad */
2390 clr_kbd(vc, kbdapplic);
2391 break;
2392 case '=': /* Appl. keypad */
2393 set_kbd(vc, kbdapplic);
2394 break;
2395 }
2396 }
2397
2398 /*
2399 * Handle special DEC control sequences ("ESC [ ? parameters char"). Parameters
2400 * are in @vc->vc_par and the char is in @c here.
2401 */
csi_DEC(struct tty_struct * tty,struct vc_data * vc,u8 c)2402 static void csi_DEC(struct tty_struct *tty, struct vc_data *vc, u8 c)
2403 {
2404 switch (c) {
2405 case 'h':
2406 csi_DEC_hl(vc, true);
2407 break;
2408 case 'l':
2409 csi_DEC_hl(vc, false);
2410 break;
2411 case 'c':
2412 if (vc->vc_par[0])
2413 vc->vc_cursor_type = CUR_MAKE(vc->vc_par[0],
2414 vc->vc_par[1],
2415 vc->vc_par[2]);
2416 else
2417 vc->vc_cursor_type = cur_default;
2418 break;
2419 case 'm':
2420 clear_selection();
2421 if (vc->vc_par[0])
2422 vc->vc_complement_mask = vc->vc_par[0] << 8 | vc->vc_par[1];
2423 else
2424 vc->vc_complement_mask = vc->vc_s_complement_mask;
2425 break;
2426 case 'n':
2427 if (vc->vc_par[0] == 5)
2428 status_report(tty);
2429 else if (vc->vc_par[0] == 6)
2430 cursor_report(vc, tty);
2431 break;
2432 }
2433 }
2434
2435 /*
2436 * Handle Control Sequence Introducer control characters. That is
2437 * "ESC [ parameters char". Parameters are in @vc->vc_par and the char is in
2438 * @c here.
2439 */
csi_ECMA(struct tty_struct * tty,struct vc_data * vc,u8 c)2440 static void csi_ECMA(struct tty_struct *tty, struct vc_data *vc, u8 c)
2441 {
2442 switch (c) {
2443 case 'G':
2444 case '`':
2445 if (vc->vc_par[0])
2446 vc->vc_par[0]--;
2447 gotoxy(vc, vc->vc_par[0], vc->state.y);
2448 break;
2449 case 'A':
2450 if (!vc->vc_par[0])
2451 vc->vc_par[0]++;
2452 gotoxy(vc, vc->state.x, vc->state.y - vc->vc_par[0]);
2453 break;
2454 case 'B':
2455 case 'e':
2456 if (!vc->vc_par[0])
2457 vc->vc_par[0]++;
2458 gotoxy(vc, vc->state.x, vc->state.y + vc->vc_par[0]);
2459 break;
2460 case 'C':
2461 case 'a':
2462 if (!vc->vc_par[0])
2463 vc->vc_par[0]++;
2464 gotoxy(vc, vc->state.x + vc->vc_par[0], vc->state.y);
2465 break;
2466 case 'D':
2467 if (!vc->vc_par[0])
2468 vc->vc_par[0]++;
2469 gotoxy(vc, vc->state.x - vc->vc_par[0], vc->state.y);
2470 break;
2471 case 'E':
2472 if (!vc->vc_par[0])
2473 vc->vc_par[0]++;
2474 gotoxy(vc, 0, vc->state.y + vc->vc_par[0]);
2475 break;
2476 case 'F':
2477 if (!vc->vc_par[0])
2478 vc->vc_par[0]++;
2479 gotoxy(vc, 0, vc->state.y - vc->vc_par[0]);
2480 break;
2481 case 'd':
2482 if (vc->vc_par[0])
2483 vc->vc_par[0]--;
2484 gotoxay(vc, vc->state.x ,vc->vc_par[0]);
2485 break;
2486 case 'H':
2487 case 'f':
2488 if (vc->vc_par[0])
2489 vc->vc_par[0]--;
2490 if (vc->vc_par[1])
2491 vc->vc_par[1]--;
2492 gotoxay(vc, vc->vc_par[1], vc->vc_par[0]);
2493 break;
2494 case 'J':
2495 csi_J(vc, vc->vc_par[0]);
2496 break;
2497 case 'K':
2498 csi_K(vc);
2499 break;
2500 case 'L':
2501 csi_L(vc);
2502 break;
2503 case 'M':
2504 csi_M(vc);
2505 break;
2506 case 'P':
2507 csi_P(vc);
2508 break;
2509 case 'c':
2510 if (!vc->vc_par[0])
2511 respond_ID(tty);
2512 break;
2513 case 'g':
2514 if (!vc->vc_par[0] && vc->state.x < VC_TABSTOPS_COUNT)
2515 set_bit(vc->state.x, vc->vc_tab_stop);
2516 else if (vc->vc_par[0] == 3)
2517 bitmap_zero(vc->vc_tab_stop, VC_TABSTOPS_COUNT);
2518 break;
2519 case 'h':
2520 csi_hl(vc, true);
2521 break;
2522 case 'l':
2523 csi_hl(vc, false);
2524 break;
2525 case 'm':
2526 csi_m(vc);
2527 break;
2528 case 'n':
2529 if (vc->vc_par[0] == 5)
2530 status_report(tty);
2531 else if (vc->vc_par[0] == 6)
2532 cursor_report(vc, tty);
2533 break;
2534 case 'q': /* DECLL - but only 3 leds */
2535 /* map 0,1,2,3 to 0,1,2,4 */
2536 if (vc->vc_par[0] < 4)
2537 vt_set_led_state(vc->vc_num,
2538 (vc->vc_par[0] < 3) ? vc->vc_par[0] : 4);
2539 break;
2540 case 'r':
2541 if (!vc->vc_par[0])
2542 vc->vc_par[0]++;
2543 if (!vc->vc_par[1])
2544 vc->vc_par[1] = vc->vc_rows;
2545 /* Minimum allowed region is 2 lines */
2546 if (vc->vc_par[0] < vc->vc_par[1] &&
2547 vc->vc_par[1] <= vc->vc_rows) {
2548 vc->vc_top = vc->vc_par[0] - 1;
2549 vc->vc_bottom = vc->vc_par[1];
2550 gotoxay(vc, 0, 0);
2551 }
2552 break;
2553 case 's':
2554 save_cur(vc);
2555 break;
2556 case 'u':
2557 restore_cur(vc);
2558 break;
2559 case 'X':
2560 csi_X(vc);
2561 break;
2562 case '@':
2563 csi_at(vc, vc->vc_par[0]);
2564 break;
2565 case ']':
2566 csi_RSB(vc);
2567 break;
2568 }
2569
2570 }
2571
vc_reset_params(struct vc_data * vc)2572 static void vc_reset_params(struct vc_data *vc)
2573 {
2574 memset(vc->vc_par, 0, sizeof(vc->vc_par));
2575 vc->vc_npar = 0;
2576 }
2577
2578 /* console_lock is held */
do_con_trol(struct tty_struct * tty,struct vc_data * vc,u8 c)2579 static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
2580 {
2581 /*
2582 * Control characters can be used in the _middle_
2583 * of an escape sequence, aside from ANSI control strings.
2584 */
2585 if (ansi_control_string(vc->vc_state) && c >= ASCII_IGNORE_FIRST &&
2586 c <= ASCII_IGNORE_LAST)
2587 return;
2588
2589 if (handle_ascii(tty, vc, c))
2590 return;
2591
2592 switch(vc->vc_state) {
2593 case ESesc: /* ESC */
2594 handle_esc(tty, vc, c);
2595 return;
2596 case ESnonstd: /* ESC ] aka OSC */
2597 switch (c) {
2598 case 'P': /* palette escape sequence */
2599 vc_reset_params(vc);
2600 vc->vc_state = ESpalette;
2601 return;
2602 case 'R': /* reset palette */
2603 reset_palette(vc);
2604 break;
2605 case '0' ... '9':
2606 vc->vc_state = ESosc;
2607 return;
2608 }
2609 vc->vc_state = ESnormal;
2610 return;
2611 case ESpalette: /* ESC ] P aka OSC P */
2612 if (isxdigit(c)) {
2613 vc->vc_par[vc->vc_npar++] = hex_to_bin(c);
2614 if (vc->vc_npar == 7) {
2615 int i = vc->vc_par[0] * 3, j = 1;
2616 vc->vc_palette[i] = 16 * vc->vc_par[j++];
2617 vc->vc_palette[i++] += vc->vc_par[j++];
2618 vc->vc_palette[i] = 16 * vc->vc_par[j++];
2619 vc->vc_palette[i++] += vc->vc_par[j++];
2620 vc->vc_palette[i] = 16 * vc->vc_par[j++];
2621 vc->vc_palette[i] += vc->vc_par[j];
2622 set_palette(vc);
2623 vc->vc_state = ESnormal;
2624 }
2625 } else
2626 vc->vc_state = ESnormal;
2627 return;
2628 case ESsquare: /* ESC [ aka CSI, parameters or modifiers expected */
2629 vc_reset_params(vc);
2630
2631 vc->vc_state = ESgetpars;
2632 switch (c) {
2633 case '[': /* Function key */
2634 vc->vc_state = ESfunckey;
2635 return;
2636 case '?':
2637 vc->vc_priv = EPdec;
2638 return;
2639 case '>':
2640 vc->vc_priv = EPgt;
2641 return;
2642 case '=':
2643 vc->vc_priv = EPeq;
2644 return;
2645 case '<':
2646 vc->vc_priv = EPlt;
2647 return;
2648 }
2649 vc->vc_priv = EPecma;
2650 fallthrough;
2651 case ESgetpars: /* ESC [ aka CSI, parameters expected */
2652 switch (c) {
2653 case ';':
2654 if (vc->vc_npar < NPAR - 1) {
2655 vc->vc_npar++;
2656 return;
2657 }
2658 break;
2659 case '0' ... '9':
2660 vc->vc_par[vc->vc_npar] *= 10;
2661 vc->vc_par[vc->vc_npar] += c - '0';
2662 return;
2663 }
2664 if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST) {
2665 vc->vc_state = EScsiignore;
2666 return;
2667 }
2668
2669 /* parameters done, handle the control char @c */
2670
2671 vc->vc_state = ESnormal;
2672
2673 switch (vc->vc_priv) {
2674 case EPdec:
2675 csi_DEC(tty, vc, c);
2676 return;
2677 case EPecma:
2678 csi_ECMA(tty, vc, c);
2679 return;
2680 default:
2681 return;
2682 }
2683 case EScsiignore:
2684 if (c >= ASCII_CSI_IGNORE_FIRST && c <= ASCII_CSI_IGNORE_LAST)
2685 return;
2686 vc->vc_state = ESnormal;
2687 return;
2688 case ESpercent: /* ESC % */
2689 vc->vc_state = ESnormal;
2690 switch (c) {
2691 case '@': /* defined in ISO 2022 */
2692 vc->vc_utf = 0;
2693 return;
2694 case 'G': /* prelim official escape code */
2695 case '8': /* retained for compatibility */
2696 vc->vc_utf = 1;
2697 return;
2698 }
2699 return;
2700 case ESfunckey: /* ESC [ [ aka CSI [ */
2701 vc->vc_state = ESnormal;
2702 return;
2703 case EShash: /* ESC # */
2704 vc->vc_state = ESnormal;
2705 if (c == '8') {
2706 /* DEC screen alignment test. kludge :-) */
2707 vc->vc_video_erase_char =
2708 (vc->vc_video_erase_char & 0xff00) | 'E';
2709 csi_J(vc, CSI_J_VISIBLE);
2710 vc->vc_video_erase_char =
2711 (vc->vc_video_erase_char & 0xff00) | ' ';
2712 do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
2713 }
2714 return;
2715 case ESsetG0: /* ESC ( */
2716 vc_setGx(vc, 0, c);
2717 vc->vc_state = ESnormal;
2718 return;
2719 case ESsetG1: /* ESC ) */
2720 vc_setGx(vc, 1, c);
2721 vc->vc_state = ESnormal;
2722 return;
2723 case ESapc: /* ESC _ */
2724 return;
2725 case ESosc: /* ESC ] [0-9] aka OSC [0-9] */
2726 return;
2727 case ESpm: /* ESC ^ */
2728 return;
2729 case ESdcs: /* ESC P */
2730 return;
2731 default:
2732 vc->vc_state = ESnormal;
2733 }
2734 }
2735
2736 struct vc_draw_region {
2737 unsigned long from, to;
2738 int x;
2739 };
2740
con_flush(struct vc_data * vc,struct vc_draw_region * draw)2741 static void con_flush(struct vc_data *vc, struct vc_draw_region *draw)
2742 {
2743 if (draw->x < 0)
2744 return;
2745
2746 vc->vc_sw->con_putcs(vc, (u16 *)draw->from,
2747 (u16 *)draw->to - (u16 *)draw->from, vc->state.y,
2748 draw->x);
2749 draw->x = -1;
2750 }
2751
vc_translate_ascii(const struct vc_data * vc,int c)2752 static inline int vc_translate_ascii(const struct vc_data *vc, int c)
2753 {
2754 if (IS_ENABLED(CONFIG_CONSOLE_TRANSLATIONS)) {
2755 if (vc->vc_toggle_meta)
2756 c |= 0x80;
2757
2758 return vc->vc_translate[c];
2759 }
2760
2761 return c;
2762 }
2763
2764
2765 /**
2766 * vc_sanitize_unicode - Replace invalid Unicode code points with ``U+FFFD``
2767 * @c: the received code point
2768 */
vc_sanitize_unicode(const int c)2769 static inline int vc_sanitize_unicode(const int c)
2770 {
2771 if (c >= 0xd800 && c <= 0xdfff)
2772 return 0xfffd;
2773
2774 return c;
2775 }
2776
2777 /**
2778 * vc_translate_unicode - Combine UTF-8 into Unicode in &vc_data.vc_utf_char
2779 * @vc: virtual console
2780 * @c: UTF-8 byte to translate
2781 * @rescan: set to true iff @c wasn't consumed here and needs to be re-processed
2782 *
2783 * * &vc_data.vc_utf_char is the being-constructed Unicode code point.
2784 * * &vc_data.vc_utf_count is the number of continuation bytes still expected to
2785 * arrive.
2786 * * &vc_data.vc_npar is the number of continuation bytes arrived so far.
2787 *
2788 * Return:
2789 * * %-1 - Input OK so far, @c consumed, further bytes expected.
2790 * * %0xFFFD - Possibility 1: input invalid, @c may have been consumed (see
2791 * desc. of @rescan). Possibility 2: input OK, @c consumed,
2792 * ``U+FFFD`` is the resulting code point. ``U+FFFD`` is valid,
2793 * ``REPLACEMENT CHARACTER``.
2794 * * otherwise - Input OK, @c consumed, resulting code point returned.
2795 */
vc_translate_unicode(struct vc_data * vc,int c,bool * rescan)2796 static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
2797 {
2798 static const u32 utf8_length_changes[] = {0x7f, 0x7ff, 0xffff, 0x10ffff};
2799
2800 /* Continuation byte received */
2801 if ((c & 0xc0) == 0x80) {
2802 /* Unexpected continuation byte? */
2803 if (!vc->vc_utf_count)
2804 goto bad_sequence;
2805
2806 vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f);
2807 vc->vc_npar++;
2808 if (--vc->vc_utf_count)
2809 goto need_more_bytes;
2810
2811 /* Got a whole character */
2812 c = vc->vc_utf_char;
2813 /* Reject overlong sequences */
2814 if (c <= utf8_length_changes[vc->vc_npar - 1] ||
2815 c > utf8_length_changes[vc->vc_npar])
2816 goto bad_sequence;
2817
2818 return vc_sanitize_unicode(c);
2819 }
2820
2821 /* Single ASCII byte or first byte of a sequence received */
2822 if (vc->vc_utf_count) {
2823 /* A continuation byte was expected */
2824 *rescan = true;
2825 vc->vc_utf_count = 0;
2826 goto bad_sequence;
2827 }
2828
2829 /* Nothing to do if an ASCII byte was received */
2830 if (c <= 0x7f)
2831 return c;
2832
2833 /* First byte of a multibyte sequence received */
2834 vc->vc_npar = 0;
2835 if ((c & 0xe0) == 0xc0) {
2836 vc->vc_utf_count = 1;
2837 vc->vc_utf_char = (c & 0x1f);
2838 } else if ((c & 0xf0) == 0xe0) {
2839 vc->vc_utf_count = 2;
2840 vc->vc_utf_char = (c & 0x0f);
2841 } else if ((c & 0xf8) == 0xf0) {
2842 vc->vc_utf_count = 3;
2843 vc->vc_utf_char = (c & 0x07);
2844 } else {
2845 goto bad_sequence;
2846 }
2847
2848 need_more_bytes:
2849 return -1;
2850
2851 bad_sequence:
2852 return 0xfffd;
2853 }
2854
vc_translate(struct vc_data * vc,int * c,bool * rescan)2855 static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
2856 {
2857 /* Do no translation at all in control states */
2858 if (vc->vc_state != ESnormal)
2859 return *c;
2860
2861 if (vc->vc_utf && !vc->vc_disp_ctrl)
2862 return *c = vc_translate_unicode(vc, *c, rescan);
2863
2864 /* no utf or alternate charset mode */
2865 return vc_translate_ascii(vc, *c);
2866 }
2867
vc_invert_attr(const struct vc_data * vc)2868 static inline unsigned char vc_invert_attr(const struct vc_data *vc)
2869 {
2870 if (!vc->vc_can_do_color)
2871 return vc->vc_attr ^ 0x08;
2872
2873 if (vc->vc_hi_font_mask == 0x100)
2874 return (vc->vc_attr & 0x11) |
2875 ((vc->vc_attr & 0xe0) >> 4) |
2876 ((vc->vc_attr & 0x0e) << 4);
2877
2878 return (vc->vc_attr & 0x88) |
2879 ((vc->vc_attr & 0x70) >> 4) |
2880 ((vc->vc_attr & 0x07) << 4);
2881 }
2882
vc_is_control(struct vc_data * vc,int tc,int c)2883 static bool vc_is_control(struct vc_data *vc, int tc, int c)
2884 {
2885 /*
2886 * A bitmap for codes <32. A bit of 1 indicates that the code
2887 * corresponding to that bit number invokes some special action (such
2888 * as cursor movement) and should not be displayed as a glyph unless
2889 * the disp_ctrl mode is explicitly enabled.
2890 */
2891 static const u32 CTRL_ACTION = BIT(ASCII_NULL) |
2892 GENMASK(ASCII_SHIFTIN, ASCII_BELL) | BIT(ASCII_CANCEL) |
2893 BIT(ASCII_SUBSTITUTE) | BIT(ASCII_ESCAPE);
2894 /* Cannot be overridden by disp_ctrl */
2895 static const u32 CTRL_ALWAYS = BIT(ASCII_NULL) | BIT(ASCII_BACKSPACE) |
2896 BIT(ASCII_LINEFEED) | BIT(ASCII_SHIFTIN) | BIT(ASCII_SHIFTOUT) |
2897 BIT(ASCII_CAR_RET) | BIT(ASCII_FORMFEED) | BIT(ASCII_ESCAPE);
2898
2899 if (vc->vc_state != ESnormal)
2900 return true;
2901
2902 if (!tc)
2903 return true;
2904
2905 /*
2906 * If the original code was a control character we only allow a glyph
2907 * to be displayed if the code is not normally used (such as for cursor
2908 * movement) or if the disp_ctrl mode has been explicitly enabled.
2909 * Certain characters (as given by the CTRL_ALWAYS bitmap) are always
2910 * displayed as control characters, as the console would be pretty
2911 * useless without them; to display an arbitrary font position use the
2912 * direct-to-font zone in UTF-8 mode.
2913 */
2914 if (c < BITS_PER_TYPE(CTRL_ALWAYS)) {
2915 if (vc->vc_disp_ctrl)
2916 return CTRL_ALWAYS & BIT(c);
2917 else
2918 return vc->vc_utf || (CTRL_ACTION & BIT(c));
2919 }
2920
2921 if (c == ASCII_DEL && !vc->vc_disp_ctrl)
2922 return true;
2923
2924 if (c == ASCII_EXT_CSI)
2925 return true;
2926
2927 return false;
2928 }
2929
vc_con_rewind(struct vc_data * vc)2930 static void vc_con_rewind(struct vc_data *vc)
2931 {
2932 if (vc->state.x && !vc->vc_need_wrap) {
2933 vc->vc_pos -= 2;
2934 vc->state.x--;
2935 }
2936 vc->vc_need_wrap = 0;
2937 }
2938
2939 #define UCS_ZWS 0x200b /* Zero Width Space */
2940 #define UCS_VS16 0xfe0f /* Variation Selector 16 */
2941 #define UCS_REPLACEMENT 0xfffd /* Replacement Character */
2942
vc_process_ucs(struct vc_data * vc,int * c,int * tc)2943 static int vc_process_ucs(struct vc_data *vc, int *c, int *tc)
2944 {
2945 u32 prev_c, curr_c = *c;
2946
2947 if (ucs_is_double_width(curr_c)) {
2948 /*
2949 * The Unicode screen memory is allocated only when
2950 * required. This is one such case as we need to remember
2951 * which displayed characters are double-width.
2952 */
2953 vc_uniscr_check(vc);
2954 return 2;
2955 }
2956
2957 if (!ucs_is_zero_width(curr_c))
2958 return 1;
2959
2960 /* From here curr_c is known to be zero-width. */
2961
2962 if (ucs_is_double_width(vc_uniscr_getc(vc, -2))) {
2963 /*
2964 * Let's merge this zero-width code point with the preceding
2965 * double-width code point by replacing the existing
2966 * zero-width space padding. To do so we rewind one column
2967 * and pretend this has a width of 1.
2968 * We give the legacy display the same initial space padding.
2969 */
2970 vc_con_rewind(vc);
2971 *tc = ' ';
2972 return 1;
2973 }
2974
2975 /* From here the preceding character, if any, must be single-width. */
2976 prev_c = vc_uniscr_getc(vc, -1);
2977
2978 if (curr_c == UCS_VS16 && prev_c != 0) {
2979 /*
2980 * VS16 (U+FE0F) is special. It typically turns the preceding
2981 * single-width character into a double-width one. Let it
2982 * have a width of 1 effectively making the combination with
2983 * the preceding character double-width.
2984 */
2985 *tc = ' ';
2986 return 1;
2987 }
2988
2989 /* try recomposition */
2990 prev_c = ucs_recompose(prev_c, curr_c);
2991 if (prev_c != 0) {
2992 vc_con_rewind(vc);
2993 *tc = *c = prev_c;
2994 return 1;
2995 }
2996
2997 /* Otherwise zero-width code points are ignored. */
2998 return 0;
2999 }
3000
vc_get_glyph(struct vc_data * vc,int tc)3001 static int vc_get_glyph(struct vc_data *vc, int tc)
3002 {
3003 int glyph = conv_uni_to_pc(vc, tc);
3004 u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
3005
3006 if (!(glyph & ~charmask))
3007 return glyph;
3008
3009 if (glyph == -1)
3010 return -1; /* nothing to display */
3011
3012 /* Glyph not found */
3013 if ((!vc->vc_utf || vc->vc_disp_ctrl || tc < 128) && !(tc & ~charmask)) {
3014 /*
3015 * In legacy mode use the glyph we get by a 1:1 mapping.
3016 * This would make absolutely no sense with Unicode in mind, but do this for
3017 * ASCII characters since a font may lack Unicode mapping info and we don't
3018 * want to end up with having question marks only.
3019 */
3020 return tc;
3021 }
3022
3023 /*
3024 * The Unicode screen memory is allocated only when required.
3025 * This is one such case: we're about to "cheat" with the displayed
3026 * character meaning the simple screen buffer won't hold the original
3027 * information, whereas the Unicode screen buffer always does.
3028 */
3029 vc_uniscr_check(vc);
3030
3031 /* Try getting a simpler fallback character. */
3032 tc = ucs_get_fallback(tc);
3033 if (tc)
3034 return vc_get_glyph(vc, tc);
3035
3036 /* Display U+FFFD (Unicode Replacement Character). */
3037 return conv_uni_to_pc(vc, UCS_REPLACEMENT);
3038 }
3039
vc_con_write_normal(struct vc_data * vc,int tc,int c,struct vc_draw_region * draw)3040 static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
3041 struct vc_draw_region *draw)
3042 {
3043 int next_c;
3044 unsigned char vc_attr = vc->vc_attr;
3045 u16 himask = vc->vc_hi_font_mask;
3046 u8 width = 1;
3047 bool inverse = false;
3048
3049 if (vc->vc_utf && !vc->vc_disp_ctrl) {
3050 width = vc_process_ucs(vc, &c, &tc);
3051 if (!width)
3052 goto out;
3053 }
3054
3055 /* Now try to find out how to display it */
3056 tc = vc_get_glyph(vc, tc);
3057 if (tc == -1)
3058 return -1; /* nothing to display */
3059 if (tc < 0) {
3060 inverse = true;
3061 tc = conv_uni_to_pc(vc, '?');
3062 if (tc < 0)
3063 tc = '?';
3064
3065 vc_attr = vc_invert_attr(vc);
3066 con_flush(vc, draw);
3067 }
3068
3069 next_c = c;
3070 while (1) {
3071 if (vc->vc_need_wrap || vc->vc_decim)
3072 con_flush(vc, draw);
3073 if (vc->vc_need_wrap) {
3074 cr(vc);
3075 lf(vc);
3076 }
3077 if (vc->vc_decim)
3078 insert_char(vc, 1);
3079 vc_uniscr_putc(vc, next_c);
3080
3081 if (himask)
3082 tc = ((tc & 0x100) ? himask : 0) |
3083 (tc & 0xff);
3084 tc |= (vc_attr << 8) & ~himask;
3085
3086 scr_writew(tc, (u16 *)vc->vc_pos);
3087
3088 if (con_should_update(vc) && draw->x < 0) {
3089 draw->x = vc->state.x;
3090 draw->from = vc->vc_pos;
3091 }
3092 if (vc->state.x == vc->vc_cols - 1) {
3093 vc->vc_need_wrap = vc->vc_decawm;
3094 draw->to = vc->vc_pos + 2;
3095 } else {
3096 vc->state.x++;
3097 draw->to = (vc->vc_pos += 2);
3098 }
3099
3100 if (!--width)
3101 break;
3102
3103 /* A space is printed in the second column */
3104 tc = conv_uni_to_pc(vc, ' ');
3105 if (tc < 0)
3106 tc = ' ';
3107 /*
3108 * Store a zero-width space in the Unicode screen given that
3109 * the previous code point is semantically double width.
3110 */
3111 next_c = UCS_ZWS;
3112 }
3113
3114 out:
3115 notify_write(vc, c);
3116
3117 if (inverse)
3118 con_flush(vc, draw);
3119
3120 return 0;
3121 }
3122
3123 /* acquires console_lock */
do_con_write(struct tty_struct * tty,const u8 * buf,int count)3124 static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
3125 {
3126 struct vc_draw_region draw = {
3127 .x = -1,
3128 };
3129 int c, tc, n = 0;
3130 unsigned int currcons;
3131 struct vc_data *vc = tty->driver_data;
3132 struct vt_notifier_param param;
3133 bool rescan;
3134
3135 if (in_interrupt())
3136 return count;
3137
3138 console_lock();
3139 currcons = vc->vc_num;
3140 if (!vc_cons_allocated(currcons)) {
3141 /* could this happen? */
3142 pr_warn_once("con_write: tty %d not allocated\n", currcons+1);
3143 console_unlock();
3144 return 0;
3145 }
3146
3147
3148 /* undraw cursor first */
3149 if (con_is_fg(vc))
3150 hide_cursor(vc);
3151
3152 param.vc = vc;
3153
3154 while (!tty->flow.stopped && count) {
3155 u8 orig = *buf;
3156 buf++;
3157 n++;
3158 count--;
3159 rescan_last_byte:
3160 c = orig;
3161 rescan = false;
3162
3163 tc = vc_translate(vc, &c, &rescan);
3164 if (tc == -1)
3165 continue;
3166
3167 param.c = tc;
3168 if (atomic_notifier_call_chain(&vt_notifier_list, VT_PREWRITE,
3169 ¶m) == NOTIFY_STOP)
3170 continue;
3171
3172 if (vc_is_control(vc, tc, c)) {
3173 con_flush(vc, &draw);
3174 do_con_trol(tty, vc, orig);
3175 continue;
3176 }
3177
3178 if (vc_con_write_normal(vc, tc, c, &draw) < 0)
3179 continue;
3180
3181 if (rescan)
3182 goto rescan_last_byte;
3183 }
3184 con_flush(vc, &draw);
3185 console_conditional_schedule();
3186 notify_update(vc);
3187 console_unlock();
3188 return n;
3189 }
3190
3191 /*
3192 * This is the console switching callback.
3193 *
3194 * Doing console switching in a process context allows
3195 * us to do the switches asynchronously (needed when we want
3196 * to switch due to a keyboard interrupt). Synchronization
3197 * with other console code and prevention of re-entrancy is
3198 * ensured with console_lock.
3199 */
console_callback(struct work_struct * ignored)3200 static void console_callback(struct work_struct *ignored)
3201 {
3202 console_lock();
3203
3204 if (want_console >= 0) {
3205 if (want_console != fg_console &&
3206 vc_cons_allocated(want_console)) {
3207 hide_cursor(vc_cons[fg_console].d);
3208 change_console(vc_cons[want_console].d);
3209 /* we only changed when the console had already
3210 been allocated - a new console is not created
3211 in an interrupt routine */
3212 }
3213 want_console = -1;
3214 }
3215 if (do_poke_blanked_console) { /* do not unblank for a LED change */
3216 do_poke_blanked_console = 0;
3217 poke_blanked_console();
3218 }
3219 if (scrollback_delta) {
3220 struct vc_data *vc = vc_cons[fg_console].d;
3221 clear_selection();
3222 if (vc->vc_mode == KD_TEXT && vc->vc_sw->con_scrolldelta)
3223 vc->vc_sw->con_scrolldelta(vc, scrollback_delta);
3224 scrollback_delta = 0;
3225 }
3226 if (blank_timer_expired) {
3227 do_blank_screen(0);
3228 blank_timer_expired = 0;
3229 }
3230 notify_update(vc_cons[fg_console].d);
3231
3232 console_unlock();
3233 }
3234
set_console(int nr)3235 int set_console(int nr)
3236 {
3237 struct vc_data *vc = vc_cons[fg_console].d;
3238
3239 if (!vc_cons_allocated(nr) || vt_dont_switch ||
3240 (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) {
3241
3242 /*
3243 * Console switch will fail in console_callback() or
3244 * change_console() so there is no point scheduling
3245 * the callback
3246 *
3247 * Existing set_console() users don't check the return
3248 * value so this shouldn't break anything
3249 */
3250 return -EINVAL;
3251 }
3252
3253 want_console = nr;
3254 schedule_console_callback();
3255
3256 return 0;
3257 }
3258
3259 struct tty_driver *console_driver;
3260
3261 #ifdef CONFIG_VT_CONSOLE
3262
3263 /**
3264 * vt_kmsg_redirect() - sets/gets the kernel message console
3265 * @new: the new virtual terminal number or -1 if the console should stay
3266 * unchanged
3267 *
3268 * By default, the kernel messages are always printed on the current virtual
3269 * console. However, the user may modify that default with the
3270 * %TIOCL_SETKMSGREDIRECT ioctl call.
3271 *
3272 * This function sets the kernel message console to be @new. It returns the old
3273 * virtual console number. The virtual terminal number %0 (both as parameter and
3274 * return value) means no redirection (i.e. always printed on the currently
3275 * active console).
3276 *
3277 * The parameter -1 means that only the current console is returned, but the
3278 * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
3279 * case to make the code more understandable.
3280 *
3281 * When the kernel is compiled without %CONFIG_VT_CONSOLE, this function ignores
3282 * the parameter and always returns %0.
3283 */
vt_kmsg_redirect(int new)3284 int vt_kmsg_redirect(int new)
3285 {
3286 static int kmsg_con;
3287
3288 if (new != -1)
3289 return xchg(&kmsg_con, new);
3290 else
3291 return kmsg_con;
3292 }
3293
3294 /*
3295 * Console on virtual terminal
3296 *
3297 * The console must be locked when we get here.
3298 */
3299
vt_console_print(struct console * co,const char * b,unsigned count)3300 static void vt_console_print(struct console *co, const char *b, unsigned count)
3301 {
3302 struct vc_data *vc = vc_cons[fg_console].d;
3303 unsigned char c;
3304 static DEFINE_SPINLOCK(printing_lock);
3305 const ushort *start;
3306 ushort start_x, cnt;
3307 int kmsg_console;
3308
3309 WARN_CONSOLE_UNLOCKED();
3310
3311 /* this protects against concurrent oops only */
3312 if (!spin_trylock(&printing_lock))
3313 return;
3314
3315 kmsg_console = vt_get_kmsg_redirect();
3316 if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
3317 vc = vc_cons[kmsg_console - 1].d;
3318
3319 if (!vc_cons_allocated(fg_console)) {
3320 /* impossible */
3321 /* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
3322 goto quit;
3323 }
3324
3325 if (vc->vc_mode != KD_TEXT)
3326 goto quit;
3327
3328 /* undraw cursor first */
3329 if (con_is_fg(vc))
3330 hide_cursor(vc);
3331
3332 start = (ushort *)vc->vc_pos;
3333 start_x = vc->state.x;
3334 cnt = 0;
3335 while (count--) {
3336 c = *b++;
3337 if (c == ASCII_LINEFEED || c == ASCII_CAR_RET ||
3338 c == ASCII_BACKSPACE || vc->vc_need_wrap) {
3339 if (cnt && con_is_visible(vc))
3340 vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
3341 cnt = 0;
3342 if (c == ASCII_BACKSPACE) {
3343 bs(vc);
3344 start = (ushort *)vc->vc_pos;
3345 start_x = vc->state.x;
3346 continue;
3347 }
3348 if (c != ASCII_CAR_RET)
3349 lf(vc);
3350 cr(vc);
3351 start = (ushort *)vc->vc_pos;
3352 start_x = vc->state.x;
3353 if (c == ASCII_LINEFEED || c == ASCII_CAR_RET)
3354 continue;
3355 }
3356 vc_uniscr_putc(vc, c);
3357 scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
3358 notify_write(vc, c);
3359 cnt++;
3360 if (vc->state.x == vc->vc_cols - 1) {
3361 vc->vc_need_wrap = 1;
3362 } else {
3363 vc->vc_pos += 2;
3364 vc->state.x++;
3365 }
3366 }
3367 if (cnt && con_is_visible(vc))
3368 vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
3369 set_cursor(vc);
3370 notify_update(vc);
3371
3372 quit:
3373 spin_unlock(&printing_lock);
3374 }
3375
vt_console_device(struct console * c,int * index)3376 static struct tty_driver *vt_console_device(struct console *c, int *index)
3377 {
3378 *index = c->index ? c->index-1 : fg_console;
3379 return console_driver;
3380 }
3381
vt_console_setup(struct console * co,char * options)3382 static int vt_console_setup(struct console *co, char *options)
3383 {
3384 return co->index >= MAX_NR_CONSOLES ? -EINVAL : 0;
3385 }
3386
3387 static struct console vt_console_driver = {
3388 .name = "tty",
3389 .setup = vt_console_setup,
3390 .write = vt_console_print,
3391 .device = vt_console_device,
3392 .unblank = unblank_screen,
3393 .flags = CON_PRINTBUFFER,
3394 .index = -1,
3395 };
3396 #endif
3397
3398 /*
3399 * Handling of Linux-specific VC ioctls
3400 */
3401
3402 /*
3403 * Generally a bit racy with respect to console_lock();.
3404 *
3405 * There are some functions which don't need it.
3406 *
3407 * There are some functions which can sleep for arbitrary periods
3408 * (paste_selection) but we don't need the lock there anyway.
3409 *
3410 * set_selection_user has locking, and definitely needs it
3411 */
3412
tioclinux(struct tty_struct * tty,unsigned long arg)3413 int tioclinux(struct tty_struct *tty, unsigned long arg)
3414 {
3415 char type, data;
3416 char __user *p = (char __user *)arg;
3417 void __user *param_aligned32 = (u32 __user *)arg + 1;
3418 void __user *param = (void __user *)arg + 1;
3419 int lines;
3420 int ret;
3421
3422 if (current->signal->tty != tty && !capable(CAP_SYS_ADMIN))
3423 return -EPERM;
3424 if (get_user(type, p))
3425 return -EFAULT;
3426 ret = 0;
3427
3428 switch (type) {
3429 case TIOCL_SETSEL:
3430 return set_selection_user(param, tty);
3431 case TIOCL_PASTESEL:
3432 if (!capable(CAP_SYS_ADMIN))
3433 return -EPERM;
3434 return paste_selection(tty);
3435 case TIOCL_UNBLANKSCREEN:
3436 console_lock();
3437 unblank_screen();
3438 console_unlock();
3439 break;
3440 case TIOCL_SELLOADLUT:
3441 if (!capable(CAP_SYS_ADMIN))
3442 return -EPERM;
3443 return sel_loadlut(param_aligned32);
3444 case TIOCL_GETSHIFTSTATE:
3445 /*
3446 * Make it possible to react to Shift+Mousebutton. Note that
3447 * 'shift_state' is an undocumented kernel-internal variable;
3448 * programs not closely related to the kernel should not use
3449 * this.
3450 */
3451 data = vt_get_shift_state();
3452 return put_user(data, p);
3453 case TIOCL_GETMOUSEREPORTING:
3454 console_lock(); /* May be overkill */
3455 data = mouse_reporting();
3456 console_unlock();
3457 return put_user(data, p);
3458 case TIOCL_SETVESABLANK:
3459 return set_vesa_blanking(param);
3460 case TIOCL_GETKMSGREDIRECT:
3461 data = vt_get_kmsg_redirect();
3462 return put_user(data, p);
3463 case TIOCL_SETKMSGREDIRECT:
3464 if (!capable(CAP_SYS_ADMIN))
3465 return -EPERM;
3466
3467 if (get_user(data, p+1))
3468 return -EFAULT;
3469
3470 vt_kmsg_redirect(data);
3471
3472 break;
3473 case TIOCL_GETFGCONSOLE:
3474 /*
3475 * No locking needed as this is a transiently correct return
3476 * anyway if the caller hasn't disabled switching.
3477 */
3478 return fg_console;
3479 case TIOCL_SCROLLCONSOLE:
3480 if (get_user(lines, (s32 __user *)param_aligned32))
3481 return -EFAULT;
3482
3483 /*
3484 * Needs the console lock here. Note that lots of other calls
3485 * need fixing before the lock is actually useful!
3486 */
3487 console_lock();
3488 scrollfront(vc_cons[fg_console].d, lines);
3489 console_unlock();
3490 break;
3491 case TIOCL_BLANKSCREEN: /* until explicitly unblanked, not only poked */
3492 console_lock();
3493 ignore_poke = 1;
3494 do_blank_screen(0);
3495 console_unlock();
3496 break;
3497 case TIOCL_BLANKEDSCREEN:
3498 return console_blanked;
3499 case TIOCL_GETBRACKETEDPASTE:
3500 return get_bracketed_paste(tty);
3501 default:
3502 return -EINVAL;
3503 }
3504
3505 return ret;
3506 }
3507
3508 /*
3509 * /dev/ttyN handling
3510 */
3511
con_write(struct tty_struct * tty,const u8 * buf,size_t count)3512 static ssize_t con_write(struct tty_struct *tty, const u8 *buf, size_t count)
3513 {
3514 int retval;
3515
3516 retval = do_con_write(tty, buf, count);
3517 con_flush_chars(tty);
3518
3519 return retval;
3520 }
3521
con_put_char(struct tty_struct * tty,u8 ch)3522 static int con_put_char(struct tty_struct *tty, u8 ch)
3523 {
3524 return do_con_write(tty, &ch, 1);
3525 }
3526
con_write_room(struct tty_struct * tty)3527 static unsigned int con_write_room(struct tty_struct *tty)
3528 {
3529 if (tty->flow.stopped)
3530 return 0;
3531 return 32768; /* No limit, really; we're not buffering */
3532 }
3533
3534 /*
3535 * con_throttle and con_unthrottle are only used for
3536 * paste_selection(), which has to stuff in a large number of
3537 * characters...
3538 */
con_throttle(struct tty_struct * tty)3539 static void con_throttle(struct tty_struct *tty)
3540 {
3541 }
3542
con_unthrottle(struct tty_struct * tty)3543 static void con_unthrottle(struct tty_struct *tty)
3544 {
3545 struct vc_data *vc = tty->driver_data;
3546
3547 wake_up_interruptible(&vc->paste_wait);
3548 }
3549
3550 /*
3551 * Turn the Scroll-Lock LED on when the tty is stopped
3552 */
con_stop(struct tty_struct * tty)3553 static void con_stop(struct tty_struct *tty)
3554 {
3555 int console_num;
3556 if (!tty)
3557 return;
3558 console_num = tty->index;
3559 if (!vc_cons_allocated(console_num))
3560 return;
3561 vt_kbd_con_stop(console_num);
3562 }
3563
3564 /*
3565 * Turn the Scroll-Lock LED off when the console is started
3566 */
con_start(struct tty_struct * tty)3567 static void con_start(struct tty_struct *tty)
3568 {
3569 int console_num;
3570 if (!tty)
3571 return;
3572 console_num = tty->index;
3573 if (!vc_cons_allocated(console_num))
3574 return;
3575 vt_kbd_con_start(console_num);
3576 }
3577
con_flush_chars(struct tty_struct * tty)3578 static void con_flush_chars(struct tty_struct *tty)
3579 {
3580 struct vc_data *vc = tty->driver_data;
3581
3582 if (in_interrupt()) /* from flush_to_ldisc */
3583 return;
3584
3585 console_lock();
3586 set_cursor(vc);
3587 console_unlock();
3588 }
3589
3590 /*
3591 * Allocate the console screen memory.
3592 */
con_install(struct tty_driver * driver,struct tty_struct * tty)3593 static int con_install(struct tty_driver *driver, struct tty_struct *tty)
3594 {
3595 unsigned int currcons = tty->index;
3596 struct vc_data *vc;
3597 int ret;
3598
3599 console_lock();
3600 ret = vc_allocate(currcons);
3601 if (ret)
3602 goto unlock;
3603
3604 vc = vc_cons[currcons].d;
3605
3606 /* Still being freed */
3607 if (vc->port.tty) {
3608 ret = -ERESTARTSYS;
3609 goto unlock;
3610 }
3611
3612 ret = tty_port_install(&vc->port, driver, tty);
3613 if (ret)
3614 goto unlock;
3615
3616 tty->driver_data = vc;
3617 vc->port.tty = tty;
3618 tty_port_get(&vc->port);
3619
3620 if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
3621 tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
3622 tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
3623 }
3624 if (vc->vc_utf)
3625 tty->termios.c_iflag |= IUTF8;
3626 else
3627 tty->termios.c_iflag &= ~IUTF8;
3628 unlock:
3629 console_unlock();
3630 return ret;
3631 }
3632
con_open(struct tty_struct * tty,struct file * filp)3633 static int con_open(struct tty_struct *tty, struct file *filp)
3634 {
3635 /* everything done in install */
3636 return 0;
3637 }
3638
3639
con_close(struct tty_struct * tty,struct file * filp)3640 static void con_close(struct tty_struct *tty, struct file *filp)
3641 {
3642 /* Nothing to do - we defer to shutdown */
3643 }
3644
con_shutdown(struct tty_struct * tty)3645 static void con_shutdown(struct tty_struct *tty)
3646 {
3647 struct vc_data *vc = tty->driver_data;
3648 BUG_ON(vc == NULL);
3649 console_lock();
3650 vc->port.tty = NULL;
3651 console_unlock();
3652 }
3653
con_cleanup(struct tty_struct * tty)3654 static void con_cleanup(struct tty_struct *tty)
3655 {
3656 struct vc_data *vc = tty->driver_data;
3657
3658 tty_port_put(&vc->port);
3659 }
3660
3661 /*
3662 * We can't deal with anything but the N_TTY ldisc,
3663 * because we can sleep in our write() routine.
3664 */
con_ldisc_ok(struct tty_struct * tty,int ldisc)3665 static int con_ldisc_ok(struct tty_struct *tty, int ldisc)
3666 {
3667 return ldisc == N_TTY ? 0 : -EINVAL;
3668 }
3669
3670 static int default_color = 7; /* white */
3671 static int default_italic_color = 2; // green (ASCII)
3672 static int default_underline_color = 3; // cyan (ASCII)
3673 module_param_named(color, default_color, int, S_IRUGO | S_IWUSR);
3674 module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
3675 module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);
3676
vc_init(struct vc_data * vc,int do_clear)3677 static void vc_init(struct vc_data *vc, int do_clear)
3678 {
3679 int j, k ;
3680
3681 set_origin(vc);
3682 vc->vc_pos = vc->vc_origin;
3683 reset_vc(vc);
3684 for (j=k=0; j<16; j++) {
3685 vc->vc_palette[k++] = default_red[j] ;
3686 vc->vc_palette[k++] = default_grn[j] ;
3687 vc->vc_palette[k++] = default_blu[j] ;
3688 }
3689 vc->vc_def_color = default_color;
3690 vc->vc_ulcolor = default_underline_color;
3691 vc->vc_itcolor = default_italic_color;
3692 vc->vc_halfcolor = 0x08; /* grey */
3693 init_waitqueue_head(&vc->paste_wait);
3694 reset_terminal(vc, do_clear);
3695 }
3696
3697 /*
3698 * This routine initializes console interrupts, and does nothing
3699 * else. If you want the screen to clear, call tty_write with
3700 * the appropriate escape-sequence.
3701 */
3702
con_init(void)3703 static int __init con_init(void)
3704 {
3705 const char *display_desc = NULL;
3706 struct vc_data *vc;
3707 unsigned int currcons = 0, i;
3708
3709 console_lock();
3710
3711 if (!conswitchp)
3712 conswitchp = &dummy_con;
3713 display_desc = conswitchp->con_startup();
3714 if (!display_desc) {
3715 fg_console = 0;
3716 console_unlock();
3717 return 0;
3718 }
3719
3720 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3721 struct con_driver *con_driver = ®istered_con_driver[i];
3722
3723 if (con_driver->con == NULL) {
3724 con_driver->con = conswitchp;
3725 con_driver->desc = display_desc;
3726 con_driver->flag = CON_DRIVER_FLAG_INIT;
3727 con_driver->first = 0;
3728 con_driver->last = MAX_NR_CONSOLES - 1;
3729 break;
3730 }
3731 }
3732
3733 for (i = 0; i < MAX_NR_CONSOLES; i++)
3734 con_driver_map[i] = conswitchp;
3735
3736 if (blankinterval) {
3737 blank_state = blank_normal_wait;
3738 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
3739 }
3740
3741 for (currcons = 0; currcons < MIN_NR_CONSOLES; currcons++) {
3742 vc_cons[currcons].d = vc = kzalloc(sizeof(struct vc_data), GFP_NOWAIT);
3743 INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK);
3744 tty_port_init(&vc->port);
3745 visual_init(vc, currcons, true);
3746 /* Assuming vc->vc_{cols,rows,screenbuf_size} are sane here. */
3747 vc->vc_screenbuf = kzalloc(vc->vc_screenbuf_size, GFP_NOWAIT);
3748 vc_init(vc, currcons || !vc->vc_sw->con_save_screen);
3749 }
3750 currcons = fg_console = 0;
3751 master_display_fg = vc = vc_cons[currcons].d;
3752 set_origin(vc);
3753 save_screen(vc);
3754 gotoxy(vc, vc->state.x, vc->state.y);
3755 csi_J(vc, CSI_J_CURSOR_TO_END);
3756 update_screen(vc);
3757 pr_info("Console: %s %s %dx%d\n",
3758 vc->vc_can_do_color ? "colour" : "mono",
3759 display_desc, vc->vc_cols, vc->vc_rows);
3760
3761 console_unlock();
3762
3763 #ifdef CONFIG_VT_CONSOLE
3764 register_console(&vt_console_driver);
3765 #endif
3766 return 0;
3767 }
3768 console_initcall(con_init);
3769
3770 static const struct tty_operations con_ops = {
3771 .install = con_install,
3772 .open = con_open,
3773 .close = con_close,
3774 .write = con_write,
3775 .write_room = con_write_room,
3776 .put_char = con_put_char,
3777 .flush_chars = con_flush_chars,
3778 .ioctl = vt_ioctl,
3779 #ifdef CONFIG_COMPAT
3780 .compat_ioctl = vt_compat_ioctl,
3781 #endif
3782 .stop = con_stop,
3783 .start = con_start,
3784 .throttle = con_throttle,
3785 .unthrottle = con_unthrottle,
3786 .resize = vt_resize,
3787 .shutdown = con_shutdown,
3788 .cleanup = con_cleanup,
3789 .ldisc_ok = con_ldisc_ok,
3790 };
3791
3792 static struct cdev vc0_cdev;
3793
show_tty_active(struct device * dev,struct device_attribute * attr,char * buf)3794 static ssize_t show_tty_active(struct device *dev,
3795 struct device_attribute *attr, char *buf)
3796 {
3797 return sprintf(buf, "tty%d\n", fg_console + 1);
3798 }
3799 static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL);
3800
3801 static struct attribute *vt_dev_attrs[] = {
3802 &dev_attr_active.attr,
3803 NULL
3804 };
3805
3806 ATTRIBUTE_GROUPS(vt_dev);
3807
vty_init(const struct file_operations * console_fops)3808 int __init vty_init(const struct file_operations *console_fops)
3809 {
3810 cdev_init(&vc0_cdev, console_fops);
3811 if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
3812 register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
3813 panic("Couldn't register /dev/tty0 driver\n");
3814 tty0dev = device_create_with_groups(&tty_class, NULL,
3815 MKDEV(TTY_MAJOR, 0), NULL,
3816 vt_dev_groups, "tty0");
3817 if (IS_ERR(tty0dev))
3818 tty0dev = NULL;
3819
3820 vcs_init();
3821
3822 console_driver = tty_alloc_driver(MAX_NR_CONSOLES, TTY_DRIVER_REAL_RAW |
3823 TTY_DRIVER_RESET_TERMIOS);
3824 if (IS_ERR(console_driver))
3825 panic("Couldn't allocate console driver\n");
3826
3827 console_driver->name = "tty";
3828 console_driver->name_base = 1;
3829 console_driver->major = TTY_MAJOR;
3830 console_driver->minor_start = 1;
3831 console_driver->type = TTY_DRIVER_TYPE_CONSOLE;
3832 console_driver->init_termios = tty_std_termios;
3833 if (default_utf8)
3834 console_driver->init_termios.c_iflag |= IUTF8;
3835 tty_set_operations(console_driver, &con_ops);
3836 if (tty_register_driver(console_driver))
3837 panic("Couldn't register console driver\n");
3838 kbd_init();
3839 console_map_init();
3840 #ifdef CONFIG_MDA_CONSOLE
3841 mda_console_init();
3842 #endif
3843 return 0;
3844 }
3845
3846 static const struct class vtconsole_class = {
3847 .name = "vtconsole",
3848 };
3849
do_bind_con_driver(const struct consw * csw,int first,int last,int deflt)3850 static int do_bind_con_driver(const struct consw *csw, int first, int last,
3851 int deflt)
3852 {
3853 struct module *owner = csw->owner;
3854 const char *desc = NULL;
3855 struct con_driver *con_driver;
3856 int i, j = -1, k = -1, retval = -ENODEV;
3857
3858 if (!try_module_get(owner))
3859 return -ENODEV;
3860
3861 WARN_CONSOLE_UNLOCKED();
3862
3863 /* check if driver is registered */
3864 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3865 con_driver = ®istered_con_driver[i];
3866
3867 if (con_driver->con == csw) {
3868 desc = con_driver->desc;
3869 retval = 0;
3870 break;
3871 }
3872 }
3873
3874 if (retval)
3875 goto err;
3876
3877 if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
3878 csw->con_startup();
3879 con_driver->flag |= CON_DRIVER_FLAG_INIT;
3880 }
3881
3882 if (deflt) {
3883 if (conswitchp)
3884 module_put(conswitchp->owner);
3885
3886 __module_get(owner);
3887 conswitchp = csw;
3888 }
3889
3890 first = max(first, con_driver->first);
3891 last = min(last, con_driver->last);
3892
3893 for (i = first; i <= last; i++) {
3894 int old_was_color;
3895 struct vc_data *vc = vc_cons[i].d;
3896
3897 if (con_driver_map[i])
3898 module_put(con_driver_map[i]->owner);
3899 __module_get(owner);
3900 con_driver_map[i] = csw;
3901
3902 if (!vc || !vc->vc_sw)
3903 continue;
3904
3905 j = i;
3906
3907 if (con_is_visible(vc)) {
3908 k = i;
3909 save_screen(vc);
3910 }
3911
3912 old_was_color = vc->vc_can_do_color;
3913 vc->vc_sw->con_deinit(vc);
3914 vc->vc_origin = (unsigned long)vc->vc_screenbuf;
3915 visual_init(vc, i, false);
3916 set_origin(vc);
3917 update_attr(vc);
3918
3919 /* If the console changed between mono <-> color, then
3920 * the attributes in the screenbuf will be wrong. The
3921 * following resets all attributes to something sane.
3922 */
3923 if (old_was_color != vc->vc_can_do_color)
3924 clear_buffer_attributes(vc);
3925 }
3926
3927 pr_info("Console: switching ");
3928 if (!deflt)
3929 pr_cont("consoles %d-%d ", first + 1, last + 1);
3930 if (j >= 0) {
3931 struct vc_data *vc = vc_cons[j].d;
3932
3933 pr_cont("to %s %s %dx%d\n",
3934 vc->vc_can_do_color ? "colour" : "mono",
3935 desc, vc->vc_cols, vc->vc_rows);
3936
3937 if (k >= 0) {
3938 vc = vc_cons[k].d;
3939 update_screen(vc);
3940 }
3941 } else {
3942 pr_cont("to %s\n", desc);
3943 }
3944
3945 retval = 0;
3946 err:
3947 module_put(owner);
3948 return retval;
3949 };
3950
3951
3952 #ifdef CONFIG_VT_HW_CONSOLE_BINDING
do_unbind_con_driver(const struct consw * csw,int first,int last,int deflt)3953 int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
3954 {
3955 struct module *owner = csw->owner;
3956 const struct consw *defcsw = NULL;
3957 struct con_driver *con_driver = NULL, *con_back = NULL;
3958 int i, retval = -ENODEV;
3959
3960 if (!try_module_get(owner))
3961 return -ENODEV;
3962
3963 WARN_CONSOLE_UNLOCKED();
3964
3965 /* check if driver is registered and if it is unbindable */
3966 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3967 con_driver = ®istered_con_driver[i];
3968
3969 if (con_driver->con == csw &&
3970 con_driver->flag & CON_DRIVER_FLAG_MODULE) {
3971 retval = 0;
3972 break;
3973 }
3974 }
3975
3976 if (retval)
3977 goto err;
3978
3979 retval = -ENODEV;
3980
3981 /* check if backup driver exists */
3982 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
3983 con_back = ®istered_con_driver[i];
3984
3985 if (con_back->con && con_back->con != csw) {
3986 defcsw = con_back->con;
3987 retval = 0;
3988 break;
3989 }
3990 }
3991
3992 if (retval)
3993 goto err;
3994
3995 if (!con_is_bound(csw))
3996 goto err;
3997
3998 first = max(first, con_driver->first);
3999 last = min(last, con_driver->last);
4000
4001 for (i = first; i <= last; i++) {
4002 if (con_driver_map[i] == csw) {
4003 module_put(csw->owner);
4004 con_driver_map[i] = NULL;
4005 }
4006 }
4007
4008 if (!con_is_bound(defcsw)) {
4009 const struct consw *defconsw = conswitchp;
4010
4011 defcsw->con_startup();
4012 con_back->flag |= CON_DRIVER_FLAG_INIT;
4013 /*
4014 * vgacon may change the default driver to point
4015 * to dummycon, we restore it here...
4016 */
4017 conswitchp = defconsw;
4018 }
4019
4020 if (!con_is_bound(csw))
4021 con_driver->flag &= ~CON_DRIVER_FLAG_INIT;
4022
4023 /* ignore return value, binding should not fail */
4024 do_bind_con_driver(defcsw, first, last, deflt);
4025 err:
4026 module_put(owner);
4027 return retval;
4028
4029 }
4030 EXPORT_SYMBOL_GPL(do_unbind_con_driver);
4031
vt_bind(struct con_driver * con)4032 static int vt_bind(struct con_driver *con)
4033 {
4034 const struct consw *defcsw = NULL, *csw = NULL;
4035 int i, more = 1, first = -1, last = -1, deflt = 0;
4036
4037 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE))
4038 goto err;
4039
4040 csw = con->con;
4041
4042 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4043 struct con_driver *con = ®istered_con_driver[i];
4044
4045 if (con->con && !(con->flag & CON_DRIVER_FLAG_MODULE)) {
4046 defcsw = con->con;
4047 break;
4048 }
4049 }
4050
4051 if (!defcsw)
4052 goto err;
4053
4054 while (more) {
4055 more = 0;
4056
4057 for (i = con->first; i <= con->last; i++) {
4058 if (con_driver_map[i] == defcsw) {
4059 if (first == -1)
4060 first = i;
4061 last = i;
4062 more = 1;
4063 } else if (first != -1)
4064 break;
4065 }
4066
4067 if (first == 0 && last == MAX_NR_CONSOLES -1)
4068 deflt = 1;
4069
4070 if (first != -1)
4071 do_bind_con_driver(csw, first, last, deflt);
4072
4073 first = -1;
4074 last = -1;
4075 deflt = 0;
4076 }
4077
4078 err:
4079 return 0;
4080 }
4081
vt_unbind(struct con_driver * con)4082 static int vt_unbind(struct con_driver *con)
4083 {
4084 const struct consw *csw = NULL;
4085 int i, more = 1, first = -1, last = -1, deflt = 0;
4086 int ret;
4087
4088 if (!con->con || !(con->flag & CON_DRIVER_FLAG_MODULE))
4089 goto err;
4090
4091 csw = con->con;
4092
4093 while (more) {
4094 more = 0;
4095
4096 for (i = con->first; i <= con->last; i++) {
4097 if (con_driver_map[i] == csw) {
4098 if (first == -1)
4099 first = i;
4100 last = i;
4101 more = 1;
4102 } else if (first != -1)
4103 break;
4104 }
4105
4106 if (first == 0 && last == MAX_NR_CONSOLES -1)
4107 deflt = 1;
4108
4109 if (first != -1) {
4110 ret = do_unbind_con_driver(csw, first, last, deflt);
4111 if (ret != 0)
4112 return ret;
4113 }
4114
4115 first = -1;
4116 last = -1;
4117 deflt = 0;
4118 }
4119
4120 err:
4121 return 0;
4122 }
4123 #else
vt_bind(struct con_driver * con)4124 static inline int vt_bind(struct con_driver *con)
4125 {
4126 return 0;
4127 }
vt_unbind(struct con_driver * con)4128 static inline int vt_unbind(struct con_driver *con)
4129 {
4130 return 0;
4131 }
4132 #endif /* CONFIG_VT_HW_CONSOLE_BINDING */
4133
store_bind(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)4134 static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
4135 const char *buf, size_t count)
4136 {
4137 struct con_driver *con = dev_get_drvdata(dev);
4138 int bind = simple_strtoul(buf, NULL, 0);
4139
4140 console_lock();
4141
4142 if (bind)
4143 vt_bind(con);
4144 else
4145 vt_unbind(con);
4146
4147 console_unlock();
4148
4149 return count;
4150 }
4151
show_bind(struct device * dev,struct device_attribute * attr,char * buf)4152 static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
4153 char *buf)
4154 {
4155 struct con_driver *con = dev_get_drvdata(dev);
4156 int bind;
4157
4158 console_lock();
4159 bind = con_is_bound(con->con);
4160 console_unlock();
4161
4162 return sysfs_emit(buf, "%i\n", bind);
4163 }
4164
show_name(struct device * dev,struct device_attribute * attr,char * buf)4165 static ssize_t show_name(struct device *dev, struct device_attribute *attr,
4166 char *buf)
4167 {
4168 struct con_driver *con = dev_get_drvdata(dev);
4169
4170 return sysfs_emit(buf, "%s %s\n",
4171 (con->flag & CON_DRIVER_FLAG_MODULE) ? "(M)" : "(S)",
4172 con->desc);
4173
4174 }
4175
4176 static DEVICE_ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind);
4177 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
4178
4179 static struct attribute *con_dev_attrs[] = {
4180 &dev_attr_bind.attr,
4181 &dev_attr_name.attr,
4182 NULL
4183 };
4184
4185 ATTRIBUTE_GROUPS(con_dev);
4186
vtconsole_init_device(struct con_driver * con)4187 static int vtconsole_init_device(struct con_driver *con)
4188 {
4189 con->flag |= CON_DRIVER_FLAG_ATTR;
4190 return 0;
4191 }
4192
vtconsole_deinit_device(struct con_driver * con)4193 static void vtconsole_deinit_device(struct con_driver *con)
4194 {
4195 con->flag &= ~CON_DRIVER_FLAG_ATTR;
4196 }
4197
4198 /**
4199 * con_is_bound - checks if driver is bound to the console
4200 * @csw: console driver
4201 *
4202 * RETURNS: zero if unbound, nonzero if bound
4203 *
4204 * Drivers can call this and if zero, they should release
4205 * all resources allocated on &consw.con_startup()
4206 */
con_is_bound(const struct consw * csw)4207 int con_is_bound(const struct consw *csw)
4208 {
4209 int i, bound = 0;
4210
4211 WARN_CONSOLE_UNLOCKED();
4212
4213 for (i = 0; i < MAX_NR_CONSOLES; i++) {
4214 if (con_driver_map[i] == csw) {
4215 bound = 1;
4216 break;
4217 }
4218 }
4219
4220 return bound;
4221 }
4222 EXPORT_SYMBOL(con_is_bound);
4223
4224 /**
4225 * con_is_visible - checks whether the current console is visible
4226 * @vc: virtual console
4227 *
4228 * RETURNS: zero if not visible, nonzero if visible
4229 */
con_is_visible(const struct vc_data * vc)4230 bool con_is_visible(const struct vc_data *vc)
4231 {
4232 WARN_CONSOLE_UNLOCKED();
4233
4234 return *vc->vc_display_fg == vc;
4235 }
4236 EXPORT_SYMBOL(con_is_visible);
4237
4238 /**
4239 * con_debug_enter - prepare the console for the kernel debugger
4240 * @vc: virtual console
4241 *
4242 * Called when the console is taken over by the kernel debugger, this
4243 * function needs to save the current console state, then put the console
4244 * into a state suitable for the kernel debugger.
4245 */
con_debug_enter(struct vc_data * vc)4246 void con_debug_enter(struct vc_data *vc)
4247 {
4248 saved_fg_console = fg_console;
4249 saved_last_console = last_console;
4250 saved_want_console = want_console;
4251 saved_vc_mode = vc->vc_mode;
4252 saved_console_blanked = console_blanked;
4253 vc->vc_mode = KD_TEXT;
4254 console_blanked = 0;
4255 if (vc->vc_sw->con_debug_enter)
4256 vc->vc_sw->con_debug_enter(vc);
4257 #ifdef CONFIG_KGDB_KDB
4258 /* Set the initial LINES variable if it is not already set */
4259 if (vc->vc_rows < 999) {
4260 int linecount;
4261 char lns[4];
4262 const char *setargs[3] = {
4263 "set",
4264 "LINES",
4265 lns,
4266 };
4267 if (kdbgetintenv(setargs[0], &linecount)) {
4268 snprintf(lns, 4, "%i", vc->vc_rows);
4269 kdb_set(2, setargs);
4270 }
4271 }
4272 if (vc->vc_cols < 999) {
4273 int colcount;
4274 char cols[4];
4275 const char *setargs[3] = {
4276 "set",
4277 "COLUMNS",
4278 cols,
4279 };
4280 if (kdbgetintenv(setargs[0], &colcount)) {
4281 snprintf(cols, 4, "%i", vc->vc_cols);
4282 kdb_set(2, setargs);
4283 }
4284 }
4285 #endif /* CONFIG_KGDB_KDB */
4286 }
4287 EXPORT_SYMBOL_GPL(con_debug_enter);
4288
4289 /**
4290 * con_debug_leave - restore console state
4291 *
4292 * Restore the console state to what it was before the kernel debugger
4293 * was invoked.
4294 */
con_debug_leave(void)4295 void con_debug_leave(void)
4296 {
4297 struct vc_data *vc;
4298
4299 fg_console = saved_fg_console;
4300 last_console = saved_last_console;
4301 want_console = saved_want_console;
4302 console_blanked = saved_console_blanked;
4303 vc_cons[fg_console].d->vc_mode = saved_vc_mode;
4304
4305 vc = vc_cons[fg_console].d;
4306 if (vc->vc_sw->con_debug_leave)
4307 vc->vc_sw->con_debug_leave(vc);
4308 }
4309 EXPORT_SYMBOL_GPL(con_debug_leave);
4310
do_register_con_driver(const struct consw * csw,int first,int last)4311 static int do_register_con_driver(const struct consw *csw, int first, int last)
4312 {
4313 struct module *owner = csw->owner;
4314 struct con_driver *con_driver;
4315 const char *desc;
4316 int i, retval;
4317
4318 WARN_CONSOLE_UNLOCKED();
4319
4320 if (!try_module_get(owner))
4321 return -ENODEV;
4322
4323 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4324 con_driver = ®istered_con_driver[i];
4325
4326 /* already registered */
4327 if (con_driver->con == csw) {
4328 retval = -EBUSY;
4329 goto err;
4330 }
4331 }
4332
4333 desc = csw->con_startup();
4334 if (!desc) {
4335 retval = -ENODEV;
4336 goto err;
4337 }
4338
4339 retval = -EINVAL;
4340
4341 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4342 con_driver = ®istered_con_driver[i];
4343
4344 if (con_driver->con == NULL &&
4345 !(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE)) {
4346 con_driver->con = csw;
4347 con_driver->desc = desc;
4348 con_driver->node = i;
4349 con_driver->flag = CON_DRIVER_FLAG_MODULE |
4350 CON_DRIVER_FLAG_INIT;
4351 con_driver->first = first;
4352 con_driver->last = last;
4353 retval = 0;
4354 break;
4355 }
4356 }
4357
4358 if (retval)
4359 goto err;
4360
4361 con_driver->dev =
4362 device_create_with_groups(&vtconsole_class, NULL,
4363 MKDEV(0, con_driver->node),
4364 con_driver, con_dev_groups,
4365 "vtcon%i", con_driver->node);
4366 if (IS_ERR(con_driver->dev)) {
4367 pr_warn("Unable to create device for %s; errno = %ld\n",
4368 con_driver->desc, PTR_ERR(con_driver->dev));
4369 con_driver->dev = NULL;
4370 } else {
4371 vtconsole_init_device(con_driver);
4372 }
4373
4374 err:
4375 module_put(owner);
4376 return retval;
4377 }
4378
4379
4380 /**
4381 * do_unregister_con_driver - unregister console driver from console layer
4382 * @csw: console driver
4383 *
4384 * DESCRIPTION: All drivers that registers to the console layer must
4385 * call this function upon exit, or if the console driver is in a state
4386 * where it won't be able to handle console services, such as the
4387 * framebuffer console without loaded framebuffer drivers.
4388 *
4389 * The driver must unbind first prior to unregistration.
4390 */
do_unregister_con_driver(const struct consw * csw)4391 int do_unregister_con_driver(const struct consw *csw)
4392 {
4393 int i;
4394
4395 /* cannot unregister a bound driver */
4396 if (con_is_bound(csw))
4397 return -EBUSY;
4398
4399 if (csw == conswitchp)
4400 return -EINVAL;
4401
4402 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4403 struct con_driver *con_driver = ®istered_con_driver[i];
4404
4405 if (con_driver->con == csw) {
4406 /*
4407 * Defer the removal of the sysfs entries since that
4408 * will acquire the kernfs s_active lock and we can't
4409 * acquire this lock while holding the console lock:
4410 * the unbind sysfs entry imposes already the opposite
4411 * order. Reset con already here to prevent any later
4412 * lookup to succeed and mark this slot as zombie, so
4413 * it won't get reused until we complete the removal
4414 * in the deferred work.
4415 */
4416 con_driver->con = NULL;
4417 con_driver->flag = CON_DRIVER_FLAG_ZOMBIE;
4418 schedule_work(&con_driver_unregister_work);
4419
4420 return 0;
4421 }
4422 }
4423
4424 return -ENODEV;
4425 }
4426 EXPORT_SYMBOL_GPL(do_unregister_con_driver);
4427
con_driver_unregister_callback(struct work_struct * ignored)4428 static void con_driver_unregister_callback(struct work_struct *ignored)
4429 {
4430 int i;
4431
4432 console_lock();
4433
4434 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4435 struct con_driver *con_driver = ®istered_con_driver[i];
4436
4437 if (!(con_driver->flag & CON_DRIVER_FLAG_ZOMBIE))
4438 continue;
4439
4440 console_unlock();
4441
4442 vtconsole_deinit_device(con_driver);
4443 device_destroy(&vtconsole_class, MKDEV(0, con_driver->node));
4444
4445 console_lock();
4446
4447 if (WARN_ON_ONCE(con_driver->con))
4448 con_driver->con = NULL;
4449 con_driver->desc = NULL;
4450 con_driver->dev = NULL;
4451 con_driver->node = 0;
4452 WARN_ON_ONCE(con_driver->flag != CON_DRIVER_FLAG_ZOMBIE);
4453 con_driver->flag = 0;
4454 con_driver->first = 0;
4455 con_driver->last = 0;
4456 }
4457
4458 console_unlock();
4459 }
4460
4461 /*
4462 * If we support more console drivers, this function is used
4463 * when a driver wants to take over some existing consoles
4464 * and become default driver for newly opened ones.
4465 *
4466 * do_take_over_console is basically a register followed by bind
4467 */
do_take_over_console(const struct consw * csw,int first,int last,int deflt)4468 int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
4469 {
4470 int err;
4471
4472 err = do_register_con_driver(csw, first, last);
4473 /*
4474 * If we get an busy error we still want to bind the console driver
4475 * and return success, as we may have unbound the console driver
4476 * but not unregistered it.
4477 */
4478 if (err == -EBUSY)
4479 err = 0;
4480 if (!err)
4481 do_bind_con_driver(csw, first, last, deflt);
4482
4483 return err;
4484 }
4485 EXPORT_SYMBOL_GPL(do_take_over_console);
4486
4487
4488 /*
4489 * give_up_console is a wrapper to unregister_con_driver. It will only
4490 * work if driver is fully unbound.
4491 */
give_up_console(const struct consw * csw)4492 void give_up_console(const struct consw *csw)
4493 {
4494 console_lock();
4495 do_unregister_con_driver(csw);
4496 console_unlock();
4497 }
4498 EXPORT_SYMBOL(give_up_console);
4499
vtconsole_class_init(void)4500 static int __init vtconsole_class_init(void)
4501 {
4502 int i;
4503
4504 i = class_register(&vtconsole_class);
4505 if (i)
4506 pr_warn("Unable to create vt console class; errno = %d\n", i);
4507
4508 /* Add system drivers to sysfs */
4509 for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
4510 struct con_driver *con = ®istered_con_driver[i];
4511
4512 if (con->con && !con->dev) {
4513 con->dev =
4514 device_create_with_groups(&vtconsole_class, NULL,
4515 MKDEV(0, con->node),
4516 con, con_dev_groups,
4517 "vtcon%i", con->node);
4518
4519 if (IS_ERR(con->dev)) {
4520 pr_warn("Unable to create device for %s; errno = %ld\n",
4521 con->desc, PTR_ERR(con->dev));
4522 con->dev = NULL;
4523 } else {
4524 vtconsole_init_device(con);
4525 }
4526 }
4527 }
4528
4529 return 0;
4530 }
4531 postcore_initcall(vtconsole_class_init);
4532
4533 /*
4534 * Screen blanking
4535 */
4536
set_vesa_blanking(u8 __user * mode_user)4537 static int set_vesa_blanking(u8 __user *mode_user)
4538 {
4539 u8 mode;
4540
4541 if (get_user(mode, mode_user))
4542 return -EFAULT;
4543
4544 console_lock();
4545 vesa_blank_mode = (mode <= VESA_BLANK_MAX) ? mode : VESA_NO_BLANKING;
4546 console_unlock();
4547
4548 return 0;
4549 }
4550
do_blank_screen(int entering_gfx)4551 void do_blank_screen(int entering_gfx)
4552 {
4553 struct vc_data *vc = vc_cons[fg_console].d;
4554 int i;
4555
4556 might_sleep();
4557
4558 WARN_CONSOLE_UNLOCKED();
4559
4560 if (console_blanked) {
4561 if (blank_state == blank_vesa_wait) {
4562 blank_state = blank_off;
4563 vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0);
4564 }
4565 return;
4566 }
4567
4568 /* entering graphics mode? */
4569 if (entering_gfx) {
4570 hide_cursor(vc);
4571 save_screen(vc);
4572 vc->vc_sw->con_blank(vc, VESA_VSYNC_SUSPEND, 1);
4573 console_blanked = fg_console + 1;
4574 blank_state = blank_off;
4575 set_origin(vc);
4576 return;
4577 }
4578
4579 blank_state = blank_off;
4580
4581 /* don't blank graphics */
4582 if (vc->vc_mode != KD_TEXT) {
4583 console_blanked = fg_console + 1;
4584 return;
4585 }
4586
4587 hide_cursor(vc);
4588 timer_delete_sync(&console_timer);
4589 blank_timer_expired = 0;
4590
4591 save_screen(vc);
4592 /* In case we need to reset origin, blanking hook returns 1 */
4593 i = vc->vc_sw->con_blank(vc, vesa_off_interval ? VESA_VSYNC_SUSPEND :
4594 (vesa_blank_mode + 1), 0);
4595 console_blanked = fg_console + 1;
4596 if (i)
4597 set_origin(vc);
4598
4599 if (console_blank_hook && console_blank_hook(1))
4600 return;
4601
4602 if (vesa_off_interval && vesa_blank_mode) {
4603 blank_state = blank_vesa_wait;
4604 mod_timer(&console_timer, jiffies + vesa_off_interval);
4605 }
4606 vt_event_post(VT_EVENT_BLANK, vc->vc_num, vc->vc_num);
4607 }
4608 EXPORT_SYMBOL(do_blank_screen);
4609
4610 /*
4611 * Called by timer as well as from vt_console_driver
4612 */
do_unblank_screen(int leaving_gfx)4613 void do_unblank_screen(int leaving_gfx)
4614 {
4615 struct vc_data *vc;
4616
4617 /* This should now always be called from a "sane" (read: can schedule)
4618 * context for the sake of the low level drivers, except in the special
4619 * case of oops_in_progress
4620 */
4621 if (!oops_in_progress)
4622 might_sleep();
4623
4624 WARN_CONSOLE_UNLOCKED();
4625
4626 ignore_poke = 0;
4627 if (!console_blanked)
4628 return;
4629 if (!vc_cons_allocated(fg_console)) {
4630 /* impossible */
4631 pr_warn("unblank_screen: tty %d not allocated ??\n",
4632 fg_console + 1);
4633 return;
4634 }
4635 vc = vc_cons[fg_console].d;
4636 if (vc->vc_mode != KD_TEXT)
4637 return; /* but leave console_blanked != 0 */
4638
4639 if (blankinterval) {
4640 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
4641 blank_state = blank_normal_wait;
4642 }
4643
4644 console_blanked = 0;
4645 if (vc->vc_sw->con_blank(vc, VESA_NO_BLANKING, leaving_gfx))
4646 /* Low-level driver cannot restore -> do it ourselves */
4647 update_screen(vc);
4648 if (console_blank_hook)
4649 console_blank_hook(0);
4650 set_palette(vc);
4651 set_cursor(vc);
4652 vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
4653 }
4654 EXPORT_SYMBOL(do_unblank_screen);
4655
4656 /*
4657 * This is called by the outside world to cause a forced unblank, mostly for
4658 * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
4659 * call it with 1 as an argument and so force a mode restore... that may kill
4660 * X or at least garbage the screen but would also make the Oops visible...
4661 */
unblank_screen(void)4662 static void unblank_screen(void)
4663 {
4664 do_unblank_screen(0);
4665 }
4666
4667 /*
4668 * We defer the timer blanking to work queue so it can take the console mutex
4669 * (console operations can still happen at irq time, but only from printk which
4670 * has the console mutex. Not perfect yet, but better than no locking
4671 */
blank_screen_t(struct timer_list * unused)4672 static void blank_screen_t(struct timer_list *unused)
4673 {
4674 blank_timer_expired = 1;
4675 schedule_work(&console_work);
4676 }
4677
poke_blanked_console(void)4678 void poke_blanked_console(void)
4679 {
4680 WARN_CONSOLE_UNLOCKED();
4681
4682 /* Add this so we quickly catch whoever might call us in a non
4683 * safe context. Nowadays, unblank_screen() isn't to be called in
4684 * atomic contexts and is allowed to schedule (with the special case
4685 * of oops_in_progress, but that isn't of any concern for this
4686 * function. --BenH.
4687 */
4688 might_sleep();
4689
4690 /* This isn't perfectly race free, but a race here would be mostly harmless,
4691 * at worst, we'll do a spurious blank and it's unlikely
4692 */
4693 timer_delete(&console_timer);
4694 blank_timer_expired = 0;
4695
4696 if (ignore_poke || !vc_cons[fg_console].d || vc_cons[fg_console].d->vc_mode == KD_GRAPHICS)
4697 return;
4698 if (console_blanked)
4699 unblank_screen();
4700 else if (blankinterval) {
4701 mod_timer(&console_timer, jiffies + (blankinterval * HZ));
4702 blank_state = blank_normal_wait;
4703 }
4704 }
4705
4706 /*
4707 * Palettes
4708 */
4709
set_palette(struct vc_data * vc)4710 static void set_palette(struct vc_data *vc)
4711 {
4712 WARN_CONSOLE_UNLOCKED();
4713
4714 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_set_palette)
4715 vc->vc_sw->con_set_palette(vc, color_table);
4716 }
4717
4718 /*
4719 * Load palette into the DAC registers. arg points to a colour
4720 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
4721 */
4722
con_set_cmap(unsigned char __user * arg)4723 int con_set_cmap(unsigned char __user *arg)
4724 {
4725 int i, j, k;
4726 unsigned char colormap[3*16];
4727
4728 if (copy_from_user(colormap, arg, sizeof(colormap)))
4729 return -EFAULT;
4730
4731 console_lock();
4732 for (i = k = 0; i < 16; i++) {
4733 default_red[i] = colormap[k++];
4734 default_grn[i] = colormap[k++];
4735 default_blu[i] = colormap[k++];
4736 }
4737 for (i = 0; i < MAX_NR_CONSOLES; i++) {
4738 if (!vc_cons_allocated(i))
4739 continue;
4740 for (j = k = 0; j < 16; j++) {
4741 vc_cons[i].d->vc_palette[k++] = default_red[j];
4742 vc_cons[i].d->vc_palette[k++] = default_grn[j];
4743 vc_cons[i].d->vc_palette[k++] = default_blu[j];
4744 }
4745 set_palette(vc_cons[i].d);
4746 }
4747 console_unlock();
4748
4749 return 0;
4750 }
4751
con_get_cmap(unsigned char __user * arg)4752 int con_get_cmap(unsigned char __user *arg)
4753 {
4754 int i, k;
4755 unsigned char colormap[3*16];
4756
4757 console_lock();
4758 for (i = k = 0; i < 16; i++) {
4759 colormap[k++] = default_red[i];
4760 colormap[k++] = default_grn[i];
4761 colormap[k++] = default_blu[i];
4762 }
4763 console_unlock();
4764
4765 if (copy_to_user(arg, colormap, sizeof(colormap)))
4766 return -EFAULT;
4767
4768 return 0;
4769 }
4770
reset_palette(struct vc_data * vc)4771 void reset_palette(struct vc_data *vc)
4772 {
4773 int j, k;
4774 for (j=k=0; j<16; j++) {
4775 vc->vc_palette[k++] = default_red[j];
4776 vc->vc_palette[k++] = default_grn[j];
4777 vc->vc_palette[k++] = default_blu[j];
4778 }
4779 set_palette(vc);
4780 }
4781
4782 /*
4783 * Font switching
4784 *
4785 * Currently we only support fonts up to 128 pixels wide, at a maximum height
4786 * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes
4787 * (shorts/ints, depending on width) reserved for each character which is
4788 * kinda wasty, but this is done in order to maintain compatibility with the
4789 * EGA/VGA fonts. It is up to the actual low-level console-driver convert data
4790 * into its favorite format (maybe we should add a `fontoffset' field to the
4791 * `display' structure so we won't have to convert the fontdata all the time.
4792 * /Jes
4793 */
4794
4795 #define max_font_width 64
4796 #define max_font_height 128
4797 #define max_font_glyphs 512
4798 #define max_font_size (max_font_glyphs*max_font_width*max_font_height)
4799
con_font_get(struct vc_data * vc,struct console_font_op * op)4800 static int con_font_get(struct vc_data *vc, struct console_font_op *op)
4801 {
4802 struct console_font font;
4803 int rc = -EINVAL;
4804 int c;
4805 unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32;
4806
4807 if (vpitch > max_font_height)
4808 return -EINVAL;
4809
4810 if (op->data) {
4811 font.data = kvzalloc(max_font_size, GFP_KERNEL);
4812 if (!font.data)
4813 return -ENOMEM;
4814 } else
4815 font.data = NULL;
4816
4817 console_lock();
4818 if (vc->vc_mode != KD_TEXT)
4819 rc = -EINVAL;
4820 else if (vc->vc_sw->con_font_get)
4821 rc = vc->vc_sw->con_font_get(vc, &font, vpitch);
4822 else
4823 rc = -ENOSYS;
4824 console_unlock();
4825
4826 if (rc)
4827 goto out;
4828
4829 c = (font.width+7)/8 * vpitch * font.charcount;
4830
4831 if (op->data && font.charcount > op->charcount)
4832 rc = -ENOSPC;
4833 if (font.width > op->width || font.height > op->height)
4834 rc = -ENOSPC;
4835 if (rc)
4836 goto out;
4837
4838 op->height = font.height;
4839 op->width = font.width;
4840 op->charcount = font.charcount;
4841
4842 if (op->data && copy_to_user(op->data, font.data, c))
4843 rc = -EFAULT;
4844
4845 out:
4846 kvfree(font.data);
4847 return rc;
4848 }
4849
con_font_set(struct vc_data * vc,const struct console_font_op * op)4850 static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
4851 {
4852 struct console_font font;
4853 int rc = -EINVAL;
4854 int size;
4855 unsigned int vpitch = op->op == KD_FONT_OP_SET_TALL ? op->height : 32;
4856
4857 if (vc->vc_mode != KD_TEXT)
4858 return -EINVAL;
4859 if (!op->data)
4860 return -EINVAL;
4861 if (op->charcount > max_font_glyphs)
4862 return -EINVAL;
4863 if (op->width <= 0 || op->width > max_font_width || !op->height ||
4864 op->height > max_font_height)
4865 return -EINVAL;
4866 if (vpitch < op->height)
4867 return -EINVAL;
4868 size = (op->width+7)/8 * vpitch * op->charcount;
4869 if (size > max_font_size)
4870 return -ENOSPC;
4871
4872 font.data = memdup_user(op->data, size);
4873 if (IS_ERR(font.data))
4874 return PTR_ERR(font.data);
4875
4876 font.charcount = op->charcount;
4877 font.width = op->width;
4878 font.height = op->height;
4879
4880 console_lock();
4881 if (vc->vc_mode != KD_TEXT)
4882 rc = -EINVAL;
4883 else if (vc->vc_sw->con_font_set) {
4884 if (vc_is_sel(vc))
4885 clear_selection();
4886 rc = vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags);
4887 } else
4888 rc = -ENOSYS;
4889 console_unlock();
4890 kfree(font.data);
4891 return rc;
4892 }
4893
con_font_default(struct vc_data * vc,struct console_font_op * op)4894 static int con_font_default(struct vc_data *vc, struct console_font_op *op)
4895 {
4896 struct console_font font = {.width = op->width, .height = op->height};
4897 char name[MAX_FONT_NAME];
4898 char *s = name;
4899 int rc;
4900
4901
4902 if (!op->data)
4903 s = NULL;
4904 else if (strncpy_from_user(name, op->data, MAX_FONT_NAME - 1) < 0)
4905 return -EFAULT;
4906 else
4907 name[MAX_FONT_NAME - 1] = 0;
4908
4909 console_lock();
4910 if (vc->vc_mode != KD_TEXT) {
4911 console_unlock();
4912 return -EINVAL;
4913 }
4914 if (vc->vc_sw->con_font_default) {
4915 if (vc_is_sel(vc))
4916 clear_selection();
4917 rc = vc->vc_sw->con_font_default(vc, &font, s);
4918 } else
4919 rc = -ENOSYS;
4920 console_unlock();
4921 if (!rc) {
4922 op->width = font.width;
4923 op->height = font.height;
4924 }
4925 return rc;
4926 }
4927
con_font_op(struct vc_data * vc,struct console_font_op * op)4928 int con_font_op(struct vc_data *vc, struct console_font_op *op)
4929 {
4930 switch (op->op) {
4931 case KD_FONT_OP_SET:
4932 case KD_FONT_OP_SET_TALL:
4933 return con_font_set(vc, op);
4934 case KD_FONT_OP_GET:
4935 case KD_FONT_OP_GET_TALL:
4936 return con_font_get(vc, op);
4937 case KD_FONT_OP_SET_DEFAULT:
4938 return con_font_default(vc, op);
4939 case KD_FONT_OP_COPY:
4940 /* was buggy and never really used */
4941 return -EINVAL;
4942 }
4943 return -ENOSYS;
4944 }
4945
4946 /*
4947 * Interface exported to selection and vcs.
4948 */
4949
4950 /* used by selection */
screen_glyph(const struct vc_data * vc,int offset)4951 u16 screen_glyph(const struct vc_data *vc, int offset)
4952 {
4953 u16 w = scr_readw(screenpos(vc, offset, true));
4954 u16 c = w & 0xff;
4955
4956 if (w & vc->vc_hi_font_mask)
4957 c |= 0x100;
4958 return c;
4959 }
4960 EXPORT_SYMBOL_GPL(screen_glyph);
4961
screen_glyph_unicode(const struct vc_data * vc,int n)4962 u32 screen_glyph_unicode(const struct vc_data *vc, int n)
4963 {
4964 u32 **uni_lines = vc->vc_uni_lines;
4965
4966 if (uni_lines)
4967 return uni_lines[n / vc->vc_cols][n % vc->vc_cols];
4968
4969 return inverse_translate(vc, screen_glyph(vc, n * 2), true);
4970 }
4971 EXPORT_SYMBOL_GPL(screen_glyph_unicode);
4972
4973 /* used by vcs - note the word offset */
screen_pos(const struct vc_data * vc,int w_offset,bool viewed)4974 unsigned short *screen_pos(const struct vc_data *vc, int w_offset, bool viewed)
4975 {
4976 return screenpos(vc, 2 * w_offset, viewed);
4977 }
4978 EXPORT_SYMBOL_GPL(screen_pos);
4979
getconsxy(const struct vc_data * vc,unsigned char xy[static2])4980 void getconsxy(const struct vc_data *vc, unsigned char xy[static 2])
4981 {
4982 /* clamp values if they don't fit */
4983 xy[0] = min(vc->state.x, 0xFFu);
4984 xy[1] = min(vc->state.y, 0xFFu);
4985 }
4986
putconsxy(struct vc_data * vc,unsigned char xy[static const2])4987 void putconsxy(struct vc_data *vc, unsigned char xy[static const 2])
4988 {
4989 hide_cursor(vc);
4990 gotoxy(vc, xy[0], xy[1]);
4991 set_cursor(vc);
4992 }
4993
vcs_scr_readw(const struct vc_data * vc,const u16 * org)4994 u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org)
4995 {
4996 if ((unsigned long)org == vc->vc_pos && softcursor_original != -1)
4997 return softcursor_original;
4998 return scr_readw(org);
4999 }
5000
vcs_scr_writew(struct vc_data * vc,u16 val,u16 * org)5001 void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
5002 {
5003 scr_writew(val, org);
5004 if ((unsigned long)org == vc->vc_pos) {
5005 softcursor_original = -1;
5006 add_softcursor(vc);
5007 }
5008 }
5009
vcs_scr_updated(struct vc_data * vc)5010 void vcs_scr_updated(struct vc_data *vc)
5011 {
5012 notify_update(vc);
5013 }
5014