diff options
author | Andrew Johnson <ajohnson@intrinsyc.com> | 2007-03-16 17:38:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-16 22:25:05 -0400 |
commit | b257bc051f06607beb3004d9a1c297085e728bec (patch) | |
tree | 2eeb60429d92b683e9593d2fcde2f22ae40a1bf4 /drivers/char | |
parent | 1174cf730179d8f029b9e93cb9a4d5bfb08d1202 (diff) |
[PATCH] swsusp: fix suspend when console is in VT_AUTO+KD_GRAPHICS mode
When the console is in VT_AUTO+KD_GRAPHICS mode, switching to the
SUSPEND_CONSOLE fails, resulting in vt_waitactive() waiting indefinitely or
until the task is interrupted. This patch tests if a console switch can
occur in set_console() and returns early if a console switch is not
possible.
[akpm@linux-foundation.org: cleanup]
Signed-off-by: Andrew Johnson <ajohnson@intrinsyc.com>
Acked-by: Pavel Machek <pavel@ucw.cz>
Cc: "Antonino A. Daplas" <adaplas@pol.net>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/vt.c | 20 | ||||
-rw-r--r-- | drivers/char/vt_ioctl.c | 2 |
2 files changed, 20 insertions, 2 deletions
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c3f8e383933b..0fefe2a28055 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2185,10 +2185,28 @@ static void console_callback(struct work_struct *ignored) | |||
2185 | release_console_sem(); | 2185 | release_console_sem(); |
2186 | } | 2186 | } |
2187 | 2187 | ||
2188 | void set_console(int nr) | 2188 | int set_console(int nr) |
2189 | { | 2189 | { |
2190 | struct vc_data *vc = vc_cons[fg_console].d; | ||
2191 | |||
2192 | if (!vc_cons_allocated(nr) || vt_dont_switch || | ||
2193 | (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) { | ||
2194 | |||
2195 | /* | ||
2196 | * Console switch will fail in console_callback() or | ||
2197 | * change_console() so there is no point scheduling | ||
2198 | * the callback | ||
2199 | * | ||
2200 | * Existing set_console() users don't check the return | ||
2201 | * value so this shouldn't break anything | ||
2202 | */ | ||
2203 | return -EINVAL; | ||
2204 | } | ||
2205 | |||
2190 | want_console = nr; | 2206 | want_console = nr; |
2191 | schedule_console_callback(); | 2207 | schedule_console_callback(); |
2208 | |||
2209 | return 0; | ||
2192 | } | 2210 | } |
2193 | 2211 | ||
2194 | struct tty_driver *console_driver; | 2212 | struct tty_driver *console_driver; |
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 3a5d301e783b..1fa2da8f4fbe 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include <linux/kbd_diacr.h> | 34 | #include <linux/kbd_diacr.h> |
35 | #include <linux/selection.h> | 35 | #include <linux/selection.h> |
36 | 36 | ||
37 | static char vt_dont_switch; | 37 | char vt_dont_switch; |
38 | extern struct tty_driver *console_driver; | 38 | extern struct tty_driver *console_driver; |
39 | 39 | ||
40 | #define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count) | 40 | #define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count) |