Merge branch 'drm-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6
[linux-2.6] / arch / ppc64 / xmon / start.c
1 /*
2  * Copyright (C) 1996 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/config.h>
10 #include <linux/string.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/sysrq.h>
14 #include <linux/init.h>
15 #include <asm/machdep.h>
16 #include <asm/io.h>
17 #include <asm/page.h>
18 #include <asm/prom.h>
19 #include <asm/processor.h>
20 #include <asm/udbg.h>
21 #include <asm/system.h>
22 #include "nonstdio.h"
23
24 #ifdef CONFIG_MAGIC_SYSRQ
25
26 static void sysrq_handle_xmon(int key, struct pt_regs *pt_regs,
27                               struct tty_struct *tty) 
28 {
29         /* ensure xmon is enabled */
30         xmon_init(1);
31         debugger(pt_regs);
32 }
33
34 static struct sysrq_key_op sysrq_xmon_op = 
35 {
36         .handler =      sysrq_handle_xmon,
37         .help_msg =     "Xmon",
38         .action_msg =   "Entering xmon",
39 };
40
41 static int __init setup_xmon_sysrq(void)
42 {
43         register_sysrq_key('x', &sysrq_xmon_op);
44         return 0;
45 }
46 __initcall(setup_xmon_sysrq);
47 #endif /* CONFIG_MAGIC_SYSRQ */
48
49 int
50 xmon_write(void *handle, void *ptr, int nb)
51 {
52         return udbg_write(ptr, nb);
53 }
54
55 int
56 xmon_read(void *handle, void *ptr, int nb)
57 {
58         return udbg_read(ptr, nb);
59 }
60
61 int
62 xmon_read_poll(void)
63 {
64         if (udbg_getc_poll)
65                 return udbg_getc_poll();
66         return -1;
67 }
68  
69 FILE *xmon_stdin;
70 FILE *xmon_stdout;
71
72 int
73 xmon_putc(int c, void *f)
74 {
75         char ch = c;
76
77         if (c == '\n')
78                 xmon_putc('\r', f);
79         return xmon_write(f, &ch, 1) == 1? c: -1;
80 }
81
82 int
83 xmon_putchar(int c)
84 {
85         return xmon_putc(c, xmon_stdout);
86 }
87
88 int
89 xmon_fputs(char *str, void *f)
90 {
91         int n = strlen(str);
92
93         return xmon_write(f, str, n) == n? 0: -1;
94 }
95
96 int
97 xmon_readchar(void)
98 {
99         char ch;
100
101         for (;;) {
102                 switch (xmon_read(xmon_stdin, &ch, 1)) {
103                 case 1:
104                         return ch;
105                 case -1:
106                         xmon_printf("read(stdin) returned -1\r\n", 0, 0);
107                         return -1;
108                 }
109         }
110 }
111
112 static char line[256];
113 static char *lineptr;
114 static int lineleft;
115
116 int
117 xmon_getchar(void)
118 {
119         int c;
120
121         if (lineleft == 0) {
122                 lineptr = line;
123                 for (;;) {
124                         c = xmon_readchar();
125                         if (c == -1 || c == 4)
126                                 break;
127                         if (c == '\r' || c == '\n') {
128                                 *lineptr++ = '\n';
129                                 xmon_putchar('\n');
130                                 break;
131                         }
132                         switch (c) {
133                         case 0177:
134                         case '\b':
135                                 if (lineptr > line) {
136                                         xmon_putchar('\b');
137                                         xmon_putchar(' ');
138                                         xmon_putchar('\b');
139                                         --lineptr;
140                                 }
141                                 break;
142                         case 'U' & 0x1F:
143                                 while (lineptr > line) {
144                                         xmon_putchar('\b');
145                                         xmon_putchar(' ');
146                                         xmon_putchar('\b');
147                                         --lineptr;
148                                 }
149                                 break;
150                         default:
151                                 if (lineptr >= &line[sizeof(line) - 1])
152                                         xmon_putchar('\a');
153                                 else {
154                                         xmon_putchar(c);
155                                         *lineptr++ = c;
156                                 }
157                         }
158                 }
159                 lineleft = lineptr - line;
160                 lineptr = line;
161         }
162         if (lineleft == 0)
163                 return -1;
164         --lineleft;
165         return *lineptr++;
166 }
167
168 char *
169 xmon_fgets(char *str, int nb, void *f)
170 {
171         char *p;
172         int c;
173
174         for (p = str; p < str + nb - 1; ) {
175                 c = xmon_getchar();
176                 if (c == -1) {
177                         if (p == str)
178                                 return NULL;
179                         break;
180                 }
181                 *p++ = c;
182                 if (c == '\n')
183                         break;
184         }
185         *p = 0;
186         return str;
187 }