1 /*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1991, 1993
4 * The Regents of the University of California. 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 * %sccs.include.redist.c%
11 *
12 * @(#)cons.c 8.1 (Berkeley) 06/11/93
13 */
14
15
16 #include <sys/param.h>
17 #include <sys/proc.h>
18 #include <sys/user.h>
19 #include <sys/systm.h>
20 #include <sys/buf.h>
21 #include <sys/ioctl.h>
22 #include <sys/tty.h>
23 #include <sys/file.h>
24 #include <sys/conf.h>
25
26 #include <i386/i386/cons.h>
27
28 /* XXX - all this could be autoconfig()ed */
29 int pccnprobe(), pccninit(), pccngetc(), pccnputc();
30 #include "com.h"
31 #if NCOM > 0
32 int comcnprobe(), comcninit(), comcngetc(), comcnputc();
33 #endif
34
35 struct consdev constab[] = {
36 { pccnprobe, pccninit, pccngetc, pccnputc },
37 #if NCOM > 0
38 { comcnprobe, comcninit, comcngetc, comcnputc },
39 #endif
40 { 0 },
41 };
42 /* end XXX */
43
44 struct tty *constty = 0; /* virtual console output device */
45 struct consdev *cn_tab; /* physical console device info */
46 struct tty *cn_tty; /* XXX: console tty struct for tprintf */
47
cninit()48 cninit()
49 {
50 register struct consdev *cp;
51
52 /*
53 * Collect information about all possible consoles
54 * and find the one with highest priority
55 */
56 for (cp = constab; cp->cn_probe; cp++) {
57 (*cp->cn_probe)(cp);
58 if (cp->cn_pri > CN_DEAD &&
59 (cn_tab == NULL || cp->cn_pri > cn_tab->cn_pri))
60 cn_tab = cp;
61 }
62 /*
63 * No console, we can handle it
64 */
65 if ((cp = cn_tab) == NULL)
66 return;
67 /*
68 * Turn on console
69 */
70 cn_tty = cp->cn_tp;
71 (*cp->cn_init)(cp);
72 }
73
cnopen(dev,flag,mode,p)74 cnopen(dev, flag, mode, p)
75 dev_t dev;
76 int flag, mode;
77 struct proc *p;
78 {
79 if (cn_tab == NULL)
80 return (0);
81 dev = cn_tab->cn_dev;
82 return ((*cdevsw[major(dev)].d_open)(dev, flag, mode, p));
83 }
84
cnclose(dev,flag,mode,p)85 cnclose(dev, flag, mode, p)
86 dev_t dev;
87 int flag, mode;
88 struct proc *p;
89 {
90 if (cn_tab == NULL)
91 return (0);
92 dev = cn_tab->cn_dev;
93 return ((*cdevsw[major(dev)].d_close)(dev, flag, mode, p));
94 }
95
cnread(dev,uio,flag)96 cnread(dev, uio, flag)
97 dev_t dev;
98 struct uio *uio;
99 {
100 if (cn_tab == NULL)
101 return (0);
102 dev = cn_tab->cn_dev;
103 return ((*cdevsw[major(dev)].d_read)(dev, uio, flag));
104 }
105
cnwrite(dev,uio,flag)106 cnwrite(dev, uio, flag)
107 dev_t dev;
108 struct uio *uio;
109 {
110 if (cn_tab == NULL)
111 return (0);
112 dev = cn_tab->cn_dev;
113 return ((*cdevsw[major(dev)].d_write)(dev, uio, flag));
114 }
115
cnioctl(dev,cmd,data,flag,p)116 cnioctl(dev, cmd, data, flag, p)
117 dev_t dev;
118 caddr_t data;
119 struct proc *p;
120 {
121 int error;
122
123 if (cn_tab == NULL)
124 return (0);
125 /*
126 * Superuser can always use this to wrest control of console
127 * output from the "virtual" console.
128 */
129 if (cmd == TIOCCONS && constty) {
130 error = suser(p->p_ucred, (u_short *) NULL);
131 if (error)
132 return (error);
133 constty = NULL;
134 return (0);
135 }
136 dev = cn_tab->cn_dev;
137 return ((*cdevsw[major(dev)].d_ioctl)(dev, cmd, data, flag, p));
138 }
139
140 /*ARGSUSED*/
cnselect(dev,rw,p)141 cnselect(dev, rw, p)
142 dev_t dev;
143 int rw;
144 struct proc *p;
145 {
146 if (cn_tab == NULL)
147 return (1);
148 return (ttselect(cn_tab->cn_dev, rw, p));
149 }
150
cngetc()151 cngetc()
152 {
153 if (cn_tab == NULL)
154 return (0);
155 return ((*cn_tab->cn_getc)(cn_tab->cn_dev));
156 }
157
cnputc(c)158 cnputc(c)
159 register int c;
160 {
161 if (cn_tab == NULL)
162 return;
163 if (c) {
164 (*cn_tab->cn_putc)(cn_tab->cn_dev, c);
165 if (c == '\n')
166 (*cn_tab->cn_putc)(cn_tab->cn_dev, '\r');
167 }
168 }
169