Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / boot / common / console.c
1 /*-
2  * Copyright (c) 1998 Michael Smith <msmith@freebsd.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD: src/sys/boot/common/console.c,v 1.5 1999/08/28 00:39:46 peter Exp $
27  * $DragonFly: src/sys/boot/common/console.c,v 1.2 2003/06/17 04:28:16 dillon Exp $
28  */
29
30 #include <stand.h>
31 #include <string.h>
32
33 #include "bootstrap.h"
34 /*
35  * Core console support
36  */
37
38 static int      cons_set(struct env_var *ev, int flags, void *value);
39 static int      cons_find(char *name);
40
41 /*
42  * Detect possible console(s) to use.  The first probed console
43  * is marked active.  Also create the console variable.
44  *      
45  * XXX Add logic for multiple console support.
46  */
47 void
48 cons_probe(void) 
49 {
50     int                 cons;
51     int                 active;
52     char                *prefconsole;
53     
54     /* Do all console probes */
55     for (cons = 0; consoles[cons] != NULL; cons++) {
56         consoles[cons]->c_flags = 0;
57         consoles[cons]->c_probe(consoles[cons]);
58     }
59     /* Now find the first working one */
60     active = -1;
61     for (cons = 0; consoles[cons] != NULL && active == -1; cons++) {
62         consoles[cons]->c_flags = 0;
63         consoles[cons]->c_probe(consoles[cons]);
64         if (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT))
65             active = cons;
66     }
67
68     /* Check to see if a console preference has already been registered */
69     prefconsole = getenv("console");
70     if (prefconsole != NULL)
71         prefconsole = strdup(prefconsole);
72     if (prefconsole != NULL) {
73         unsetenv("console");            /* we want to replace this */
74         for (cons = 0; consoles[cons] != NULL; cons++)
75             /* look for the nominated console, use it if it's functional */
76             if (!strcmp(prefconsole, consoles[cons]->c_name) &&
77                 (consoles[cons]->c_flags == (C_PRESENTIN | C_PRESENTOUT)))
78                 active = cons;
79         free(prefconsole);
80     }
81     if (active == -1)
82         active = 0;
83     consoles[active]->c_flags |= (C_ACTIVEIN | C_ACTIVEOUT);
84     consoles[active]->c_init(0);
85
86     printf("Console: %s\n", consoles[active]->c_desc);
87     env_setenv("console", EV_VOLATILE, consoles[active]->c_name, cons_set,
88         env_nounset);
89 }
90
91 int
92 getchar(void)
93 {
94     int         cons;
95     int         rv;
96     
97     /* Loop forever polling all active consoles */
98     for(;;)
99         for (cons = 0; consoles[cons] != NULL; cons++)
100             if ((consoles[cons]->c_flags & C_ACTIVEIN) && 
101                 ((rv = consoles[cons]->c_in()) != -1))
102                 return(rv);
103 }
104
105 int
106 ischar(void)
107 {
108     int         cons;
109
110     for (cons = 0; consoles[cons] != NULL; cons++)
111         if ((consoles[cons]->c_flags & C_ACTIVEIN) && 
112             (consoles[cons]->c_ready() != 0))
113                 return(1);
114     return(0);
115 }
116
117 void
118 putchar(int c)
119 {
120     int         cons;
121     
122     /* Expand newlines */
123     if (c == '\n')
124         putchar('\r');
125     
126     for (cons = 0; consoles[cons] != NULL; cons++)
127         if (consoles[cons]->c_flags & C_ACTIVEOUT)
128             consoles[cons]->c_out(c);
129 }
130
131 static int
132 cons_find(char *name)
133 {
134     int         cons;
135     
136     for (cons = 0; consoles[cons] != NULL; cons++)
137         if (!strcmp(consoles[cons]->c_name, name))
138             return(cons);
139     return(-1);
140 }
141     
142
143 /*
144  * Select a console.
145  *
146  * XXX Note that the console system design allows for some extension
147  *     here (eg. multiple consoles, input/output only, etc.)
148  */
149 static int
150 cons_set(struct env_var *ev, int flags, void *value)
151 {
152     int         cons, active;
153
154     if ((value == NULL) || ((active = cons_find(value)) == -1)) {
155         if (value != NULL) 
156             printf("no such console '%s'\n", (char *)value);
157         printf("Available consoles:\n");
158         for (cons = 0; consoles[cons] != NULL; cons++)
159             printf("    %s\n", consoles[cons]->c_name);
160         return(CMD_ERROR);
161     }
162
163     /* disable all current consoles */
164     for (cons = 0; consoles[cons] != NULL; cons++)
165         consoles[cons]->c_flags &= ~(C_ACTIVEIN | C_ACTIVEOUT);
166     
167     /* enable selected console */
168     consoles[active]->c_flags |= C_ACTIVEIN | C_ACTIVEOUT;
169     consoles[active]->c_init(0);
170
171     env_setenv(ev->ev_name, flags | EV_NOHOOK, value, NULL, NULL);
172     return(CMD_OK);
173 }