Annotation of sys/arch/mvmeppc/dev/bugtty.c, Revision 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