linux/drivers/tty/vt/vt.c

// SPDX-License-Identifier: GPL-2.0
/*
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

/*
 * Hopefully this will be a rather complete VT102 implementation.
 *
 * Beeping thanks to John T Kohl.
 *
 * Virtual Consoles, Screen Blanking, Screen Dumping, Color, Graphics
 *   Chars, and VT100 enhancements by Peter MacDonald.
 *
 * Copy and paste function by Andrew Haylett,
 *   some enhancements by Alessandro Rubini.
 *
 * Code to check for different video-cards mostly by Galen Hunt,
 * <[email protected]>
 *
 * Rudimentary ISO 10646/Unicode/UTF-8 character set support by
 * Markus Kuhn, <[email protected]>.
 *
 * Dynamic allocation of consoles, [email protected], May 1994
 * Resizing of consoles, aeb, 940926
 *
 * Code for xterm like mouse click reporting by Peter Orbaek 20-Jul-94
 * <[email protected]>
 *
 * User-defined bell sound, new setterm control sequences and printk
 * redirection by Martin Mares <[email protected]> 19-Nov-95
 *
 * APM screenblank bug fixed Takashi Manabe <[email protected]>
 *
 * Merge with the abstract console driver by Geert Uytterhoeven
 * <[email protected]>, Jan 1997.
 *
 *   Original m68k console driver modifications by
 *
 *     - Arno Griffioen <[email protected]>
 *     - David Carter <[email protected]>
 * 
 *   The abstract console driver provides a generic interface for a text
 *   console. It supports VGA text mode, frame buffer based graphical consoles
 *   and special graphics processors that are only accessible through some
 *   registers (e.g. a TMS340x0 GSP).
 *
 *   The interface to the hardware is specified using a special structure
 *   (struct consw) which contains function pointers to console operations
 *   (see <linux/console.h> for more information).
 *
 * Support for changeable cursor shape
 * by Pavel Machek <[email protected]>, August 1997
 *
 * Ported to i386 and con_scrolldelta fixed
 * by Emmanuel Marty <[email protected]>, April 1998
 *
 * Resurrected character buffers in videoram plus lots of other trickery
 * by Martin Mares <[email protected]>, July 1998
 *
 * Removed old-style timers, introduced console_timer, made timer
 * deletion SMP-safe.  17Jun00, Andrew Morton
 *
 * Removed console_lock, enabled interrupts across all console operations
 * 13 March 2001, Andrew Morton
 *
 * Fixed UTF-8 mode so alternate charset modes always work according
 * to control sequences interpreted in do_con_trol function
 * preserving backward VT100 semigraphics compatibility,
 * malformed UTF sequences represented as sequences of replacement glyphs,
 * original codes or '?' as a last resort if replacement glyph is undefined
 * by Adam Tla/lka <[email protected]>, Aug 2006
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched/signal.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kd.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/major.h>
#include <linux/mm.h>
#include <linux/console.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
#include <linux/tiocl.h>
#include <linux/kbd_kern.h>
#include <linux/consolemap.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/pm.h>
#include <linux/font.h>
#include <linux/bitops.h>
#include <linux/notifier.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/kdb.h>
#include <linux/ctype.h>
#include <linux/bsearch.h>
#include <linux/gcd.h>

#define MAX_NR_CON_DRIVER

#define CON_DRIVER_FLAG_MODULE
#define CON_DRIVER_FLAG_INIT
#define CON_DRIVER_FLAG_ATTR
#define CON_DRIVER_FLAG_ZOMBIE

struct con_driver {};

static struct con_driver registered_con_driver[MAX_NR_CON_DRIVER];
const struct consw *conswitchp;

/*
 * Here is the default bell parameters: 750HZ, 1/8th of a second
 */
#define DEFAULT_BELL_PITCH
#define DEFAULT_BELL_DURATION
#define DEFAULT_CURSOR_BLINK_MS

struct vc vc_cons [MAX_NR_CONSOLES];
EXPORT_SYMBOL();

static const struct consw *con_driver_map[MAX_NR_CONSOLES];

static int con_open(struct tty_struct *, struct file *);
static void vc_init(struct vc_data *vc, int do_clear);
static void gotoxy(struct vc_data *vc, int new_x, int new_y);
static void save_cur(struct vc_data *vc);
static void reset_terminal(struct vc_data *vc, int do_clear);
static void con_flush_chars(struct tty_struct *tty);
static int set_vesa_blanking(u8 __user *mode);
static void set_cursor(struct vc_data *vc);
static void hide_cursor(struct vc_data *vc);
static void console_callback(struct work_struct *ignored);
static void con_driver_unregister_callback(struct work_struct *ignored);
static void blank_screen_t(struct timer_list *unused);
static void set_palette(struct vc_data *vc);
static void unblank_screen(void);

