| 1 | /* | 
|---|
| 2 | *  linux/include/linux/console.h | 
|---|
| 3 | * | 
|---|
| 4 | *  Copyright (C) 1993        Hamish Macdonald | 
|---|
| 5 | * | 
|---|
| 6 | * This file is subject to the terms and conditions of the GNU General Public | 
|---|
| 7 | * License.  See the file COPYING in the main directory of this archive | 
|---|
| 8 | * for more details. | 
|---|
| 9 | * | 
|---|
| 10 | * Changed: | 
|---|
| 11 | * 10-Mar-94: Arno Griffioen: Conversion for vt100 emulator port from PC LINUX | 
|---|
| 12 | */ | 
|---|
| 13 |  | 
|---|
| 14 | #ifndef _LINUX_CONSOLE_H_ | 
|---|
| 15 | #define _LINUX_CONSOLE_H_ 1 | 
|---|
| 16 |  | 
|---|
| 17 | #include <linux/atomic.h> | 
|---|
| 18 | #include <linux/bits.h> | 
|---|
| 19 | #include <linux/irq_work.h> | 
|---|
| 20 | #include <linux/rculist.h> | 
|---|
| 21 | #include <linux/rcuwait.h> | 
|---|
| 22 | #include <linux/types.h> | 
|---|
| 23 | #include <linux/vesa.h> | 
|---|
| 24 |  | 
|---|
| 25 | struct vc_data; | 
|---|
| 26 | struct console_font_op; | 
|---|
| 27 | struct console_font; | 
|---|
| 28 | struct module; | 
|---|
| 29 | struct tty_struct; | 
|---|
| 30 | struct notifier_block; | 
|---|
| 31 |  | 
|---|
| 32 | enum con_scroll { | 
|---|
| 33 | SM_UP, | 
|---|
| 34 | SM_DOWN, | 
|---|
| 35 | }; | 
|---|
| 36 |  | 
|---|
| 37 | enum vc_intensity; | 
|---|
| 38 |  | 
|---|
| 39 | /** | 
|---|
| 40 | * struct consw - callbacks for consoles | 
|---|
| 41 | * | 
|---|
| 42 | * @owner:      the module to get references of when this console is used | 
|---|
| 43 | * @con_startup: set up the console and return its name (like VGA, EGA, ...) | 
|---|
| 44 | * @con_init:   initialize the console on @vc. @init is true for the very first | 
|---|
| 45 | *		call on this @vc. | 
|---|
| 46 | * @con_deinit: deinitialize the console from @vc. | 
|---|
| 47 | * @con_clear:  erase @count characters at [@x, @y] on @vc. @count >= 1. | 
|---|
| 48 | * @con_putc:   emit one character with attributes @ca to [@x, @y] on @vc. | 
|---|
| 49 | *		(optional -- @con_putcs would be called instead) | 
|---|
| 50 | * @con_putcs:  emit @count characters with attributes @s to [@x, @y] on @vc. | 
|---|
| 51 | * @con_cursor: enable/disable cursor depending on @enable | 
|---|
| 52 | * @con_scroll: move lines from @top to @bottom in direction @dir by @lines. | 
|---|
| 53 | *		Return true if no generic handling should be done. | 
|---|
| 54 | *		Invoked by csi_M and printing to the console. | 
|---|
| 55 | * @con_switch: notifier about the console switch; it is supposed to return | 
|---|
| 56 | *		true if a redraw is needed. | 
|---|
| 57 | * @con_blank:  blank/unblank the console. The target mode is passed in @blank. | 
|---|
| 58 | *		@mode_switch is set if changing from/to text/graphics. The hook | 
|---|
| 59 | *		is supposed to return true if a redraw is needed. | 
|---|
| 60 | * @con_font_set: set console @vc font to @font with height @vpitch. @flags can | 
|---|
| 61 | *		be %KD_FONT_FLAG_DONT_RECALC. (optional) | 
|---|
| 62 | * @con_font_get: fetch the current font on @vc of height @vpitch into @font. | 
|---|
| 63 | *		(optional) | 
|---|
| 64 | * @con_font_default: set default font on @vc. @name can be %NULL or font name | 
|---|
| 65 | *		to search for. @font can be filled back. (optional) | 
|---|
| 66 | * @con_resize:	resize the @vc console to @width x @height. @from_user is true | 
|---|
| 67 | *		when this change comes from the user space. | 
|---|
| 68 | * @con_set_palette: sets the palette of the console @vc to @table (optional) | 
|---|
| 69 | * @con_scrolldelta: the contents of the console should be scrolled by @lines. | 
|---|
| 70 | *		     Invoked by user. (optional) | 
|---|
| 71 | * @con_set_origin: set origin (see &vc_data::vc_origin) of the @vc. If not | 
|---|
| 72 | *		provided or returns false, the origin is set to | 
|---|
| 73 | *		@vc->vc_screenbuf. (optional) | 
|---|
| 74 | * @con_save_screen: save screen content into @vc->vc_screenbuf. Called e.g. | 
|---|
| 75 | *		upon entering graphics. (optional) | 
|---|
| 76 | * @con_build_attr: build attributes based on @color, @intensity and other | 
|---|
| 77 | *		parameters. The result is used for both normal and erase | 
|---|
| 78 | *		characters. (optional) | 
|---|
| 79 | * @con_invert_region: invert a region of length @count on @vc starting at @p. | 
|---|
| 80 | *		(optional) | 
|---|
| 81 | * @con_debug_enter: prepare the console for the debugger. This includes, but | 
|---|
| 82 | *		is not limited to, unblanking the console, loading an | 
|---|
| 83 | *		appropriate palette, and allowing debugger generated output. | 
|---|
| 84 | *		(optional) | 
|---|
| 85 | * @con_debug_leave: restore the console to its pre-debug state as closely as | 
|---|
| 86 | *		possible. (optional) | 
|---|
| 87 | */ | 
|---|
| 88 | struct consw { | 
|---|
| 89 | struct module *owner; | 
|---|
| 90 | const char *(*con_startup)(void); | 
|---|
| 91 | void	(*con_init)(struct vc_data *vc, bool init); | 
|---|
| 92 | void	(*con_deinit)(struct vc_data *vc); | 
|---|
| 93 | void	(*con_clear)(struct vc_data *vc, unsigned int y, | 
|---|
| 94 | unsigned int x, unsigned int count); | 
|---|
| 95 | void	(*con_putc)(struct vc_data *vc, u16 ca, unsigned int y, | 
|---|
| 96 | unsigned int x); | 
|---|
| 97 | void	(*con_putcs)(struct vc_data *vc, const u16 *s, | 
|---|
| 98 | unsigned int count, unsigned int ypos, | 
|---|
| 99 | unsigned int xpos); | 
|---|
| 100 | void	(*con_cursor)(struct vc_data *vc, bool enable); | 
|---|
| 101 | bool	(*con_scroll)(struct vc_data *vc, unsigned int top, | 
|---|
| 102 | unsigned int bottom, enum con_scroll dir, | 
|---|
| 103 | unsigned int lines); | 
|---|
| 104 | bool	(*con_switch)(struct vc_data *vc); | 
|---|
| 105 | bool	(*con_blank)(struct vc_data *vc, enum vesa_blank_mode blank, | 
|---|
| 106 | bool mode_switch); | 
|---|
| 107 | int	(*con_font_set)(struct vc_data *vc, | 
|---|
| 108 | const struct console_font *font, | 
|---|
| 109 | unsigned int vpitch, unsigned int flags); | 
|---|
| 110 | int	(*con_font_get)(struct vc_data *vc, struct console_font *font, | 
|---|
| 111 | unsigned int vpitch); | 
|---|
| 112 | int	(*con_font_default)(struct vc_data *vc, | 
|---|
| 113 | struct console_font *font, const char *name); | 
|---|
| 114 | int     (*con_resize)(struct vc_data *vc, unsigned int width, | 
|---|
| 115 | unsigned int height, bool from_user); | 
|---|
| 116 | void	(*con_set_palette)(struct vc_data *vc, | 
|---|
| 117 | const unsigned char *table); | 
|---|
| 118 | void	(*con_scrolldelta)(struct vc_data *vc, int lines); | 
|---|
| 119 | bool	(*con_set_origin)(struct vc_data *vc); | 
|---|
| 120 | void	(*con_save_screen)(struct vc_data *vc); | 
|---|
| 121 | u8	(*con_build_attr)(struct vc_data *vc, u8 color, | 
|---|
| 122 | enum vc_intensity intensity, | 
|---|
| 123 | bool blink, bool underline, bool reverse, bool italic); | 
|---|
| 124 | void	(*con_invert_region)(struct vc_data *vc, u16 *p, int count); | 
|---|
| 125 | void	(*con_debug_enter)(struct vc_data *vc); | 
|---|
| 126 | void	(*con_debug_leave)(struct vc_data *vc); | 
|---|
| 127 | }; | 
|---|
| 128 |  | 
|---|
| 129 | extern const struct consw *conswitchp; | 
|---|
| 130 |  | 
|---|
| 131 | extern const struct consw dummy_con;	/* dummy console buffer */ | 
|---|
| 132 | extern const struct consw vga_con;	/* VGA text console */ | 
|---|
| 133 | extern const struct consw newport_con;	/* SGI Newport console  */ | 
|---|
| 134 |  | 
|---|
| 135 | struct screen_info; | 
|---|
| 136 | #ifdef CONFIG_VGA_CONSOLE | 
|---|
| 137 | void vgacon_register_screen(struct screen_info *si); | 
|---|
| 138 | #else | 
|---|
| 139 | static inline void vgacon_register_screen(struct screen_info *si) { } | 
|---|
| 140 | #endif | 
|---|
| 141 |  | 
|---|
| 142 | int con_is_bound(const struct consw *csw); | 
|---|
| 143 | int do_unregister_con_driver(const struct consw *csw); | 
|---|
| 144 | int do_take_over_console(const struct consw *sw, int first, int last, int deflt); | 
|---|
| 145 | void give_up_console(const struct consw *sw); | 
|---|
| 146 | #ifdef CONFIG_VT | 
|---|
| 147 | void con_debug_enter(struct vc_data *vc); | 
|---|
| 148 | void con_debug_leave(void); | 
|---|
| 149 | #else | 
|---|
| 150 | static inline void con_debug_enter(struct vc_data *vc) { } | 
|---|
| 151 | static inline void con_debug_leave(void) { } | 
|---|
| 152 | #endif | 
|---|
| 153 |  | 
|---|
| 154 | /* | 
|---|
| 155 | * The interface for a console, or any other device that wants to capture | 
|---|
| 156 | * console messages (printer driver?) | 
|---|
| 157 | */ | 
|---|
| 158 |  | 
|---|
| 159 | /** | 
|---|
| 160 | * enum cons_flags - General console flags | 
|---|
| 161 | * @CON_PRINTBUFFER:	Used by newly registered consoles to avoid duplicate | 
|---|
| 162 | *			output of messages that were already shown by boot | 
|---|
| 163 | *			consoles or read by userspace via syslog() syscall. | 
|---|
| 164 | * @CON_CONSDEV:	Indicates that the console driver is backing | 
|---|
| 165 | *			/dev/console. | 
|---|
| 166 | * @CON_ENABLED:	Indicates if a console is allowed to print records. If | 
|---|
| 167 | *			false, the console also will not advance to later | 
|---|
| 168 | *			records. | 
|---|
| 169 | * @CON_BOOT:		Marks the console driver as early console driver which | 
|---|
| 170 | *			is used during boot before the real driver becomes | 
|---|
| 171 | *			available. It will be automatically unregistered | 
|---|
| 172 | *			when the real console driver is registered unless | 
|---|
| 173 | *			"keep_bootcon" parameter is used. | 
|---|
| 174 | * @CON_ANYTIME:	A misnomed historical flag which tells the core code | 
|---|
| 175 | *			that the legacy @console::write callback can be invoked | 
|---|
| 176 | *			on a CPU which is marked OFFLINE. That is misleading as | 
|---|
| 177 | *			it suggests that there is no contextual limit for | 
|---|
| 178 | *			invoking the callback. The original motivation was | 
|---|
| 179 | *			readiness of the per-CPU areas. | 
|---|
| 180 | * @CON_BRL:		Indicates a braille device which is exempt from | 
|---|
| 181 | *			receiving the printk spam for obvious reasons. | 
|---|
| 182 | * @CON_EXTENDED:	The console supports the extended output format of | 
|---|
| 183 | *			/dev/kmesg which requires a larger output buffer. | 
|---|
| 184 | * @CON_SUSPENDED:	Indicates if a console is suspended. If true, the | 
|---|
| 185 | *			printing callbacks must not be called. | 
|---|
| 186 | * @CON_NBCON:		Console can operate outside of the legacy style console_lock | 
|---|
| 187 | *			constraints. | 
|---|
| 188 | */ | 
|---|
| 189 | enum cons_flags { | 
|---|
| 190 | CON_PRINTBUFFER		= BIT(0), | 
|---|
| 191 | CON_CONSDEV		= BIT(1), | 
|---|
| 192 | CON_ENABLED		= BIT(2), | 
|---|
| 193 | CON_BOOT		= BIT(3), | 
|---|
| 194 | CON_ANYTIME		= BIT(4), | 
|---|
| 195 | CON_BRL			= BIT(5), | 
|---|
| 196 | CON_EXTENDED		= BIT(6), | 
|---|
| 197 | CON_SUSPENDED		= BIT(7), | 
|---|
| 198 | CON_NBCON		= BIT(8), | 
|---|
| 199 | }; | 
|---|
| 200 |  | 
|---|
| 201 | /** | 
|---|
| 202 | * struct nbcon_state - console state for nbcon consoles | 
|---|
| 203 | * @atom:	Compound of the state fields for atomic operations | 
|---|
| 204 | * | 
|---|
| 205 | * @req_prio:		The priority of a handover request | 
|---|
| 206 | * @prio:		The priority of the current owner | 
|---|
| 207 | * @unsafe:		Console is busy in a non takeover region | 
|---|
| 208 | * @unsafe_takeover:	A hostile takeover in an unsafe state happened in the | 
|---|
| 209 | *			past. The console cannot be safe until re-initialized. | 
|---|
| 210 | * @cpu:		The CPU on which the owner runs | 
|---|
| 211 | * | 
|---|
| 212 | * To be used for reading and preparing of the value stored in the nbcon | 
|---|
| 213 | * state variable @console::nbcon_state. | 
|---|
| 214 | * | 
|---|
| 215 | * The @prio and @req_prio fields are particularly important to allow | 
|---|
| 216 | * spin-waiting to timeout and give up without the risk of a waiter being | 
|---|
| 217 | * assigned the lock after giving up. | 
|---|
| 218 | */ | 
|---|
| 219 | struct nbcon_state { | 
|---|
| 220 | union { | 
|---|
| 221 | unsigned int	atom; | 
|---|
| 222 | struct { | 
|---|
| 223 | unsigned int prio		:  2; | 
|---|
| 224 | unsigned int req_prio		:  2; | 
|---|
| 225 | unsigned int unsafe		:  1; | 
|---|
| 226 | unsigned int unsafe_takeover	:  1; | 
|---|
| 227 | unsigned int cpu		: 24; | 
|---|
| 228 | }; | 
|---|
| 229 | }; | 
|---|
| 230 | }; | 
|---|
| 231 |  | 
|---|
| 232 | /* | 
|---|
| 233 | * The nbcon_state struct is used to easily create and interpret values that | 
|---|
| 234 | * are stored in the @console::nbcon_state variable. Ensure this struct stays | 
|---|
| 235 | * within the size boundaries of the atomic variable's underlying type in | 
|---|
| 236 | * order to avoid any accidental truncation. | 
|---|
| 237 | */ | 
|---|
| 238 | static_assert(sizeof(struct nbcon_state) <= sizeof(int)); | 
|---|
| 239 |  | 
|---|
| 240 | /** | 
|---|
| 241 | * enum nbcon_prio - console owner priority for nbcon consoles | 
|---|
| 242 | * @NBCON_PRIO_NONE:		Unused | 
|---|
| 243 | * @NBCON_PRIO_NORMAL:		Normal (non-emergency) usage | 
|---|
| 244 | * @NBCON_PRIO_EMERGENCY:	Emergency output (WARN/OOPS...) | 
|---|
| 245 | * @NBCON_PRIO_PANIC:		Panic output | 
|---|
| 246 | * @NBCON_PRIO_MAX:		The number of priority levels | 
|---|
| 247 | * | 
|---|
| 248 | * A higher priority context can takeover the console when it is | 
|---|
| 249 | * in the safe state. The final attempt to flush consoles in panic() | 
|---|
| 250 | * can be allowed to do so even in an unsafe state (Hope and pray). | 
|---|
| 251 | */ | 
|---|
| 252 | enum nbcon_prio { | 
|---|
| 253 | NBCON_PRIO_NONE = 0, | 
|---|
| 254 | NBCON_PRIO_NORMAL, | 
|---|
| 255 | NBCON_PRIO_EMERGENCY, | 
|---|
| 256 | NBCON_PRIO_PANIC, | 
|---|
| 257 | NBCON_PRIO_MAX, | 
|---|
| 258 | }; | 
|---|
| 259 |  | 
|---|
| 260 | struct console; | 
|---|
| 261 | struct printk_buffers; | 
|---|
| 262 |  | 
|---|
| 263 | /** | 
|---|
| 264 | * struct nbcon_context - Context for console acquire/release | 
|---|
| 265 | * @console:			The associated console | 
|---|
| 266 | * @spinwait_max_us:		Limit for spin-wait acquire | 
|---|
| 267 | * @prio:			Priority of the context | 
|---|
| 268 | * @allow_unsafe_takeover:	Allow performing takeover even if unsafe. Can | 
|---|
| 269 | *				be used only with NBCON_PRIO_PANIC @prio. It | 
|---|
| 270 | *				might cause a system freeze when the console | 
|---|
| 271 | *				is used later. | 
|---|
| 272 | * @backlog:			Ringbuffer has pending records | 
|---|
| 273 | * @pbufs:			Pointer to the text buffer for this context | 
|---|
| 274 | * @seq:			The sequence number to print for this context | 
|---|
| 275 | */ | 
|---|
| 276 | struct nbcon_context { | 
|---|
| 277 | /* members set by caller */ | 
|---|
| 278 | struct console		*console; | 
|---|
| 279 | unsigned int		spinwait_max_us; | 
|---|
| 280 | enum nbcon_prio		prio; | 
|---|
| 281 | unsigned int		allow_unsafe_takeover	: 1; | 
|---|
| 282 |  | 
|---|
| 283 | /* members set by emit */ | 
|---|
| 284 | unsigned int		backlog			: 1; | 
|---|
| 285 |  | 
|---|
| 286 | /* members set by acquire */ | 
|---|
| 287 | struct printk_buffers	*pbufs; | 
|---|
| 288 | u64			seq; | 
|---|
| 289 | }; | 
|---|
| 290 |  | 
|---|
| 291 | /** | 
|---|
| 292 | * struct nbcon_write_context - Context handed to the nbcon write callbacks | 
|---|
| 293 | * @ctxt:		The core console context | 
|---|
| 294 | * @outbuf:		Pointer to the text buffer for output | 
|---|
| 295 | * @len:		Length to write | 
|---|
| 296 | * @unsafe_takeover:	If a hostile takeover in an unsafe state has occurred | 
|---|
| 297 | */ | 
|---|
| 298 | struct nbcon_write_context { | 
|---|
| 299 | struct nbcon_context	__private ctxt; | 
|---|
| 300 | char			*outbuf; | 
|---|
| 301 | unsigned int		len; | 
|---|
| 302 | bool			unsafe_takeover; | 
|---|
| 303 | }; | 
|---|
| 304 |  | 
|---|
| 305 | /** | 
|---|
| 306 | * struct console - The console descriptor structure | 
|---|
| 307 | * @name:		The name of the console driver | 
|---|
| 308 | * @write:		Legacy write callback to output messages (Optional) | 
|---|
| 309 | * @read:		Read callback for console input (Optional) | 
|---|
| 310 | * @device:		The underlying TTY device driver (Optional) | 
|---|
| 311 | * @unblank:		Callback to unblank the console (Optional) | 
|---|
| 312 | * @setup:		Callback for initializing the console (Optional) | 
|---|
| 313 | * @exit:		Callback for teardown of the console (Optional) | 
|---|
| 314 | * @match:		Callback for matching a console (Optional) | 
|---|
| 315 | * @flags:		Console flags. See enum cons_flags | 
|---|
| 316 | * @index:		Console index, e.g. port number | 
|---|
| 317 | * @cflag:		TTY control mode flags | 
|---|
| 318 | * @ispeed:		TTY input speed | 
|---|
| 319 | * @ospeed:		TTY output speed | 
|---|
| 320 | * @seq:		Sequence number of the next ringbuffer record to print | 
|---|
| 321 | * @dropped:		Number of unreported dropped ringbuffer records | 
|---|
| 322 | * @data:		Driver private data | 
|---|
| 323 | * @node:		hlist node for the console list | 
|---|
| 324 | * | 
|---|
| 325 | * @nbcon_state:	State for nbcon consoles | 
|---|
| 326 | * @nbcon_seq:		Sequence number of the next record for nbcon to print | 
|---|
| 327 | * @nbcon_device_ctxt:	Context available for non-printing operations | 
|---|
| 328 | * @nbcon_prev_seq:	Seq num the previous nbcon owner was assigned to print | 
|---|
| 329 | * @pbufs:		Pointer to nbcon private buffer | 
|---|
| 330 | * @kthread:		Printer kthread for this console | 
|---|
| 331 | * @rcuwait:		RCU-safe wait object for @kthread waking | 
|---|
| 332 | * @irq_work:		Defer @kthread waking to IRQ work context | 
|---|
| 333 | */ | 
|---|
| 334 | struct console { | 
|---|
| 335 | char			name[16]; | 
|---|
| 336 | void			(*write)(struct console *co, const char *s, unsigned int count); | 
|---|
| 337 | int			(*read)(struct console *co, char *s, unsigned int count); | 
|---|
| 338 | struct tty_driver	*(*device)(struct console *co, int *index); | 
|---|
| 339 | void			(*unblank)(void); | 
|---|
| 340 | int			(*setup)(struct console *co, char *options); | 
|---|
| 341 | int			(*exit)(struct console *co); | 
|---|
| 342 | int			(*match)(struct console *co, char *name, int idx, char *options); | 
|---|
| 343 | short			flags; | 
|---|
| 344 | short			index; | 
|---|
| 345 | int			cflag; | 
|---|
| 346 | uint			ispeed; | 
|---|
| 347 | uint			ospeed; | 
|---|
| 348 | u64			seq; | 
|---|
| 349 | unsigned long		dropped; | 
|---|
| 350 | void			*data; | 
|---|
| 351 | struct hlist_node	node; | 
|---|
| 352 |  | 
|---|
| 353 | /* nbcon console specific members */ | 
|---|
| 354 |  | 
|---|
| 355 | /** | 
|---|
| 356 | * @write_atomic: | 
|---|
| 357 | * | 
|---|
| 358 | * NBCON callback to write out text in any context. (Optional) | 
|---|
| 359 | * | 
|---|
| 360 | * This callback is called with the console already acquired. However, | 
|---|
| 361 | * a higher priority context is allowed to take it over by default. | 
|---|
| 362 | * | 
|---|
| 363 | * The callback must call nbcon_enter_unsafe() and nbcon_exit_unsafe() | 
|---|
| 364 | * around any code where the takeover is not safe, for example, when | 
|---|
| 365 | * manipulating the serial port registers. | 
|---|
| 366 | * | 
|---|
| 367 | * nbcon_enter_unsafe() will fail if the context has lost the console | 
|---|
| 368 | * ownership in the meantime. In this case, the callback is no longer | 
|---|
| 369 | * allowed to go forward. It must back out immediately and carefully. | 
|---|
| 370 | * The buffer content is also no longer trusted since it no longer | 
|---|
| 371 | * belongs to the context. | 
|---|
| 372 | * | 
|---|
| 373 | * The callback should allow the takeover whenever it is safe. It | 
|---|
| 374 | * increases the chance to see messages when the system is in trouble. | 
|---|
| 375 | * If the driver must reacquire ownership in order to finalize or | 
|---|
| 376 | * revert hardware changes, nbcon_reacquire_nobuf() can be used. | 
|---|
| 377 | * However, on reacquire the buffer content is no longer available. A | 
|---|
| 378 | * reacquire cannot be used to resume printing. | 
|---|
| 379 | * | 
|---|
| 380 | * The callback can be called from any context (including NMI). | 
|---|
| 381 | * Therefore it must avoid usage of any locking and instead rely | 
|---|
| 382 | * on the console ownership for synchronization. | 
|---|
| 383 | */ | 
|---|
| 384 | void (*write_atomic)(struct console *con, struct nbcon_write_context *wctxt); | 
|---|
| 385 |  | 
|---|
| 386 | /** | 
|---|
| 387 | * @write_thread: | 
|---|
| 388 | * | 
|---|
| 389 | * NBCON callback to write out text in task context. | 
|---|
| 390 | * | 
|---|
| 391 | * This callback must be called only in task context with both | 
|---|
| 392 | * device_lock() and the nbcon console acquired with | 
|---|
| 393 | * NBCON_PRIO_NORMAL. | 
|---|
| 394 | * | 
|---|
| 395 | * The same rules for console ownership verification and unsafe | 
|---|
| 396 | * sections handling applies as with write_atomic(). | 
|---|
| 397 | * | 
|---|
| 398 | * The console ownership handling is necessary for synchronization | 
|---|
| 399 | * against write_atomic() which is synchronized only via the context. | 
|---|
| 400 | * | 
|---|
| 401 | * The device_lock() provides the primary serialization for operations | 
|---|
| 402 | * on the device. It might be as relaxed (mutex)[*] or as tight | 
|---|
| 403 | * (disabled preemption and interrupts) as needed. It allows | 
|---|
| 404 | * the kthread to operate in the least restrictive mode[**]. | 
|---|
| 405 | * | 
|---|
| 406 | * [*] Standalone nbcon_context_try_acquire() is not safe with | 
|---|
| 407 | *     the preemption enabled, see nbcon_owner_matches(). But it | 
|---|
| 408 | *     can be safe when always called in the preemptive context | 
|---|
| 409 | *     under the device_lock(). | 
|---|
| 410 | * | 
|---|
| 411 | * [**] The device_lock() makes sure that nbcon_context_try_acquire() | 
|---|
| 412 | *      would never need to spin which is important especially with | 
|---|
| 413 | *      PREEMPT_RT. | 
|---|
| 414 | */ | 
|---|
| 415 | void (*write_thread)(struct console *con, struct nbcon_write_context *wctxt); | 
|---|
| 416 |  | 
|---|
| 417 | /** | 
|---|
| 418 | * @device_lock: | 
|---|
| 419 | * | 
|---|
| 420 | * NBCON callback to begin synchronization with driver code. | 
|---|
| 421 | * | 
|---|
| 422 | * Console drivers typically must deal with access to the hardware | 
|---|
| 423 | * via user input/output (such as an interactive login shell) and | 
|---|
| 424 | * output of kernel messages via printk() calls. This callback is | 
|---|
| 425 | * called by the printk-subsystem whenever it needs to synchronize | 
|---|
| 426 | * with hardware access by the driver. It should be implemented to | 
|---|
| 427 | * use whatever synchronization mechanism the driver is using for | 
|---|
| 428 | * itself (for example, the port lock for uart serial consoles). | 
|---|
| 429 | * | 
|---|
| 430 | * The callback is always called from task context. It may use any | 
|---|
| 431 | * synchronization method required by the driver. | 
|---|
| 432 | * | 
|---|
| 433 | * IMPORTANT: The callback MUST disable migration. The console driver | 
|---|
| 434 | *	may be using a synchronization mechanism that already takes | 
|---|
| 435 | *	care of this (such as spinlocks). Otherwise this function must | 
|---|
| 436 | *	explicitly call migrate_disable(). | 
|---|
| 437 | * | 
|---|
| 438 | * The flags argument is provided as a convenience to the driver. It | 
|---|
| 439 | * will be passed again to device_unlock(). It can be ignored if the | 
|---|
| 440 | * driver does not need it. | 
|---|
| 441 | */ | 
|---|
| 442 | void (*device_lock)(struct console *con, unsigned long *flags); | 
|---|
| 443 |  | 
|---|
| 444 | /** | 
|---|
| 445 | * @device_unlock: | 
|---|
| 446 | * | 
|---|
| 447 | * NBCON callback to finish synchronization with driver code. | 
|---|
| 448 | * | 
|---|
| 449 | * It is the counterpart to device_lock(). | 
|---|
| 450 | * | 
|---|
| 451 | * This callback is always called from task context. It must | 
|---|
| 452 | * appropriately re-enable migration (depending on how device_lock() | 
|---|
| 453 | * disabled migration). | 
|---|
| 454 | * | 
|---|
| 455 | * The flags argument is the value of the same variable that was | 
|---|
| 456 | * passed to device_lock(). | 
|---|
| 457 | */ | 
|---|
| 458 | void (*device_unlock)(struct console *con, unsigned long flags); | 
|---|
| 459 |  | 
|---|
| 460 | atomic_t		__private nbcon_state; | 
|---|
| 461 | atomic_long_t		__private nbcon_seq; | 
|---|
| 462 | struct nbcon_context	__private nbcon_device_ctxt; | 
|---|
| 463 | atomic_long_t           __private nbcon_prev_seq; | 
|---|
| 464 |  | 
|---|
| 465 | struct printk_buffers	*pbufs; | 
|---|
| 466 | struct task_struct	*kthread; | 
|---|
| 467 | struct rcuwait		rcuwait; | 
|---|
| 468 | struct irq_work		irq_work; | 
|---|
| 469 | }; | 
|---|
| 470 |  | 
|---|
| 471 | #ifdef CONFIG_LOCKDEP | 
|---|
| 472 | extern void lockdep_assert_console_list_lock_held(void); | 
|---|
| 473 | #else | 
|---|
| 474 | static inline void lockdep_assert_console_list_lock_held(void) | 
|---|
| 475 | { | 
|---|
| 476 | } | 
|---|
| 477 | #endif | 
|---|
| 478 |  | 
|---|
| 479 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 
|---|
| 480 | extern bool console_srcu_read_lock_is_held(void); | 
|---|
| 481 | #else | 
|---|
| 482 | static inline bool console_srcu_read_lock_is_held(void) | 
|---|
| 483 | { | 
|---|
| 484 | return 1; | 
|---|
| 485 | } | 
|---|
| 486 | #endif | 
|---|
| 487 |  | 
|---|
| 488 | extern int console_srcu_read_lock(void); | 
|---|
| 489 | extern void console_srcu_read_unlock(int cookie); | 
|---|
| 490 |  | 
|---|
| 491 | extern void console_list_lock(void) __acquires(console_mutex); | 
|---|
| 492 | extern void console_list_unlock(void) __releases(console_mutex); | 
|---|
| 493 |  | 
|---|
| 494 | extern struct hlist_head console_list; | 
|---|
| 495 |  | 
|---|
| 496 | /** | 
|---|
| 497 | * console_srcu_read_flags - Locklessly read flags of a possibly registered | 
|---|
| 498 | *				console | 
|---|
| 499 | * @con:	struct console pointer of console to read flags from | 
|---|
| 500 | * | 
|---|
| 501 | * Locklessly reading @con->flags provides a consistent read value because | 
|---|
| 502 | * there is at most one CPU modifying @con->flags and that CPU is using only | 
|---|
| 503 | * read-modify-write operations to do so. | 
|---|
| 504 | * | 
|---|
| 505 | * Requires console_srcu_read_lock to be held, which implies that @con might | 
|---|
| 506 | * be a registered console. The purpose of holding console_srcu_read_lock is | 
|---|
| 507 | * to guarantee that the console state is valid (CON_SUSPENDED/CON_ENABLED) | 
|---|
| 508 | * and that no exit/cleanup routines will run if the console is currently | 
|---|
| 509 | * undergoing unregistration. | 
|---|
| 510 | * | 
|---|
| 511 | * If the caller is holding the console_list_lock or it is _certain_ that | 
|---|
| 512 | * @con is not and will not become registered, the caller may read | 
|---|
| 513 | * @con->flags directly instead. | 
|---|
| 514 | * | 
|---|
| 515 | * Context: Any context. | 
|---|
| 516 | * Return: The current value of the @con->flags field. | 
|---|
| 517 | */ | 
|---|
| 518 | static inline short console_srcu_read_flags(const struct console *con) | 
|---|
| 519 | { | 
|---|
| 520 | WARN_ON_ONCE(!console_srcu_read_lock_is_held()); | 
|---|
| 521 |  | 
|---|
| 522 | /* | 
|---|
| 523 | * The READ_ONCE() matches the WRITE_ONCE() when @flags are modified | 
|---|
| 524 | * for registered consoles with console_srcu_write_flags(). | 
|---|
| 525 | */ | 
|---|
| 526 | return data_race(READ_ONCE(con->flags)); | 
|---|
| 527 | } | 
|---|
| 528 |  | 
|---|
| 529 | /** | 
|---|
| 530 | * console_srcu_write_flags - Write flags for a registered console | 
|---|
| 531 | * @con:	struct console pointer of console to write flags to | 
|---|
| 532 | * @flags:	new flags value to write | 
|---|
| 533 | * | 
|---|
| 534 | * Only use this function to write flags for registered consoles. It | 
|---|
| 535 | * requires holding the console_list_lock. | 
|---|
| 536 | * | 
|---|
| 537 | * Context: Any context. | 
|---|
| 538 | */ | 
|---|
| 539 | static inline void console_srcu_write_flags(struct console *con, short flags) | 
|---|
| 540 | { | 
|---|
| 541 | lockdep_assert_console_list_lock_held(); | 
|---|
| 542 |  | 
|---|
| 543 | /* This matches the READ_ONCE() in console_srcu_read_flags(). */ | 
|---|
| 544 | WRITE_ONCE(con->flags, flags); | 
|---|
| 545 | } | 
|---|
| 546 |  | 
|---|
| 547 | /* Variant of console_is_registered() when the console_list_lock is held. */ | 
|---|
| 548 | static inline bool console_is_registered_locked(const struct console *con) | 
|---|
| 549 | { | 
|---|
| 550 | lockdep_assert_console_list_lock_held(); | 
|---|
| 551 | return !hlist_unhashed(h: &con->node); | 
|---|
| 552 | } | 
|---|
| 553 |  | 
|---|
| 554 | /* | 
|---|
| 555 | * console_is_registered - Check if the console is registered | 
|---|
| 556 | * @con:	struct console pointer of console to check | 
|---|
| 557 | * | 
|---|
| 558 | * Context: Process context. May sleep while acquiring console list lock. | 
|---|
| 559 | * Return: true if the console is in the console list, otherwise false. | 
|---|
| 560 | * | 
|---|
| 561 | * If false is returned for a console that was previously registered, it | 
|---|
| 562 | * can be assumed that the console's unregistration is fully completed, | 
|---|
| 563 | * including the exit() callback after console list removal. | 
|---|
| 564 | */ | 
|---|
| 565 | static inline bool console_is_registered(const struct console *con) | 
|---|
| 566 | { | 
|---|
| 567 | bool ret; | 
|---|
| 568 |  | 
|---|
| 569 | console_list_lock(); | 
|---|
| 570 | ret = console_is_registered_locked(con); | 
|---|
| 571 | console_list_unlock(); | 
|---|
| 572 | return ret; | 
|---|
| 573 | } | 
|---|
| 574 |  | 
|---|
| 575 | /** | 
|---|
| 576 | * for_each_console_srcu() - Iterator over registered consoles | 
|---|
| 577 | * @con:	struct console pointer used as loop cursor | 
|---|
| 578 | * | 
|---|
| 579 | * Although SRCU guarantees the console list will be consistent, the | 
|---|
| 580 | * struct console fields may be updated by other CPUs while iterating. | 
|---|
| 581 | * | 
|---|
| 582 | * Requires console_srcu_read_lock to be held. Can be invoked from | 
|---|
| 583 | * any context. | 
|---|
| 584 | */ | 
|---|
| 585 | #define for_each_console_srcu(con)					\ | 
|---|
| 586 | hlist_for_each_entry_srcu(con, &console_list, node,		\ | 
|---|
| 587 | console_srcu_read_lock_is_held()) | 
|---|
| 588 |  | 
|---|
| 589 | /** | 
|---|
| 590 | * for_each_console() - Iterator over registered consoles | 
|---|
| 591 | * @con:	struct console pointer used as loop cursor | 
|---|
| 592 | * | 
|---|
| 593 | * The console list and the &console.flags are immutable while iterating. | 
|---|
| 594 | * | 
|---|
| 595 | * Requires console_list_lock to be held. | 
|---|
| 596 | */ | 
|---|
| 597 | #define for_each_console(con)						\ | 
|---|
| 598 | lockdep_assert_console_list_lock_held();			\ | 
|---|
| 599 | hlist_for_each_entry(con, &console_list, node) | 
|---|
| 600 |  | 
|---|
| 601 | #ifdef CONFIG_PRINTK | 
|---|
| 602 | extern void nbcon_cpu_emergency_enter(void); | 
|---|
| 603 | extern void nbcon_cpu_emergency_exit(void); | 
|---|
| 604 | extern bool nbcon_can_proceed(struct nbcon_write_context *wctxt); | 
|---|
| 605 | extern bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt); | 
|---|
| 606 | extern bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt); | 
|---|
| 607 | extern void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt); | 
|---|
| 608 | #else | 
|---|
| 609 | static inline void nbcon_cpu_emergency_enter(void) { } | 
|---|
| 610 | static inline void nbcon_cpu_emergency_exit(void) { } | 
|---|
| 611 | static inline bool nbcon_can_proceed(struct nbcon_write_context *wctxt) { return false; } | 
|---|
| 612 | static inline bool nbcon_enter_unsafe(struct nbcon_write_context *wctxt) { return false; } | 
|---|
| 613 | static inline bool nbcon_exit_unsafe(struct nbcon_write_context *wctxt) { return false; } | 
|---|
| 614 | static inline void nbcon_reacquire_nobuf(struct nbcon_write_context *wctxt) { } | 
|---|
| 615 | #endif | 
|---|
| 616 |  | 
|---|
| 617 | extern int console_set_on_cmdline; | 
|---|
| 618 | extern struct console *early_console; | 
|---|
| 619 |  | 
|---|
| 620 | enum con_flush_mode { | 
|---|
| 621 | CONSOLE_FLUSH_PENDING, | 
|---|
| 622 | CONSOLE_REPLAY_ALL, | 
|---|
| 623 | }; | 
|---|
| 624 |  | 
|---|
| 625 | extern int add_preferred_console(const char *name, const short idx, char *options); | 
|---|
| 626 | extern void console_force_preferred_locked(struct console *con); | 
|---|
| 627 | extern void register_console(struct console *); | 
|---|
| 628 | extern int unregister_console(struct console *); | 
|---|
| 629 | extern void console_lock(void); | 
|---|
| 630 | extern int console_trylock(void); | 
|---|
| 631 | extern void console_unlock(void); | 
|---|
| 632 | extern void console_conditional_schedule(void); | 
|---|
| 633 | extern void console_unblank(void); | 
|---|
| 634 | extern void console_flush_on_panic(enum con_flush_mode mode); | 
|---|
| 635 | extern struct tty_driver *console_device(int *); | 
|---|
| 636 | extern void console_suspend(struct console *); | 
|---|
| 637 | extern void console_resume(struct console *); | 
|---|
| 638 | extern int is_console_locked(void); | 
|---|
| 639 | extern int braille_register_console(struct console *, int index, | 
|---|
| 640 | char *console_options, char *braille_options); | 
|---|
| 641 | extern int braille_unregister_console(struct console *); | 
|---|
| 642 | #ifdef CONFIG_TTY | 
|---|
| 643 | extern void console_sysfs_notify(void); | 
|---|
| 644 | #else | 
|---|
| 645 | static inline void console_sysfs_notify(void) | 
|---|
| 646 | { } | 
|---|
| 647 | #endif | 
|---|
| 648 | extern bool console_suspend_enabled; | 
|---|
| 649 |  | 
|---|
| 650 | /* Suspend and resume console messages over PM events */ | 
|---|
| 651 | extern void console_suspend_all(void); | 
|---|
| 652 | extern void console_resume_all(void); | 
|---|
| 653 |  | 
|---|
| 654 | int mda_console_init(void); | 
|---|
| 655 |  | 
|---|
| 656 | void vcs_make_sysfs(int index); | 
|---|
| 657 | void vcs_remove_sysfs(int index); | 
|---|
| 658 |  | 
|---|
| 659 | /* Some debug stub to catch some of the obvious races in the VT code */ | 
|---|
| 660 | #define WARN_CONSOLE_UNLOCKED()						\ | 
|---|
| 661 | WARN_ON(!atomic_read(&ignore_console_lock_warning) &&		\ | 
|---|
| 662 | !is_console_locked() && !oops_in_progress) | 
|---|
| 663 | /* | 
|---|
| 664 | * Increment ignore_console_lock_warning if you need to quiet | 
|---|
| 665 | * WARN_CONSOLE_UNLOCKED() for debugging purposes. | 
|---|
| 666 | */ | 
|---|
| 667 | extern atomic_t ignore_console_lock_warning; | 
|---|
| 668 |  | 
|---|
| 669 | DEFINE_LOCK_GUARD_0(console_lock, console_lock(), console_unlock()); | 
|---|
| 670 |  | 
|---|
| 671 | extern void console_init(void); | 
|---|
| 672 |  | 
|---|
| 673 | /* For deferred console takeover */ | 
|---|
| 674 | void dummycon_register_output_notifier(struct notifier_block *nb); | 
|---|
| 675 | void dummycon_unregister_output_notifier(struct notifier_block *nb); | 
|---|
| 676 |  | 
|---|
| 677 | #endif /* _LINUX_CONSOLE_H */ | 
|---|
| 678 |  | 
|---|