Merge branch 'for-3.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[platform/adaptation/renesas_rcar/renesas_kernel.git] / arch / powerpc / xmon / nonstdio.c
1 /*
2  * Copyright (C) 1996-2005 Paul Mackerras.
3  *
4  *      This program is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU General Public License
6  *      as published by the Free Software Foundation; either version
7  *      2 of the License, or (at your option) any later version.
8  */
9 #include <linux/string.h>
10 #include <asm/udbg.h>
11 #include <asm/time.h>
12 #include "nonstdio.h"
13
14
15 static int xmon_write(const void *ptr, int nb)
16 {
17         return udbg_write(ptr, nb);
18 }
19
20 static int xmon_readchar(void)
21 {
22         if (udbg_getc)
23                 return udbg_getc();
24         return -1;
25 }
26
27 int xmon_putchar(int c)
28 {
29         char ch = c;
30
31         if (c == '\n')
32                 xmon_putchar('\r');
33         return xmon_write(&ch, 1) == 1? c: -1;
34 }
35
36 static char line[256];
37 static char *lineptr;
38 static int lineleft;
39
40 static int xmon_getchar(void)
41 {
42         int c;
43
44         if (lineleft == 0) {
45                 lineptr = line;
46                 for (;;) {
47                         c = xmon_readchar();
48                         if (c == -1 || c == 4)
49                                 break;
50                         if (c == '\r' || c == '\n') {
51                                 *lineptr++ = '\n';
52                                 xmon_putchar('\n');
53                                 break;
54                         }
55                         switch (c) {
56                         case 0177:
57                         case '\b':
58                                 if (lineptr > line) {
59                                         xmon_putchar('\b');
60                                         xmon_putchar(' ');
61                                         xmon_putchar('\b');
62                                         --lineptr;
63                                 }
64                                 break;
65                         case 'U' & 0x1F:
66                                 while (lineptr > line) {
67                                         xmon_putchar('\b');
68                                         xmon_putchar(' ');
69                                         xmon_putchar('\b');
70                                         --lineptr;
71                                 }
72                                 break;
73                         default:
74                                 if (lineptr >= &line[sizeof(line) - 1])
75                                         xmon_putchar('\a');
76                                 else {
77                                         xmon_putchar(c);
78                                         *lineptr++ = c;
79                                 }
80                         }
81                 }
82                 lineleft = lineptr - line;
83                 lineptr = line;
84         }
85         if (lineleft == 0)
86                 return -1;
87         --lineleft;
88         return *lineptr++;
89 }
90
91 char *xmon_gets(char *str, int nb)
92 {
93         char *p;
94         int c;
95
96         for (p = str; p < str + nb - 1; ) {
97                 c = xmon_getchar();
98                 if (c == -1) {
99                         if (p == str)
100                                 return NULL;
101                         break;
102                 }
103                 *p++ = c;
104                 if (c == '\n')
105                         break;
106         }
107         *p = 0;
108         return str;
109 }
110
111 void xmon_printf(const char *format, ...)
112 {
113         va_list args;
114         static char xmon_outbuf[1024];
115         int rc, n;
116
117         va_start(args, format);
118         n = vsnprintf(xmon_outbuf, sizeof(xmon_outbuf), format, args);
119         va_end(args);
120
121         rc = xmon_write(xmon_outbuf, n);
122
123         if (n && rc == 0) {
124                 /* No udbg hooks, fallback to printk() - dangerous */
125                 printk(xmon_outbuf);
126         }
127 }
128
129 void xmon_puts(const char *str)
130 {
131         xmon_write(str, strlen(str));
132 }