#define vt_get_kmsg_redirect()

int default_utf8 =;
module_param(default_utf8, int, S_IRUGO | S_IWUSR);
int global_cursor_default =;
module_param(global_cursor_default, int, S_IRUGO | S_IWUSR);
EXPORT_SYMBOL();

static int cur_default =;
module_param(cur_default, int, S_IRUGO | S_IWUSR);

/*
 * ignore_poke: don't unblank the screen when things are typed.  This is
 * mainly for the privacy of braille terminal users.
 */
static int ignore_poke;

int do_poke_blanked_console;
int console_blanked;
EXPORT_SYMBOL();

static enum vesa_blank_mode vesa_blank_mode;
static int vesa_off_interval;
static int blankinterval;
core_param();

static DECLARE_WORK(console_work, console_callback);
static DECLARE_WORK(con_driver_unregister_work, con_driver_unregister_callback);

/*
 * fg_console is the current virtual console,
 * last_console is the last used one,
 * want_console is the console we want to switch to,
 * saved_* variants are for save/restore around kernel debugger enter/leave
 */
int fg_console;
EXPORT_SYMBOL();
int last_console;
int want_console =;

static int saved_fg_console;
static int saved_last_console;
static int saved_want_console;
static int saved_vc_mode;
static int saved_console_blanked;

/*
 * For each existing display, we have a pointer to console currently visible
 * on that display, allowing consoles other than fg_console to be refreshed
 * appropriately. Unless the low-level driver supplies its own display_fg
 * variable, we use this one for the "master display".
 */
static struct vc_data *master_display_fg;

/*
 * Unfortunately, we need to delay tty echo when we're currently writing to the
 * console since the code is (and always was) not re-entrant, so we schedule
 * all flip requests to process context with schedule-task() and run it from
 * console_callback().
 */

/*
 * For the same reason, we defer scrollback to the console callback.
 */
static int scrollback_delta;

/*
 * Hook so that the power management routines can (un)blank
 * the console on our behalf.
 */
int (*console_blank_hook)(int);
EXPORT_SYMBOL();

static DEFINE_TIMER(console_timer, blank_screen_t);
static int blank_state;
static int blank_timer_expired;
enum {};

/*
 * /sys/class/tty/tty0/
 *
 * the attribute 'active' contains the name of the current vc
 * console and it supports poll() to detect vc switches
 */
static struct device *tty0dev;

/*
 * Notifier list for console events.
 */
static ATOMIC_NOTIFIER_HEAD(vt_notifier_list);

int register_vt_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL_GPL();

int unregister_vt_notifier(struct notifier_block *nb)
{}
EXPORT_SYMBOL_GPL();

static void notify_write(struct vc_data *vc, unsigned int unicode)
{}

static void notify_update(struct vc_data *vc)
{}
/*
 *	Low-Level Functions
 */

static inline bool con_is_fg(const struct vc_data *vc)
{}

static inline bool con_should_update(const struct vc_data *vc)
{}

static inline u16 *screenpos(const struct vc_data *vc, unsigned int offset,
			     bool viewed)
{}

static void con_putc(struct vc_data *vc, u16 ca, unsigned int y, unsigned int x)
{}

/* Called  from the keyboard irq path.. */
static inline void scrolldelta(int lines)
{}

void schedule_console_callback(void)
{}

/*
 * Code to manage unicode-based screen buffers
 */

/*
 * Our screen buffer is preceded by an array of line pointers so that
 * scrolling only implies some pointer shuffling.
 */

static u32 **vc_uniscr_alloc(unsigned int cols, unsigned int rows)
{}

static void vc_uniscr_free(u32 **uni_lines)
{}

static void vc_uniscr_set(struct vc_data *vc, u32 **new_uni_lines)
{}

static void vc_uniscr_putc(struct vc_data *vc, u32 uc)
{}

static void vc_uniscr_insert(struct vc_data *vc, unsigned int nr)
{}

static void vc_uniscr_delete(struct vc_data *vc, unsigned int nr)
{}

static void vc_uniscr_clear_line(struct vc_data *vc, unsigned int x,
				 unsigned int nr)
{}

static void vc_uniscr_clear_lines(struct vc_data *vc, unsigned int y,
				  unsigned int nr)
{}

/* juggling array rotation algorithm (complexity O(N), size complexity O(1)) */
static void juggle_array(u32 **array, unsigned int size, unsigned int nr)
{}

