xref: /linux/arch/sparc/prom/printf.c (revision 0d456bad36d42d16022be045c8a53ddbb59ee478)
1 /*
2  * printf.c:  Internal prom library printf facility.
3  *
4  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
5  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
6  * Copyright (c) 2002 Pete Zaitcev (zaitcev@yahoo.com)
7  *
8  * We used to warn all over the code: DO NOT USE prom_printf(),
9  * and yet people do. Anton's banking code was outputting banks
10  * with prom_printf for most of the 2.4 lifetime. Since an effective
11  * stick is not available, we deployed a carrot: an early printk
12  * through PROM by means of -p boot option. This ought to fix it.
13  * USE printk; if you need, deploy -p.
14  */
15 
16 #include <linux/kernel.h>
17 #include <linux/compiler.h>
18 #include <linux/spinlock.h>
19 
20 #include <asm/openprom.h>
21 #include <asm/oplib.h>
22 
23 #define CONSOLE_WRITE_BUF_SIZE	1024
24 
25 static char ppbuf[1024];
26 static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
27 static DEFINE_RAW_SPINLOCK(console_write_lock);
28 
29 void notrace prom_write(const char *buf, unsigned int n)
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;
39 	while (n-- != 0) {
40 		char ch = *buf++;
41 		if (ch == '\n') {
42 			*dest++ = '\r';
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;
51 		}
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);
57 }
58 
59 void notrace prom_printf(const char *fmt, ...)
60 {
61 	va_list args;
62 	int i;
63 
64 	va_start(args, fmt);
65 	i = vscnprintf(ppbuf, sizeof(ppbuf), fmt, args);
66 	va_end(args);
67 
68 	prom_write(ppbuf, i);
69 }
70