Added netdev_nullify to natsemi_remove()
[gpxe.git] / src / core / console.c
blob6f55d5583fe1807cbd8d67ebc30375ef8b4b3f16
1 #include "stddef.h"
2 #include "console.h"
3 #include <gpxe/process.h>
5 /** @file */
7 #include "bios.h"
9 static struct console_driver console_drivers[0]
10 __table_start ( struct console_driver, console );
11 static struct console_driver console_drivers_end[0]
12 __table_end ( struct console_driver, console );
14 /**
15 * Write a single character to each console device.
17 * @v character Character to be written
18 * @ret None -
19 * @err None -
21 * The character is written out to all enabled console devices, using
22 * each device's console_driver::putchar() method.
25 void putchar ( int character ) {
26 struct console_driver *console;
28 /* Automatic LF -> CR,LF translation */
29 if ( character == '\n' )
30 putchar ( '\r' );
32 for ( console = console_drivers; console < console_drivers_end ;
33 console++ ) {
34 if ( ( ! console->disabled ) && console->putchar )
35 console->putchar ( character );
39 /**
40 * Check to see if any input is available on any console.
42 * @v None -
43 * @ret console Console device that has input available, if any.
44 * @ret NULL No console device has input available.
45 * @err None -
47 * All enabled console devices are checked once for available input
48 * using each device's console_driver::iskey() method. The first
49 * console device that has available input will be returned, if any.
52 static struct console_driver * has_input ( void ) {
53 struct console_driver *console;
55 for ( console = console_drivers; console < console_drivers_end ;
56 console++ ) {
57 if ( ( ! console->disabled ) && console->iskey ) {
58 if ( console->iskey () )
59 return console;
62 return NULL;
65 /**
66 * Read a single character from any console.
68 * @v None -
69 * @ret character Character read from a console.
70 * @err None -
72 * A character will be read from the first enabled console device that
73 * has input available using that console's console_driver::getchar()
74 * method. If no console has input available to be read, this method
75 * will block. To perform a non-blocking read, use something like
77 * @code
79 * int key = iskey() ? getchar() : -1;
81 * @endcode
83 * The character read will not be echoed back to any console.
85 * @bug We need a cleaner way to pick up cpu_nap(). It makes a
86 * real-mode call, and so we don't want to use it with LinuxBIOS.
89 int getchar ( void ) {
90 struct console_driver *console;
91 int character = 256;
93 while ( character == 256 ) {
94 /* Doze for a while (until the next interrupt). This works
95 * fine, because the keyboard is interrupt-driven, and the
96 * timer interrupt (approx. every 50msec) takes care of the
97 * serial port, which is read by polling. This reduces the
98 * power dissipation of a modern CPU considerably, and also
99 * makes Etherboot waiting for user interaction waste a lot
100 * less CPU time in a VMware session.
102 cpu_nap();
104 /* Keep processing background tasks while we wait for
105 * input.
107 step();
109 console = has_input();
110 if ( console && console->getchar )
111 character = console->getchar ();
114 /* CR -> LF translation */
115 if ( character == '\r' )
116 character = '\n';
118 return character;
121 /** Check for available input on any console.
123 * @v None -
124 * @ret True Input is available on a console
125 * @ret False Input is not available on any console
126 * @err None -
128 * All enabled console devices are checked once for available input
129 * using each device's console_driver::iskey() method. If any console
130 * device has input available, this call will return True. If this
131 * call returns True, you can then safely call getchar() without
132 * blocking.
135 int iskey ( void ) {
136 return has_input() ? 1 : 0;