static void vc_uniscr_scroll(struct vc_data *vc, unsigned int top,
			     unsigned int bottom, enum con_scroll dir,
			     unsigned int nr)
{}

static void 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)
{}

/*
 * Called from vcs_read() to make sure unicode screen retrieval is possible.
 * This will initialize the unicode screen buffer if not already done.
 * This returns 0 if OK, or a negative error code otherwise.
 * In particular, -ENODATA is returned if the console is not in UTF-8 mode.
 */
int vc_uniscr_check(struct vc_data *vc)
{}

/*
 * Called from vcs_read() to get the unicode data from the screen.
 * This must be preceded by a successful call to vc_uniscr_check() once
 * the console lock has been taken.
 */
void vc_uniscr_copy_line(const struct vc_data *vc, void *dest, bool viewed,
			 unsigned int row, unsigned int col, unsigned int nr)
{}

static void con_scroll(struct vc_data *vc, unsigned int top,
		       unsigned int bottom, enum con_scroll dir,
		       unsigned int nr)
{}

static void do_update_region(struct vc_data *vc, unsigned long start, int count)
{}

void update_region(struct vc_data *vc, unsigned long start, int count)
{}
EXPORT_SYMBOL();

/* Structure of attributes is hardware-dependent */

static u8 build_attr(struct vc_data *vc, u8 _color,
		enum vc_intensity _intensity, bool _blink, bool _underline,
		bool _reverse, bool _italic)
{}

static void update_attr(struct vc_data *vc)
{}

/* Note: inverting the screen twice should revert to the original state */
void invert_screen(struct vc_data *vc, int offset, int count, bool viewed)
{}

/* used by selection: complement pointer position */
void complement_pos(struct vc_data *vc, int offset)
{}

static void insert_char(struct vc_data *vc, unsigned int nr)
{}

static void delete_char(struct vc_data *vc, unsigned int nr)
{}

static int softcursor_original =;

static void add_softcursor(struct vc_data *vc)
{}

static void hide_softcursor(struct vc_data *vc)
{}

static void hide_cursor(struct vc_data *vc)
{}

static void set_cursor(struct vc_data *vc)
{}

static void set_origin(struct vc_data *vc)
{}

static void save_screen(struct vc_data *vc)
{}

static void flush_scrollback(struct vc_data *vc)
{}

/*
 *	Redrawing of screen
 */

void clear_buffer_attributes(struct vc_data *vc)
{}

void redraw_screen(struct vc_data *vc, int is_switch)
{}
EXPORT_SYMBOL();

/*
 *	Allocation, freeing and resizing of VTs.
 */

int vc_cons_allocated(unsigned int i)
{}

static void visual_init(struct vc_data *vc, int num, bool init)
{}


static void visual_deinit(struct vc_data *vc)
{}

static void vc_port_destruct(struct tty_port *port)
{}

static const struct tty_port_operations vc_port_ops =;

/*
 * Change # of rows and columns (0 means unchanged/the size of fg_console)
 * [this is to be used together with some user program
 * like resize that changes the hardware videomode]
 */
#define VC_MAXCOL
#define VC_MAXROW

int vc_allocate(unsigned int currcons)	/* return 0 on success */
{}

static inline int resize_screen(struct vc_data *vc, int width, int height,
				bool from_user)
{}

/**
 * vc_do_resize - resizing method for the tty
 * @tty: tty being resized
 * @vc: virtual console private data
 * @cols: columns
 * @lines: lines
 * @from_user: invoked by a user?
 *
 * Resize a virtual console, clipping according to the actual constraints. If
 * the caller passes a tty structure then update the termios winsize
 * information and perform any necessary signal handling.
 *
 * Locking: Caller must hold the console semaphore. Takes the termios rwsem and
 * ctrl.lock of the tty IFF a tty is passed.
 */
static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
			unsigned int cols, unsigned int lines, bool from_user)
{}

/**
 * __vc_resize - resize a VT
 * @vc: virtual console
 * @cols: columns
 * @rows: rows
 * @from_user: invoked by a user?
 *
 * Resize a virtual console as seen from the console end of things. We use the
 * common vc_do_resize() method to update the structures.
 *
 * Locking: The caller must hold the console sem to protect console internals
 * and @vc->port.tty.
 */
int __vc_resize(struct vc_data *vc, unsigned int cols, unsigned int rows,
		bool from_user)
{}
EXPORT_SYMBOL();

/**
 * vt_resize - resize a VT
 * @tty: tty to resize
 * @ws: winsize attributes
 *
 * Resize a virtual terminal. This is called by the tty layer as we register
 * our own handler for resizing. The mutual helper does all the actual work.
 *
 * Locking: Takes the console sem and the called methods then take the tty
 * termios_rwsem and the tty ctrl.lock in that order.
 */
