aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/prom/printf.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-11-30 23:15:58 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-30 23:15:58 -0500
commit595a251c0740785fd3c0d2156d78578c7479811e (patch)
tree513cee9d682b12c2c4e490f7e91422e82530c4b8 /arch/sparc/prom/printf.c
parent12c7a35ee6a1c605e740733f2cbd5b5079f09f0f (diff)
sparc: Write to prom console using indirect buffer.
sparc64 systems have a restriction in that passing in buffer addressses above 4GB to prom calls is not reliable. We end up violating this when we do prom console writes, because we use an on-stack buffer to translate '\n' into '\r\n'. So instead, do this translation into an intermediate buffer, which is in the kernel image and thus below 4GB, then pass that to the PROM console write calls. On the 32-bit side we don't have to deal with any of these issues, so the new prom_console_write_buf() uses the existing prom_nbputchar() implementation. However we can now mark those routines static. Since the 64-bit side completely uses new code we can delete the putchar bits as they are now completely unused. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/prom/printf.c')
-rw-r--r--arch/sparc/prom/printf.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c
index 24031971f806..d9682f06b3b0 100644
--- a/arch/sparc/prom/printf.c
+++ b/arch/sparc/prom/printf.c
@@ -15,23 +15,45 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/compiler.h> 17#include <linux/compiler.h>
18#include <linux/spinlock.h>
18 19
19#include <asm/openprom.h> 20#include <asm/openprom.h>
20#include <asm/oplib.h> 21#include <asm/oplib.h>
21 22
23#define CONSOLE_WRITE_BUF_SIZE 1024
24
22static char ppbuf[1024]; 25static char ppbuf[1024];
26static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
27static DEFINE_RAW_SPINLOCK(console_write_lock);
23 28
24void notrace prom_write(const char *buf, unsigned int n) 29void notrace prom_write(const char *buf, unsigned int n)
25{ 30{
31 unsigned int dest_len;
32 unsigned long flags;
33 char *dest;
34
35 dest = console_write_buf;
36 raw_spin_lock_irqsave(&console_write_lock, flags);
37
38 dest_len = 0;
26 while (n-- != 0) { 39 while (n-- != 0) {
27 char ch = *buf; 40 char ch = *buf++;
28 if (ch == '\n') { 41 if (ch == '\n') {
29 char tmp = '\r'; 42 *dest++ = '\r';
30 prom_putchar(&tmp); 43 dest_len++;
44 }
45 *dest++ = ch;
46 dest_len++;
47 if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
48 prom_console_write_buf(console_write_buf, dest_len);
49 dest = console_write_buf;
50 dest_len = 0;
31 } 51 }
32 prom_putchar(buf);
33 buf++;
34 } 52 }
53 if (dest_len)
54 prom_console_write_buf(console_write_buf, dest_len);
55
56 raw_spin_unlock_irqrestore(&console_write_lock, flags);
35} 57}
36 58
37void notrace prom_printf(const char *fmt, ...) 59void notrace prom_printf(const char *fmt, ...)