diff options
author | Kyle McMartin <kyle@shortfin.cabal.ca> | 2008-02-19 02:34:34 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@shortfin.cabal.ca> | 2008-03-15 22:12:03 -0400 |
commit | ef1afd4d79f0479960ff36bb5fe6ec6eba1ebff2 (patch) | |
tree | 71351cd3150e87a2d5a5c2ae06ea143e7345cf14 /arch/parisc/kernel/pdc_cons.c | |
parent | d0347b49c9a877a33c59f80de1a9dbabd5244205 (diff) |
[PARISC] pdc_console: fix bizarre panic on boot
Commit 721fdf34167580ff98263c74cead8871d76936e6 introduced a subtle bug
by accidently removing the "static" from iodc_dbuf. This resulted in, what
appeared to be, a trap without *current set to a task. Probably the result of
a trap in real mode while calling firmware.
Also do other misc clean ups. Since the only input from firmware is non
blocking, share iodc_dbuf between input and output, and spinlock the
only callers.
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/pdc_cons.c')
-rw-r--r-- | arch/parisc/kernel/pdc_cons.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c index e7afc899d717..ccb68090781e 100644 --- a/arch/parisc/kernel/pdc_cons.c +++ b/arch/parisc/kernel/pdc_cons.c | |||
@@ -52,15 +52,30 @@ | |||
52 | #include <linux/tty.h> | 52 | #include <linux/tty.h> |
53 | #include <asm/pdc.h> /* for iodc_call() proto and friends */ | 53 | #include <asm/pdc.h> /* for iodc_call() proto and friends */ |
54 | 54 | ||
55 | static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED; | ||
55 | 56 | ||
56 | static void pdc_console_write(struct console *co, const char *s, unsigned count) | 57 | static void pdc_console_write(struct console *co, const char *s, unsigned count) |
57 | { | 58 | { |
58 | pdc_iodc_print(s, count); | 59 | int i = 0; |
60 | unsigned long flags; | ||
61 | |||
62 | spin_lock_irqsave(&pdc_console_lock, flags); | ||
63 | do { | ||
64 | i += pdc_iodc_print(s + i, count - i); | ||
65 | } while (i < count); | ||
66 | spin_unlock_irqrestore(&pdc_console_lock, flags); | ||
59 | } | 67 | } |
60 | 68 | ||
61 | int pdc_console_poll_key(struct console *co) | 69 | int pdc_console_poll_key(struct console *co) |
62 | { | 70 | { |
63 | return pdc_iodc_getc(); | 71 | int c; |
72 | unsigned long flags; | ||
73 | |||
74 | spin_lock_irqsave(&pdc_console_lock, flags); | ||
75 | c = pdc_iodc_getc(); | ||
76 | spin_unlock_irqrestore(&pdc_console_lock, flags); | ||
77 | |||
78 | return c; | ||
64 | } | 79 | } |
65 | 80 | ||
66 | static int pdc_console_setup(struct console *co, char *options) | 81 | static int pdc_console_setup(struct console *co, char *options) |