static int vt_resize(struct tty_struct *tty, struct winsize *ws)
{}

struct vc_data *vc_deallocate(unsigned int currcons)
{}

/*
 *	VT102 emulator
 */

enum {};

#define set_kbd(vc, x)
#define clr_kbd(vc, x)
#define is_kbd(vc, x)

#define decarm
#define decckm
#define kbdapplic
#define lnm

const unsigned char color_table[] =;
EXPORT_SYMBOL();

/* the default colour table, for VGA+ colour systems */
unsigned char default_red[] =;
module_param_array();
EXPORT_SYMBOL();

unsigned char default_grn[] =;
module_param_array();
EXPORT_SYMBOL();

unsigned char default_blu[] =;
module_param_array();
EXPORT_SYMBOL();

/*
 * gotoxy() must verify all boundaries, because the arguments
 * might also be negative. If the given position is out of
 * bounds, the cursor is placed at the nearest margin.
 */
static void gotoxy(struct vc_data *vc, int new_x, int new_y)
{}

/* for absolute user moves, when decom is set */
static void gotoxay(struct vc_data *vc, int new_x, int new_y)
{}

void scrollback(struct vc_data *vc)
{}

void scrollfront(struct vc_data *vc, int lines)
{}

static void lf(struct vc_data *vc)
{}

static void ri(struct vc_data *vc)
{}

static inline void cr(struct vc_data *vc)
{}

static inline void bs(struct vc_data *vc)
{}

static inline void del(struct vc_data *vc)
{}

enum CSI_J {};

static void csi_J(struct vc_data *vc, enum CSI_J vpar)
{}

enum {};

static void csi_K(struct vc_data *vc)
{}

/* erase the following count positions */
static void csi_X(struct vc_data *vc)
{}

static void default_attr(struct vc_data *vc)
{}

struct rgb {};

static void rgb_from_256(unsigned int i, struct rgb *c)
{}

static void rgb_foreground(struct vc_data *vc, const struct rgb *c)
{}

static void rgb_background(struct vc_data *vc, const struct rgb *c)
{}

/*
 * ITU T.416 Higher colour modes. They break the usual properties of SGR codes
 * and thus need to be detected and ignored by hand. That standard also
 * wants : rather than ; as separators but sequences containing : are currently
 * completely ignored by the parser.
 *
 * Subcommands 3 (CMY) and 4 (CMYK) are so insane there's no point in
 * supporting them.
 */
static int vc_t416_color(struct vc_data *vc, int i,
		void(*set_color)(struct vc_data *vc, const struct rgb *c))
{}

enum {};

/* console_lock is held */
static void csi_m(struct vc_data *vc)
{}

static void respond_string(const char *p, size_t len, struct tty_port *port)
{}

static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
{}

static inline void status_report(struct tty_struct *tty)
{}

static inline void respond_ID(struct tty_struct *tty)
{}

void mouse_report(struct tty_struct *tty, int butt, int mrx, int mry)
{}

/* invoked via ioctl(TIOCLINUX) and through set_selection_user */
int mouse_reporting(void)
{}

enum {};

/* console_lock is held */
static void csi_DEC_hl(struct vc_data *vc, bool on_off)
{}

enum {};

/* console_lock is held */
static void csi_hl(struct vc_data *vc, bool on_off)
{}

enum CSI_right_square_bracket {};

/*
 * csi_RSB - csi+] (Right Square Bracket) handler
 *
 * These are linux console private sequences.
 *
 * console_lock is held
 */
static void csi_RSB(struct vc_data *vc)
{}

/* console_lock is held */
static void csi_at(struct vc_data *vc, unsigned int nr)
{}

/* console_lock is held */
static void csi_L(struct vc_data *vc)
{}

/* console_lock is held */
static void csi_P(struct vc_data *vc)
{}

/* console_lock is held */
static void csi_M(struct vc_data *vc)
{}

/* console_lock is held (except via vc_init->reset_terminal */
static void save_cur(struct vc_data *vc)
{}

/* console_lock is held */
static void restore_cur(struct vc_data *vc)
{}

