Annotation of src/sys/dev/cons.c, Revision 1.22
1.22 ! christos 1: /* $NetBSD: cons.c,v 1.21 1994/10/30 22:16:37 mycroft Exp $ */
1.18 cgd 2:
1.1 cgd 3: /*
4: * Copyright (c) 1988 University of Utah.
1.17 cgd 5: * Copyright (c) 1990, 1993
6: * The Regents of the University of California. All rights reserved.
1.1 cgd 7: *
8: * This code is derived from software contributed to Berkeley by
9: * the Systems Programming Group of the University of Utah Computer
10: * Science Department.
11: *
12: * Redistribution and use in source and binary forms, with or without
13: * modification, are permitted provided that the following conditions
14: * are met:
15: * 1. Redistributions of source code must retain the above copyright
16: * notice, this list of conditions and the following disclaimer.
17: * 2. Redistributions in binary form must reproduce the above copyright
18: * notice, this list of conditions and the following disclaimer in the
19: * documentation and/or other materials provided with the distribution.
20: * 3. All advertising materials mentioning features or use of this software
21: * must display the following acknowledgement:
22: * This product includes software developed by the University of
23: * California, Berkeley and its contributors.
24: * 4. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
1.17 cgd 40: * from: Utah $Hdr: cons.c 1.7 92/01/21$
41: *
42: * @(#)cons.c 8.2 (Berkeley) 1/12/94
1.1 cgd 43: */
44:
1.10 cgd 45: #include <sys/param.h>
46: #include <sys/proc.h>
47: #include <sys/user.h>
48: #include <sys/systm.h>
49: #include <sys/buf.h>
50: #include <sys/ioctl.h>
51: #include <sys/tty.h>
52: #include <sys/file.h>
53: #include <sys/conf.h>
54: #include <sys/vnode.h>
1.1 cgd 55:
1.11 cgd 56: #include <dev/cons.h>
1.1 cgd 57:
1.10 cgd 58: extern struct consdev constab[];
1.1 cgd 59:
1.10 cgd 60: struct tty *constty = NULL; /* virtual console output device */
1.1 cgd 61: struct consdev *cn_tab; /* physical console device info */
1.13 cgd 62: struct vnode *cn_devvp; /* vnode for underlying device. */
63:
1.6 deraadt 64:
1.7 andrew 65: void
1.1 cgd 66: cninit()
67: {
68: register struct consdev *cp;
69:
70: /*
71: * Collect information about all possible consoles
72: * and find the one with highest priority
73: */
74: for (cp = constab; cp->cn_probe; cp++) {
75: (*cp->cn_probe)(cp);
76: if (cp->cn_pri > CN_DEAD &&
77: (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
78: cn_tab = cp;
79: }
80: /*
81: * No console, we can handle it
82: */
83: if ((cp = cn_tab) == NULL)
84: return;
85: /*
86: * Turn on console
87: */
88: (*cp->cn_init)(cp);
89: }
90:
1.7 andrew 91: int
1.1 cgd 92: cnopen(dev, flag, mode, p)
93: dev_t dev;
94: int flag, mode;
95: struct proc *p;
96: {
1.21 mycroft 97:
1.1 cgd 98: if (cn_tab == NULL)
99: return (0);
1.10 cgd 100:
101: /*
102: * always open the 'real' console device, so we don't get nailed
103: * later. This follows normal device semantics; they always get
104: * open() calls.
105: */
1.1 cgd 106: dev = cn_tab->cn_dev;
1.13 cgd 107: if (cn_devvp == NULLVP) {
1.15 cgd 108: /* try to get a reference on its vnode, but fail silently */
109: cdevvp(dev, &cn_devvp);
1.13 cgd 110: }
1.22 ! christos 111: return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p, NULL));
1.1 cgd 112: }
113:
1.7 andrew 114: int
1.1 cgd 115: cnclose(dev, flag, mode, p)
116: dev_t dev;
117: int flag, mode;
118: struct proc *p;
119: {
1.10 cgd 120: struct vnode *vp;
121:
1.1 cgd 122: if (cn_tab == NULL)
123: return (0);
1.10 cgd 124:
125: /*
126: * If the real console isn't otherwise open, close it.
127: * If it's otherwise open, don't close it, because that'll
128: * screw up others who have it open.
129: */
1.1 cgd 130: dev = cn_tab->cn_dev;
1.13 cgd 131: if (cn_devvp != NULLVP) {
132: /* release our reference to real dev's vnode */
133: vrele(cn_devvp);
134: cn_devvp = NULLVP;
135: }
1.16 mycroft 136: if (vfinddev(dev, VCHR, &vp) && vcount(vp))
1.10 cgd 137: return (0);
1.1 cgd 138: return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
139: }
140:
1.7 andrew 141: int
1.1 cgd 142: cnread(dev, uio, flag)
143: dev_t dev;
144: struct uio *uio;
145: {
1.21 mycroft 146:
1.10 cgd 147: /*
148: * If we would redirect input, punt. This will keep strange
149: * things from happening to people who are using the real
150: * console. Nothing should be using /dev/console for
151: * input (except a shell in single-user mode, but then,
152: * one wouldn't TIOCCONS then).
153: */
154: if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
155: return 0;
156: else if (cn_tab == NULL)
157: return ENXIO;
158:
1.1 cgd 159: dev = cn_tab->cn_dev;
160: return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
161: }
162:
1.7 andrew 163: int
1.1 cgd 164: cnwrite(dev, uio, flag)
165: dev_t dev;
166: struct uio *uio;
167: {
1.21 mycroft 168:
1.10 cgd 169: /*
170: * Redirect output, if that's appropriate.
171: * If there's no real console, return ENXIO.
172: */
173: if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
1.2 cgd 174: dev = constty->t_dev;
1.10 cgd 175: else if (cn_tab == NULL)
176: return ENXIO;
1.2 cgd 177: else
178: dev = cn_tab->cn_dev;
1.1 cgd 179: return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
180: }
181:
1.7 andrew 182: int
1.1 cgd 183: cnioctl(dev, cmd, data, flag, p)
184: dev_t dev;
1.20 cgd 185: u_long cmd;
1.1 cgd 186: caddr_t data;
1.20 cgd 187: int flag;
1.1 cgd 188: struct proc *p;
189: {
190: int error;
191:
192: /*
193: * Superuser can always use this to wrest control of console
194: * output from the "virtual" console.
195: */
1.10 cgd 196: if (cmd == TIOCCONS && constty != NULL) {
1.1 cgd 197: error = suser(p->p_ucred, (u_short *) NULL);
198: if (error)
199: return (error);
200: constty = NULL;
201: return (0);
202: }
1.10 cgd 203:
204: /*
205: * Redirect the ioctl, if that's appropriate.
206: * Note that strange things can happen, if a program does
207: * ioctls on /dev/console, then the console is redirected
208: * out from under it.
209: */
1.12 cgd 210: if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
1.10 cgd 211: dev = constty->t_dev;
212: else if (cn_tab == NULL)
213: return ENXIO;
214: else
215: dev = cn_tab->cn_dev;
1.1 cgd 216: return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
217: }
218:
219: /*ARGSUSED*/
1.7 andrew 220: int
1.1 cgd 221: cnselect(dev, rw, p)
222: dev_t dev;
223: int rw;
224: struct proc *p;
225: {
1.21 mycroft 226:
1.10 cgd 227: /*
228: * Redirect the ioctl, if that's appropriate.
229: * I don't want to think of the possible side effects
230: * of console redirection here.
231: */
1.12 cgd 232: if (constty != NULL && (cn_tab == NULL || cn_tab->cn_pri != CN_REMOTE))
1.10 cgd 233: dev = constty->t_dev;
234: else if (cn_tab == NULL)
235: return ENXIO;
236: else
237: dev = cn_tab->cn_dev;
1.1 cgd 238: return (ttselect(cn_tab->cn_dev, rw, p));
239: }
240:
1.7 andrew 241: int
1.1 cgd 242: cngetc()
243: {
1.21 mycroft 244:
1.1 cgd 245: if (cn_tab == NULL)
246: return (0);
247: return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
248: }
249:
1.7 andrew 250: int
1.1 cgd 251: cnputc(c)
252: register int c;
253: {
1.21 mycroft 254:
1.1 cgd 255: if (cn_tab == NULL)
256: return;
257: if (c) {
258: (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
259: if (c == '\n')
260: (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
261: }
1.19 mycroft 262: }
263:
264: void
265: cnpollc(on)
266: int on;
267: {
268: static int refcount = 0;
269:
270: if (cn_tab == NULL)
271: return;
272: if (!on)
273: --refcount;
274: if (refcount == 0)
275: (*cn_tab->cn_pollc)(cn_tab->cn_dev, on);
276: if (on)
277: ++refcount;
1.21 mycroft 278: }
279:
280: void
281: nullcnpollc(on)
282: int on;
283: {
284:
1.2 cgd 285: }
CVSweb <webmaster@jp.NetBSD.org>