kern_cons.c revision 798
1139823Simp/*
22788Sdg * Copyright (c) 1988 University of Utah.
32788Sdg * Copyright (c) 1991 The Regents of the University of California.
42788Sdg * All rights reserved.
52788Sdg *
62788Sdg * This code is derived from software contributed to Berkeley by
72788Sdg * the Systems Programming Group of the University of Utah Computer
82788Sdg * Science Department.
92788Sdg *
102788Sdg * Redistribution and use in source and binary forms, with or without
112788Sdg * modification, are permitted provided that the following conditions
122788Sdg * are met:
132788Sdg * 1. Redistributions of source code must retain the above copyright
142788Sdg *    notice, this list of conditions and the following disclaimer.
152788Sdg * 2. Redistributions in binary form must reproduce the above copyright
162788Sdg *    notice, this list of conditions and the following disclaimer in the
172788Sdg *    documentation and/or other materials provided with the distribution.
182788Sdg * 3. All advertising materials mentioning features or use of this software
192788Sdg *    must display the following acknowledgement:
202788Sdg *	This product includes software developed by the University of
212788Sdg *	California, Berkeley and its contributors.
222788Sdg * 4. Neither the name of the University nor the names of its contributors
232788Sdg *    may be used to endorse or promote products derived from this software
242788Sdg *    without specific prior written permission.
252788Sdg *
262788Sdg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
272788Sdg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
282788Sdg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2910941Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
302788Sdg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
311541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32172467Ssilby * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33172467Ssilby * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34172467Ssilby * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35118622Shsu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3655009Sshin * SUCH DAMAGE.
37220746Sbz *
3855009Sshin *	from: @(#)cons.c	7.2 (Berkeley) 5/9/91
39163953Srrs *	$Id: cons.c,v 1.5 1993/11/07 17:41:32 wollman Exp $
40178167Sqingli */
4130966Sjoerg
422788Sdg
43111145Sjlemon#include "sys/param.h"
448426Swollman#include "sys/proc.h"
452788Sdg#include "sys/user.h"
462788Sdg#include "sys/systm.h"
47185895Szec#include "sys/buf.h"
4812426Sphk#include "sys/ioctl.h"
4944078Sdfr#include "sys/tty.h"
5012172Sphk#include "sys/file.h"
511541Srgrimes#include "sys/conf.h"
52220746Sbz#include "machine/stdarg.h"
53220746Sbz
54220746Sbz#include "machine/cons.h"
55220746Sbz
56220746Sbz/* XXX - all this could be autoconfig()ed */
57220746Sbzint pccnprobe(), pccninit(), pccngetc(), pccnputc();
58220746Sbz#include "com.h"
592788Sdg#if NCOM > 0
60257176Sglebiusint comcnprobe(), comcninit(), comcngetc(), comcnputc();
612788Sdg#endif
62178167Sqingli
63178167Sqinglistruct	consdev constab[] = {
64178167Sqingli	{ pccnprobe,	pccninit,	pccngetc,	pccnputc },
65196019Srwatson#if NCOM > 0
66221021Sbz	{ comcnprobe,	comcninit,	comcngetc,	comcnputc },
671541Srgrimes#endif
68221021Sbz	{ 0 },
692788Sdg};
70221021Sbz/* end XXX */
71221021Sbz
72221021Sbzstruct	tty *constty = 0;	/* virtual console output device */
732788Sdgstruct	consdev *cn_tab;	/* physical console device info */
74186119Sqinglistruct	tty *cn_tty;		/* XXX: console tty struct for tprintf */
752788Sdg
762788Sdgvoid
772788Sdgcninit()
782788Sdg{
792788Sdg	register struct consdev *cp;
802788Sdg
812788Sdg	/*
822788Sdg	 * Collect information about all possible consoles
832788Sdg	 * and find the one with highest priority
8462587Sitojun	 */
8555009Sshin	for (cp = constab; cp->cn_probe; cp++) {
862788Sdg		(*cp->cn_probe)(cp);
872788Sdg		if (cp->cn_pri > CN_DEAD &&
882788Sdg		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
891541Srgrimes			cn_tab = cp;
90148918Sobrien	}
91148918Sobrien	/*
92171167Sgnn	 * No console, we can handle it
93105199Ssam	 */
94171167Sgnn	if ((cp = cn_tab) == NULL)
95105199Ssam		return;
96163953Srrs	/*
97163953Srrs	 * Turn on console
98163953Srrs	 */
99163953Srrs	cn_tty = cp->cn_tp;
100163953Srrs	(*cp->cn_init)(cp);
101163953Srrs}
102163953Srrs
103222272Sbzint
104222272Sbzcnopen(dev, flag, mode, p)
1052788Sdg	dev_t dev;
1062531Swollman	int flag, mode;
107136695Sandre	struct proc *p;
108152242Sru{
109152242Sru	if (cn_tab == NULL)
110152242Sru		return (0);
111152242Sru	dev = cn_tab->cn_dev;
112152242Sru	return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
113136695Sandre}
114136695Sandre
11582884Sjulianint
116152242Srucnclose(dev, flag, mode, p)
117152242Sru	dev_t dev;
118152242Sru	int flag, mode;
119152242Sru	struct proc *p;
120152242Sru{
121204140Sbz	if (cn_tab == NULL)
122204140Sbz		return (0);
123204140Sbz	dev = cn_tab->cn_dev;
124152242Sru	return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
125152242Sru}
126152242Sru
1272788Sdgint
128152242Srucnread(dev, uio, flag)
129152242Sru	dev_t dev;
130152242Sru	struct uio *uio;
131152242Sru	int flag;
132152242Sru{
133152242Sru	if (cn_tab == NULL)
134152242Sru		return (0);
135194062Svanhu	dev = cn_tab->cn_dev;
136152242Sru	return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
137193731Szec}
138193731Szec
139193731Szecint
140152242Srucnwrite(dev, uio, flag)
1412788Sdg	dev_t dev;
142152242Sru	struct uio *uio;
143152242Sru	int flag;
144152242Sru{
145152242Sru	if (cn_tab == NULL)
146152242Sru		return (0);
147152242Sru	if (constty)					/* 16 Aug 92*/
148152242Sru		dev = constty->t_dev;
149152242Sru	else
150152242Sru		dev = cn_tab->cn_dev;
151193731Szec	return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
152193731Szec}
153193731Szec
154152242Sruint
155152242Srucnioctl(dev, cmd, data, flag, p)
156152242Sru	dev_t dev;
1572788Sdg	int cmd;
158163953Srrs	caddr_t data;
159163953Srrs	int flag;
160223963Stuexen	struct proc *p;
161197326Stuexen{
162197326Stuexen	int error;
163197326Stuexen
164197326Stuexen	if (cn_tab == NULL)
165197326Stuexen		return (0);
166197326Stuexen	/*
167197326Stuexen	 * Superuser can always use this to wrest control of console
168197326Stuexen	 * output from the "virtual" console.
169197326Stuexen	 */
170197326Stuexen	if (cmd == TIOCCONS && constty) {
171197326Stuexen		error = suser(p->p_ucred, (u_short *) NULL);
172197326Stuexen		if (error)
173163953Srrs			return (error);
174163953Srrs		constty = NULL;
175197326Stuexen		return (0);
176197326Stuexen	}
177197326Stuexen	dev = cn_tab->cn_dev;
178197326Stuexen	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
179197326Stuexen}
180197326Stuexen
181197326Stuexen/*ARGSUSED*/
182197326Stuexenint
183197326Stuexencnselect(dev, rw, p)
184163953Srrs	dev_t dev;
185163953Srrs	int rw;
186163953Srrs	struct proc *p;
187264212Skevlo{
188264212Skevlo	if (cn_tab == NULL)
189264212Skevlo		return (1);
190264212Skevlo	return (ttselect(cn_tab->cn_dev, rw, p));
191264212Skevlo}
192264212Skevlo
193264212Skevloint
194264212Skevlocngetc()
195264212Skevlo{
196264212Skevlo	if (cn_tab == NULL)
197264212Skevlo		return (0);
198264212Skevlo	return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
199264212Skevlo}
200264212Skevlo
201152242Sruvoid
202152242Srucnputc(c)
203152242Sru	register int c;
204152242Sru{
205152242Sru	if (cn_tab == NULL)
206152242Sru		return;
207152242Sru	if (c) {
208152242Sru		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
2092788Sdg		if (c == '\n')
210152242Sru			(*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
211152242Sru	}
212152242Sru}
213152242Sru
214152242Sruint
215152242Srupg(const char *p, ...) {
216152242Sru  va_list args;
217152242Sru  va_start(args, p);
2182788Sdg  printf("%r\n>", p, args);
219152242Sru  return(cngetc());
220152242Sru}
221152242Sru
222152242Sru
223152242Sru