diff options
| -rw-r--r-- | arch/sparc/include/asm/oplib_32.h | 4 | ||||
| -rw-r--r-- | arch/sparc/include/asm/oplib_64.h | 4 | ||||
| -rw-r--r-- | arch/sparc/prom/console_32.c | 14 | ||||
| -rw-r--r-- | arch/sparc/prom/console_64.c | 27 | ||||
| -rw-r--r-- | arch/sparc/prom/printf.c | 32 |
5 files changed, 52 insertions, 29 deletions
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 40bc9efb1ac4..9e5c64084b86 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h | |||
| @@ -102,8 +102,8 @@ extern int prom_getrev(void); | |||
| 102 | /* Get the prom firmware revision. */ | 102 | /* Get the prom firmware revision. */ |
| 103 | extern int prom_getprev(void); | 103 | extern int prom_getprev(void); |
| 104 | 104 | ||
| 105 | /* Blocking put character to console. */ | 105 | /* Write a buffer of characters to the console. */ |
| 106 | extern void prom_putchar(const char *buf); | 106 | extern void prom_console_write_buf(const char *buf, int len); |
| 107 | 107 | ||
| 108 | /* Prom's internal routines, don't use in kernel/boot code. */ | 108 | /* Prom's internal routines, don't use in kernel/boot code. */ |
| 109 | extern void prom_printf(const char *fmt, ...); | 109 | extern void prom_printf(const char *fmt, ...); |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index d4613738c537..8cd0df34e82b 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
| @@ -94,8 +94,8 @@ extern void prom_halt_power_off(void) __attribute__ ((noreturn)); | |||
| 94 | */ | 94 | */ |
| 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); | 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); |
| 96 | 96 | ||
| 97 | /* Blocking put character to console. */ | 97 | /* Write a buffer of characters to the console. */ |
| 98 | extern void prom_putchar(const char *buf); | 98 | extern void prom_console_write_buf(const char *buf, int len); |
| 99 | 99 | ||
| 100 | /* Prom's internal routines, don't use in kernel/boot code. */ | 100 | /* Prom's internal routines, don't use in kernel/boot code. */ |
| 101 | extern void prom_printf(const char *fmt, ...); | 101 | extern void prom_printf(const char *fmt, ...); |
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 157019e29fd4..48863108a44c 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c | |||
| @@ -43,12 +43,14 @@ static int prom_nbputchar(const char *buf) | |||
| 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | /* Blocking version of put character routine above. */ | 46 | void prom_console_write_buf(const char *buf, int len) |
| 47 | void prom_putchar(const char *buf) | ||
| 48 | { | 47 | { |
| 49 | while (1) { | 48 | while (len) { |
| 50 | int err = prom_nbputchar(buf); | 49 | int n = prom_nbputchar(buf); |
| 51 | if (!err) | 50 | if (n) |
| 52 | break; | 51 | continue; |
| 52 | len--; | ||
| 53 | buf++; | ||
| 53 | } | 54 | } |
| 54 | } | 55 | } |
| 56 | |||
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 0da88d10beff..ed39e75828bd 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
| @@ -15,35 +15,34 @@ | |||
| 15 | 15 | ||
| 16 | extern int prom_stdin, prom_stdout; | 16 | extern int prom_stdin, prom_stdout; |
| 17 | 17 | ||
| 18 | /* Non blocking put character to console device, returns -1 if | 18 | static int __prom_console_write_buf(const char *buf, int len) |
| 19 | * unsuccessful. | ||
| 20 | */ | ||
| 21 | static int prom_nbputchar(const char *buf) | ||
| 22 | { | 19 | { |
| 23 | unsigned long args[7]; | 20 | unsigned long args[7]; |
| 21 | int ret; | ||
| 24 | 22 | ||
| 25 | args[0] = (unsigned long) "write"; | 23 | args[0] = (unsigned long) "write"; |
| 26 | args[1] = 3; | 24 | args[1] = 3; |
| 27 | args[2] = 1; | 25 | args[2] = 1; |
| 28 | args[3] = (unsigned int) prom_stdout; | 26 | args[3] = (unsigned int) prom_stdout; |
| 29 | args[4] = (unsigned long) buf; | 27 | args[4] = (unsigned long) buf; |
| 30 | args[5] = 1; | 28 | args[5] = (unsigned int) len; |
| 31 | args[6] = (unsigned long) -1; | 29 | args[6] = (unsigned long) -1; |
| 32 | 30 | ||
| 33 | p1275_cmd_direct(args); | 31 | p1275_cmd_direct(args); |
| 34 | 32 | ||
| 35 | if (args[6] == 1) | 33 | ret = (int) args[6]; |
| 36 | return 0; | 34 | if (ret < 0) |
| 37 | else | ||
| 38 | return -1; | 35 | return -1; |
| 36 | return ret; | ||
| 39 | } | 37 | } |
| 40 | 38 | ||
| 41 | /* Blocking version of put character routine above. */ | 39 | void prom_console_write_buf(const char *buf, int len) |
| 42 | void prom_putchar(const char *buf) | ||
| 43 | { | 40 | { |
| 44 | while (1) { | 41 | while (len) { |
| 45 | int err = prom_nbputchar(buf); | 42 | int n = __prom_console_write_buf(buf, len); |
| 46 | if (!err) | 43 | if (n < 0) |
| 47 | break; | 44 | continue; |
| 45 | len -= n; | ||
| 46 | buf += len; | ||
| 48 | } | 47 | } |
| 49 | } | 48 | } |
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 | |||
| 22 | static char ppbuf[1024]; | 25 | static char ppbuf[1024]; |
| 26 | static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; | ||
| 27 | static DEFINE_RAW_SPINLOCK(console_write_lock); | ||
| 23 | 28 | ||
| 24 | void notrace prom_write(const char *buf, unsigned int n) | 29 | void 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 | ||
| 37 | void notrace prom_printf(const char *fmt, ...) | 59 | void notrace prom_printf(const char *fmt, ...) |
