Annotation of sys/arch/aviion/dev/dart.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: dart.c,v 1.1.1.1 2006/05/09 18:13:32 miod Exp $ */
! 2:
! 3: /*
! 4: * Mach Operating System
! 5: * Copyright (c) 1993-1991 Carnegie Mellon University
! 6: * All Rights Reserved.
! 7: *
! 8: * Permission to use, copy, modify and distribute this software and its
! 9: * documentation is hereby granted, provided that both the copyright
! 10: * notice and this permission notice appear in all copies of the
! 11: * software, derivative works or modified versions, and any portions
! 12: * thereof, and that both notices appear in supporting documentation.
! 13: *
! 14: * CARNEGIE MELLON AND OMRON ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 15: * CONDITION. CARNEGIE MELLON AND OMRON DISCLAIM ANY LIABILITY OF ANY KIND
! 16: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 17: *
! 18: * Carnegie Mellon requests users of this software to return to
! 19: *
! 20: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 21: * School of Computer Science
! 22: * Carnegie Mellon University
! 23: * Pittsburgh PA 15213-3890
! 24: *
! 25: * any improvements or extensions that they make and grant Carnegie the
! 26: * rights to redistribute these changes.
! 27: */
! 28:
! 29: #include <sys/param.h>
! 30: #include <sys/ioctl.h>
! 31: #include <sys/proc.h>
! 32: #include <sys/tty.h>
! 33: #include <sys/systm.h>
! 34: #include <sys/device.h>
! 35: #include <sys/syslog.h>
! 36:
! 37: #include <machine/autoconf.h>
! 38: #include <machine/conf.h>
! 39: #include <machine/cpu.h>
! 40:
! 41: #include <dev/cons.h>
! 42:
! 43: #include <machine/av400.h>
! 44: #include <aviion/dev/sysconreg.h>
! 45: #include <aviion/dev/dartreg.h>
! 46: #include <aviion/dev/dartvar.h>
! 47:
! 48: #ifdef DDB
! 49: #include <ddb/db_var.h>
! 50: #endif
! 51:
! 52: struct cfdriver dart_cd = {
! 53: NULL, "dart", DV_TTY
! 54: };
! 55:
! 56: /* console is on the first port */
! 57: #define CONS_PORT A_PORT
! 58: #ifdef USE_PROM_CONSOLE
! 59: #define dartcn_sv sc->sc_sv_reg_storage
! 60: #else
! 61: struct dart_sv_reg dartcn_sv;
! 62: #endif
! 63:
! 64: /* prototypes */
! 65: cons_decl(dart);
! 66: int dart_speed(int);
! 67: struct tty *darttty(dev_t);
! 68: void dartstart(struct tty *);
! 69: int dartmctl(struct dartsoftc *, int, int, int);
! 70: int dartparam(struct tty *, struct termios *);
! 71: void dartmodemtrans(struct dartsoftc *, unsigned int, unsigned int);
! 72: void dartrint(struct dartsoftc *, int);
! 73: void dartxint(struct dartsoftc *, int);
! 74:
! 75: /*
! 76: * DUART registers are mapped as the least-significant byte of 32-bit
! 77: * addresses. The following macros hide this.
! 78: */
! 79:
! 80: #define dart_read(sc, reg) \
! 81: bus_space_read_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2))
! 82: #define dart_write(sc, reg, val) \
! 83: bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, 3 + ((reg) << 2), (val))
! 84:
! 85: #define DART_CHIP(dev) (minor(dev) >> 1)
! 86: #define DART_PORT(dev) (minor(dev) & 1)
! 87:
! 88: void
! 89: dart_common_attach(struct dartsoftc *sc)
! 90: {
! 91: if (sc->sc_console) {
! 92: sc->sc_sv_reg = &dartcn_sv;
! 93:
! 94: if (A_PORT != CONS_PORT) {
! 95: sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
! 96: sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
! 97: sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
! 98: sc->sc_sv_reg->sv_cr[A_PORT] = TXEN | RXEN;
! 99: sc->sc_sv_reg->sv_opr |= OPDTRA | OPRTSA;
! 100: } else {
! 101: sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
! 102: sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
! 103: sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
! 104: sc->sc_sv_reg->sv_cr[B_PORT] = TXEN | RXEN;
! 105: sc->sc_sv_reg->sv_opr |= OPDTRB | OPRTSB;
! 106: }
! 107: } else {
! 108: sc->sc_sv_reg = &sc->sc_sv_reg_storage;
! 109:
! 110: sc->sc_sv_reg->sv_mr1[A_PORT] = PARDIS | RXRTS | CL8;
! 111: sc->sc_sv_reg->sv_mr2[A_PORT] = /* TXCTS | */ SB1;
! 112: sc->sc_sv_reg->sv_csr[A_PORT] = BD9600;
! 113: sc->sc_sv_reg->sv_cr[A_PORT] = TXEN | RXEN;
! 114:
! 115: sc->sc_sv_reg->sv_mr1[B_PORT] = PARDIS | RXRTS | CL8;
! 116: sc->sc_sv_reg->sv_mr2[B_PORT] = /* TXCTS | */ SB1;
! 117: sc->sc_sv_reg->sv_csr[B_PORT] = BD9600;
! 118: sc->sc_sv_reg->sv_cr[B_PORT] = TXEN | RXEN;
! 119:
! 120: sc->sc_sv_reg->sv_opr = OPDTRA | OPRTSA | OPDTRB | OPRTSB;
! 121:
! 122: /* Start out with Tx and RX interrupts disabled */
! 123: /* Enable input port change interrupt */
! 124: sc->sc_sv_reg->sv_imr = IIPCHG;
! 125: }
! 126:
! 127: /* reset port a */
! 128: if (sc->sc_console == 0 || CONS_PORT != A_PORT) {
! 129: dart_write(sc, DART_CRA, RXRESET | TXDIS | RXDIS);
! 130: DELAY_CR;
! 131: dart_write(sc, DART_CRA, TXRESET | TXDIS | RXDIS);
! 132: DELAY_CR;
! 133: dart_write(sc, DART_CRA, ERRRESET | TXDIS | RXDIS);
! 134: DELAY_CR;
! 135: dart_write(sc, DART_CRA, BRKINTRESET | TXDIS | RXDIS);
! 136: DELAY_CR;
! 137: dart_write(sc, DART_CRA, MRRESET | TXDIS | RXDIS);
! 138: #if 0
! 139: DELAY_CR;
! 140: #endif
! 141:
! 142: dart_write(sc, DART_MR1A, sc->sc_sv_reg->sv_mr1[A_PORT]);
! 143: dart_write(sc, DART_MR2A, sc->sc_sv_reg->sv_mr2[A_PORT]);
! 144: dart_write(sc, DART_CSRA, sc->sc_sv_reg->sv_csr[A_PORT]);
! 145: dart_write(sc, DART_CRA, sc->sc_sv_reg->sv_cr[A_PORT]);
! 146: }
! 147:
! 148: /* reset port b */
! 149: if (sc->sc_console == 0 || CONS_PORT != B_PORT) {
! 150: dart_write(sc, DART_CRB, RXRESET | TXDIS | RXDIS);
! 151: DELAY_CR;
! 152: dart_write(sc, DART_CRB, TXRESET | TXDIS | RXDIS);
! 153: DELAY_CR;
! 154: dart_write(sc, DART_CRB, ERRRESET | TXDIS | RXDIS);
! 155: DELAY_CR;
! 156: dart_write(sc, DART_CRB, BRKINTRESET | TXDIS | RXDIS);
! 157: DELAY_CR;
! 158: dart_write(sc, DART_CRB, MRRESET | TXDIS | RXDIS);
! 159: #if 0
! 160: DELAY_CR;
! 161: #endif
! 162:
! 163: dart_write(sc, DART_MR1B, sc->sc_sv_reg->sv_mr1[B_PORT]);
! 164: dart_write(sc, DART_MR2B, sc->sc_sv_reg->sv_mr2[B_PORT]);
! 165: dart_write(sc, DART_CSRB, sc->sc_sv_reg->sv_csr[B_PORT]);
! 166: dart_write(sc, DART_CRB, sc->sc_sv_reg->sv_cr[B_PORT]);
! 167: }
! 168:
! 169: /* initialize common register of a DUART */
! 170: dart_write(sc, DART_OPRS, sc->sc_sv_reg->sv_opr);
! 171:
! 172: #if 0
! 173: dart_write(sc, DART_CTUR, SLCTIM >> 8);
! 174: dart_write(sc, DART_CTLR, SLCTIM & 0xff);
! 175: dart_write(sc, DART_ACR, BDSET2 | CCLK16 | IPDCDIB | IPDCDIA);
! 176: #endif
! 177: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 178: #if 0
! 179: dart_write(sc, DART_OPCR, OPSET);
! 180: #endif
! 181: #if 0
! 182: dart_write(sc, DART_IVR, SYSCON_VECT + SYSCV_SCC);
! 183: #endif
! 184:
! 185: sc->sc_dart[A_PORT].tty = sc->sc_dart[B_PORT].tty = NULL;
! 186: sc->sc_dart[A_PORT].dart_swflags = sc->sc_dart[B_PORT].dart_swflags = 0;
! 187: if (sc->sc_console)
! 188: sc->sc_dart[CONS_PORT].dart_swflags |= TIOCFLAG_SOFTCAR;
! 189:
! 190: printf("\n");
! 191: }
! 192:
! 193: /* speed tables */
! 194: const struct dart_s {
! 195: int kspeed;
! 196: int dspeed;
! 197: } dart_speeds[] = {
! 198: { B0, 0 }, /* 0 baud, special HUP condition */
! 199: { B50, NOBAUD }, /* 50 baud, not implemented */
! 200: { B75, BD75 }, /* 75 baud */
! 201: { B110, BD110 }, /* 110 baud */
! 202: { B134, BD134 }, /* 134.5 baud */
! 203: { B150, BD150 }, /* 150 baud */
! 204: { B200, NOBAUD }, /* 200 baud, not implemented */
! 205: { B300, BD300 }, /* 300 baud */
! 206: { B600, BD600 }, /* 600 baud */
! 207: { B1200, BD1200 }, /* 1200 baud */
! 208: { B1800, BD1800 }, /* 1800 baud */
! 209: { B2400, BD2400 }, /* 2400 baud */
! 210: { B4800, BD4800 }, /* 4800 baud */
! 211: { B9600, BD9600 }, /* 9600 baud */
! 212: { B19200, BD19200 }, /* 19200 baud */
! 213: { -1, NOBAUD }, /* anything more is uncivilized */
! 214: };
! 215:
! 216: int
! 217: dart_speed(int speed)
! 218: {
! 219: const struct dart_s *ds;
! 220:
! 221: for (ds = dart_speeds; ds->kspeed != -1; ds++)
! 222: if (ds->kspeed == speed)
! 223: return ds->dspeed;
! 224:
! 225: return NOBAUD;
! 226: }
! 227:
! 228: struct tty *
! 229: darttty(dev_t dev)
! 230: {
! 231: u_int port, chip;
! 232: struct dartsoftc *sc;
! 233:
! 234: chip = DART_CHIP(dev);
! 235: port = DART_PORT(dev);
! 236: if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS)
! 237: return (NULL);
! 238:
! 239: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 240: if (sc == NULL)
! 241: return (NULL);
! 242:
! 243: return sc->sc_dart[port].tty;
! 244: }
! 245:
! 246: void
! 247: dartstart(struct tty *tp)
! 248: {
! 249: struct dartsoftc *sc;
! 250: dev_t dev;
! 251: int s;
! 252: u_int port, chip;
! 253: int c, tries;
! 254: bus_addr_t ptaddr;
! 255:
! 256: if ((tp->t_state & TS_ISOPEN) == 0)
! 257: return;
! 258:
! 259: dev = tp->t_dev;
! 260: chip = DART_CHIP(dev);
! 261: port = DART_PORT(dev);
! 262: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 263: ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
! 264:
! 265: s = spltty();
! 266:
! 267: if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
! 268: goto bail;
! 269:
! 270: if (tp->t_outq.c_cc <= tp->t_lowat) {
! 271: if (tp->t_state & TS_ASLEEP) {
! 272: tp->t_state &= ~TS_ASLEEP;
! 273: wakeup((caddr_t)&tp->t_outq);
! 274: }
! 275: selwakeup(&tp->t_wsel);
! 276: if (tp->t_outq.c_cc == 0)
! 277: goto bail;
! 278: }
! 279:
! 280: tp->t_state |= TS_BUSY;
! 281: while (tp->t_outq.c_cc != 0) {
! 282:
! 283: /* load transmitter until it is full */
! 284: for (tries = 10000; tries != 0; tries --)
! 285: if (dart_read(sc, ptaddr + DART_SRA) & TXRDY)
! 286: break;
! 287:
! 288: if (tries == 0) {
! 289: timeout_add(&tp->t_rstrt_to, 1);
! 290: tp->t_state |= TS_TIMEOUT;
! 291: break;
! 292: } else {
! 293: c = getc(&tp->t_outq);
! 294:
! 295: dart_write(sc, ptaddr + DART_TBA, c & 0xff);
! 296:
! 297: sc->sc_sv_reg->sv_imr |=
! 298: port == A_PORT ? ITXRDYA : ITXRDYB;
! 299: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 300: }
! 301: }
! 302: tp->t_state &= ~TS_BUSY;
! 303:
! 304: bail:
! 305: splx(s);
! 306: }
! 307:
! 308: int
! 309: dartstop(struct tty *tp, int flag)
! 310: {
! 311: int s;
! 312:
! 313: s = spltty();
! 314: if (tp->t_state & TS_BUSY) {
! 315: if ((tp->t_state & TS_TTSTOP) == 0)
! 316: tp->t_state |= TS_FLUSH;
! 317: }
! 318: splx(s);
! 319:
! 320: return 0;
! 321: }
! 322:
! 323: /*
! 324: * To be called at spltty - tty already locked.
! 325: * Returns status of carrier.
! 326: */
! 327: int
! 328: dartmctl(struct dartsoftc *sc, int port, int flags, int how)
! 329: {
! 330: int newflags, flagsmask;
! 331: struct dart_info *dart;
! 332: int s;
! 333:
! 334: dart = &sc->sc_dart[port];
! 335:
! 336: s = spltty();
! 337:
! 338: flagsmask = port == A_PORT ? (OPDTRA | OPRTSA) : (OPDTRB | OPRTSB);
! 339: newflags = (flags & TIOCM_DTR ? (OPDTRA | OPDTRB) : 0) |
! 340: (flags & TIOCM_RTS ? (OPRTSA | OPRTSB) : 0);
! 341: newflags &= flagsmask; /* restrict to the port we are acting on */
! 342:
! 343: switch (how) {
! 344: case DMSET:
! 345: dart_write(sc, DART_OPRS, newflags);
! 346: dart_write(sc, DART_OPRR, ~newflags);
! 347: /* only replace the sv_opr bits for the port we are acting on */
! 348: sc->sc_sv_reg->sv_opr &= ~flagsmask;
! 349: sc->sc_sv_reg->sv_opr |= newflags;
! 350: break;
! 351: case DMBIS:
! 352: dart_write(sc, DART_OPRS, newflags);
! 353: sc->sc_sv_reg->sv_opr |= newflags;
! 354: break;
! 355: case DMBIC:
! 356: dart_write(sc, DART_OPRR, newflags);
! 357: sc->sc_sv_reg->sv_opr &= ~newflags;
! 358: break;
! 359: case DMGET:
! 360: flags = 0;
! 361: if (port == A_PORT) {
! 362: if (sc->sc_sv_reg->sv_opr & OPDTRA)
! 363: flags |= TIOCM_DTR;
! 364: if (sc->sc_sv_reg->sv_opr & OPRTSA)
! 365: flags |= TIOCM_RTS;
! 366: } else {
! 367: if (sc->sc_sv_reg->sv_opr & OPDTRB)
! 368: flags |= TIOCM_DTR;
! 369: if (sc->sc_sv_reg->sv_opr & OPRTSB)
! 370: flags |= TIOCM_RTS;
! 371: }
! 372: break;
! 373: }
! 374:
! 375: splx(s);
! 376: return (flags);
! 377: }
! 378:
! 379: int
! 380: dartioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
! 381: {
! 382: int error;
! 383: u_int port, chip;
! 384: struct tty *tp;
! 385: struct dart_info *dart;
! 386: struct dartsoftc *sc;
! 387:
! 388: chip = DART_CHIP(dev);
! 389: port = DART_PORT(dev);
! 390: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 391: dart = &sc->sc_dart[port];
! 392:
! 393: tp = dart->tty;
! 394: if (tp == NULL)
! 395: return (ENXIO);
! 396:
! 397: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
! 398: if (error >= 0)
! 399: return(error);
! 400:
! 401: error = ttioctl(tp, cmd, data, flag, p);
! 402: if (error >= 0)
! 403: return(error);
! 404:
! 405: switch (cmd) {
! 406: case TIOCSBRK:
! 407: case TIOCCBRK:
! 408: break;
! 409: case TIOCSDTR:
! 410: (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIS);
! 411: break;
! 412: case TIOCCDTR:
! 413: (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMBIC);
! 414: break;
! 415: case TIOCMSET:
! 416: (void)dartmctl(sc, port, *(int *) data, DMSET);
! 417: break;
! 418: case TIOCMBIS:
! 419: (void)dartmctl(sc, port, *(int *) data, DMBIS);
! 420: break;
! 421: case TIOCMBIC:
! 422: (void)dartmctl(sc, port, *(int *) data, DMBIC);
! 423: break;
! 424: case TIOCMGET:
! 425: *(int *)data = dartmctl(sc, port, 0, DMGET);
! 426: break;
! 427: case TIOCGFLAGS:
! 428: *(int *)data = dart->dart_swflags;
! 429: break;
! 430: case TIOCSFLAGS:
! 431: error = suser(p, 0);
! 432: if (error != 0)
! 433: return (EPERM);
! 434:
! 435: dart->dart_swflags = *(int *)data;
! 436: dart->dart_swflags &= /* only allow valid flags */
! 437: (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | TIOCFLAG_CRTSCTS);
! 438: break;
! 439: default:
! 440: return (ENOTTY);
! 441: }
! 442:
! 443: return (0);
! 444: }
! 445:
! 446: int
! 447: dartparam(struct tty *tp, struct termios *t)
! 448: {
! 449: int flags;
! 450: u_int port, chip;
! 451: int speeds;
! 452: unsigned char mr1, mr2;
! 453: struct dart_info *dart;
! 454: struct dartsoftc *sc;
! 455: dev_t dev;
! 456: bus_addr_t ptaddr;
! 457:
! 458: dev = tp->t_dev;
! 459: chip = DART_CHIP(dev);
! 460: port = DART_PORT(dev);
! 461: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 462: dart = &sc->sc_dart[port];
! 463: ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
! 464:
! 465: tp->t_ispeed = t->c_ispeed;
! 466: tp->t_ospeed = t->c_ospeed;
! 467: tp->t_cflag = t->c_cflag;
! 468:
! 469: flags = tp->t_flags;
! 470:
! 471: /* Reset to make global changes*/
! 472: /* disable Tx and Rx */
! 473:
! 474: if (sc->sc_console == 0 || CONS_PORT != port) {
! 475: if (port == A_PORT)
! 476: sc->sc_sv_reg->sv_imr &= ~(ITXRDYA | IRXRDYA);
! 477: else
! 478: sc->sc_sv_reg->sv_imr &= ~(ITXRDYB | IRXRDYB);
! 479: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 480:
! 481: /* hang up on zero baud rate */
! 482: if (tp->t_ispeed == 0) {
! 483: dartmctl(sc, port, HUPCL, DMSET);
! 484: return (0);
! 485: } else {
! 486: /* set baudrate */
! 487: speeds = dart_speed(tp->t_ispeed);
! 488: if (speeds == NOBAUD)
! 489: speeds = sc->sc_sv_reg->sv_csr[port];
! 490: dart_write(sc, ptaddr + DART_CSRA, speeds);
! 491: sc->sc_sv_reg->sv_csr[port] = speeds;
! 492: }
! 493:
! 494: /* get saved mode registers and clear set up parameters */
! 495: mr1 = sc->sc_sv_reg->sv_mr1[port];
! 496: mr1 &= ~(CLMASK | PARTYPEMASK | PARMODEMASK);
! 497:
! 498: mr2 = sc->sc_sv_reg->sv_mr2[port];
! 499: mr2 &= ~SBMASK;
! 500:
! 501: /* set up character size */
! 502: switch (t->c_cflag & CSIZE) {
! 503: case CL8:
! 504: mr1 |= CL8;
! 505: break;
! 506: case CL7:
! 507: mr1 |= CL7;
! 508: break;
! 509: case CL6:
! 510: mr1 |= CL6;
! 511: break;
! 512: case CL5:
! 513: mr1 |= CL5;
! 514: break;
! 515: }
! 516:
! 517: /* set up stop bits */
! 518: if (tp->t_ospeed == B110)
! 519: mr2 |= SB2;
! 520: else
! 521: mr2 |= SB1;
! 522:
! 523: /* set up parity */
! 524: if (t->c_cflag & PARENB) {
! 525: mr1 |= PAREN;
! 526: if (t->c_cflag & PARODD)
! 527: mr1 |= ODDPAR;
! 528: else
! 529: mr1 |= EVENPAR;
! 530: } else
! 531: mr1 |= PARDIS;
! 532:
! 533: if (sc->sc_sv_reg->sv_mr1[port] != mr1 ||
! 534: sc->sc_sv_reg->sv_mr2[port] != mr2) {
! 535: /* write mode registers to duart */
! 536: dart_write(sc, ptaddr + DART_CRA, MRRESET);
! 537: dart_write(sc, ptaddr + DART_MR1A, mr1);
! 538: dart_write(sc, ptaddr + DART_MR2A, mr2);
! 539:
! 540: /* save changed mode registers */
! 541: sc->sc_sv_reg->sv_mr1[port] = mr1;
! 542: sc->sc_sv_reg->sv_mr2[port] = mr2;
! 543: }
! 544: }
! 545:
! 546: /* enable transmitter? */
! 547: if (tp->t_state & TS_BUSY) {
! 548: sc->sc_sv_reg->sv_imr |= port == A_PORT ? ITXRDYA : ITXRDYB;
! 549: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 550: }
! 551:
! 552: /* re-enable the receiver */
! 553: #if 0
! 554: DELAY_CR;
! 555: #endif
! 556: sc->sc_sv_reg->sv_imr |= port == A_PORT ? IRXRDYA : IRXRDYB;
! 557: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 558:
! 559: return (0);
! 560: }
! 561:
! 562: void
! 563: dartmodemtrans(struct dartsoftc *sc, unsigned int ip, unsigned int ipcr)
! 564: {
! 565: unsigned int dcdstate;
! 566: struct tty *tp;
! 567: int port;
! 568: struct dart_info *dart;
! 569:
! 570: /* input is inverted at port!!! */
! 571: if (ipcr & IPCRDCDA) {
! 572: port = A_PORT;
! 573: dcdstate = !(ip & IPDCDA);
! 574: } else if (ipcr & IPCRDCDB) {
! 575: port = B_PORT;
! 576: dcdstate = !(ip & IPDCDB);
! 577: } else {
! 578: #ifdef DIAGNOSTIC
! 579: printf("dartmodemtrans: unknown transition ip=0x%x ipcr=0x%x\n",
! 580: ip, ipcr);
! 581: #endif
! 582: return;
! 583: }
! 584:
! 585: dart = &sc->sc_dart[port];
! 586: tp = dart->tty;
! 587: if (tp != NULL)
! 588: ttymodem(tp, dcdstate);
! 589: }
! 590:
! 591: int
! 592: dartopen(dev_t dev, int flag, int mode, struct proc *p)
! 593: {
! 594: int s;
! 595: u_int port, chip;
! 596: struct dart_info *dart;
! 597: struct dartsoftc *sc;
! 598: struct tty *tp;
! 599:
! 600: chip = DART_CHIP(dev);
! 601: port = DART_PORT(dev);
! 602: if (dart_cd.cd_ndevs <= chip || port >= NDARTPORTS)
! 603: return (ENODEV);
! 604: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 605: if (sc == NULL)
! 606: return (ENODEV);
! 607: dart = &sc->sc_dart[port];
! 608:
! 609: s = spltty();
! 610: if (dart->tty != NULL)
! 611: tp = dart->tty;
! 612: else
! 613: tp = dart->tty = ttymalloc();
! 614:
! 615: tp->t_oproc = dartstart;
! 616: tp->t_param = dartparam;
! 617: tp->t_dev = dev;
! 618:
! 619: if ((tp->t_state & TS_ISOPEN) == 0) {
! 620: ttychars(tp);
! 621:
! 622: if (tp->t_ispeed == 0) {
! 623: tp->t_iflag = TTYDEF_IFLAG;
! 624: tp->t_oflag = TTYDEF_OFLAG;
! 625: tp->t_lflag = TTYDEF_LFLAG;
! 626: tp->t_ispeed = tp->t_ospeed = B9600;
! 627: if (sc->sc_console && port == CONS_PORT) {
! 628: /* console is 8N1 */
! 629: tp->t_cflag = (CREAD | CS8 | HUPCL);
! 630: } else {
! 631: tp->t_cflag = TTYDEF_CFLAG;
! 632: }
! 633: }
! 634:
! 635: if (dart->dart_swflags & TIOCFLAG_CLOCAL)
! 636: tp->t_cflag |= CLOCAL;
! 637: if (dart->dart_swflags & TIOCFLAG_CRTSCTS)
! 638: tp->t_cflag |= CRTSCTS;
! 639: if (dart->dart_swflags & TIOCFLAG_MDMBUF)
! 640: tp->t_cflag |= MDMBUF;
! 641:
! 642: dartparam(tp, &tp->t_termios);
! 643: ttsetwater(tp);
! 644:
! 645: (void)dartmctl(sc, port, TIOCM_DTR | TIOCM_RTS, DMSET);
! 646: tp->t_state |= TS_CARR_ON;
! 647: } else if (tp->t_state & TS_XCLUDE && p->p_ucred->cr_uid != 0) {
! 648: splx(s);
! 649: return (EBUSY);
! 650: }
! 651:
! 652: /*
! 653: * Reset the tty pointer, as there could have been a dialout
! 654: * use of the tty with a dialin open waiting.
! 655: */
! 656: tp->t_dev = dev;
! 657: splx(s);
! 658: return ((*linesw[tp->t_line].l_open)(dev, tp));
! 659: }
! 660:
! 661: int
! 662: dartclose(dev_t dev, int flag, int mode, struct proc *p)
! 663: {
! 664: struct tty *tp;
! 665: struct dart_info *dart;
! 666: struct dartsoftc *sc;
! 667: u_int port, chip;
! 668:
! 669: chip = DART_CHIP(dev);
! 670: port = DART_PORT(dev);
! 671: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 672: dart = &sc->sc_dart[port];
! 673:
! 674: tp = dart->tty;
! 675: (*linesw[tp->t_line].l_close)(tp, flag);
! 676: ttyclose(tp);
! 677:
! 678: return (0);
! 679: }
! 680:
! 681: int
! 682: dartread(dev_t dev, struct uio *uio, int flag)
! 683: {
! 684: u_int port, chip;
! 685: struct tty *tp;
! 686: struct dart_info *dart;
! 687: struct dartsoftc *sc;
! 688:
! 689: chip = DART_CHIP(dev);
! 690: port = DART_PORT(dev);
! 691: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 692: dart = &sc->sc_dart[port];
! 693:
! 694: tp = dart->tty;
! 695: if (tp == NULL)
! 696: return (ENXIO);
! 697: return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
! 698: }
! 699:
! 700: int
! 701: dartwrite(dev_t dev, struct uio *uio, int flag)
! 702: {
! 703: u_int port, chip;
! 704: struct tty *tp;
! 705: struct dart_info *dart;
! 706: struct dartsoftc *sc;
! 707:
! 708: chip = DART_CHIP(dev);
! 709: port = DART_PORT(dev);
! 710: sc = (struct dartsoftc *)dart_cd.cd_devs[chip];
! 711: dart = &sc->sc_dart[port];
! 712:
! 713: tp = dart->tty;
! 714: if (tp == NULL)
! 715: return (ENXIO);
! 716: return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
! 717: }
! 718:
! 719: void
! 720: dartrint(struct dartsoftc *sc, int port)
! 721: {
! 722: struct tty *tp;
! 723: unsigned char data, sr;
! 724: struct dart_info *dart;
! 725: bus_addr_t ptaddr;
! 726:
! 727: dart = &sc->sc_dart[port];
! 728: ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
! 729: tp = dart->tty;
! 730:
! 731: /* read status reg */
! 732: while ((sr = dart_read(sc, ptaddr + DART_SRA)) & RXRDY) {
! 733: /* read data and reset receiver */
! 734: data = dart_read(sc, ptaddr + DART_RBA);
! 735:
! 736: if ((tp->t_state & (TS_ISOPEN|TS_WOPEN)) == 0 &&
! 737: (sc->sc_console == 0 || CONS_PORT != port)) {
! 738: return;
! 739: }
! 740:
! 741: if (sr & RBRK) {
! 742: /* clear break state */
! 743: dart_write(sc, ptaddr + DART_CRA, BRKINTRESET);
! 744: DELAY_CR;
! 745: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
! 746:
! 747: #if defined(DDB)
! 748: if (db_console != 0 &&
! 749: sc->sc_console && port == CONS_PORT)
! 750: Debugger();
! 751: #endif
! 752: } else {
! 753: if (sr & (FRERR | PERR | ROVRN)) { /* errors */
! 754: if (sr & ROVRN)
! 755: log(LOG_WARNING, "%s port %c: "
! 756: "receiver overrun\n",
! 757: sc->sc_dev.dv_xname, 'A' + port);
! 758: if (sr & FRERR)
! 759: log(LOG_WARNING, "%s port %c: "
! 760: "framing error\n",
! 761: sc->sc_dev.dv_xname, 'A' + port);
! 762: if (sr & PERR)
! 763: log(LOG_WARNING, "%s port %c: "
! 764: "parity error\n",
! 765: sc->sc_dev.dv_xname, 'A' + port);
! 766: /* clear error state */
! 767: dart_write(sc, ptaddr + DART_CRA, ERRRESET);
! 768: } else {
! 769: /* no errors */
! 770: (*linesw[tp->t_line].l_rint)(data,tp);
! 771: }
! 772: }
! 773: }
! 774: }
! 775:
! 776: void
! 777: dartxint(struct dartsoftc *sc, int port)
! 778: {
! 779: struct tty *tp;
! 780: struct dart_info *dart;
! 781:
! 782: dart = &sc->sc_dart[port];
! 783: tp = dart->tty;
! 784:
! 785: if ((tp->t_state & (TS_ISOPEN|TS_WOPEN))==0)
! 786: goto out;
! 787:
! 788: if (tp->t_state & TS_BUSY) {
! 789: tp->t_state &= ~(TS_BUSY | TS_FLUSH);
! 790: dartstart(tp);
! 791: if (tp->t_state & TS_BUSY) {
! 792: /* do not disable transmitter, yet */
! 793: return;
! 794: }
! 795: }
! 796: out:
! 797:
! 798: /* disable transmitter */
! 799: sc->sc_sv_reg->sv_imr &= port == A_PORT ? ~ITXRDYA : ~ITXRDYB;
! 800: dart_write(sc, DART_IMR, sc->sc_sv_reg->sv_imr);
! 801: }
! 802:
! 803: int
! 804: dartintr(void *arg)
! 805: {
! 806: struct dartsoftc *sc = arg;
! 807: unsigned char isr, imr;
! 808: int port;
! 809:
! 810: /* read interrupt status register and mask with imr */
! 811: isr = dart_read(sc, DART_ISR);
! 812: imr = sc->sc_sv_reg->sv_imr;
! 813:
! 814: if ((isr & imr) == 0) {
! 815: /*
! 816: * We got an interrupt on a disabled condition (such as TX
! 817: * ready change on a disabled port). This should not happen,
! 818: * but we have to claim the interrupt anyway.
! 819: */
! 820: #ifdef DIAGNOSTIC
! 821: printf("%s: spurious interrupt, isr %x imr %x\n",
! 822: sc->sc_dev.dv_xname, isr, imr);
! 823: #endif
! 824: return (1);
! 825: }
! 826: isr &= imr;
! 827:
! 828: if (isr & IIPCHG) {
! 829: unsigned int ip, ipcr;
! 830:
! 831: ip = dart_read(sc, DART_IP);
! 832: ipcr = dart_read(sc, DART_IPCR);
! 833: dartmodemtrans(sc, ip, ipcr);
! 834: return (1);
! 835: }
! 836:
! 837: if (isr & (IRXRDYA | ITXRDYA))
! 838: port = 0;
! 839: #ifdef DIAGNOSTIC
! 840: else if ((isr & (IRXRDYB | ITXRDYB)) == 0) {
! 841: printf("%s: spurious interrupt, isr %x\n",
! 842: sc->sc_dev.dv_xname, isr);
! 843: return (1); /* claim it anyway */
! 844: }
! 845: #endif
! 846: else
! 847: port = 1;
! 848:
! 849: if (isr & (IRXRDYA | IRXRDYB))
! 850: dartrint(sc, port);
! 851: if (isr & (ITXRDYA | ITXRDYB))
! 852: dartxint(sc, port);
! 853: if (isr & (port == A_PORT ? IBRKA : IBRKB))
! 854: dart_write(sc, port == A_PORT ? DART_CRA : DART_CRB,
! 855: BRKINTRESET);
! 856:
! 857: return (1);
! 858: }
! 859:
! 860: /*
! 861: * Console interface routines.
! 862: #ifdef USE_PROM_CONSOLE
! 863: * Since we select the actual console after all devices are attached,
! 864: * we can safely pick the appropriate softc and use its information.
! 865: #endif
! 866: */
! 867:
! 868: #ifdef USE_PROM_CONSOLE
! 869: #define dart_cnread(reg) dart_read(sc, (reg))
! 870: #define dart_cnwrite(reg, val) dart_write(sc, (reg), (val))
! 871: #else
! 872: #define dart_cnread(reg) \
! 873: *(volatile u_int8_t *)(DART_BASE + 3 + ((reg) << 2))
! 874: #define dart_cnwrite(reg, val) \
! 875: *(volatile u_int8_t *)(DART_BASE + 3 + ((reg) << 2)) = (val)
! 876: #endif
! 877:
! 878: void
! 879: dartcnprobe(struct consdev *cp)
! 880: {
! 881: int maj;
! 882:
! 883: if (badaddr(DART_BASE, 4) != 0)
! 884: return;
! 885:
! 886: #ifdef USE_PROM_CONSOLE
! 887: /* do not attach as console if dart has been disabled */
! 888: if (dart_cd.cd_ndevs == 0 || dart_cd.cd_devs[0] == NULL)
! 889: return;
! 890: #endif
! 891:
! 892: /* locate the major number */
! 893: for (maj = 0; maj < nchrdev; maj++)
! 894: if (cdevsw[maj].d_open == dartopen)
! 895: break;
! 896: if (maj == nchrdev)
! 897: return;
! 898:
! 899: cp->cn_dev = makedev(maj, CONS_PORT);
! 900: cp->cn_pri = CN_NORMAL;
! 901: }
! 902:
! 903: void
! 904: dartcninit(cp)
! 905: struct consdev *cp;
! 906: {
! 907: #ifndef USE_PROM_CONSOLE
! 908: dartcn_sv.sv_mr1[CONS_PORT] = PARDIS | RXRTS | CL8;
! 909: dartcn_sv.sv_mr2[CONS_PORT] = /* TXCTS | */ SB1;
! 910: dartcn_sv.sv_csr[CONS_PORT] = BD9600;
! 911: dartcn_sv.sv_cr[CONS_PORT] = TXEN | RXEN;
! 912: dartcn_sv.sv_opr = CONS_PORT == A_PORT ? (OPDTRA | OPRTSA) :
! 913: (OPDTRB | OPRTSB);
! 914: dartcn_sv.sv_imr = IIPCHG;
! 915:
! 916: dart_cnwrite(DART_CRA, RXRESET | TXDIS | RXDIS);
! 917: DELAY_CR;
! 918: dart_cnwrite(DART_CRA, TXRESET | TXDIS | RXDIS);
! 919: DELAY_CR;
! 920: dart_cnwrite(DART_CRA, ERRRESET | TXDIS | RXDIS);
! 921: DELAY_CR;
! 922: dart_cnwrite(DART_CRA, BRKINTRESET | TXDIS | RXDIS);
! 923: DELAY_CR;
! 924: dart_cnwrite(DART_CRA, MRRESET | TXDIS | RXDIS);
! 925: DELAY_CR;
! 926:
! 927: dart_cnwrite(DART_MR1A, dartcn_sv.sv_mr1[CONS_PORT]);
! 928: dart_cnwrite(DART_MR2A, dartcn_sv.sv_mr2[CONS_PORT]);
! 929: dart_cnwrite(DART_CSRA, dartcn_sv.sv_csr[CONS_PORT]);
! 930: dart_cnwrite(DART_CRA, dartcn_sv.sv_cr[CONS_PORT]);
! 931:
! 932: dart_cnwrite(DART_OPRS, dartcn_sv.sv_opr);
! 933:
! 934: dart_cnwrite(DART_IMR, dartcn_sv.sv_imr);
! 935: #endif
! 936: }
! 937:
! 938: void
! 939: dartcnputc(dev_t dev, int c)
! 940: {
! 941: #ifdef USE_PROM_CONSOLE
! 942: struct dartsoftc *sc;
! 943: #endif
! 944: int s;
! 945: u_int port;
! 946: bus_addr_t ptaddr;
! 947:
! 948: #ifdef USE_PROM_CONSOLE
! 949: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
! 950: port = DART_PORT(dev);
! 951: #else
! 952: port = CONS_PORT;
! 953: #endif
! 954: ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
! 955:
! 956: s = spltty();
! 957:
! 958: /* inhibit interrupts on the chip */
! 959: dart_cnwrite(DART_IMR, dartcn_sv.sv_imr &
! 960: (CONS_PORT == A_PORT ? ~ITXRDYA : ~ITXRDYB));
! 961: /* make sure transmitter is enabled */
! 962: #if 0
! 963: DELAY_CR;
! 964: #endif
! 965: dart_cnwrite(ptaddr + DART_CRA, TXEN);
! 966:
! 967: while ((dart_cnread(ptaddr + DART_SRA) & TXRDY) == 0)
! 968: ;
! 969: dart_cnwrite(ptaddr + DART_TBA, c);
! 970:
! 971: /* wait for transmitter to empty */
! 972: while ((dart_cnread(ptaddr + DART_SRA) & TXEMT) == 0)
! 973: ;
! 974:
! 975: /* restore the previous state */
! 976: dart_cnwrite(DART_IMR, dartcn_sv.sv_imr);
! 977: #if 0
! 978: DELAY_CR;
! 979: #endif
! 980: dart_cnwrite(ptaddr + DART_CRA, dartcn_sv.sv_cr[0]);
! 981:
! 982: splx(s);
! 983: }
! 984:
! 985: int
! 986: dartcngetc(dev_t dev)
! 987: {
! 988: #ifdef USE_PROM_CONSOLE
! 989: struct dartsoftc *sc;
! 990: #endif
! 991: unsigned char sr; /* status reg of port a/b */
! 992: u_char c; /* received character */
! 993: int s;
! 994: u_int port;
! 995: bus_addr_t ptaddr;
! 996:
! 997: #ifdef USE_PROM_CONSOLE
! 998: sc = (struct dartsoftc *)dart_cd.cd_devs[0];
! 999: port = DART_PORT(dev);
! 1000: #else
! 1001: port = CONS_PORT;
! 1002: #endif
! 1003: ptaddr = port == A_PORT ? DART_A_BASE : DART_B_BASE;
! 1004:
! 1005: s = spltty();
! 1006:
! 1007: /* enable receiver */
! 1008: dart_cnwrite(ptaddr + DART_CRA, RXEN);
! 1009:
! 1010: for (;;) {
! 1011: /* read status reg */
! 1012: sr = dart_cnread(ptaddr + DART_SRA);
! 1013:
! 1014: /* receiver interrupt handler*/
! 1015: if (sr & RXRDY) {
! 1016: /* read character from port */
! 1017: c = dart_cnread(ptaddr + DART_RBA);
! 1018:
! 1019: /* check break condition */
! 1020: if (sr & RBRK) {
! 1021: /* clear break state */
! 1022: dart_cnwrite(ptaddr + DART_CRA, BRKINTRESET);
! 1023: DELAY_CR;
! 1024: dart_cnwrite(ptaddr + DART_CRA, ERRRESET);
! 1025: break;
! 1026: }
! 1027:
! 1028: if (sr & (FRERR | PERR | ROVRN)) {
! 1029: /* clear error state */
! 1030: dart_cnwrite(ptaddr + DART_CRA, ERRRESET);
! 1031: } else {
! 1032: break;
! 1033: }
! 1034: }
! 1035: }
! 1036: splx(s);
! 1037:
! 1038: return ((int)c);
! 1039: }
CVSweb