/**
 * enum vc_ctl_state - control characters state of a vt
 *
 * @ESnormal:		initial state, no control characters parsed
 * @ESesc:		ESC parsed
 * @ESsquare:		CSI parsed -- modifiers/parameters/ctrl chars expected
 * @ESgetpars:		CSI parsed -- parameters/ctrl chars expected
 * @ESfunckey:		CSI [ parsed
 * @EShash:		ESC # parsed
 * @ESsetG0:		ESC ( parsed
 * @ESsetG1:		ESC ) parsed
 * @ESpercent:		ESC % parsed
 * @EScsiignore:	CSI [0x20-0x3f] parsed
 * @ESnonstd:		OSC parsed
 * @ESpalette:		OSC P parsed
 * @ESosc:		OSC [0-9] parsed
 * @ESANSI_first:	first state for ignoring ansi control sequences
 * @ESapc:		ESC _ parsed
 * @ESpm:		ESC ^ parsed
 * @ESdcs:		ESC P parsed
 * @ESANSI_last:	last state for ignoring ansi control sequences
 */
enum vc_ctl_state {};

/* console_lock is held (except via vc_init()) */
static void reset_terminal(struct vc_data *vc, int do_clear)
{}

static void vc_setGx(struct vc_data *vc, unsigned int which, u8 c)
{}

static bool ansi_control_string(enum vc_ctl_state state)
{}

enum {};

/*
 * Handle ascii characters in control sequences and change states accordingly.
 * E.g. ESC sets the state of vc to ESesc.
 *
 * Returns: true if @c handled.
 */
static bool handle_ascii(struct tty_struct *tty, struct vc_data *vc, u8 c)
{}

/*
 * Handle a character (@c) following an ESC (when @vc is in the ESesc state).
 * E.g. previous ESC with @c == '[' here yields the ESsquare state (that is:
 * CSI).
 */
static void handle_esc(struct tty_struct *tty, struct vc_data *vc, u8 c)
{}

/*
 * Handle special DEC control sequences ("ESC [ ? parameters char"). Parameters
 * are in @vc->vc_par and the char is in @c here.
 */
static void csi_DEC(struct tty_struct *tty, struct vc_data *vc, u8 c)
{}

/*
 * Handle Control Sequence Introducer control characters. That is
 * "ESC [ parameters char". Parameters are in @vc->vc_par and the char is in
 * @c here.
 */
static void csi_ECMA(struct tty_struct *tty, struct vc_data *vc, u8 c)
{}

static void vc_reset_params(struct vc_data *vc)
{}

/* console_lock is held */
static void do_con_trol(struct tty_struct *tty, struct vc_data *vc, u8 c)
{}

/* is_double_width() is based on the wcwidth() implementation by
 * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
 * Latest version: https://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
 */
struct interval {};

static int ucs_cmp(const void *key, const void *elt)
{}

static int is_double_width(uint32_t ucs)
{}

struct vc_draw_region {};

static void con_flush(struct vc_data *vc, struct vc_draw_region *draw)
{}

static inline int vc_translate_ascii(const struct vc_data *vc, int c)
{}


/**
 * vc_sanitize_unicode - Replace invalid Unicode code points with ``U+FFFD``
 * @c: the received code point
 */
static inline int vc_sanitize_unicode(const int c)
{}

/**
 * vc_translate_unicode - Combine UTF-8 into Unicode in &vc_data.vc_utf_char
 * @vc: virtual console
 * @c: UTF-8 byte to translate
 * @rescan: set to true iff @c wasn't consumed here and needs to be re-processed
 *
 * * &vc_data.vc_utf_char is the being-constructed Unicode code point.
 * * &vc_data.vc_utf_count is the number of continuation bytes still expected to
 *   arrive.
 * * &vc_data.vc_npar is the number of continuation bytes arrived so far.
 *
 * Return:
 * * %-1 - Input OK so far, @c consumed, further bytes expected.
 * * %0xFFFD - Possibility 1: input invalid, @c may have been consumed (see
 *             desc. of @rescan). Possibility 2: input OK, @c consumed,
 *             ``U+FFFD`` is the resulting code point. ``U+FFFD`` is valid,
 *             ``REPLACEMENT CHARACTER``.
 * * otherwise - Input OK, @c consumed, resulting code point returned.
 */
static int vc_translate_unicode(struct vc_data *vc, int c, bool *rescan)
{}

static int vc_translate(struct vc_data *vc, int *c, bool *rescan)
{}

static inline unsigned char vc_invert_attr(const struct vc_data *vc)
{}

static bool vc_is_control(struct vc_data *vc, int tc, int c)
{}

static int vc_con_write_normal(struct vc_data *vc, int tc, int c,
		struct vc_draw_region *draw)
{}

/* acquires console_lock */
static int do_con_write(struct tty_struct *tty, const u8 *buf, int count)
{}

/*
 * This is the console switching callback.
 *
 * Doing console switching in a process context allows
 * us to do the switches asynchronously (needed when we want
 * to switch due to a keyboard interrupt).  Synchronization
 * with other console code and prevention of re-entrancy is
 * ensured with console_lock.
 */
