kern_cons.c revision 3728
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.15 1994/08/31 07:44:22 davidg 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#if NSC > 0
60int pccnprobe(), pccninit(), pccngetc(), pccncheckc(), pccnputc();
61#endif
62
63#include "sio.h"
64#if NSIO > 0
65int siocnprobe(), siocninit(), siocngetc(), siocncheckc(), siocnputc();
66#endif
67
68struct	consdev constab[] = {
69#if NSC > 0
70	{ pccnprobe,	pccninit,	pccngetc,	pccncheckc,	pccnputc },
71#endif
72#if NSIO > 0
73	{ siocnprobe,	siocninit,	siocngetc,	siocncheckc,	siocnputc },
74#endif
75	{ 0 },
76};
77/* end XXX */
78
79struct	tty *constty = 0;	/* virtual console output device */
80struct	consdev *cn_tab;	/* physical console device info */
81struct	tty *cn_tty;		/* XXX: console tty struct for tprintf */
82
83void
84cninit()
85{
86	register struct consdev *cp;
87
88	/*
89	 * Collect information about all possible consoles
90	 * and find the one with highest priority
91	 */
92	for (cp = constab; cp->cn_probe; cp++) {
93		(*cp->cn_probe)(cp);
94		if (cp->cn_pri > CN_DEAD &&
95		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
96			cn_tab = cp;
97	}
98	/*
99	 * No console, we can handle it
100	 */
101	if ((cp = cn_tab) == NULL)
102		return;
103	/*
104	 * Turn on console
105	 */
106	cn_tty = cp->cn_tp;
107	(*cp->cn_init)(cp);
108}
109
110int
111cnopen(dev, flag, mode, p)
112	dev_t dev;
113	int flag, mode;
114	struct proc *p;
115{
116	struct vnode *vp = 0;
117
118	if (cn_tab == NULL)
119		return (0);
120
121	dev = cn_tab->cn_dev;
122	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
123		return (0);
124
125	return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
126}
127
128int
129cnclose(dev, flag, mode, p)
130	dev_t dev;
131	int flag, mode;
132	struct proc *p;
133{
134	struct vnode *vp = 0;
135
136	if (cn_tab == NULL)
137		return (0);
138
139	dev = cn_tab->cn_dev;
140	if (vfinddev(dev, VCHR, &vp) && vcount(vp))
141		return (0);
142
143	return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
144}
145
146int
147cnread(dev, uio, flag)
148	dev_t dev;
149	struct uio *uio;
150	int flag;
151{
152	if (cn_tab == NULL)
153		return (0);
154	dev = cn_tab->cn_dev;
155	return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
156}
157
158int
159cnwrite(dev, uio, flag)
160	dev_t dev;
161	struct uio *uio;
162	int flag;
163{
164	if (cn_tab == NULL)
165		return (0);
166	if (constty)
167		dev = constty->t_dev;
168	else
169		dev = cn_tab->cn_dev;
170	return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
171}
172
173int
174cnioctl(dev, cmd, data, flag, p)
175	dev_t dev;
176	int cmd;
177	caddr_t data;
178	int flag;
179	struct proc *p;
180{
181	int error;
182
183	if (cn_tab == NULL)
184		return (0);
185	/*
186	 * Superuser can always use this to wrest control of console
187	 * output from the "virtual" console.
188	 */
189	if (cmd == TIOCCONS && constty) {
190		error = suser(p->p_ucred, (u_short *) NULL);
191		if (error)
192			return (error);
193		constty = NULL;
194		return (0);
195	}
196	dev = cn_tab->cn_dev;
197	return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
198}
199
200/*ARGSUSED*/
201int
202cnselect(dev, rw, p)
203	dev_t dev;
204	int rw;
205	struct proc *p;
206{
207	if (cn_tab == NULL)
208		return (1);
209	return (ttselect(cn_tab->cn_dev, rw, p));
210}
211
212int
213cngetc()
214{
215	if (cn_tab == NULL)
216		return (0);
217	return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
218}
219
220int
221cncheckc()
222{
223	if (cn_tab == NULL)
224		return (0);
225	return ((*cn_tab->cn_checkc)(cn_tab->cn_dev));
226}
227
228void
229cnputc(c)
230	register int c;
231{
232	if (cn_tab == NULL)
233		return;
234	if (c) {
235		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
236		if (c == '\n')
237			(*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
238	}
239}
240
241int
242pg(const char *p, ...) {
243  va_list args;
244  va_start(args, p);
245  printf("%r\n>", p, args);
246  return(cngetc());
247}
248
249
250