|
|
1.1 ! root 1: /* dz.c 4.3 11/9/80 */ ! 2: ! 3: #include "../conf/dz.h" ! 4: #if NDZ11 > 0 ! 5: /* ! 6: * DZ-11 Driver ! 7: */ ! 8: #include "../h/param.h" ! 9: #include "../h/systm.h" ! 10: #include "../h/tty.h" ! 11: #include "../h/dir.h" ! 12: #include "../h/user.h" ! 13: #include "../h/map.h" ! 14: #include "../h/pte.h" ! 15: #include "../h/uba.h" ! 16: #include "../h/conf.h" ! 17: #include "../h/pdma.h" ! 18: #include "../h/bk.h" ! 19: #include "../h/file.h" ! 20: #include "../h/mx.h" ! 21: ! 22: /* ! 23: * When running dz's using only SAE (silo alarm) on input ! 24: * it is necessary to call dzrint() at clock interrupt time. ! 25: * This is unsafe unless spl5()s in tty code are changed to ! 26: * spl6()s to block clock interrupts. Note that the dh driver ! 27: * currently in use works the same way as the dz, even though ! 28: * we could try to more intelligently manage its silo. ! 29: * Thus don't take this out if you have no dz's unless you ! 30: * change clock.c and dhtimer(). ! 31: */ ! 32: #define spl5 spl6 ! 33: ! 34: #define NDZ (NDZ11*8) ! 35: ! 36: #define BITS7 020 ! 37: #define BITS8 030 ! 38: #define TWOSB 040 ! 39: #define PENABLE 0100 ! 40: #define OPAR 0200 ! 41: #define MSE 040 /* Master Scan Enable */ ! 42: #define RIE 0100 /* Receiver Interrupt Enable */ ! 43: #define SAE 010000 /* Silo Alarm Enable */ ! 44: #define TIE 040000 /* Transmit Interrupt Enable */ ! 45: #define DZ_IEN (MSE+RIE+TIE+SAE) ! 46: #define PERROR 010000 ! 47: #define FRERROR 020000 ! 48: #define OVERRUN 040000 ! 49: #define SSPEED 7 /* std speed = 300 baud */ ! 50: ! 51: ! 52: #define dzlpr dzrbuf ! 53: #define dzmsr dzbrk ! 54: #define ON 1 ! 55: #define OFF 0 ! 56: ! 57: int dzstart(); ! 58: int dzxint(); ! 59: int ttrstrt(); ! 60: struct tty dz_tty[NDZ]; ! 61: int dz_cnt = { NDZ }; ! 62: int dzact; ! 63: ! 64: struct device { ! 65: short dzcsr; ! 66: short dzrbuf; ! 67: char dztcr; ! 68: char dzdtr; ! 69: char dztbuf; ! 70: char dzbrk; ! 71: }; ! 72: ! 73: struct pdma dzpdma[] = { ! 74: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint, ! 75: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint, ! 76: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint, ! 77: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint, ! 78: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint, ! 79: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint, ! 80: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint, ! 81: (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint, ! 82: #if NDZ11 >= 2 ! 83: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint, ! 84: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint, ! 85: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint, ! 86: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint, ! 87: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint, ! 88: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint, ! 89: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint, ! 90: (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint, ! 91: #endif ! 92: #if NDZ11 >= 3 ! 93: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint, ! 94: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint, ! 95: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint, ! 96: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint, ! 97: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint, ! 98: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint, ! 99: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint, ! 100: (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint, ! 101: #endif ! 102: #if NDZ11 >= 4 ! 103: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint, ! 104: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint, ! 105: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint, ! 106: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint, ! 107: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint, ! 108: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint, ! 109: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint, ! 110: (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint, ! 111: #endif ! 112: }; ! 113: char dz_timer; ! 114: char dz_speeds[] = { ! 115: 0, 020 , 021 , 022 , 023 , 024 , 0, 025, ! 116: 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, ! 117: }; ! 118: ! 119: /*ARGSUSED*/ ! 120: dzopen(d, flag) ! 121: { ! 122: register struct tty *tp; ! 123: register dev; ! 124: extern dzscan(); ! 125: ! 126: dev = minor(d); ! 127: if (dev >= dz_cnt) { ! 128: u.u_error = ENXIO; ! 129: return; ! 130: } ! 131: if (dz_timer == 0) { ! 132: dz_timer++; ! 133: timeout(dzscan, (caddr_t)0, 60); ! 134: } ! 135: tp = &dz_tty[dev]; ! 136: tp->t_addr = (caddr_t)&dzpdma[dev]; ! 137: tp->t_oproc = dzstart; ! 138: tp->t_iproc = NULL; ! 139: tp->t_state |= WOPEN; ! 140: if ((tp->t_state & ISOPEN) == 0) { ! 141: ttychars(tp); ! 142: tp->t_ospeed = tp->t_ispeed = SSPEED; ! 143: tp->t_flags = ODDP|EVENP|ECHO; ! 144: /*tp->t_state |= HUPCLS;*/ ! 145: dzparam(dev); ! 146: } else if (tp->t_state&XCLUDE && u.u_uid != 0) { ! 147: u.u_error = EBUSY; ! 148: return; ! 149: } ! 150: dzmodem(dev, ON); ! 151: (void) spl5(); ! 152: while ((tp->t_state & CARR_ON) == 0) { ! 153: tp->t_state |= WOPEN; ! 154: sleep((caddr_t)&tp->t_rawq, TTIPRI); ! 155: } ! 156: (void) spl0(); ! 157: (*linesw[tp->t_line].l_open)(d, tp); ! 158: } ! 159: ! 160: dzclose(d) ! 161: { ! 162: register struct tty *tp; ! 163: register dev; ! 164: ! 165: dev = minor(d); ! 166: tp = &dz_tty[dev]; ! 167: (*linesw[tp->t_line].l_close)(tp); ! 168: if (tp->t_state & HUPCLS) ! 169: dzmodem(dev, OFF); ! 170: ttyclose(tp); ! 171: } ! 172: ! 173: dzread(d) ! 174: { ! 175: register struct tty *tp; ! 176: ! 177: tp = &dz_tty[minor(d)]; ! 178: (*linesw[tp->t_line].l_read)(tp); ! 179: } ! 180: ! 181: dzwrite(d) ! 182: { ! 183: register struct tty *tp; ! 184: ! 185: tp = &dz_tty[minor(d)]; ! 186: (*linesw[tp->t_line].l_write)(tp); ! 187: } ! 188: ! 189: /*ARGSUSED*/ ! 190: dzrint(dev) ! 191: { ! 192: register struct tty *tp; ! 193: register int c; ! 194: register struct device *dzaddr; ! 195: register struct tty *tp0; ! 196: int s; ! 197: ! 198: s = spl6(); /* see comment in clock.c */ ! 199: /* as long as we are here, service them all */ ! 200: for (dev = 0; dev < NDZ; dev += 8) { ! 201: if ((dzact & (1<<(dev>>3))) == 0) ! 202: continue; ! 203: dzaddr = dzpdma[dev].p_addr; ! 204: tp0 = &dz_tty[dev]; ! 205: while ((c = dzaddr->dzrbuf) < 0) { /* char present */ ! 206: tp = tp0 + ((c>>8)&07); ! 207: if (tp >= &dz_tty[dz_cnt]) ! 208: continue; ! 209: if ((tp->t_state & ISOPEN) == 0) { ! 210: wakeup((caddr_t)&tp->t_rawq); ! 211: continue; ! 212: } ! 213: if (c&FRERROR) ! 214: /* framing error = break */ ! 215: if (tp->t_flags & RAW) ! 216: c = 0; /* null for getty */ ! 217: else ! 218: #ifdef IIASA ! 219: continue; ! 220: #else ! 221: c = tun.t_intrc; ! 222: #endif ! 223: if (c&OVERRUN) ! 224: printf("o"); ! 225: if (c&PERROR) ! 226: /* parity error */ ! 227: if (((tp->t_flags & (EVENP|ODDP)) == EVENP) ! 228: || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) ! 229: continue; ! 230: if (tp->t_line == NETLDISC) { ! 231: c &= 0177; ! 232: BKINPUT(c, tp); ! 233: } else ! 234: (*linesw[tp->t_line].l_rint)(c, tp); ! 235: } ! 236: } ! 237: splx(s); ! 238: } ! 239: ! 240: /*ARGSUSED*/ ! 241: dzioctl(dev, cmd, addr, flag) ! 242: caddr_t addr; ! 243: dev_t dev; ! 244: { ! 245: register struct tty *tp; ! 246: static char dz_brk[NDZ11]; ! 247: ! 248: tp = &dz_tty[minor(dev)]; ! 249: cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); ! 250: if (cmd == 0) ! 251: return; ! 252: if (ttioctl(cmd, tp, addr, dev, flag)) { ! 253: if (cmd==TIOCSETP || cmd==TIOCSETN) ! 254: dzparam(minor(dev)); ! 255: } else switch(cmd) { ! 256: case TIOCSBRK: ! 257: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = ! 258: (dz_brk[minor(dev)>>3] |= 1 << (dev&07)); ! 259: break; ! 260: case TIOCCBRK: ! 261: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = ! 262: (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07))); ! 263: break; ! 264: case TIOCSDTR: ! 265: dzmodem(minor(dev), ON); ! 266: break; ! 267: case TIOCCDTR: ! 268: dzmodem(minor(dev), OFF); ! 269: break; ! 270: default: ! 271: u.u_error = ENOTTY; ! 272: } ! 273: } ! 274: ! 275: dzparam(dev) ! 276: { ! 277: register struct tty *tp; ! 278: register struct device *dzaddr; ! 279: register short lpr; ! 280: ! 281: tp = &dz_tty[dev]; ! 282: dzaddr = dzpdma[dev].p_addr; ! 283: dzaddr->dzcsr = DZ_IEN; ! 284: dzact |= (1<<(dev>>3)); ! 285: if (tp->t_ispeed == 0) { ! 286: dzmodem(dev, OFF); /* hang up line */ ! 287: return; ! 288: } ! 289: lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07); ! 290: #ifndef IIASA ! 291: if (tp->t_flags & RAW) ! 292: lpr |= BITS8; ! 293: else ! 294: lpr |= (BITS7|PENABLE); ! 295: if ((tp->t_flags & EVENP) == 0) ! 296: lpr |= OPAR; ! 297: #else IIASA ! 298: if ((tp->t_flags & (EVENP|ODDP)) == (EVENP|ODDP)) ! 299: lpr |= BITS8; ! 300: else if (tp->t_flags & EVENP) ! 301: lpr |= (BITS7|PENABLE); ! 302: else if (tp->t_flags & ODDP) ! 303: lpr |= (BITS7|OPAR|PENABLE); ! 304: else ! 305: lpr |= BITS7; ! 306: #endif IIASA ! 307: if (tp->t_ispeed == 3) ! 308: lpr |= TWOSB; /* 110 baud: 2 stop bits */ ! 309: dzaddr->dzlpr = lpr; ! 310: } ! 311: ! 312: dzxint(tp) ! 313: register struct tty *tp; ! 314: { ! 315: register struct pdma *dp; ! 316: register s; ! 317: s = spl6(); /* block the clock */ ! 318: ! 319: dp = &dzpdma[tp-dz_tty]; ! 320: tp->t_state &= ~BUSY; ! 321: if (tp->t_state & FLUSH) ! 322: tp->t_state &= ~FLUSH; ! 323: else ! 324: ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); ! 325: if (tp->t_line) ! 326: (*linesw[tp->t_line].l_start)(tp); ! 327: else ! 328: dzstart(tp); ! 329: if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) ! 330: dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8)); ! 331: splx(s); ! 332: } ! 333: ! 334: dzstart(tp) ! 335: register struct tty *tp; ! 336: { ! 337: register struct pdma *dp; ! 338: register struct device *dzaddr; ! 339: register cc; ! 340: int sps; ! 341: ! 342: dp = &dzpdma[tp-dz_tty]; ! 343: dzaddr = dp->p_addr; ! 344: sps = spl5(); ! 345: if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) ! 346: goto out; ! 347: if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 348: tp->t_state &= ~ASLEEP; ! 349: if (tp->t_chan) ! 350: mcstart(tp->t_chan, (caddr_t)&tp->t_outq); ! 351: else ! 352: wakeup((caddr_t)&tp->t_outq); ! 353: } ! 354: if (tp->t_outq.c_cc == 0) ! 355: goto out; ! 356: if (tp->t_flags&RAW) ! 357: cc = ndqb(&tp->t_outq, 0); ! 358: else { ! 359: cc = ndqb(&tp->t_outq, 0200); ! 360: if (cc == 0) { ! 361: cc = getc(&tp->t_outq); ! 362: timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6); ! 363: tp->t_state |= TIMEOUT; ! 364: goto out; ! 365: } ! 366: } ! 367: tp->t_state |= BUSY; ! 368: dp->p_end = dp->p_mem = tp->t_outq.c_cf; ! 369: dp->p_end += cc; ! 370: dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8); ! 371: out: ! 372: splx(sps); ! 373: } ! 374: ! 375: /* ! 376: * Stop output on a line. ! 377: * Assume call is made at spl6. ! 378: */ ! 379: /*ARGSUSED*/ ! 380: dzstop(tp, flag) ! 381: register struct tty *tp; ! 382: { ! 383: register struct pdma *dp; ! 384: register int s; ! 385: ! 386: dp = &dzpdma[tp-dz_tty]; ! 387: s = spl6(); ! 388: if (tp->t_state & BUSY) { ! 389: dp->p_end = dp->p_mem; ! 390: if ((tp->t_state&TTSTOP)==0) { ! 391: tp->t_state |= FLUSH; ! 392: } ! 393: } ! 394: splx(s); ! 395: } ! 396: ! 397: dzmodem(dev, flag) ! 398: register int dev; ! 399: { ! 400: register struct device *dzaddr; ! 401: register char bit; ! 402: ! 403: dzaddr = dzpdma[dev].p_addr; ! 404: bit = 1<<(dev&07); ! 405: if (flag == OFF) ! 406: dzaddr->dzdtr &= ~bit; ! 407: else ! 408: dzaddr->dzdtr |= bit; ! 409: } ! 410: ! 411: dzscan() ! 412: { ! 413: register i; ! 414: register struct device *dzaddr; ! 415: register bit; ! 416: register struct tty *tp; ! 417: ! 418: for (i = 0; i < dz_cnt ; i++) { ! 419: dzaddr = dzpdma[i].p_addr; ! 420: tp = &dz_tty[i]; ! 421: bit = 1<<(i&07); ! 422: if (dzaddr->dzmsr & bit) { ! 423: /* carrier present */ ! 424: if ((tp->t_state & CARR_ON) == 0) { ! 425: wakeup((caddr_t)&tp->t_rawq); ! 426: tp->t_state |= CARR_ON; ! 427: } ! 428: } else { ! 429: if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) { ! 430: /* carrier lost */ ! 431: if (tp->t_state&ISOPEN) { ! 432: gsignal(tp->t_pgrp, SIGHUP); ! 433: gsignal(tp->t_pgrp, SIGCONT); ! 434: dzaddr->dzdtr &= ~bit; ! 435: flushtty(tp, FREAD|FWRITE); ! 436: } ! 437: tp->t_state &= ~CARR_ON; ! 438: } ! 439: } ! 440: } ! 441: timeout(dzscan, (caddr_t)0, 2*HZ); ! 442: } ! 443: ! 444: dztimer() ! 445: { ! 446: ! 447: dzrint(0); ! 448: } ! 449: ! 450: /* ! 451: * Reset state of driver if UBA reset was necessary. ! 452: * Reset parameters and restart transmission on open lines. ! 453: */ ! 454: dzreset() ! 455: { ! 456: int d; ! 457: register struct tty *tp; ! 458: ! 459: printf(" dz"); ! 460: for (d = 0; d < NDZ; d++) { ! 461: tp = &dz_tty[d]; ! 462: if (tp->t_state & (ISOPEN|WOPEN)) { ! 463: dzparam(d); ! 464: dzmodem(d, ON); ! 465: tp->t_state &= ~BUSY; ! 466: dzstart(tp); ! 467: } ! 468: } ! 469: dztimer(); ! 470: } ! 471: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.