static void console_callback(struct work_struct *ignored)
{}

int set_console(int nr)
{}

struct tty_driver *console_driver;

#ifdef CONFIG_VT_CONSOLE

/**
 * vt_kmsg_redirect() - sets/gets the kernel message console
 * @new: the new virtual terminal number or -1 if the console should stay
 *	unchanged
 *
 * By default, the kernel messages are always printed on the current virtual
 * console. However, the user may modify that default with the
 * %TIOCL_SETKMSGREDIRECT ioctl call.
 *
 * This function sets the kernel message console to be @new. It returns the old
 * virtual console number. The virtual terminal number %0 (both as parameter and
 * return value) means no redirection (i.e. always printed on the currently
 * active console).
 *
 * The parameter -1 means that only the current console is returned, but the
 * value is not modified. You may use the macro vt_get_kmsg_redirect() in that
 * case to make the code more understandable.
 *
 * When the kernel is compiled without %CONFIG_VT_CONSOLE, this function ignores
 * the parameter and always returns %0.
 */
int vt_kmsg_redirect(int new)
{}

/*
 *	Console on virtual terminal
 *
 * The console must be locked when we get here.
 */

static void vt_console_print(struct console *co, const char *b, unsigned count)
{}

static struct tty_driver *vt_console_device(struct console *c, int *index)
{}

static int vt_console_setup(struct console *co, char *options)
{}

static struct console vt_console_driver =;
#endif

/*
 *	Handling of Linux-specific VC ioctls
 */

/*
 * Generally a bit racy with respect to console_lock();.
 *
 * There are some functions which don't need it.
 *
 * There are some functions which can sleep for arbitrary periods
 * (paste_selection) but we don't need the lock there anyway.
 *
 * set_selection_user has locking, and definitely needs it
 */

int tioclinux(struct tty_struct *tty, unsigned long arg)
{}

/*
 * /dev/ttyN handling
 */

static ssize_t con_write(struct tty_struct *tty, const u8 *buf, size_t count)
{}

static int con_put_char(struct tty_struct *tty, u8 ch)
{}

static unsigned int con_write_room(struct tty_struct *tty)
{}

/*
 * con_throttle and con_unthrottle are only used for
 * paste_selection(), which has to stuff in a large number of
 * characters...
 */
static void con_throttle(struct tty_struct *tty)
{}

static void con_unthrottle(struct tty_struct *tty)
{}

/*
 * Turn the Scroll-Lock LED on when the tty is stopped
 */
static void con_stop(struct tty_struct *tty)
{}

/*
 * Turn the Scroll-Lock LED off when the console is started
 */
static void con_start(struct tty_struct *tty)
{}

static void con_flush_chars(struct tty_struct *tty)
{}

/*
 * Allocate the console screen memory.
 */
static int con_install(struct tty_driver *driver, struct tty_struct *tty)
{}

static int con_open(struct tty_struct *tty, struct file *filp)
{}


static void con_close(struct tty_struct *tty, struct file *filp)
{}

static void con_shutdown(struct tty_struct *tty)
{}

static void con_cleanup(struct tty_struct *tty)
{}

/*
 * We can't deal with anything but the N_TTY ldisc,
 * because we can sleep in our write() routine.
 */
static int con_ldisc_ok(struct tty_struct *tty, int ldisc)
{}

static int default_color           =; /* white */
static int default_italic_color    =; // green (ASCII)
static int default_underline_color =; // cyan (ASCII)
module_param_named(color, default_color, int, S_IRUGO | S_IWUSR);
module_param_named(italic, default_italic_color, int, S_IRUGO | S_IWUSR);
module_param_named(underline, default_underline_color, int, S_IRUGO | S_IWUSR);

static void vc_init(struct vc_data *vc, int do_clear)
{}

/*
 * This routine initializes console interrupts, and does nothing
 * else. If you want the screen to clear, call tty_write with
 * the appropriate escape-sequence.
 */

static int __init con_init(void)
{}
console_initcall(con_init);

static const struct tty_operations con_ops =;

static struct cdev vc0_cdev;

static ssize_t show_tty_active(struct device *dev,
				struct device_attribute *attr, char *buf)
{}
static DEVICE_ATTR(active, S_IRUGO, show_tty_active, NULL);

static struct attribute *vt_dev_attrs[] =;

ATTRIBUTE_GROUPS();

int __init vty_init(const struct file_operations *console_fops)
{}

static const struct class vtconsole_class =;

