aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r--drivers/char/vt.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index 7cdb6ee569cd..4a9eb3044e52 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -104,6 +104,7 @@
104#include <linux/io.h> 104#include <linux/io.h>
105#include <asm/system.h> 105#include <asm/system.h>
106#include <linux/uaccess.h> 106#include <linux/uaccess.h>
107#include <linux/kdb.h>
107 108
108#define MAX_NR_CON_DRIVER 16 109#define MAX_NR_CON_DRIVER 16
109 110
@@ -187,10 +188,15 @@ static DECLARE_WORK(console_work, console_callback);
187 * fg_console is the current virtual console, 188 * fg_console is the current virtual console,
188 * last_console is the last used one, 189 * last_console is the last used one,
189 * want_console is the console we want to switch to, 190 * want_console is the console we want to switch to,
191 * saved_* variants are for save/restore around kernel debugger enter/leave
190 */ 192 */
191int fg_console; 193int fg_console;
192int last_console; 194int last_console;
193int want_console = -1; 195int want_console = -1;
196int saved_fg_console;
197int saved_last_console;
198int saved_want_console;
199int saved_vc_mode;
194 200
195/* 201/*
196 * For each existing display, we have a pointer to console currently visible 202 * For each existing display, we have a pointer to console currently visible
@@ -3414,6 +3420,78 @@ int con_is_bound(const struct consw *csw)
3414EXPORT_SYMBOL(con_is_bound); 3420EXPORT_SYMBOL(con_is_bound);
3415 3421
3416/** 3422/**
3423 * con_debug_enter - prepare the console for the kernel debugger
3424 * @sw: console driver
3425 *
3426 * Called when the console is taken over by the kernel debugger, this
3427 * function needs to save the current console state, then put the console
3428 * into a state suitable for the kernel debugger.
3429 *
3430 * RETURNS:
3431 * Zero on success, nonzero if a failure occurred when trying to prepare
3432 * the console for the debugger.
3433 */
3434int con_debug_enter(struct vc_data *vc)
3435{
3436 int ret = 0;
3437
3438 saved_fg_console = fg_console;
3439 saved_last_console = last_console;
3440 saved_want_console = want_console;
3441 saved_vc_mode = vc->vc_mode;
3442 vc->vc_mode = KD_TEXT;
3443 console_blanked = 0;
3444 if (vc->vc_sw->con_debug_enter)
3445 ret = vc->vc_sw->con_debug_enter(vc);
3446#ifdef CONFIG_KGDB_KDB
3447 /* Set the initial LINES variable if it is not already set */
3448 if (vc->vc_rows < 999) {
3449 int linecount;
3450 char lns[4];
3451 const char *setargs[3] = {
3452 "set",
3453 "LINES",
3454 lns,
3455 };
3456 if (kdbgetintenv(setargs[0], &linecount)) {
3457 snprintf(lns, 4, "%i", vc->vc_rows);
3458 kdb_set(2, setargs);
3459 }
3460 }
3461#endif /* CONFIG_KGDB_KDB */
3462 return ret;
3463}
3464EXPORT_SYMBOL_GPL(con_debug_enter);
3465
3466/**
3467 * con_debug_leave - restore console state
3468 * @sw: console driver
3469 *
3470 * Restore the console state to what it was before the kernel debugger
3471 * was invoked.
3472 *
3473 * RETURNS:
3474 * Zero on success, nonzero if a failure occurred when trying to restore
3475 * the console.
3476 */
3477int con_debug_leave(void)
3478{
3479 struct vc_data *vc;
3480 int ret = 0;
3481
3482 fg_console = saved_fg_console;
3483 last_console = saved_last_console;
3484 want_console = saved_want_console;
3485 vc_cons[fg_console].d->vc_mode = saved_vc_mode;
3486
3487 vc = vc_cons[fg_console].d;
3488 if (vc->vc_sw->con_debug_leave)
3489 ret = vc->vc_sw->con_debug_leave(vc);
3490 return ret;
3491}
3492EXPORT_SYMBOL_GPL(con_debug_leave);
3493
3494/**
3417 * register_con_driver - register console driver to console layer 3495 * register_con_driver - register console driver to console layer
3418 * @csw: console driver 3496 * @csw: console driver
3419 * @first: the first console to take over, minimum value is 0 3497 * @first: the first console to take over, minimum value is 0