Annotation of sys/arch/mvmeppc/dev/bugtty.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: bugtty.c,v 1.10 2004/05/14 20:38:32 miod Exp $ */
2:
3: /* Copyright (c) 1998 Steve Murphree, Jr.
4: * Copyright (c) 1995 Dale Rahn.
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. The name of the author may not be used to endorse or promote products
16: * derived from this software without specific prior written permission.
17: *
18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28: */
29:
30: #include <sys/param.h>
31: #include <sys/systm.h>
32: #include <sys/ioctl.h>
33: #include <sys/device.h>
34: #include <sys/tty.h>
35: #include <sys/proc.h>
36: #include <sys/uio.h>
37: #include <sys/queue.h>
38:
39: #include <machine/autoconf.h>
40: #include <machine/bugio.h>
41: #include <machine/conf.h>
42: #include <machine/cpu.h>
43:
44: #include <dev/cons.h>
45:
46: #include "bugtty.h"
47:
48: int bugttymatch(struct device *parent, void *self, void *aux);
49: void bugttyattach(struct device *parent, struct device *self, void *aux);
50:
51: struct cfattach bugtty_ca = {
52: sizeof(struct device), bugttymatch, bugttyattach
53: };
54:
55: struct cfdriver bugtty_cd = {
56: NULL, "bugtty", DV_TTY
57: };
58:
59: /* prototypes */
60: cons_decl(bugtty);
61: cdev_decl(bugtty);
62:
63: int bugttymctl(dev_t dev, int bits, int how);
64: int bugttyparam(struct tty *tp, struct termios *tm);
65: void bugtty_chkinput(void);
66:
67: #define DIALOUT(x) ((x) & 0x80)
68: #define SWFLAGS(dev) (bugttyswflags | (DIALOUT(dev) ? TIOCFLAG_SOFTCAR : 0))
69:
70: #define BUGBUF 80
71: char bugtty_ibuffer[BUGBUF+1];
72: volatile char *pinchar = bugtty_ibuffer;
73: char bug_obuffer[BUGBUF+1];
74:
75: #define BUGTTYS 4
76: struct tty *bugtty_tty[BUGTTYS];
77:
78: int
79: bugttymatch(parent, self, aux)
80: struct device *parent;
81: void *self;
82: void *aux;
83: {
84: struct confargs *ca = aux;
85:
86: if (strcmp(ca->ca_name, bugtty_cd.cd_name) != 0)
87: return (0);
88:
89: return (1);
90: }
91:
92: void
93: bugttyattach(parent, self, aux)
94: struct device *parent;
95: struct device *self;
96: void *aux;
97: {
98: printf(": fallback console\n");
99: }
100:
101: #define BUGTTYUNIT(x) ((x) & (0x7f))
102: void bugttyoutput(struct tty *tp);
103:
104: int bugttydefaultrate = TTYDEF_SPEED;
105: int bugttyswflags;
106:
107: struct tty *
108: bugttytty(dev)
109: dev_t dev;
110: {
111: int unit;
112: unit = BUGTTYUNIT(dev);
113: if (unit >= BUGTTYS) {
114: return (NULL);
115: }
116: return bugtty_tty[unit];
117: }
118:
119: int
120: bugttymctl(dev, bits, how)
121: dev_t dev;
122: int bits, how;
123: {
124: int s;
125:
126: /*printf("mctl: dev %x, bits %x, how %x,",dev, bits, how);*/
127:
128: /* settings are currently ignored */
129: s = spltty();
130: switch (how) {
131: case DMSET:
132: break;
133: case DMBIC:
134: break;
135: case DMBIS:
136: break;
137: case DMGET:
138: break;
139: }
140: splx(s);
141:
142: bits = 0;
143: /* proper defaults? */
144: bits |= TIOCM_DTR;
145: bits |= TIOCM_RTS;
146: bits |= TIOCM_CTS;
147: bits |= TIOCM_CD;
148: /* bits |= TIOCM_RI; */
149: bits |= TIOCM_DSR;
150:
151: /* printf("retbits %x\n", bits); */
152: return (bits);
153: }
154:
155: int
156: bugttyopen(dev, flag, mode, p)
157: dev_t dev;
158: int flag, mode;
159: struct proc *p;
160: {
161: int s, unit = BUGTTYUNIT(dev);
162: struct tty *tp;
163:
164: s = spltty();
165: if (bugtty_tty[unit]) {
166: tp = bugtty_tty[unit];
167: } else {
168: tp = bugtty_tty[unit] = ttymalloc();
169: }
170: tp->t_oproc = bugttyoutput;
171: tp->t_param = NULL;
172: tp->t_dev = dev;
173:
174: if ((tp->t_state & TS_ISOPEN) == 0) {
175: tp->t_state |= TS_WOPEN;
176: ttychars(tp);
177: if (tp->t_ispeed == 0) {
178: /*
179: * only when cleared do we reset to defaults.
180: */
181: tp->t_iflag = TTYDEF_IFLAG;
182: tp->t_oflag = TTYDEF_OFLAG;
183: tp->t_cflag = TTYDEF_CFLAG;
184: tp->t_lflag = TTYDEF_LFLAG;
185: tp->t_ispeed = tp->t_ospeed = bugttydefaultrate;
186: }
187: /* bugtty does not have carrier */
188: tp->t_cflag |= CLOCAL;
189: /*
190: * do these all the time
191: */
192: if (bugttyswflags & TIOCFLAG_CLOCAL)
193: tp->t_cflag |= CLOCAL;
194: if (bugttyswflags & TIOCFLAG_CRTSCTS)
195: tp->t_cflag |= CRTSCTS;
196: if (bugttyswflags & TIOCFLAG_MDMBUF)
197: tp->t_cflag |= MDMBUF;
198: bugttyparam(tp, &tp->t_termios);
199: ttsetwater(tp);
200:
201: (void)bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMSET);
202: /*
203: if ((SWFLAGS(dev) & TIOCFLAG_SOFTCAR) ||
204: (bugttymctl(dev, 0, DMGET) & TIOCM_CD))
205: tp->t_state |= TS_CARR_ON;
206: else
207: tp->t_state &= ~TS_CARR_ON;
208: */
209: tp->t_state |= TS_CARR_ON;
210: } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
211: splx(s);
212: return (EBUSY);
213: }
214:
215: /*
216: * if NONBLOCK requested, ignore carrier
217: */
218: /*
219: if (flag & O_NONBLOCK)
220: goto done;
221: */
222:
223: splx(s);
224: /*
225: * Reset the tty pointer, as there could have been a dialout
226: * use of the tty with a dialin open waiting.
227: */
228: tp->t_dev = dev;
229: return ((*linesw[tp->t_line].l_open)(dev, tp));
230: }
231:
232: int
233: bugttyparam(tp, tm)
234: struct tty *tp;
235: struct termios *tm;
236: {
237: return (0);
238: }
239:
240: void
241: bugttyoutput(tp)
242: struct tty *tp;
243: {
244: int cc, s, cnt;
245:
246: /* only supports one unit */
247:
248: if ((tp->t_state & TS_ISOPEN) == 0)
249: return;
250:
251: s = spltty();
252: cc = tp->t_outq.c_cc;
253: while (cc > 0) {
254: cnt = min(BUGBUF, cc);
255: cnt = q_to_b(&tp->t_outq, bug_obuffer, cnt);
256: mvmeprom_outstr(bug_obuffer, &bug_obuffer[cnt]);
257: cc -= cnt;
258: }
259: splx(s);
260: }
261:
262: int
263: bugttyclose(dev, flag, mode, p)
264: dev_t dev;
265: int flag, mode;
266: struct proc *p;
267: {
268: int unit = BUGTTYUNIT(dev);
269: struct tty *tp = bugtty_tty[unit];
270:
271: (*linesw[tp->t_line].l_close)(tp, flag);
272:
273: ttyclose(tp);
274: #if 0
275: bugtty_tty[unit] = NULL;
276: #endif
277: return (0);
278: }
279:
280: int
281: bugttyread(dev, uio, flag)
282: dev_t dev;
283: struct uio *uio;
284: int flag;
285: {
286: struct tty *tp;
287:
288: if ((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL)
289: return (ENXIO);
290: return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
291: }
292:
293: /* only to be called at splclk() */
294: void
295: bugtty_chkinput()
296: {
297: struct tty *tp;
298:
299: tp = bugtty_tty[0]; /* assumes console on the first port... */
300: if (tp == NULL)
301: return;
302:
303: while (mvmeprom_instat() != 0) {
304: u_char c = mvmeprom_getchar() & 0xff;
305: (*linesw[tp->t_line].l_rint)(c, tp);
306: }
307: }
308:
309: int
310: bugttywrite(dev, uio, flag)
311: dev_t dev;
312: struct uio *uio;
313: int flag;
314: {
315: #if 0
316: /* bypass tty output routines. */
317: int i, cnt, s;
318: int oldoff;
319:
320: s = spltty();
321: oldoff = uio->uio_offset;
322: do {
323: uiomove(bug_obuffer, BUGBUF, uio);
324: bugoutstr(bug_obuffer, &bug_obuffer[uio->uio_offset - oldoff]);
325: oldoff = uio->uio_offset;
326: } while (uio->uio_resid != 0);
327: splx(s);
328:
329: return (0);
330: #else
331: struct tty *tp;
332: if((tp = bugtty_tty[BUGTTYUNIT(dev)]) == NULL)
333: return (ENXIO);
334: return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
335: #endif
336: }
337:
338: int
339: bugttyioctl(dev, cmd, data, flag, p)
340: dev_t dev;
341: u_long cmd;
342: caddr_t data;
343: int flag;
344: struct proc *p;
345: {
346: int unit = BUGTTYUNIT(dev);
347: struct tty *tp = bugtty_tty[unit];
348: int error;
349:
350: if (!tp)
351: return (ENXIO);
352:
353: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
354: if (error >= 0)
355: return (error);
356:
357: error = ttioctl(tp, cmd, data, flag, p);
358: if (error >= 0)
359: return (error);
360:
361: switch (cmd) {
362: case TIOCSBRK:
363: /* */
364: break;
365:
366: case TIOCCBRK:
367: /* */
368: break;
369:
370: case TIOCSDTR:
371: (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIS);
372: break;
373:
374: case TIOCCDTR:
375: (void) bugttymctl(dev, TIOCM_DTR | TIOCM_RTS, DMBIC);
376: break;
377:
378: case TIOCMSET:
379: (void) bugttymctl(dev, *(int *) data, DMSET);
380: break;
381:
382: case TIOCMBIS:
383: (void) bugttymctl(dev, *(int *) data, DMBIS);
384: break;
385:
386: case TIOCMBIC:
387: (void) bugttymctl(dev, *(int *) data, DMBIC);
388: break;
389:
390: case TIOCMGET:
391: *(int *)data = bugttymctl(dev, 0, DMGET);
392: break;
393: case TIOCGFLAGS:
394: *(int *)data = SWFLAGS(dev);
395: break;
396: case TIOCSFLAGS:
397: error = suser(p, 0);
398: if (error != 0)
399: return (EPERM);
400:
401: bugttyswflags = *(int *)data;
402: bugttyswflags &= /* only allow valid flags */
403: (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
404: break;
405: default:
406: return (ENOTTY);
407: }
408:
409: return (0);
410: }
411:
412: int
413: bugttystop(tp, flag)
414: struct tty *tp;
415: int flag;
416: {
417: int s;
418:
419: s = spltty();
420: if (tp->t_state & TS_BUSY) {
421: if ((tp->t_state & TS_TTSTOP) == 0)
422: tp->t_state |= TS_FLUSH;
423: }
424: splx(s);
425: return (0);
426: }
427:
428: /*
429: * bugtty is the last possible choice for a console device.
430: */
431: void
432: bugttycnprobe(cp)
433: struct consdev *cp;
434: {
435: int maj;
436:
437: /* locate the major number */
438: for (maj = 0; maj < nchrdev; maj++)
439: if (cdevsw[maj].d_open == bugttyopen)
440: break;
441:
442: cp->cn_dev = makedev(maj, 0);
443: cp->cn_pri = CN_NORMAL;
444: }
445:
446: void
447: bugttycninit(cp)
448: struct consdev *cp;
449: {
450: /* Nothing to do */
451: }
452:
453: int
454: bugttycngetc(dev)
455: dev_t dev;
456: {
457: return (mvmeprom_getchar());
458: }
459:
460: void
461: bugttycnputc(dev, c)
462: dev_t dev;
463: char c;
464: {
465: mvmeprom_outchar(c);
466: }
CVSweb