static int do_bind_con_driver(const struct consw *csw, int first, int last,
			   int deflt)
{
	struct module *owner = csw->owner;
	const char *desc = NULL;
	struct con_driver *con_driver;
	int i, j = -1, k = -1, retval = -ENODEV;

	if (!try_module_get(owner))
		return -ENODEV;

	WARN_CONSOLE_UNLOCKED();

	/* check if driver is registered */
	for (i = 0; i < MAX_NR_CON_DRIVER; i++) {
		con_driver = &registered_con_driver[i];

		if (con_driver->con == csw) {
			desc = con_driver->desc;
			retval = 0;
			break;
		}
	}

	if (retval)
		goto err;

	if (!(con_driver->flag & CON_DRIVER_FLAG_INIT)) {
		csw->con_startup();
		con_driver->flag |= CON_DRIVER_FLAG_INIT;
	}

	if (deflt) {
		if (conswitchp)
			module_put(conswitchp->owner);

		__module_get(owner);
		conswitchp = csw;
	}

	first = max(first, con_driver->first);
	last = min(last, con_driver->last);

	for (i = first; i <= last; i++) {
		int old_was_color;
		struct vc_data *vc = vc_cons[i].d;

		if (con_driver_map[i])
			module_put(con_driver_map[i]->owner);
		__module_get(owner);
		con_driver_map[i] = csw;

		if (!vc || !vc->vc_sw)
			continue;

		j = i;

		if (con_is_visible(vc)) {
			k = i;
			save_screen(vc);
		}

		old_was_color = vc->vc_can_do_color;
		vc->vc_sw->con_deinit(vc);
		vc->vc_origin = (unsigned long)vc->vc_screenbuf;
		visual_init(vc, i, false);
		set_origin(vc);
		update_attr(vc);

		/* If the console changed between mono <-> color, then
		 * the attributes in the screenbuf will be wrong.  The
		 * following resets all attributes to something sane.
		 */
		if (old_was_color != vc->vc_can_do_color)
			clear_buffer_attributes(vc);
	}

	pr_info("Console: switching ");
	if (!deflt)
		pr_cont("consoles %d-%d ", first + 1, last + 1);
	if (j >= 0) {
		struct vc_data *vc = vc_cons[j].d;

		pr_cont("to %s %s %dx%d\n",
			vc->vc_can_do_color ? "colour" : "mono",
			desc, vc->vc_cols, vc->vc_rows);

		if (k >= 0) {
			vc = vc_cons[k].d;
			update_screen(vc);
		}
	} else {
		pr_cont("to %s\n", desc);
	}

	retval = 0;
err:
	module_put(owner);
	return retval;
};


#ifdef CONFIG_VT_HW_CONSOLE_BINDING
int do_unbind_con_driver(const struct consw *csw, int first, int last, int deflt)
{}
EXPORT_SYMBOL_GPL();

static int vt_bind(struct con_driver *con)
{}

static int vt_unbind(struct con_driver *con)
{}
#else
static inline int vt_bind(struct con_driver *con)
{
	return 0;
}
static inline int vt_unbind(struct con_driver *con)
{
	return 0;
}
#endif /* CONFIG_VT_HW_CONSOLE_BINDING */

static ssize_t store_bind(struct device *dev, struct device_attribute *attr,
			  const char *buf, size_t count)
{}

static ssize_t show_bind(struct device *dev, struct device_attribute *attr,
			 char *buf)
{}

static ssize_t show_name(struct device *dev, struct device_attribute *attr,
			 char *buf)
{}

static DEVICE_ATTR(bind, S_IRUGO|S_IWUSR, show_bind, store_bind);
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);

static struct attribute *con_dev_attrs[] =;

ATTRIBUTE_GROUPS();

static int vtconsole_init_device(struct con_driver *con)
{}

static void vtconsole_deinit_device(struct con_driver *con)
{}

/**
 * con_is_bound - checks if driver is bound to the console
 * @csw: console driver
 *
 * RETURNS: zero if unbound, nonzero if bound
 *
 * Drivers can call this and if zero, they should release
 * all resources allocated on &consw.con_startup()
 */
int con_is_bound(const struct consw *csw)
{}
EXPORT_SYMBOL();

/**
 * con_is_visible - checks whether the current console is visible
 * @vc: virtual console
 *
 * RETURNS: zero if not visible, nonzero if visible
 */
bool con_is_visible(const struct vc_data *vc)
{}
EXPORT_SYMBOL();

/**
 * con_debug_enter - prepare the console for the kernel debugger
 * @vc: virtual console
 *
 * Called when the console is taken over by the kernel debugger, this
 * function needs to save the current console state, then put the console
 * into a state suitable for the kernel debugger.
 */
void con_debug_enter(struct vc_data *vc)
{}
EXPORT_SYMBOL_GPL();

