kern_cons.c revision 301
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 *	@(#)cons.c	7.2 (Berkeley) 5/9/91
39 *
40 * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
41 * --------------------         -----   ----------------------
42 * CURRENT PATCH LEVEL:         1       00083
43 * --------------------         -----   ----------------------
44 *
45 * 16 Aug 92	Pace Willisson		/dev/console redirect (xterm -C, etc.)
46 * 14 Mar 93	Chris G. Demetriou	Moved pg() here from isa/pccons.c
47 */
48
49
50#include "sys/param.h"
51#include "sys/proc.h"
52#include "sys/user.h"
53#include "sys/systm.h"
54#include "sys/buf.h"
55#include "sys/ioctl.h"
56#include "sys/tty.h"
57#include "sys/file.h"
58#include "sys/conf.h"
59#include "sys/vnode.h"
60
61#include "cons.h"
62
63/* XXX - all this could be autoconfig()ed */
64int pccnprobe(), pccninit(), pccngetc(), pccnputc();
65#include "com.h"
66#if NCOM > 0
67int comcnprobe(), comcninit(), comcngetc(), comcnputc();
68#endif
69
70struct	consdev constab[] = {
71	{ pccnprobe,	pccninit,	pccngetc,	pccnputc },
72#if NCOM > 0
73	{ comcnprobe,	comcninit,	comcngetc,	comcnputc },
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
83cninit()
84{
85	register struct consdev *cp;
86
87	/*
88	 * Collect information about all possible consoles
89	 * and find the one with highest priority
90	 */
91	for (cp = constab; cp->cn_probe; cp++) {
92		(*cp->cn_probe)(cp);
93		if (cp->cn_pri > CN_DEAD &&
94		    (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
95			cn_tab = cp;
96	}
97	/*
98	 * No console, we can handle it
99	 */
100	if ((cp = cn_tab) == NULL)
101		return;
102	/*
103	 * Turn on console
104	 */
105	cn_tty = cp->cn_tp;
106	(*cp->cn_init)(cp);
107}
108
109static struct vnode	*cnopenvp = NULLVP;
110
111
112cnopen(dev, flag, mode, p)
113	dev_t dev;
114	int flag, mode;
115	struct proc *p;
116{
117	int		error;
118
119
120	if (cn_tab == NULL)
121		return (0);
122	dev = cn_tab->cn_dev;
123	if (cnopenvp == NULLVP)
124		if ((error = getdevvp(dev, &cnopenvp, VCHR))) {
125			printf("cnopen: getdevvp returned %d !\n", error);
126			return(error);
127		}
128	return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
129}
130
131cnclose(dev, flag, mode, p)
132	dev_t dev;
133	int flag, mode;
134	struct proc *p;
135{
136	int		error;
137
138
139	if (cn_tab == NULL)
140		return (0);
141	dev = cn_tab->cn_dev;
142	if (vcount(cnopenvp) <= 1)
143		error = (*cdevsw[major(dev)].d_close)(dev, flag, mode, p);
144	else
145		error = 0;
146	if (error == 0) {
147		vrele(cnopenvp);
148		cnopenvp = NULLVP;
149	return(error);
150	}
151}
152
153cnread(dev, uio, flag)
154	dev_t dev;
155	struct uio *uio;
156{
157	if (cn_tab == NULL)
158		return (0);
159	dev = cn_tab->cn_dev;
160	return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
161}
162
163cnwrite(dev, uio, flag)
164	dev_t dev;
165	struct uio *uio;
166{
167	if (cn_tab == NULL)
168		return (0);
169	if (constty)					/* 16 Aug 92*/
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
176cnioctl(dev, cmd, data, flag, p)
177	dev_t dev;
178	caddr_t data;
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*/
201cnselect(dev, rw, p)
202	dev_t dev;
203	int rw;
204	struct proc *p;
205{
206	if (cn_tab == NULL)
207		return (1);
208	return (ttselect(cn_tab->cn_dev, rw, p));
209}
210
211cngetc()
212{
213	if (cn_tab == NULL)
214		return (0);
215	return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
216}
217
218cnputc(c)
219	register int c;
220{
221	if (cn_tab == NULL)
222		return;
223	if (c) {
224		(*cn_tab->cn_putc)(cn_tab->cn_dev, c);
225		if (c == '\n')
226			(*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
227	}
228}
229
230pg(p,q,r,s,t,u,v,w,x,y,z) char *p; {
231	printf(p,q,r,s,t,u,v,w,x,y,z);
232	printf("\n>");
233	return(cngetc());
234}
235
236
237