summaryrefslogtreecommitdiffstats
path: root/arch/parisc/kernel/pdc_cons.c
diff options
context:
space:
mode:
authorKyle McMartin2008-02-19 08:34:34 +0100
committerKyle McMartin2008-03-16 03:12:03 +0100
commitef1afd4d79f0479960ff36bb5fe6ec6eba1ebff2 (patch)
tree71351cd3150e87a2d5a5c2ae06ea143e7345cf14 /arch/parisc/kernel/pdc_cons.c
parent[PARISC] dump_stack in show_regs (diff)
downloadkernel-qcow2-linux-ef1afd4d79f0479960ff36bb5fe6ec6eba1ebff2.tar.gz
kernel-qcow2-linux-ef1afd4d79f0479960ff36bb5fe6ec6eba1ebff2.tar.xz
kernel-qcow2-linux-ef1afd4d79f0479960ff36bb5fe6ec6eba1ebff2.zip
[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.c19
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 @@
#include <linux/tty.h>
#include <asm/pdc.h> /* for iodc_call() proto and friends */
+static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED;
static void pdc_console_write(struct console *co, const char *s, unsigned count)
{
- pdc_iodc_print(s, count);
+ int i = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_console_lock, flags);
+ do {
+ i += pdc_iodc_print(s + i, count - i);
+ } while (i < count);
+ spin_unlock_irqrestore(&pdc_console_lock, flags);
}
int pdc_console_poll_key(struct console *co)
{
- return pdc_iodc_getc();
+ int c;
+ unsigned long flags;
+
+ spin_lock_irqsave(&pdc_console_lock, flags);
+ c = pdc_iodc_getc();
+ spin_unlock_irqrestore(&pdc_console_lock, flags);
+
+ return c;
}
static int pdc_console_setup(struct console *co, char *options)