Oh GACK! src-clean doesn't quite work that easily since cleandist rebuilds the
[unix-history] / sys / i386 / isa / codrv / co_cons.c
CommitLineData
15637ed4
RG
1/*-
2 * Copyright (c) 1990 The Regents of the University of California.
3 * Copyright (c) 1992 by Holger Veit
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * William Jolitz and Don Ahn.
8 * Significant parts are added and rewritten by Holger Veit.
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 * @(#)co_cons.c $Revision: 1.11 $ (Contributed to 386bsd) $Date: 93/01/23 23:14:33 $
39 */
40static char *rcsid = "$Header: /usr/src/sys.386bsd/i386/isa/codrv/RCS/co_cons.c,v 1.11 93/01/23 23:14:33 root Exp Locker: root $";
41
42/*
43 * History: See CO_HISTORY
44 */
45
46#include "co.h"
47#include "pc.h"
48#if NCO == 1
49#if NPC == 0
50
51/*
52 * code to work keyboard & display for PC-style console
53 */
54#include "co_hdr.h"
55
56unsigned __debug = 0; /* 0xffe, exported to elsewhere */
57static unsigned __color;
58
59struct tty *dev2tty(dev_t dev)
60{
61 register n = minor(dev);
62
63 /* also checks valid minor # */
64 if (n < nvty)
65 return &pccons[n];
66 else
67 return 0;
68}
69
70static int tty2vty(struct tty *tp)
71{
72 int i;
73 for (i=0; i<nvty; i++)
74 if (vtys[i].ttyp==tp) return i;
75 return -1;
76}
77
78/*
79 * open a vty device. Name 'pcopen' is historical
80 *
81 */
82int pcopen(dev_t dev, int flag, int mode, struct proc *p)
83{
84 register struct tty *tp = dev2tty(dev);
85
86 if (!tp) return ENXIO;
87
88 /* increment ref count */
89 vtys[minor(dev)].ttycnt++;
90
91 tp->t_oproc = pcstart;
92 tp->t_param = pcparam;
93 tp->t_dev = dev;
94
95 consoftc.cs_flags |= CO_OPEN|CO_INITTTY;
96 consoftc.cs_opencnt++;
97
98 if ((tp->t_state & TS_ISOPEN) == 0) {
99 tp->t_state |= TS_WOPEN;
100 ttychars(tp);
101 tp->t_iflag = TTYDEF_IFLAG;
102 tp->t_oflag = TTYDEF_OFLAG;
103 tp->t_cflag = TTYDEF_CFLAG;
104 tp->t_lflag = TTYDEF_LFLAG;
105 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
106 tp->t_iflag &= ~ISTRIP;
107 pcparam(tp, &tp->t_termios);
108 ttsetwater(tp);
109 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
110 return (EBUSY);
111 tp->t_state |= TS_CARR_ON;
112 return ((*linesw[tp->t_line].l_open)(dev, tp));
113}
114
115/*
116 * Close a vty
117 */
118/*ARGSUSED*/
119int pcclose(dev_t dev, int flag, int mode, struct proc *p)
120{
121 register struct tty *tp = dev2tty(dev);
122 struct vty *vp = &vtys[minor(dev)];
123
124 if (!tp) return ENXIO;
125
126 /* decrement vty reference count */
127 if (vp->ttycnt > 0) vp->ttycnt--;
128
129 if (consoftc.cs_opencnt==0) {
130 consoftc.cs_flags &= ~CO_OPEN;
131
132 /* reset the keyboard state */
133 reset_kbd_flags();
134 initrb(&co_buf);
135 }
136 else
137 consoftc.cs_opencnt--;
138
139 (*linesw[tp->t_line].l_close)(tp, flag);
140 ttyclose(tp);
141
142 return(0);
143}
144
145/*
146 * read from vty
147 */
148/*ARGSUSED*/
149int pcread(dev_t dev, struct uio *uio, int flag)
150{
151 register struct tty *tp = dev2tty(dev);
152 if (!tp) return ENXIO;
153
154 /* this does not belong to here, but anybody always wants to
155 strip the 8th bit, very likely the shell */
156 tp->t_iflag &= ~ISTRIP;
157 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
158}
159
160/*
161 * write to vty
162 */
163/*ARGSUSED*/
164int pcwrite(dev_t dev, struct uio *uio, int flag)
165{
166 register struct tty *tp = dev2tty(dev);
167 if (!tp) return ENXIO;
168
169 /* we allow writing, but we don't know where it goes to */
170 /*if (consoftc.cs_flags & CO_OPENRAW) return EBUSY; */
171
172 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
173}
174
175/*
176 * execute vty ioctl
177 * This does no longer accept keyboard and vga oriented ioctls
178 */
179int pcioctl(dev_t dev, int cmd, caddr_t data, int flag)
180{
181 /* call the ioctl handler */
182 return consioctl(dev, cmd, data, flag);
183}
184
185int pcconsintr = 1;
186/*
187 * Got a console transmission interrupt -
188 * the console processor wants another character.
189 *
190 * -hv- is this really used?
191 */
192pcxint(dev)
193 dev_t dev;
194{
195 register struct tty *tp = dev2tty(dev);
196 register int unit;
197
198 if (!tp) return;
199
200 if (!pcconsintr)
201 return;
202 tp->t_state &= ~TS_BUSY;
203 consoftc.cs_timo = 0;
204 if (tp->t_line)
205 (*linesw[tp->t_line].l_start)(tp);
206 else
207 pcstart(tp);
208}
209
210int pcstart(register struct tty *tp)
211{
212 int c, s, vp;
213
214 s = spltty();
215 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
216 goto out;
217 do {
218 if (RB_LEN(&tp->t_out) <= tp->t_lowat) {
219 if (tp->t_state&TS_ASLEEP) {
220 tp->t_state &= ~TS_ASLEEP;
221 wakeup((caddr_t)&tp->t_out);
222 }
223 if (tp->t_wsel) {
224 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
225 tp->t_wsel = 0;
226 tp->t_state &= ~TS_WCOLL;
227 }
228 }
229 if (RB_LEN(&tp->t_out) == 0)
230 goto out;
231 c = getc(&tp->t_out);
232 tp->t_state |= TS_BUSY;
233 splx(s);
234 vp = tty2vty(tp);
235 if (vp < 0) panic("pcstart: unknown vty");
236 sput(vp, c, 0);
237 tp->t_state &= ~TS_BUSY;
238 (void)spltty();
239 } while(1);
240out:
241 splx(s);
242}
243
244/* interface for console device */
245void pccnprobe(struct consdev *cp)
246{
247 int maj;
248 int dev = 0;
249
250 /* locate the major number */
251 for (maj = 0; maj < nchrdev; maj++)
252 if (cdevsw[maj].d_open == pcopen)
253 break;
254
255maj = 12;
256 /* initialize required fields */
257 cp->cn_dev = makedev(maj, 0);
258 cp->cn_tp = &pccons[0];
259 cp->cn_pri = CN_INTERNAL;
260}
261
262/* interface for console device */
263/* ARGSUSED */
264void pccninit(struct consdev *cp)
265{
266 /*
267 * For now, don't screw with it.
268 */
269 /* crtat = 0; */
270}
271
272/* interface for console device */
273/* ARGSUSED */
274void pccnputc(dev_t dev, int c)
275{
276 int clr = __color;
277
278 if (!dev2tty(dev)) return; /* ignore if invalid */
279
280 if (clr == 0)
281 clr = 0x30;
282 else
283 clr |= 0x60;
284
285 if (c == '\n')
286 sput(minor(dev), '\r', clr);
287 sput(minor(dev), c, clr);
288}
289
290#ifdef notyetused
291/*
292 * Print a character on console.
293 */
294pcputchar(c, tp)
295 char c;
296 register struct tty *tp;
297{
298 sput(0, c, 0x2);
299 if (c=='\n') getchar();
300}
301#endif
302
303/* interface for console device */
304/* ARGSUSED */
305int pccngetc(dev_t dev)
306{
307 register int s;
308 register XCHAR *cp;
309
310 s = spltty(); /* block cointr while we poll */
311 while ((cp = kbd_sgetc(0))==NULL);
312 splx(s);
313 if (*cp == '\r') return('\n');
314 return (char)*cp;
315}
316
317#ifdef notyetused
318pcgetchar(tp)
319 register struct tty *tp;
320{
321 XCHAR *cp;
322
323 cp = kbd_sgetc(0); /* this is surely ASCII */
324 return (char)(*cp&0xff);
325}
326#endif
327
328/*
329 * Set line parameters
330 */
331int pcparam(struct tty *tp, struct termios *t)
332{
333 register int cflag = t->c_cflag;
334 /* and copy to tty */
335 tp->t_ispeed = t->c_ispeed;
336 tp->t_ospeed = t->c_ospeed;
337 tp->t_cflag = cflag;
338
339 return(0);
340}
341
342#ifdef KDB
343/*
344 * Turn input polling on/off (used by debugger).
345 */
346/*ARGSUSED*/
347int pcpoll(int onoff)
348{
349}
350#endif
351
352#ifdef OLD_PATCHKIT
353int pg(char *p,int q,int r,int s,int t,int u,int v,int w,int x,int y,int z)
354{
355 printf(p,q,r,s,t,u,v,w,x,y,z);
356 printf("\n");
357 return(getchar());
358}
359#endif
360
361/* special characters */
362#define bs 8
363#define lf 10
364#define cr 13
365#define cntlc 3
366#define del 0177
367#define cntld 4
368
369int getchar()
370{
371 XCHAR thechar,*c;
372 register delay;
373 int x;
374
375 consoftc.cs_flags |= CO_POLLING;
376 x = splhigh();
377 sput(0, '>', 1);
378 /*while (1) {*/
379 while ((c=kbd_sgetc(0))==NULL);
380 thechar = *c;
381 consoftc.cs_flags &= ~CO_POLLING;
382 splx(x);
383 switch (thechar) {
384 default: if (thechar >= ' ')
385 sput(0, thechar, 1);
386 return(thechar);
387 case cr:
388 case lf: sput(0, '\r', 1);
389 sput(0, '\n', 1);
390 return(lf);
391 case bs:
392 case del:
393 sput(0, '\b', 1);
394 sput(0, ' ', 1);
395 sput(0, '\b', 1);
396 return(thechar);
397 case cntlc:
398 sput(0, '^', 1) ; sput(0, 'C', 1) ; sput(0, '\r', 1) ; sput(0, '\n', 1) ;
399 cpu_reset();
400 case cntld:
401 sput(0, '^', 1) ; sput(0, 'D', 1) ; sput(0, '\r', 1) ; sput(0, '\n', 1) ;
402 return(0);
403 }
404 /*}*/
405}
406
407#ifdef notyetused
408#include "machine/stdarg.h"
409static nrow;
410
411#define DPAUSE 1
412void
413#ifdef __STDC__
414dprintf(unsigned flgs, const char *fmt, ...)
415#else
416dprintf(flgs, fmt /*, va_alist */)
417 char *fmt;
418 unsigned flgs;
419#endif
420{ extern unsigned __debug;
421 va_list ap;
422
423 if((flgs&__debug) > DPAUSE) {
424 __color = ffs(flgs&__debug)+1;
425 va_start(ap,fmt);
426 kprintf(fmt, 1, (struct tty *)0, ap);
427 va_end(ap);
428 if (flgs&DPAUSE || nrow%24 == 23) {
429 int x;
430 x = splhigh();
431 if (nrow%24 == 23) nrow = 0;
432 (void)kbd_sgetc(0);
433 splx(x);
434 }
435 }
436 __color = 0;
437}
438#endif
439
440#endif /* NPC=0 */
441#endif /* NCO=1 */