|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)dz.c 7.9 (Berkeley) 6/28/90 ! 7: */ ! 8: ! 9: #include "dz.h" ! 10: #if NDZ > 0 ! 11: /* ! 12: * DZ-11/DZ-32 Driver ! 13: * ! 14: * This driver mimics dh.c; see it for explanation of common code. ! 15: */ ! 16: #include "param.h" ! 17: #include "systm.h" ! 18: #include "ioctl.h" ! 19: #include "tty.h" ! 20: #include "user.h" ! 21: #include "proc.h" ! 22: #include "map.h" ! 23: #include "buf.h" ! 24: #include "vm.h" ! 25: #include "conf.h" ! 26: #include "bkmac.h" ! 27: #include "file.h" ! 28: #include "uio.h" ! 29: #include "kernel.h" ! 30: #include "syslog.h" ! 31: ! 32: #include "pdma.h" ! 33: #include "ubavar.h" ! 34: #include "dzreg.h" ! 35: #include "machine/pte.h" ! 36: ! 37: /* ! 38: * Driver information for auto-configuration stuff. ! 39: */ ! 40: int dzprobe(), dzattach(), dzrint(); ! 41: struct uba_device *dzinfo[NDZ]; ! 42: u_short dzstd[] = { 0 }; ! 43: struct uba_driver dzdriver = ! 44: { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; ! 45: ! 46: #define NDZLINE (NDZ*8) ! 47: #define FASTTIMER (hz/30) /* rate to drain silos, when in use */ ! 48: ! 49: int dzstart(), dzxint(), dzdma(); ! 50: int ttrstrt(); ! 51: struct tty dz_tty[NDZLINE]; ! 52: int dz_cnt = { NDZLINE }; ! 53: int dzact; ! 54: int dzsilos; /* mask of dz's with silo in use */ ! 55: int dzchars[NDZ]; /* recent input count */ ! 56: int dzrate[NDZ]; /* smoothed input count */ ! 57: int dztimerintvl; /* time interval for dztimer */ ! 58: int dzhighrate = 100; /* silo on if dzchars > dzhighrate */ ! 59: int dzlowrate = 75; /* silo off if dzrate < dzlowrate */ ! 60: ! 61: #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) ! 62: ! 63: /* ! 64: * Software copy of dzbrk since it isn't readable ! 65: */ ! 66: char dz_brk[NDZ]; ! 67: char dzsoftCAR[NDZ]; ! 68: char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ ! 69: ! 70: /* ! 71: * The dz11 doesn't interrupt on carrier transitions, so ! 72: * we have to use a timer to watch it. ! 73: */ ! 74: char dz_timer; /* timer started? */ ! 75: ! 76: /* ! 77: * Pdma structures for fast output code ! 78: */ ! 79: struct pdma dzpdma[NDZLINE]; ! 80: ! 81: struct speedtab dzspeedtab[] = { ! 82: 0, 0, ! 83: 50, 020, ! 84: 75, 021, ! 85: 110, 022, ! 86: 134, 023, ! 87: 150, 024, ! 88: 300, 025, ! 89: 600, 026, ! 90: 1200, 027, ! 91: 1800, 030, ! 92: 2400, 032, ! 93: 4800, 034, ! 94: 9600, 036, ! 95: 19200, 037, ! 96: EXTA, 037, ! 97: -1, -1 ! 98: }; ! 99: ! 100: #ifndef PORTSELECTOR ! 101: #define ISPEED TTYDEF_SPEED ! 102: #define LFLAG TTYDEF_LFLAG ! 103: #else ! 104: #define ISPEED B4800 ! 105: #define LFLAG (TTYDEF_LFLAG&~ECHO) ! 106: #endif ! 107: ! 108: dzprobe(reg) ! 109: caddr_t reg; ! 110: { ! 111: register int br, cvec; ! 112: register struct dzdevice *dzaddr = (struct dzdevice *)reg; ! 113: ! 114: #ifdef lint ! 115: br = 0; cvec = br; br = cvec; ! 116: dzrint(0); dzxint((struct tty *)0); ! 117: #endif ! 118: dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; ! 119: if (dzaddr->dzcsr & DZ_32) ! 120: dzaddr->dzlnen = 1; ! 121: else ! 122: dzaddr->dztcr = 1; /* enable any line */ ! 123: DELAY(100000); ! 124: dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ ! 125: if (cvec && cvec != 0x200) ! 126: cvec -= 4; ! 127: return (sizeof (struct dzdevice)); ! 128: } ! 129: ! 130: dzattach(ui) ! 131: register struct uba_device *ui; ! 132: { ! 133: register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; ! 134: register struct tty *tp = &dz_tty[ui->ui_unit*8]; ! 135: register int cntr; ! 136: extern dzscan(); ! 137: ! 138: for (cntr = 0; cntr < 8; cntr++) { ! 139: pdp->p_addr = (struct dzdevice *)ui->ui_addr; ! 140: pdp->p_arg = (int)tp; ! 141: pdp->p_fcn = dzxint; ! 142: pdp++, tp++; ! 143: } ! 144: dzsoftCAR[ui->ui_unit] = ui->ui_flags; ! 145: if (dz_timer == 0) { ! 146: dz_timer++; ! 147: timeout(dzscan, (caddr_t)0, hz); ! 148: dztimerintvl = FASTTIMER; ! 149: } ! 150: } ! 151: ! 152: /*ARGSUSED*/ ! 153: dzopen(dev, flag) ! 154: dev_t dev; ! 155: { ! 156: register struct tty *tp; ! 157: register int unit; ! 158: int error, dzparam(); ! 159: ! 160: unit = minor(dev); ! 161: if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) ! 162: return (ENXIO); ! 163: tp = &dz_tty[unit]; ! 164: tp->t_addr = (caddr_t)&dzpdma[unit]; ! 165: tp->t_oproc = dzstart; ! 166: tp->t_param = dzparam; ! 167: tp->t_dev = dev; ! 168: if ((tp->t_state & TS_ISOPEN) == 0) { ! 169: tp->t_state |= TS_WOPEN; ! 170: ttychars(tp); ! 171: #ifndef PORTSELECTOR ! 172: if (tp->t_ispeed == 0) { ! 173: #endif ! 174: tp->t_iflag = TTYDEF_IFLAG; ! 175: tp->t_oflag = TTYDEF_OFLAG; ! 176: tp->t_cflag = TTYDEF_CFLAG; ! 177: tp->t_lflag = LFLAG; ! 178: tp->t_ispeed = tp->t_ospeed = ISPEED; ! 179: #ifdef PORTSELECTOR ! 180: tp->t_cflag |= HUPCL; ! 181: #else ! 182: } ! 183: #endif ! 184: dzparam(tp, &tp->t_termios); ! 185: ttsetwater(tp); ! 186: } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) ! 187: return (EBUSY); ! 188: (void) dzmctl(dev, DZ_ON, DMSET); ! 189: (void) spl5(); ! 190: while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && ! 191: (tp->t_state & TS_CARR_ON) == 0) { ! 192: tp->t_state |= TS_WOPEN; ! 193: if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, ! 194: ttopen, 0)) ! 195: break; ! 196: } ! 197: (void) spl0(); ! 198: if (error) ! 199: return (error); ! 200: return ((*linesw[tp->t_line].l_open)(dev, tp)); ! 201: } ! 202: ! 203: /*ARGSUSED*/ ! 204: dzclose(dev, flag) ! 205: dev_t dev; ! 206: { ! 207: register struct tty *tp; ! 208: register int unit; ! 209: register struct dzdevice *dzaddr; ! 210: int dz; ! 211: ! 212: unit = minor(dev); ! 213: dz = unit >> 3; ! 214: tp = &dz_tty[unit]; ! 215: (*linesw[tp->t_line].l_close)(tp); ! 216: dzaddr = dzpdma[unit].p_addr; ! 217: if (dzaddr->dzcsr&DZ_32) ! 218: (void) dzmctl(dev, DZ_BRK, DMBIC); ! 219: else ! 220: dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); ! 221: if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || ! 222: (tp->t_state&TS_ISOPEN) == 0) ! 223: (void) dzmctl(dev, DZ_OFF, DMSET); ! 224: return (ttyclose(tp)); ! 225: } ! 226: ! 227: dzread(dev, uio, flag) ! 228: dev_t dev; ! 229: struct uio *uio; ! 230: { ! 231: register struct tty *tp; ! 232: ! 233: tp = &dz_tty[minor(dev)]; ! 234: return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); ! 235: } ! 236: ! 237: dzwrite(dev, uio, flag) ! 238: dev_t dev; ! 239: struct uio *uio; ! 240: { ! 241: register struct tty *tp; ! 242: ! 243: tp = &dz_tty[minor(dev)]; ! 244: return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); ! 245: } ! 246: ! 247: /*ARGSUSED*/ ! 248: dzrint(dz) ! 249: int dz; ! 250: { ! 251: register struct tty *tp; ! 252: register int c, cc; ! 253: register struct dzdevice *dzaddr; ! 254: register struct tty *tp0; ! 255: register int unit; ! 256: int overrun = 0; ! 257: ! 258: if ((dzact & (1<<dz)) == 0) ! 259: return; ! 260: unit = dz * 8; ! 261: dzaddr = dzpdma[unit].p_addr; ! 262: tp0 = &dz_tty[unit]; ! 263: dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ ! 264: dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ ! 265: while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ ! 266: c = dzaddr->dzmtsr; ! 267: tp = tp0 + (c&7); ! 268: if (tp >= &dz_tty[dz_cnt]) ! 269: break; ! 270: dzaddr->dzlcs = c&7; /* get status of modem lines */ ! 271: dzwait(dzaddr); /* wait for them */ ! 272: if (c & DZ_CD) /* carrier status change? */ ! 273: if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ ! 274: /* carrier present */ ! 275: (void)(*linesw[tp->t_line].l_modem)(tp, 1); ! 276: } else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0) ! 277: dzaddr->dzlcs = DZ_ACK|(c&7); ! 278: } ! 279: while ((c = dzaddr->dzrbuf) < 0) { /* char present */ ! 280: cc = c&0xff; ! 281: dzchars[dz]++; ! 282: tp = tp0 + ((c>>8)&07); ! 283: if (tp >= &dz_tty[dz_cnt]) ! 284: continue; ! 285: if ((tp->t_state & TS_ISOPEN) == 0) { ! 286: wakeup((caddr_t)&tp->t_rawq); ! 287: #ifdef PORTSELECTOR ! 288: if ((tp->t_state&TS_WOPEN) == 0) ! 289: #endif ! 290: continue; ! 291: } ! 292: if (c&DZ_FE) ! 293: cc |= TTY_FE; ! 294: if (c&DZ_DO && overrun == 0) { ! 295: log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7); ! 296: overrun = 1; ! 297: } ! 298: if (c&DZ_PE) ! 299: cc |= TTY_PE; ! 300: (*linesw[tp->t_line].l_rint)(cc, tp); ! 301: } ! 302: } ! 303: ! 304: /*ARGSUSED*/ ! 305: dzioctl(dev, cmd, data, flag) ! 306: dev_t dev; ! 307: caddr_t data; ! 308: { ! 309: register struct tty *tp; ! 310: register int unit = minor(dev); ! 311: register int dz = unit >> 3; ! 312: register struct dzdevice *dzaddr; ! 313: int error; ! 314: ! 315: tp = &dz_tty[unit]; ! 316: error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); ! 317: if (error >= 0) ! 318: return (error); ! 319: error = ttioctl(tp, cmd, data, flag); ! 320: if (error >= 0) ! 321: return (error); ! 322: ! 323: switch (cmd) { ! 324: ! 325: case TIOCSBRK: ! 326: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; ! 327: if (dzaddr->dzcsr&DZ_32) ! 328: (void) dzmctl(dev, DZ_BRK, DMBIS); ! 329: else ! 330: dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); ! 331: break; ! 332: ! 333: case TIOCCBRK: ! 334: dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; ! 335: if (dzaddr->dzcsr&DZ_32) ! 336: (void) dzmctl(dev, DZ_BRK, DMBIC); ! 337: else ! 338: dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); ! 339: break; ! 340: ! 341: case TIOCSDTR: ! 342: (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); ! 343: break; ! 344: ! 345: case TIOCCDTR: ! 346: (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); ! 347: break; ! 348: ! 349: case TIOCMSET: ! 350: (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); ! 351: break; ! 352: ! 353: case TIOCMBIS: ! 354: (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); ! 355: break; ! 356: ! 357: case TIOCMBIC: ! 358: (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); ! 359: break; ! 360: ! 361: case TIOCMGET: ! 362: *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); ! 363: break; ! 364: ! 365: default: ! 366: return (ENOTTY); ! 367: } ! 368: return (0); ! 369: } ! 370: ! 371: dmtodz(bits) ! 372: register int bits; ! 373: { ! 374: register int b; ! 375: ! 376: b = (bits >>1) & 0370; ! 377: if (bits & DML_ST) b |= DZ_ST; ! 378: if (bits & DML_RTS) b |= DZ_RTS; ! 379: if (bits & DML_DTR) b |= DZ_DTR; ! 380: if (bits & DML_LE) b |= DZ_LE; ! 381: return(b); ! 382: } ! 383: ! 384: dztodm(bits) ! 385: register int bits; ! 386: { ! 387: register int b; ! 388: ! 389: b = (bits << 1) & 0360; ! 390: if (bits & DZ_DSR) b |= DML_DSR; ! 391: if (bits & DZ_DTR) b |= DML_DTR; ! 392: if (bits & DZ_ST) b |= DML_ST; ! 393: if (bits & DZ_RTS) b |= DML_RTS; ! 394: return(b); ! 395: } ! 396: ! 397: dzparam(tp, t) ! 398: register struct tty *tp; ! 399: register struct termios *t; ! 400: { ! 401: register struct dzdevice *dzaddr; ! 402: register int lpr; ! 403: register int cflag = t->c_cflag; ! 404: int unit = minor(tp->t_dev); ! 405: int ospeed = ttspeedtab(t->c_ospeed, dzspeedtab); ! 406: ! 407: /* check requested parameters */ ! 408: if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) || ! 409: (cflag&CSIZE) == CS5 || (cflag&CSIZE) == CS6) ! 410: return(EINVAL); ! 411: /* and copy to tty */ ! 412: tp->t_ispeed = t->c_ispeed; ! 413: tp->t_ospeed = t->c_ospeed; ! 414: tp->t_cflag = cflag; ! 415: ! 416: dzaddr = dzpdma[unit].p_addr; ! 417: if (dzsilos & (1 << (unit >> 3))) ! 418: dzaddr->dzcsr = DZ_IEN | DZ_SAE; ! 419: else ! 420: dzaddr->dzcsr = DZ_IEN; ! 421: dzact |= (1<<(unit>>3)); ! 422: if (ospeed == 0) { ! 423: (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ ! 424: return; ! 425: } ! 426: lpr = (ospeed<<8) | (unit & 07); ! 427: if ((cflag&CSIZE) == CS7) ! 428: lpr |= BITS7; ! 429: else ! 430: lpr |= BITS8; ! 431: if (cflag&PARENB) ! 432: lpr |= PENABLE; ! 433: if (cflag&PARODD) ! 434: lpr |= OPAR; ! 435: if (cflag&CSTOPB) ! 436: lpr |= TWOSB; ! 437: dzaddr->dzlpr = lpr; ! 438: return 0; ! 439: } ! 440: ! 441: dzxint(tp) ! 442: register struct tty *tp; ! 443: { ! 444: register struct pdma *dp; ! 445: register dz, unit; ! 446: ! 447: dp = (struct pdma *)tp->t_addr; ! 448: tp->t_state &= ~TS_BUSY; ! 449: if (tp->t_state & TS_FLUSH) ! 450: tp->t_state &= ~TS_FLUSH; ! 451: else { ! 452: ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); ! 453: dp->p_end = dp->p_mem = tp->t_outq.c_cf; ! 454: } ! 455: if (tp->t_line) ! 456: (*linesw[tp->t_line].l_start)(tp); ! 457: else ! 458: dzstart(tp); ! 459: dz = minor(tp->t_dev) >> 3; ! 460: unit = minor(tp->t_dev) & 7; ! 461: if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) ! 462: if (dp->p_addr->dzcsr & DZ_32) ! 463: dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); ! 464: else ! 465: dp->p_addr->dztcr &= ~(1<<unit); ! 466: } ! 467: ! 468: dzstart(tp) ! 469: register struct tty *tp; ! 470: { ! 471: register struct pdma *dp; ! 472: register struct dzdevice *dzaddr; ! 473: register int cc; ! 474: int s, dz, unit; ! 475: ! 476: dp = (struct pdma *)tp->t_addr; ! 477: dzaddr = dp->p_addr; ! 478: s = spl5(); ! 479: if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) ! 480: goto out; ! 481: if (tp->t_outq.c_cc <= tp->t_lowat) { ! 482: if (tp->t_state&TS_ASLEEP) { ! 483: tp->t_state &= ~TS_ASLEEP; ! 484: wakeup((caddr_t)&tp->t_outq); ! 485: } ! 486: if (tp->t_wsel) { ! 487: selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); ! 488: tp->t_wsel = 0; ! 489: tp->t_state &= ~TS_WCOLL; ! 490: } ! 491: } ! 492: if (tp->t_outq.c_cc == 0) ! 493: goto out; ! 494: if (tp->t_flags & (RAW|LITOUT)) ! 495: cc = ndqb(&tp->t_outq, 0); ! 496: else { ! 497: cc = ndqb(&tp->t_outq, 0200); ! 498: if (cc == 0) { ! 499: cc = getc(&tp->t_outq); ! 500: timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); ! 501: tp->t_state |= TS_TIMEOUT; ! 502: goto out; ! 503: } ! 504: } ! 505: tp->t_state |= TS_BUSY; ! 506: dp->p_end = dp->p_mem = tp->t_outq.c_cf; ! 507: dp->p_end += cc; ! 508: dz = minor(tp->t_dev) >> 3; ! 509: unit = minor(tp->t_dev) & 7; ! 510: if (dzaddr->dzcsr & DZ_32) ! 511: dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); ! 512: else ! 513: dzaddr->dztcr |= (1<<unit); ! 514: out: ! 515: splx(s); ! 516: } ! 517: ! 518: /* ! 519: * Stop output on a line. ! 520: */ ! 521: /*ARGSUSED*/ ! 522: dzstop(tp, flag) ! 523: register struct tty *tp; ! 524: { ! 525: register struct pdma *dp; ! 526: register int s; ! 527: ! 528: dp = (struct pdma *)tp->t_addr; ! 529: s = spl5(); ! 530: if (tp->t_state & TS_BUSY) { ! 531: dp->p_end = dp->p_mem; ! 532: if ((tp->t_state&TS_TTSTOP)==0) ! 533: tp->t_state |= TS_FLUSH; ! 534: } ! 535: splx(s); ! 536: } ! 537: ! 538: dzmctl(dev, bits, how) ! 539: dev_t dev; ! 540: int bits, how; ! 541: { ! 542: register struct dzdevice *dzaddr; ! 543: register int unit, mbits; ! 544: int b, s; ! 545: ! 546: unit = minor(dev); ! 547: b = 1<<(unit&7); ! 548: dzaddr = dzpdma[unit].p_addr; ! 549: s = spl5(); ! 550: if (dzaddr->dzcsr & DZ_32) { ! 551: dzwait(dzaddr) ! 552: DELAY(100); /* IS 100 TOO MUCH? */ ! 553: dzaddr->dzlcs = unit&7; ! 554: DELAY(100); ! 555: dzwait(dzaddr) ! 556: DELAY(100); ! 557: mbits = dzaddr->dzlcs; ! 558: mbits &= 0177770; ! 559: } else { ! 560: mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; ! 561: mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; ! 562: mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; ! 563: } ! 564: switch (how) { ! 565: case DMSET: ! 566: mbits = bits; ! 567: break; ! 568: ! 569: case DMBIS: ! 570: mbits |= bits; ! 571: break; ! 572: ! 573: case DMBIC: ! 574: mbits &= ~bits; ! 575: break; ! 576: ! 577: case DMGET: ! 578: (void) splx(s); ! 579: return(mbits); ! 580: } ! 581: if (dzaddr->dzcsr & DZ_32) { ! 582: mbits |= DZ_ACK|(unit&7); ! 583: dzaddr->dzlcs = mbits; ! 584: } else { ! 585: if (mbits & DZ_DTR) ! 586: dzaddr->dzdtr |= b; ! 587: else ! 588: dzaddr->dzdtr &= ~b; ! 589: } ! 590: if (mbits & DZ_DTR && dzsoftCAR[unit >> 3] & b) ! 591: dz_tty[unit].t_state |= TS_CARR_ON; ! 592: (void) splx(s); ! 593: return(mbits); ! 594: } ! 595: ! 596: int dztransitions, dzfasttimers; /*DEBUG*/ ! 597: dzscan() ! 598: { ! 599: register i; ! 600: register struct dzdevice *dzaddr; ! 601: register bit; ! 602: register struct tty *tp; ! 603: register car; ! 604: int olddzsilos = dzsilos; ! 605: int dztimer(); ! 606: ! 607: for (i = 0; i < dz_cnt ; i++) { ! 608: dzaddr = dzpdma[i].p_addr; ! 609: if (dzaddr == 0) ! 610: continue; ! 611: tp = &dz_tty[i]; ! 612: bit = 1<<(i&07); ! 613: car = 0; ! 614: if (dzsoftCAR[i>>3]&bit) ! 615: car = 1; ! 616: else if (dzaddr->dzcsr & DZ_32) { ! 617: dzaddr->dzlcs = i&07; ! 618: dzwait(dzaddr); ! 619: car = dzaddr->dzlcs & DZ_CD; ! 620: } else ! 621: car = dzaddr->dzmsr&bit; ! 622: if (car) { ! 623: /* carrier present */ ! 624: if ((tp->t_state & TS_CARR_ON) == 0) ! 625: (void)(*linesw[tp->t_line].l_modem)(tp, 1); ! 626: } else if ((tp->t_state&TS_CARR_ON) && ! 627: (*linesw[tp->t_line].l_modem)(tp, 0) == 0) ! 628: dzaddr->dzdtr &= ~bit; ! 629: } ! 630: for (i = 0; i < NDZ; i++) { ! 631: ave(dzrate[i], dzchars[i], 8); ! 632: if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) { ! 633: dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE; ! 634: dzsilos |= (1 << i); ! 635: dztransitions++; /*DEBUG*/ ! 636: } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) { ! 637: dzpdma[i << 3].p_addr->dzcsr = DZ_IEN; ! 638: dzsilos &= ~(1 << i); ! 639: } ! 640: dzchars[i] = 0; ! 641: } ! 642: if (dzsilos && !olddzsilos) ! 643: timeout(dztimer, (caddr_t)0, dztimerintvl); ! 644: timeout(dzscan, (caddr_t)0, hz); ! 645: } ! 646: ! 647: dztimer() ! 648: { ! 649: register int dz; ! 650: register int s; ! 651: ! 652: if (dzsilos == 0) ! 653: return; ! 654: s = spl5(); ! 655: dzfasttimers++; /*DEBUG*/ ! 656: for (dz = 0; dz < NDZ; dz++) ! 657: if (dzsilos & (1 << dz)) ! 658: dzrint(dz); ! 659: splx(s); ! 660: timeout(dztimer, (caddr_t) 0, dztimerintvl); ! 661: } ! 662: ! 663: /* ! 664: * Reset state of driver if UBA reset was necessary. ! 665: * Reset parameters and restart transmission on open lines. ! 666: */ ! 667: dzreset(uban) ! 668: int uban; ! 669: { ! 670: register int unit; ! 671: register struct tty *tp; ! 672: register struct uba_device *ui; ! 673: ! 674: for (unit = 0; unit < NDZLINE; unit++) { ! 675: ui = dzinfo[unit >> 3]; ! 676: if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) ! 677: continue; ! 678: if (unit%8 == 0) ! 679: printf(" dz%d", unit>>3); ! 680: tp = &dz_tty[unit]; ! 681: if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { ! 682: dzparam(unit); ! 683: (void) dzmctl(unit, DZ_ON, DMSET); ! 684: tp->t_state &= ~TS_BUSY; ! 685: dzstart(tp); ! 686: } ! 687: } ! 688: } ! 689: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.