|
|
1.1 ! root 1: /* dz.c 4.29 81/08/31 */ ! 2: ! 3: #include "dz.h" ! 4: #if NDZ > 0 ! 5: /* ! 6: * DZ-11 Driver ! 7: * ! 8: * This driver mimics dh.c; see it for explanation of common code. ! 9: */ ! 10: #include "bk.h" ! 11: #include "../h/param.h" ! 12: #include "../h/systm.h" ! 13: #include "../h/tty.h" ! 14: #include "../h/dir.h" ! 15: #include "../h/user.h" ! 16: #include "../h/map.h" ! 17: #include "../h/pte.h" ! 18: #include "../h/buf.h" ! 19: #include "../h/vm.h" ! 20: #include "../h/ubavar.h" ! 21: #include "../h/conf.h" ! 22: #include "../h/pdma.h" ! 23: #include "../h/bk.h" ! 24: #include "../h/file.h" ! 25: #include "../h/mx.h" ! 26: ! 27: /* ! 28: * Driver information for auto-configuration stuff. ! 29: */ ! 30: int dzprobe(), dzattach(), dzrint(); ! 31: struct uba_device *dzinfo[NDZ]; ! 32: u_short dzstd[] = { 0 }; ! 33: struct uba_driver dzdriver = ! 34: { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; ! 35: ! 36: #define NDZLINE (NDZ*8) ! 37: ! 38: /* ! 39: * Registers and bits ! 40: */ ! 41: ! 42: /* Bits in dzlpr */ ! 43: #define BITS7 020 ! 44: #define BITS8 030 ! 45: #define TWOSB 040 ! 46: #define PENABLE 0100 ! 47: #define OPAR 0200 ! 48: ! 49: /* Bits in dzrbuf */ ! 50: #define DZ_PE 010000 ! 51: #define DZ_FE 020000 ! 52: #define DZ_DO 040000 ! 53: ! 54: /* Bits in dzcsr */ ! 55: #define DZ_CLR 020 /* Reset dz */ ! 56: #define DZ_MSE 040 /* Master Scan Enable */ ! 57: #define DZ_RIE 0100 /* Receiver Interrupt Enable */ ! 58: #define DZ_SAE 010000 /* Silo Alarm Enable */ ! 59: #define DZ_TIE 040000 /* Transmit Interrupt Enable */ ! 60: #define DZ_IEN (DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) ! 61: ! 62: /* Flags for modem-control */ ! 63: #define DZ_ON 1 ! 64: #define DZ_OFF 0 ! 65: ! 66: int dzstart(), dzxint(), dzdma(); ! 67: int ttrstrt(); ! 68: struct tty dz_tty[NDZLINE]; ! 69: int dz_cnt = { NDZLINE }; ! 70: int dzact; ! 71: ! 72: struct device { ! 73: short dzcsr; /* control-status register */ ! 74: short dzrbuf; /* receiver buffer */ ! 75: #define dzlpr dzrbuf /* line parameter reg is write of dzrbuf */ ! 76: char dztcr; /* transmit control register */ ! 77: char dzdtr; /* data terminal ready */ ! 78: char dztbuf; /* transmit buffer */ ! 79: char dzbrk; /* break control */ ! 80: #define dzmsr dzbrk /* modem status register */ ! 81: }; ! 82: /* ! 83: * Software copy of dzbrk since it isn't readable ! 84: */ ! 85: char dz_brk[NDZ]; ! 86: char dzsoftCAR[NDZ]; ! 87: ! 88: /* ! 89: * The dz doesn't interrupt on carrier transitions, so ! 90: * we have to use a timer to watch it. ! 91: */ ! 92: char dz_timer; /* timer started? */ ! 93: ! 94: /* ! 95: * Pdma structures for fast output code ! 96: */ ! 97: struct pdma dzpdma[NDZLINE]; ! 98: ! 99: char dz_speeds[] = ! 100: { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 }; ! 101: ! 102: dzprobe(reg) ! 103: caddr_t reg; ! 104: { ! 105: register int br, cvec; ! 106: register struct device *dzaddr = (struct device *)reg; ! 107: ! 108: #ifdef lint ! 109: br = 0; cvec = br; br = cvec; ! 110: #endif ! 111: dzaddr->dzcsr = DZ_TIE|DZ_MSE; ! 112: dzaddr->dztcr = 1; /* enable any line */ ! 113: DELAY(100000); ! 114: dzaddr->dzcsr = DZ_CLR; /* reset everything */ ! 115: if (cvec && cvec != 0x200) ! 116: cvec -= 4; ! 117: return (1); ! 118: } ! 119: ! 120: dzattach(ui) ! 121: register struct uba_device *ui; ! 122: { ! 123: register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; ! 124: register struct tty *tp = &dz_tty[ui->ui_unit*8]; ! 125: register int cntr; ! 126: extern dzscan(); ! 127: ! 128: for (cntr = 0; cntr < 8; cntr++) { ! 129: pdp->p_addr = (struct device *)ui->ui_addr; ! 130: pdp->p_arg = (int)tp; ! 131: pdp->p_fcn = dzxint; ! 132: pdp++, tp++; ! 133: } ! 134: dzsoftCAR[ui->ui_unit] = ui->ui_flags; ! 135: if (dz_timer == 0) { ! 136: dz_timer++; ! 137: timeout(dzscan, (caddr_t)0, hz); ! 138: } ! 139: } ! 140: ! 141: /*ARGSUSED*/ ! 142: dzopen(dev, flag) ! 143: dev_t dev; ! 144: { ! 145: register struct tty *tp; ! 146: register int unit; ! 147: ! 148: unit = minor(dev); ! 149: if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { ! 150: u.u_error = ENXIO; ! 151: return; ! 152: } ! 153: tp = &dz_tty[unit]; ! 154: tp->t_addr = (caddr_t)&dzpdma[unit]; ! 155: tp->t_oproc = dzstart; ! 156: tp->t_iproc = NULL; ! 157: tp->t_state |= WOPEN; ! 158: if ((tp->t_state & ISOPEN) == 0) { ! 159: ttychars(tp); ! 160: tp->t_ospeed = tp->t_ispeed = B300; ! 161: tp->t_flags = ODDP|EVENP|ECHO; ! 162: /* tp->t_state |= HUPCLS; */ ! 163: dzparam(unit); ! 164: } else if (tp->t_state&XCLUDE && u.u_uid != 0) { ! 165: u.u_error = EBUSY; ! 166: return; ! 167: } ! 168: dzmodem(unit, DZ_ON); ! 169: (void) spl5(); ! 170: while ((tp->t_state & CARR_ON) == 0) { ! 171: tp->t_state |= WOPEN; ! 172: sleep((caddr_t)&tp->t_rawq, TTIPRI); ! 173: } ! 174: (void) spl0(); ! 175: (*linesw[tp->t_line].l_open)(dev, tp); ! 176: } ! 177: ! 178: /*ARGSUSED*/ ! 179: dzclose(dev, flag) ! 180: dev_t dev; ! 181: { ! 182: register struct tty *tp; ! 183: register int unit; ! 184: int dz; ! 185: ! 186: unit = minor(dev); ! 187: dz = unit >> 3; ! 188: tp = &dz_tty[unit]; ! 189: (*linesw[tp->t_line].l_close)(tp); ! 190: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = ! 191: (dz_brk[dz] &= ~(1 << (unit&07))); ! 192: if (tp->t_state & HUPCLS) ! 193: dzmodem(unit, DZ_OFF); ! 194: ttyclose(tp); ! 195: } ! 196: ! 197: dzread(dev) ! 198: dev_t dev; ! 199: { ! 200: register struct tty *tp; ! 201: ! 202: tp = &dz_tty[minor(dev)]; ! 203: (*linesw[tp->t_line].l_read)(tp); ! 204: } ! 205: ! 206: dzwrite(dev) ! 207: dev_t dev; ! 208: { ! 209: register struct tty *tp; ! 210: ! 211: tp = &dz_tty[minor(dev)]; ! 212: (*linesw[tp->t_line].l_write)(tp); ! 213: } ! 214: ! 215: /*ARGSUSED*/ ! 216: dzrint(dz) ! 217: int dz; ! 218: { ! 219: register struct tty *tp; ! 220: register int c; ! 221: register struct device *dzaddr; ! 222: register struct tty *tp0; ! 223: register int unit; ! 224: int overrun = 0; ! 225: ! 226: if ((dzact & (1<<dz)) == 0) ! 227: return; ! 228: unit = dz * 8; ! 229: dzaddr = dzpdma[unit].p_addr; ! 230: tp0 = &dz_tty[unit]; ! 231: while ((c = dzaddr->dzrbuf) < 0) { /* char present */ ! 232: tp = tp0 + ((c>>8)&07); ! 233: if (tp >= &dz_tty[dz_cnt]) ! 234: continue; ! 235: if ((tp->t_state & ISOPEN) == 0) { ! 236: wakeup((caddr_t)&tp->t_rawq); ! 237: continue; ! 238: } ! 239: if (c&DZ_FE) ! 240: if (tp->t_flags & RAW) ! 241: c = 0; ! 242: else ! 243: c = tun.t_intrc; ! 244: if (c&DZ_DO && overrun == 0) { ! 245: printf("dz%d: silo overflow\n", dz); ! 246: overrun = 1; ! 247: } ! 248: if (c&DZ_PE) ! 249: if (((tp->t_flags & (EVENP|ODDP)) == EVENP) ! 250: || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) ! 251: continue; ! 252: #if NBK > 0 ! 253: if (tp->t_line == NETLDISC) { ! 254: c &= 0177; ! 255: BKINPUT(c, tp); ! 256: } else ! 257: #endif ! 258: (*linesw[tp->t_line].l_rint)(c, tp); ! 259: } ! 260: } ! 261: ! 262: /*ARGSUSED*/ ! 263: dzioctl(dev, cmd, addr, flag) ! 264: dev_t dev; ! 265: caddr_t addr; ! 266: { ! 267: register struct tty *tp; ! 268: register int unit = minor(dev); ! 269: register int dz = unit >> 3; ! 270: ! 271: tp = &dz_tty[unit]; ! 272: cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); ! 273: if (cmd == 0) ! 274: return; ! 275: if (ttioctl(tp, cmd, addr, flag)) { ! 276: if (cmd==TIOCSETP || cmd==TIOCSETN) ! 277: dzparam(unit); ! 278: } else switch(cmd) { ! 279: ! 280: case TIOCSBRK: ! 281: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = ! 282: (dz_brk[dz] |= 1 << (unit&07)); ! 283: break; ! 284: case TIOCCBRK: ! 285: ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = ! 286: (dz_brk[dz] &= ~(1 << (unit&07))); ! 287: break; ! 288: case TIOCSDTR: ! 289: dzmodem(unit, DZ_ON); ! 290: break; ! 291: case TIOCCDTR: ! 292: dzmodem(unit, DZ_OFF); ! 293: break; ! 294: default: ! 295: u.u_error = ENOTTY; ! 296: } ! 297: } ! 298: ! 299: dzparam(unit) ! 300: register int unit; ! 301: { ! 302: register struct tty *tp; ! 303: register struct device *dzaddr; ! 304: register int lpr; ! 305: ! 306: tp = &dz_tty[unit]; ! 307: dzaddr = dzpdma[unit].p_addr; ! 308: dzaddr->dzcsr = DZ_IEN; ! 309: dzact |= (1<<(unit>>3)); ! 310: if (tp->t_ispeed == 0) { ! 311: dzmodem(unit, DZ_OFF); /* hang up line */ ! 312: return; ! 313: } ! 314: lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); ! 315: if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) ! 316: lpr |= BITS8; ! 317: else ! 318: lpr |= (BITS7|PENABLE); ! 319: if ((tp->t_flags & EVENP) == 0) ! 320: lpr |= OPAR; ! 321: if (tp->t_ispeed == B110) ! 322: lpr |= TWOSB; ! 323: dzaddr->dzlpr = lpr; ! 324: } ! 325: ! 326: dzxint(tp) ! 327: register struct tty *tp; ! 328: { ! 329: register struct pdma *dp; ! 330: register s; ! 331: ! 332: s = spl5(); /* block pdma interrupts */ ! 333: dp = (struct pdma *)tp->t_addr; ! 334: tp->t_state &= ~BUSY; ! 335: if (tp->t_state & FLUSH) ! 336: tp->t_state &= ~FLUSH; ! 337: else ! 338: ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); ! 339: if (tp->t_line) ! 340: (*linesw[tp->t_line].l_start)(tp); ! 341: else ! 342: dzstart(tp); ! 343: if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) ! 344: dp->p_addr->dztcr &= ~(1 << (minor(tp->t_dev)&07)); ! 345: splx(s); ! 346: } ! 347: ! 348: dzstart(tp) ! 349: register struct tty *tp; ! 350: { ! 351: register struct pdma *dp; ! 352: register struct device *dzaddr; ! 353: register int cc; ! 354: int s; ! 355: ! 356: dp = (struct pdma *)tp->t_addr; ! 357: dzaddr = dp->p_addr; ! 358: s = spl5(); ! 359: if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) ! 360: goto out; ! 361: if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { ! 362: tp->t_state &= ~ASLEEP; ! 363: if (tp->t_chan) ! 364: mcstart(tp->t_chan, (caddr_t)&tp->t_outq); ! 365: else ! 366: wakeup((caddr_t)&tp->t_outq); ! 367: } ! 368: if (tp->t_outq.c_cc == 0) ! 369: goto out; ! 370: if (tp->t_flags&RAW || tp->t_local&LLITOUT) ! 371: cc = ndqb(&tp->t_outq, 0); ! 372: else { ! 373: cc = ndqb(&tp->t_outq, 0200); ! 374: if (cc == 0) { ! 375: cc = getc(&tp->t_outq); ! 376: timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); ! 377: tp->t_state |= TIMEOUT; ! 378: goto out; ! 379: } ! 380: } ! 381: tp->t_state |= BUSY; ! 382: dp->p_end = dp->p_mem = tp->t_outq.c_cf; ! 383: dp->p_end += cc; ! 384: dzaddr->dztcr |= 1 << (minor(tp->t_dev) & 07); /* force intr */ ! 385: out: ! 386: splx(s); ! 387: } ! 388: ! 389: /* ! 390: * Stop output on a line. ! 391: */ ! 392: /*ARGSUSED*/ ! 393: dzstop(tp, flag) ! 394: register struct tty *tp; ! 395: { ! 396: register struct pdma *dp; ! 397: register int s; ! 398: ! 399: dp = (struct pdma *)tp->t_addr; ! 400: s = spl5(); ! 401: if (tp->t_state & BUSY) { ! 402: dp->p_end = dp->p_mem; ! 403: if ((tp->t_state&TTSTOP)==0) ! 404: tp->t_state |= FLUSH; ! 405: } ! 406: splx(s); ! 407: } ! 408: ! 409: dzmodem(unit, flag) ! 410: register int unit; ! 411: { ! 412: register struct device *dzaddr; ! 413: register char bit; ! 414: ! 415: dzaddr = dzpdma[unit].p_addr; ! 416: bit = 1<<(unit&07); ! 417: if (flag == DZ_OFF) ! 418: dzaddr->dzdtr &= ~bit; ! 419: else ! 420: dzaddr->dzdtr |= bit; ! 421: } ! 422: ! 423: dzscan() ! 424: { ! 425: register i; ! 426: register struct device *dzaddr; ! 427: register bit; ! 428: register struct tty *tp; ! 429: ! 430: for (i = 0; i < dz_cnt ; i++) { ! 431: dzaddr = dzpdma[i].p_addr; ! 432: if (dzaddr == 0) ! 433: continue; ! 434: tp = &dz_tty[i]; ! 435: bit = 1<<(i&07); ! 436: if ((dzsoftCAR[i>>3]&bit) || (dzaddr->dzmsr&bit)) { ! 437: /* carrier present */ ! 438: if ((tp->t_state & CARR_ON) == 0) { ! 439: wakeup((caddr_t)&tp->t_rawq); ! 440: tp->t_state |= CARR_ON; ! 441: } ! 442: } else { ! 443: if ((tp->t_state&CARR_ON) && ! 444: (tp->t_local&LNOHANG)==0) { ! 445: /* carrier lost */ ! 446: if (tp->t_state&ISOPEN) { ! 447: gsignal(tp->t_pgrp, SIGHUP); ! 448: gsignal(tp->t_pgrp, SIGCONT); ! 449: dzaddr->dzdtr &= ~bit; ! 450: flushtty(tp, FREAD|FWRITE); ! 451: } ! 452: tp->t_state &= ~CARR_ON; ! 453: } ! 454: } ! 455: } ! 456: timeout(dzscan, (caddr_t)0, 2*hz); ! 457: } ! 458: ! 459: dztimer() ! 460: { ! 461: int dz; ! 462: ! 463: for (dz = 0; dz < NDZ; dz++) ! 464: dzrint(dz); ! 465: } ! 466: ! 467: /* ! 468: * Reset state of driver if UBA reset was necessary. ! 469: * Reset parameters and restart transmission on open lines. ! 470: */ ! 471: dzreset(uban) ! 472: int uban; ! 473: { ! 474: register int unit; ! 475: register struct tty *tp; ! 476: register struct uba_device *ui; ! 477: ! 478: for (unit = 0; unit < NDZLINE; unit++) { ! 479: ui = dzinfo[unit >> 3]; ! 480: if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) ! 481: continue; ! 482: if (unit%8 == 0) ! 483: printf(" dz%d", unit>>3); ! 484: tp = &dz_tty[unit]; ! 485: if (tp->t_state & (ISOPEN|WOPEN)) { ! 486: dzparam(unit); ! 487: dzmodem(unit, DZ_ON); ! 488: tp->t_state &= ~BUSY; ! 489: dzstart(tp); ! 490: } ! 491: } ! 492: dztimer(); ! 493: } ! 494: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.