kern_cons.c revision 5161
1/*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1991 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	from: @(#)cons.c	7.2 (Berkeley) 5/9/91
39 *	$Id: cons.c,v 1.18 1994/12/18 19:35:09 joerg Exp $
40 */
41
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/proc.h>
46#include <sys/user.h>
47#include <sys/buf.h>
48#include <sys/ioctl.h>
49#include <sys/tty.h>
50#include <sys/file.h>
51#include <sys/conf.h>
52#include <sys/vnode.h>
53#include <machine/stdarg.h>
54
55#include <machine/cons.h>
56
57/* XXX - all this could be autoconfig()ed */
58#include "sc.h"
59#include "vt.h"
60#if NSC > 0 || NVT > 0
61int pccnprobe(), pccninit(), pccngetc(), pccncheckc(), pccnputc();
62#endif
63
64#include "sio.h"
65#if NSIO > 0
66int siocnprobe(), siocninit(), siocngetc(), siocncheckc(), siocnputc();
67#endif
68
69struct	consdev constab[] = {
70#if NSC > 0 || NVT > 0
71	{ pccnprobe,	pccninit,	pccngetc,	pccncheckc,	pccnputc },
72#endif
73#if NSIO > 0
74	{ siocnprobe,	siocninit,	siocngetc,	siocncheckc,	siocnputc },
75#endif
76	{ 0 },
77};
78/* end XXX */
79
80struct	tty *constty = 0;	/* virtual console output device */
81struct	consdev *cn_tab;	/* physical console device info */
82struct	tty *cn_tty;		/* XXX: console tty struct for tprintf */
83
84void
85cninit()
86{
87	register struct consdev *cp;
88
89	/*
90	 * Collect information about all possible consoles
91	 * and find the one with highest priority
92	 */
93	for (cp = constab; cp->cn_probe; cp++) {
94		(*cp->cn_probe)(cp);
95		if (cp->cn_pri > CN_DEAD &&
96		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
97			cn_tab = cp;
98	}
99	/*
100	 * No console, we can handle it
101	 */
102	if ((cp = cn_tab) == NULL)
103		return;
104	/*
105	 * Turn on console
106	 */
107	cn_tty = cp->cn_tp;
108	(*cp->cn_init)(cp);
109}
110
111int
112cnopen(dev, flag, mode, p)
113	dev_t dev;
114	int flag, mode;
115	struct proc *p;
116{
117	struct vnode *vp = 0;
118
119	if (cn_tab == NULL)
120		return (0);
121
122	dev = cn_tab->cn_dev;
123	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
124		return (0);
125
126	return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
127}
128
129int
130cnclose(dev, flag, mode, p)
131	dev_t dev;
132	int flag, mode;
133	struct proc *p;
134{
135	struct vnode *vp = 0;
136
137	if (cn_tab == NULL)
138		return (0);
139
140	dev = cn_tab->cn_dev;
141	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
142		return (0);
143
144	return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
145}
146
147int
148cnread(dev, uio, flag)
149	dev_t dev;
150	struct uio *uio;
151	int flag;
152{
153	if (cn_tab == NULL)
154		return (0);
155	dev = cn_tab->cn_dev;
156	return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
157}
158
159int
160cnwrite(dev, uio, flag)
161	dev_t dev;
162	struct uio *uio;
163	int flag;
164{
165	if (cn_tab == NULL)
166		return (0);
167	if (constty)
168		dev = constty->t_dev;
169	else
170		dev = cn_tab->cn_dev;
171	return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
172}
173
174int
175cnioctl(dev, cmd, data, flag, p)
176	dev_t dev;
177	int cmd;
178	caddr_t data;
179	int flag;
180	struct proc *p;
181{
182	int error;
183
184	if (cn_tab == NULL)
185		return (0);
186	/*
187	 * Superuser can always use this to wrest control of console
188	 * output from the "virtual" console.
189	 */
190	if (cmd == TIOCCONS && constty) {
191		error = suser(p->p_ucred, (u_short *) NULL);
192		if (error)
193			return (error);
194		constty = NULL;
195		return (0);
196	}
197	dev = cn_tab->cn_dev;
198	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
199}
200
201/*ARGSUSED*/
202int
203cnselect(dev, rw, p)
204	dev_t dev;
205	int rw;
206	struct proc *p;
207{
208	if (cn_tab == NULL)
209		return (1);
210	return (ttselect(cn_tab->cn_dev, rw, p));
211}
212
213int
214cngetc()
215{
216	int c;
217	if (cn_tab == NULL)
218		return (0);
219	c = (*cn_tab->cn_getc)(cn_tab->cn_dev);
220	if (c == '\r') c = '\n'; /* console input is always ICRNL */
221	return (c);
222}
223
224int
225cncheckc()
226{
227	if (cn_tab == NULL)
228		return (0);
229	return ((*cn_tab->cn_checkc)(cn_tab->cn_dev));
230}
231
232void
233cnputc(c)
234	register int c;
235{
236	if (cn_tab == NULL)
237		return;
238	if (c) {
239		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
240		if (c == '\n')
241			(*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
242	}
243}
244
245int
246pg(const char *p, ...) {
247  va_list args;
248  va_start(args, p);
249  printf("%r\n>", p, args);
250  return(cngetc());
251}
252
253
254