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 |
