diff options
Diffstat (limited to 'drivers/char/vt.c')
-rw-r--r-- | drivers/char/vt.c | 78 |
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 | */ |
191 | int fg_console; | 193 | int fg_console; |
192 | int last_console; | 194 | int last_console; |
193 | int want_console = -1; | 195 | int want_console = -1; |
196 | int saved_fg_console; | ||
197 | int saved_last_console; | ||
198 | int saved_want_console; | ||
199 | int 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) | |||
3414 | EXPORT_SYMBOL(con_is_bound); | 3420 | EXPORT_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 | */ | ||
3434 | int 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 | } | ||
3464 | EXPORT_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 | */ | ||
3477 | int 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 | } | ||
3492 | EXPORT_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 |