3 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arsenio@tin.it
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
39 LIST_HEAD(console_list
);
40 EXPORT_SYMBOL(console_list
);
42 #define CONSOLE_UNINITIALIZED 0
43 #define CONSOLE_INIT_EARLY 1
44 #define CONSOLE_INIT_FULL 2
46 extern char version_string
[];
48 static void display_banner (void)
50 printf (RELOC("\n\n%s\n\n"), RELOC_VAR(version_string
));
51 printf(RELOC("Board: " CONFIG_BOARDINFO
"\n"));
54 static int __initdata initialized
= 0;
56 static int console_std_set(struct device_d
*dev
, struct param_d
*param
,
59 struct console_device
*cdev
= dev
->type_data
;
60 unsigned int flag
= 0, i
= 0;
62 if (strchr(val
, 'i') && cdev
->f_caps
& CONSOLE_STDIN
) {
63 cdev
->active
[i
++] = 'i';
64 flag
|= CONSOLE_STDIN
;
67 if (strchr(val
, 'o') && cdev
->f_caps
& CONSOLE_STDOUT
) {
68 cdev
->active
[i
++] = 'o';
69 flag
|= CONSOLE_STDOUT
;
72 if (strchr(val
, 'e') && cdev
->f_caps
& CONSOLE_STDERR
) {
73 cdev
->active
[i
++] = 'e';
74 flag
|= CONSOLE_STDERR
;
78 cdev
->f_active
= flag
;
83 static int console_baudrate_set(struct device_d
*dev
, struct param_d
*param
,
86 struct console_device
*cdev
= dev
->type_data
;
90 baudrate
= simple_strtoul(val
, NULL
, 10);
93 printf("## Switch baudrate to %d bps and press ENTER ...\n",
96 cdev
->setbrg(cdev
, baudrate
);
100 } while (c
!= '\r' && c
!= '\n');
102 cdev
->setbrg(cdev
, baudrate
);
104 sprintf(cdev
->baudrate_string
, "%d", baudrate
);
109 static struct kfifo
*console_input_buffer
;
110 static struct kfifo
*console_output_buffer
;
112 int getc_buffer_flush(void)
114 console_input_buffer
= kfifo_alloc(1024);
115 console_output_buffer
= kfifo_alloc(1024);
119 postcore_initcall(getc_buffer_flush
);
121 int console_register(struct console_device
*newcdev
)
123 struct device_d
*dev
= &newcdev
->class_dev
;
127 strcpy(dev
->name
, "cs");
128 dev
->type_data
= newcdev
;
129 register_device(dev
);
131 if (newcdev
->setbrg
) {
132 newcdev
->baudrate_param
.set
= console_baudrate_set
;
133 newcdev
->baudrate_param
.name
= "baudrate";
134 sprintf(newcdev
->baudrate_string
, "%d",
136 console_baudrate_set(dev
, &newcdev
->baudrate_param
,
137 newcdev
->baudrate_string
);
138 newcdev
->baudrate_param
.value
= newcdev
->baudrate_string
;
139 dev_add_param(dev
, &newcdev
->baudrate_param
);
142 newcdev
->active_param
.set
= console_std_set
;
143 newcdev
->active_param
.name
= "active";
144 newcdev
->active_param
.value
= newcdev
->active
;
145 dev_add_param(dev
, &newcdev
->active_param
);
147 initialized
= CONSOLE_INIT_FULL
;
148 #ifdef CONFIG_CONSOLE_ACTIVATE_ALL
149 console_std_set(dev
, &newcdev
->active_param
, "ioe");
151 #ifdef CONFIG_CONSOLE_ACTIVATE_FIRST
152 if (list_empty(&console_list
)) {
154 console_std_set(dev
, &newcdev
->active_param
, "ioe");
158 list_add_tail(&newcdev
->list
, &console_list
);
160 if (console_output_buffer
) {
161 while (kfifo_getc(console_output_buffer
, &ch
) == 0)
162 console_putc(CONSOLE_STDOUT
, ch
);
163 kfifo_free(console_output_buffer
);
164 console_output_buffer
= NULL
;
167 #ifndef CONFIG_HAS_EARLY_INIT
174 EXPORT_SYMBOL(console_register
);
176 static int getc_raw(void)
178 struct console_device
*cdev
;
182 for_each_console(cdev
) {
183 if (!(cdev
->f_active
& CONSOLE_STDIN
))
186 if (cdev
->tstc(cdev
))
187 return cdev
->getc(cdev
);
190 /* no active console found. bail out */
201 * For 100us we read the characters from the serial driver
202 * into a kfifo. This helps us not to lose characters
203 * in small hardware fifos.
205 start
= get_time_ns();
208 kfifo_putc(console_input_buffer
, getc_raw());
210 start
= get_time_ns();
212 if (is_timeout(start
, 100 * USECOND
) &&
213 kfifo_len(console_input_buffer
))
217 kfifo_getc(console_input_buffer
, &ch
);
228 return read(fd
, &c
, 1);
230 EXPORT_SYMBOL(fgetc
);
234 struct console_device
*cdev
;
236 for_each_console(cdev
) {
237 if (!(cdev
->f_active
& CONSOLE_STDIN
))
239 if (cdev
->tstc(cdev
))
247 void __initdata
*early_console_base
;
249 void console_putc(unsigned int ch
, char c
)
251 struct console_device
*cdev
;
252 int init
= INITDATA(initialized
);
255 case CONSOLE_UNINITIALIZED
:
256 kfifo_putc(console_output_buffer
, c
);
259 #ifdef CONFIG_HAS_EARLY_INIT
260 case CONSOLE_INIT_EARLY
:
261 early_console_putc(INITDATA(early_console_base
), c
);
265 case CONSOLE_INIT_FULL
:
266 for_each_console(cdev
) {
267 if (cdev
->f_active
& ch
) {
269 cdev
->putc(cdev
, '\r');
275 /* If we have problems inititalizing our data
281 EXPORT_SYMBOL(console_putc
);
283 int fputc(int fd
, char c
)
285 if(list_empty(&console_list
)) {
296 return write(fd
, &c
, 1);
299 EXPORT_SYMBOL(fputc
);
301 void console_puts(unsigned int ch
, const char *str
)
306 console_putc(ch
, '\r');
307 console_putc(ch
, *s
);
311 EXPORT_SYMBOL(console_puts
);
313 int fputs(int fd
, const char *s
)
320 return write(fd
, s
, strlen(s
));
323 EXPORT_SYMBOL(fputs
);
325 void console_flush(void)
327 struct console_device
*cdev
;
329 for_each_console(cdev
) {
334 EXPORT_SYMBOL(console_flush
);
336 void fprintf (int file
, const char *fmt
, ...)
340 char printbuffer
[CFG_PBSIZE
];
342 va_start (args
, fmt
);
344 /* For this to work, printbuffer must be larger than
345 * anything we ever want to print.
347 i
= vsprintf (printbuffer
, fmt
, args
);
350 /* Print the string */
351 fputs (file
, printbuffer
);
353 EXPORT_SYMBOL(fprintf
);
355 int printf (const char *fmt
, ...)
359 char printbuffer
[CFG_PBSIZE
];
361 va_start (args
, fmt
);
363 /* For this to work, printbuffer must be larger than
364 * anything we ever want to print.
366 i
= vsprintf (printbuffer
, fmt
, args
);
369 /* Print the string */
374 EXPORT_SYMBOL(printf
);
376 int vprintf (const char *fmt
, va_list args
)
379 char printbuffer
[CFG_PBSIZE
];
381 /* For this to work, printbuffer must be larger than
382 * anything we ever want to print.
384 i
= vsprintf (printbuffer
, fmt
, args
);
386 /* Print the string */
391 EXPORT_SYMBOL(vprintf
);
393 #ifndef ARCH_HAS_CTRLC
394 /* test if ctrl-c was pressed */
397 if (tstc() && getc() == 3)
401 EXPORT_SYMBOL(ctrlc
);
402 #endif /* ARCH_HAS_CTRC */
404 #ifdef CONFIG_HAS_EARLY_INIT
406 void early_console_start(const char *name
, int baudrate
)
408 void *base
= get_early_console_base(name
);
411 early_console_init(base
, baudrate
);
412 INITDATA(initialized
) = CONSOLE_INIT_EARLY
;
413 INITDATA(early_console_base
) = base
;