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