kern_cons.c revision 2056
150276Speter/*
2166124Srafan * Copyright (c) 1988 University of Utah.
350276Speter * Copyright (c) 1991 The Regents of the University of California.
450276Speter * All rights reserved.
550276Speter *
650276Speter * This code is derived from software contributed to Berkeley by
750276Speter * the Systems Programming Group of the University of Utah Computer
850276Speter * Science Department.
950276Speter *
1050276Speter * Redistribution and use in source and binary forms, with or without
1150276Speter * modification, are permitted provided that the following conditions
1250276Speter * are met:
1350276Speter * 1. Redistributions of source code must retain the above copyright
1450276Speter *    notice, this list of conditions and the following disclaimer.
1550276Speter * 2. Redistributions in binary form must reproduce the above copyright
1650276Speter *    notice, this list of conditions and the following disclaimer in the
1750276Speter *    documentation and/or other materials provided with the distribution.
1850276Speter * 3. All advertising materials mentioning features or use of this software
1950276Speter *    must display the following acknowledgement:
2050276Speter *	This product includes software developed by the University of
2150276Speter *	California, Berkeley and its contributors.
2250276Speter * 4. Neither the name of the University nor the names of its contributors
2350276Speter *    may be used to endorse or promote products derived from this software
2450276Speter *    without specific prior written permission.
2550276Speter *
2650276Speter * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2750276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2850276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2950276Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30166124Srafan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3150276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3250276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3350276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3450276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3550276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3650276Speter * SUCH DAMAGE.
3750276Speter *
3850276Speter *	from: @(#)cons.c	7.2 (Berkeley) 5/9/91
3950276Speter *	$Id: cons.c,v 1.12 1994/05/25 08:52:56 rgrimes Exp $
40166124Srafan */
4150276Speter
4250276Speter
4350276Speter#include <sys/param.h>
4450276Speter#include <sys/systm.h>
4550276Speter#include <sys/proc.h>
46166124Srafan#include <sys/user.h>
4750276Speter#include <sys/buf.h>
4850276Speter#include <sys/ioctl.h>
4950276Speter#include <sys/tty.h>
5050276Speter#include <sys/file.h>
5150276Speter#include <sys/conf.h>
5276726Speter#include <sys/vnode.h>
53166124Srafan#include <machine/stdarg.h>
5450276Speter
5550276Speter#include <machine/cons.h>
56166124Srafan
57166124Srafan/* XXX - all this could be autoconfig()ed */
58166124Srafanint pccnprobe(), pccninit(), pccngetc(), pccnputc();
5950276Speter
6050276Speter#include "sio.h"
61166124Srafan#if NSIO > 0
6250276Speterint siocnprobe(), siocninit(), siocngetc(), siocnputc();
63166124Srafan#endif
6450276Speter
65166124Srafan#include "com.h"
66166124Srafan#if NCOM > 0
6750276Speterint comcnprobe(), comcninit(), comcngetc(), comcnputc();
6850276Speter#endif
6950276Speter
7050276Speterstruct	consdev constab[] = {
71166124Srafan	{ pccnprobe,	pccninit,	pccngetc,	pccnputc },
7250276Speter#if NSIO > 0
7350276Speter	{ siocnprobe,	siocninit,	siocngetc,	siocnputc },
74166124Srafan#endif
7550276Speter#if NCOM > 0
76166124Srafan	{ comcnprobe,	comcninit,	comcngetc,	comcnputc },
77166124Srafan#endif
7850276Speter	{ 0 },
7950276Speter};
8050276Speter/* end XXX */
8150276Speter
82166124Srafanstruct	tty *constty = 0;	/* virtual console output device */
83166124Srafanstruct	consdev *cn_tab;	/* physical console device info */
8450276Speterstruct	tty *cn_tty;		/* XXX: console tty struct for tprintf */
8550276Speter
8650276Spetervoid
8750276Spetercninit()
8850276Speter{
8950276Speter	register struct consdev *cp;
9050276Speter
9150276Speter	/*
9250276Speter	 * Collect information about all possible consoles
9350276Speter	 * and find the one with highest priority
9476726Speter	 */
95166124Srafan	for (cp = constab; cp->cn_probe; cp++) {
9650276Speter		(*cp->cn_probe)(cp);
97166124Srafan		if (cp->cn_pri > CN_DEAD &&
9850276Speter		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
9950276Speter			cn_tab = cp;
100166124Srafan	}
101166124Srafan	/*
10250276Speter	 * No console, we can handle it
10350276Speter	 */
104166124Srafan	if ((cp = cn_tab) == NULL)
10550276Speter		return;
10650276Speter	/*
10750276Speter	 * Turn on console
108	 */
109	cn_tty = cp->cn_tp;
110	(*cp->cn_init)(cp);
111}
112
113int
114cnopen(dev, flag, mode, p)
115	dev_t dev;
116	int flag, mode;
117	struct proc *p;
118{
119	struct vnode *vp = 0;
120
121	if (cn_tab == NULL)
122		return (0);
123
124	dev = cn_tab->cn_dev;
125	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
126		return (0);
127
128	return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
129}
130
131int
132cnclose(dev, flag, mode, p)
133	dev_t dev;
134	int flag, mode;
135	struct proc *p;
136{
137	struct vnode *vp = 0;
138
139	if (cn_tab == NULL)
140		return (0);
141
142	dev = cn_tab->cn_dev;
143	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
144		return (0);
145
146	return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
147}
148
149int
150cnread(dev, uio, flag)
151	dev_t dev;
152	struct uio *uio;
153	int flag;
154{
155	if (cn_tab == NULL)
156		return (0);
157	dev = cn_tab->cn_dev;
158	return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
159}
160
161int
162cnwrite(dev, uio, flag)
163	dev_t dev;
164	struct uio *uio;
165	int flag;
166{
167	if (cn_tab == NULL)
168		return (0);
169	if (constty)
170		dev = constty->t_dev;
171	else
172		dev = cn_tab->cn_dev;
173	return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
174}
175
176int
177cnioctl(dev, cmd, data, flag, p)
178	dev_t dev;
179	int cmd;
180	caddr_t data;
181	int flag;
182	struct proc *p;
183{
184	int error;
185
186	if (cn_tab == NULL)
187		return (0);
188	/*
189	 * Superuser can always use this to wrest control of console
190	 * output from the "virtual" console.
191	 */
192	if (cmd == TIOCCONS && constty) {
193		error = suser(p->p_ucred, (u_short *) NULL);
194		if (error)
195			return (error);
196		constty = NULL;
197		return (0);
198	}
199	dev = cn_tab->cn_dev;
200	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
201}
202
203/*ARGSUSED*/
204int
205cnselect(dev, rw, p)
206	dev_t dev;
207	int rw;
208	struct proc *p;
209{
210	if (cn_tab == NULL)
211		return (1);
212	return (ttselect(cn_tab->cn_dev, rw, p));
213}
214
215int
216cngetc()
217{
218	if (cn_tab == NULL)
219		return (0);
220	return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
221}
222
223void
224cnputc(c)
225	register int c;
226{
227	if (cn_tab == NULL)
228		return;
229	if (c) {
230		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
231		if (c == '\n')
232			(*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
233	}
234}
235
236int
237pg(const char *p, ...) {
238  va_list args;
239  va_start(args, p);
240  printf("%r\n>", p, args);
241  return(cngetc());
242}
243
244
245