/**
 * con_debug_leave - restore console state
 *
 * Restore the console state to what it was before the kernel debugger
 * was invoked.
 */
void con_debug_leave(void)
{}
EXPORT_SYMBOL_GPL();

static int do_register_con_driver(const struct consw *csw, int first, int last)
{}


/**
 * do_unregister_con_driver - unregister console driver from console layer
 * @csw: console driver
 *
 * DESCRIPTION: All drivers that registers to the console layer must
 * call this function upon exit, or if the console driver is in a state
 * where it won't be able to handle console services, such as the
 * framebuffer console without loaded framebuffer drivers.
 *
 * The driver must unbind first prior to unregistration.
 */
int do_unregister_con_driver(const struct consw *csw)
{}
EXPORT_SYMBOL_GPL();

static void con_driver_unregister_callback(struct work_struct *ignored)
{}

/*
 *	If we support more console drivers, this function is used
 *	when a driver wants to take over some existing consoles
 *	and become default driver for newly opened ones.
 *
 *	do_take_over_console is basically a register followed by bind
 */
int do_take_over_console(const struct consw *csw, int first, int last, int deflt)
{}
EXPORT_SYMBOL_GPL();


/*
 * give_up_console is a wrapper to unregister_con_driver. It will only
 * work if driver is fully unbound.
 */
void give_up_console(const struct consw *csw)
{}
EXPORT_SYMBOL();

static int __init vtconsole_class_init(void)
{}
postcore_initcall(vtconsole_class_init);

/*
 *	Screen blanking
 */

static int set_vesa_blanking(u8 __user *mode_user)
{}

void do_blank_screen(int entering_gfx)
{}
EXPORT_SYMBOL();

/*
 * Called by timer as well as from vt_console_driver
 */
void do_unblank_screen(int leaving_gfx)
{}
EXPORT_SYMBOL();

/*
 * This is called by the outside world to cause a forced unblank, mostly for
 * oopses. Currently, I just call do_unblank_screen(0), but we could eventually
 * call it with 1 as an argument and so force a mode restore... that may kill
 * X or at least garbage the screen but would also make the Oops visible...
 */
static void unblank_screen(void)
{}

/*
 * We defer the timer blanking to work queue so it can take the console mutex
 * (console operations can still happen at irq time, but only from printk which
 * has the console mutex. Not perfect yet, but better than no locking
 */
static void blank_screen_t(struct timer_list *unused)
{}

void poke_blanked_console(void)
{}

/*
 *	Palettes
 */

static void set_palette(struct vc_data *vc)
{}

/*
 * Load palette into the DAC registers. arg points to a colour
 * map, 3 bytes per colour, 16 colours, range from 0 to 255.
 */

int con_set_cmap(unsigned char __user *arg)
{}

int con_get_cmap(unsigned char __user *arg)
{}

void reset_palette(struct vc_data *vc)
{}

/*
 *  Font switching
 *
 *  Currently we only support fonts up to 128 pixels wide, at a maximum height
 *  of 128 pixels. Userspace fontdata may have to be stored with 32 bytes
 *  (shorts/ints, depending on width) reserved for each character which is
 *  kinda wasty, but this is done in order to maintain compatibility with the
 *  EGA/VGA fonts. It is up to the actual low-level console-driver convert data
 *  into its favorite format (maybe we should add a `fontoffset' field to the
 *  `display' structure so we won't have to convert the fontdata all the time.
 *  /Jes
 */

#define max_font_width
#define max_font_height
#define max_font_glyphs
#define max_font_size

static int con_font_get(struct vc_data *vc, struct console_font_op *op)
{}

static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
{}

static int con_font_default(struct vc_data *vc, struct console_font_op *op)
{}

int con_font_op(struct vc_data *vc, struct console_font_op *op)
{}

/*
 *	Interface exported to selection and vcs.
 */

/* used by selection */
u16 screen_glyph(const struct vc_data *vc, int offset)
{}
EXPORT_SYMBOL_GPL();

u32 screen_glyph_unicode(const struct vc_data *vc, int n)
{}
EXPORT_SYMBOL_GPL();

/* used by vcs - note the word offset */
unsigned short *screen_pos(const struct vc_data *vc, int w_offset, bool viewed)
{}
EXPORT_SYMBOL_GPL();

void getconsxy(const struct vc_data *vc, unsigned char xy[static 2])
{}

void putconsxy(struct vc_data *vc, unsigned char xy[static const 2])
{}

u16 vcs_scr_readw(const struct vc_data *vc, const u16 *org)
{}

void vcs_scr_writew(struct vc_data *vc, u16 val, u16 *org)
{}

void vcs_scr_updated(struct vc_data *vc)
{}