Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * printf.c:  Internal prom library printf facility.
0004  *
0005  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
0006  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
0007  * Copyright (c) 2002 Pete Zaitcev (zaitcev@yahoo.com)
0008  *
0009  * We used to warn all over the code: DO NOT USE prom_printf(),
0010  * and yet people do. Anton's banking code was outputting banks
0011  * with prom_printf for most of the 2.4 lifetime. Since an effective
0012  * stick is not available, we deployed a carrot: an early printk
0013  * through PROM by means of -p boot option. This ought to fix it.
0014  * USE printk; if you need, deploy -p.
0015  */
0016 
0017 #include <linux/kernel.h>
0018 #include <linux/compiler.h>
0019 #include <linux/spinlock.h>
0020 
0021 #include <asm/openprom.h>
0022 #include <asm/oplib.h>
0023 
0024 #define CONSOLE_WRITE_BUF_SIZE  1024
0025 
0026 static char ppbuf[1024];
0027 static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
0028 static DEFINE_RAW_SPINLOCK(console_write_lock);
0029 
0030 void notrace prom_write(const char *buf, unsigned int n)
0031 {
0032     unsigned int dest_len;
0033     unsigned long flags;
0034     char *dest;
0035 
0036     dest = console_write_buf;
0037     raw_spin_lock_irqsave(&console_write_lock, flags);
0038 
0039     dest_len = 0;
0040     while (n-- != 0) {
0041         char ch = *buf++;
0042         if (ch == '\n') {
0043             *dest++ = '\r';
0044             dest_len++;
0045         }
0046         *dest++ = ch;
0047         dest_len++;
0048         if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) {
0049             prom_console_write_buf(console_write_buf, dest_len);
0050             dest = console_write_buf;
0051             dest_len = 0;
0052         }
0053     }
0054     if (dest_len)
0055         prom_console_write_buf(console_write_buf, dest_len);
0056 
0057     raw_spin_unlock_irqrestore(&console_write_lock, flags);
0058 }
0059 
0060 void notrace prom_printf(const char *fmt, ...)
0061 {
0062     va_list args;
0063     int i;
0064 
0065     va_start(args, fmt);
0066     i = vscnprintf(ppbuf, sizeof(ppbuf), fmt, args);
0067     va_end(args);
0068 
0069     prom_write(ppbuf, i);
0070 }