1*16191Skarels /* dz.c 6.2 84/03/15 */ 217Sbill 31935Swnj #include "dz.h" 42645Swnj #if NDZ > 0 517Sbill /* 610019Ssam * DZ-11/DZ-32 Driver 72469Swnj * 82469Swnj * This driver mimics dh.c; see it for explanation of common code. 917Sbill */ 102731Swnj #include "bk.h" 119773Ssam 129773Ssam #include "../machine/pte.h" 139773Ssam 1417Sbill #include "../h/param.h" 1517Sbill #include "../h/systm.h" 169551Ssam #include "../h/ioctl.h" 1717Sbill #include "../h/tty.h" 1817Sbill #include "../h/dir.h" 1917Sbill #include "../h/user.h" 206157Ssam #include "../h/proc.h" 2117Sbill #include "../h/map.h" 222395Swnj #include "../h/buf.h" 232567Swnj #include "../h/vm.h" 2417Sbill #include "../h/conf.h" 25114Sbill #include "../h/bk.h" 26871Sbill #include "../h/file.h" 277727Sroot #include "../h/uio.h" 2810869Ssam #include "../h/kernel.h" 29145Sbill 308474Sroot #include "../vaxuba/pdma.h" 318474Sroot #include "../vaxuba/ubavar.h" 3210019Ssam #include "../vaxuba/dzreg.h" 338474Sroot 342469Swnj /* 352469Swnj * Driver information for auto-configuration stuff. 362469Swnj */ 372606Swnj int dzprobe(), dzattach(), dzrint(); 382976Swnj struct uba_device *dzinfo[NDZ]; 392395Swnj u_short dzstd[] = { 0 }; 402395Swnj struct uba_driver dzdriver = 412606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 422395Swnj 432645Swnj #define NDZLINE (NDZ*8) 44*16191Skarels #define FASTTIMER (hz/30) /* rate to drain silos, when in use */ 452469Swnj 462469Swnj int dzstart(), dzxint(), dzdma(); 47114Sbill int ttrstrt(); 482645Swnj struct tty dz_tty[NDZLINE]; 492645Swnj int dz_cnt = { NDZLINE }; 50119Sbill int dzact; 51*16191Skarels int dzsilos; /* mask of dz's with silo in use */ 52*16191Skarels int dzchars[NDZ]; /* recent input count */ 53*16191Skarels int dzrate[NDZ]; /* smoothed input count */ 54*16191Skarels int dztimerintvl; /* time interval for dztimer */ 55*16191Skarels int dzhighrate = 100; /* silo on if dzchars > dzhighrate */ 56*16191Skarels int dzlowrate = 75; /* silo off if dzrate < dzlowrate */ 5717Sbill 585731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 595731Sroot 602469Swnj /* 612469Swnj * Software copy of dzbrk since it isn't readable 622469Swnj */ 632645Swnj char dz_brk[NDZ]; 642645Swnj char dzsoftCAR[NDZ]; 655731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 6617Sbill 672469Swnj /* 685731Sroot * The dz11 doesn't interrupt on carrier transitions, so 692469Swnj * we have to use a timer to watch it. 702469Swnj */ 712469Swnj char dz_timer; /* timer started? */ 722469Swnj 732469Swnj /* 742469Swnj * Pdma structures for fast output code 752469Swnj */ 762645Swnj struct pdma dzpdma[NDZLINE]; 772469Swnj 782395Swnj char dz_speeds[] = 796814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 8017Sbill 816616Ssam #ifndef PORTSELECTOR 826616Ssam #define ISPEED B300 836616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 846616Ssam #else 856616Ssam #define ISPEED B4800 866616Ssam #define IFLAGS (EVENP|ODDP) 876616Ssam #endif 886616Ssam 892606Swnj dzprobe(reg) 902395Swnj caddr_t reg; 912395Swnj { 922457Swnj register int br, cvec; 9310019Ssam register struct dzdevice *dzaddr = (struct dzdevice *)reg; 942395Swnj 952606Swnj #ifdef lint 963102Swnj br = 0; cvec = br; br = cvec; 974933Swnj dzrint(0); dzxint((struct tty *)0); 982606Swnj #endif 995731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1005731Sroot if (dzaddr->dzcsr & DZ_32) 1015731Sroot dzaddr->dzlnen = 1; 1025731Sroot else 1035731Sroot dzaddr->dztcr = 1; /* enable any line */ 1042457Swnj DELAY(100000); 1055731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1062457Swnj if (cvec && cvec != 0x200) 1072457Swnj cvec -= 4; 10810019Ssam return (sizeof (struct dzdevice)); 1092395Swnj } 1102395Swnj 1112606Swnj dzattach(ui) 1122976Swnj register struct uba_device *ui; 1132395Swnj { 1142395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1152395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1162606Swnj register int cntr; 1172645Swnj extern dzscan(); 1182395Swnj 1192606Swnj for (cntr = 0; cntr < 8; cntr++) { 12010019Ssam pdp->p_addr = (struct dzdevice *)ui->ui_addr; 1212395Swnj pdp->p_arg = (int)tp; 1222395Swnj pdp->p_fcn = dzxint; 1232395Swnj pdp++, tp++; 1242395Swnj } 1252567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1262627Swnj if (dz_timer == 0) { 1272627Swnj dz_timer++; 1282756Swnj timeout(dzscan, (caddr_t)0, hz); 129*16191Skarels dztimerintvl = FASTTIMER; 1302627Swnj } 1312395Swnj } 1322395Swnj 13317Sbill /*ARGSUSED*/ 1342395Swnj dzopen(dev, flag) 1352395Swnj dev_t dev; 13617Sbill { 13717Sbill register struct tty *tp; 1382395Swnj register int unit; 13917Sbill 1402395Swnj unit = minor(dev); 1418568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 1428568Sroot return (ENXIO); 1432395Swnj tp = &dz_tty[unit]; 1442395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 14517Sbill tp->t_oproc = dzstart; 1465407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 14717Sbill ttychars(tp); 1486616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 1496616Ssam tp->t_flags = IFLAGS; 1505407Swnj /* tp->t_state |= TS_HUPCLS; */ 1512395Swnj dzparam(unit); 1528568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 1538568Sroot return (EBUSY); 1546157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 155114Sbill (void) spl5(); 1565407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 1575407Swnj tp->t_state |= TS_WOPEN; 15817Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 15917Sbill } 160114Sbill (void) spl0(); 1618568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 16217Sbill } 16317Sbill 1642395Swnj /*ARGSUSED*/ 1652395Swnj dzclose(dev, flag) 1662395Swnj dev_t dev; 16717Sbill { 16817Sbill register struct tty *tp; 1692395Swnj register int unit; 17010019Ssam register struct dzdevice *dzaddr; 1716150Ssam int dz; 17217Sbill 1732395Swnj unit = minor(dev); 1742395Swnj dz = unit >> 3; 1752395Swnj tp = &dz_tty[unit]; 17617Sbill (*linesw[tp->t_line].l_close)(tp); 1775731Sroot dzaddr = dzpdma[unit].p_addr; 1785731Sroot if (dzaddr->dzcsr&DZ_32) 1796157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 1805731Sroot else 1815731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 1826842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 1836157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 18417Sbill ttyclose(tp); 18517Sbill } 18617Sbill 1877727Sroot dzread(dev, uio) 1882395Swnj dev_t dev; 1897727Sroot struct uio *uio; 19017Sbill { 19117Sbill register struct tty *tp; 19217Sbill 1932395Swnj tp = &dz_tty[minor(dev)]; 1947727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 19517Sbill } 19617Sbill 1977833Sroot dzwrite(dev, uio) 1982395Swnj dev_t dev; 1997833Sroot struct uio *uio; 20017Sbill { 20117Sbill register struct tty *tp; 20217Sbill 2032395Swnj tp = &dz_tty[minor(dev)]; 2048531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 20517Sbill } 20617Sbill 207119Sbill /*ARGSUSED*/ 2082395Swnj dzrint(dz) 2092395Swnj int dz; 21017Sbill { 21117Sbill register struct tty *tp; 21217Sbill register int c; 21310019Ssam register struct dzdevice *dzaddr; 214119Sbill register struct tty *tp0; 2152395Swnj register int unit; 2162923Swnj int overrun = 0; 21717Sbill 2182457Swnj if ((dzact & (1<<dz)) == 0) 2192457Swnj return; 2202457Swnj unit = dz * 8; 2212457Swnj dzaddr = dzpdma[unit].p_addr; 2222457Swnj tp0 = &dz_tty[unit]; 2235731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2245731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2255731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2265731Sroot c = dzaddr->dzmtsr; 2275731Sroot tp = tp0 + (c&7); 2285731Sroot if (tp >= &dz_tty[dz_cnt]) 2295731Sroot break; 2305731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2315731Sroot dzwait(dzaddr); /* wait for them */ 2325731Sroot if (c & DZ_CD) /* carrier status change? */ 2335731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2345731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2355731Sroot wakeup((caddr_t)&tp->t_rawq); 2365731Sroot tp->t_state |= TS_CARR_ON; 2375731Sroot } 2385731Sroot } else { /* no carrier */ 2395731Sroot if (tp->t_state&TS_CARR_ON) { 2405731Sroot gsignal(tp->t_pgrp, SIGHUP); 2415731Sroot gsignal(tp->t_pgrp, SIGCONT); 2425731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 24312777Ssam ttyflush(tp, FREAD|FWRITE); 2445731Sroot } 2455731Sroot tp->t_state &= ~TS_CARR_ON; 2465731Sroot } 2475731Sroot } 2482457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 249*16191Skarels dzchars[dz]++; 2502457Swnj tp = tp0 + ((c>>8)&07); 2512457Swnj if (tp >= &dz_tty[dz_cnt]) 25217Sbill continue; 2535407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 2542457Swnj wakeup((caddr_t)&tp->t_rawq); 2556616Ssam #ifdef PORTSELECTOR 2566616Ssam if ((tp->t_state&TS_WOPEN) == 0) 2576616Ssam #endif 2582457Swnj continue; 2592457Swnj } 2602469Swnj if (c&DZ_FE) 2612457Swnj if (tp->t_flags & RAW) 2622469Swnj c = 0; 2632457Swnj else 2649551Ssam c = tp->t_intrc; 2652923Swnj if (c&DZ_DO && overrun == 0) { 2665731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 2672923Swnj overrun = 1; 2682923Swnj } 2692469Swnj if (c&DZ_PE) 2702457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 2712457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 27217Sbill continue; 2732731Swnj #if NBK > 0 2742457Swnj if (tp->t_line == NETLDISC) { 2752457Swnj c &= 0177; 2762457Swnj BKINPUT(c, tp); 2772457Swnj } else 2782731Swnj #endif 2792457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 28017Sbill } 28117Sbill } 28217Sbill 28317Sbill /*ARGSUSED*/ 2847631Ssam dzioctl(dev, cmd, data, flag) 2852395Swnj dev_t dev; 2867631Ssam caddr_t data; 28717Sbill { 28817Sbill register struct tty *tp; 2892395Swnj register int unit = minor(dev); 2902395Swnj register int dz = unit >> 3; 29110019Ssam register struct dzdevice *dzaddr; 2928568Sroot int error; 29317Sbill 2942395Swnj tp = &dz_tty[unit]; 2958568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 2968568Sroot if (error >= 0) 2978568Sroot return (error); 2988568Sroot error = ttioctl(tp, cmd, data, flag); 2998568Sroot if (error >= 0) { 3007631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 3012395Swnj dzparam(unit); 3028568Sroot return (error); 3038568Sroot } 3048568Sroot switch (cmd) { 3052395Swnj 306170Sbill case TIOCSBRK: 3075731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3085731Sroot if (dzaddr->dzcsr&DZ_32) 3096157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3105731Sroot else 3115731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 312170Sbill break; 3137631Ssam 314170Sbill case TIOCCBRK: 3155731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3165731Sroot if (dzaddr->dzcsr&DZ_32) 3176157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3185731Sroot else 3195731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 320170Sbill break; 3217631Ssam 322170Sbill case TIOCSDTR: 3236157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 324170Sbill break; 3257631Ssam 326170Sbill case TIOCCDTR: 3276157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 328170Sbill break; 3297631Ssam 3305731Sroot case TIOCMSET: 3317631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 3325731Sroot break; 3337631Ssam 3345731Sroot case TIOCMBIS: 3357631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 3365731Sroot break; 3377631Ssam 3385731Sroot case TIOCMBIC: 3397631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 3405731Sroot break; 3417631Ssam 3425731Sroot case TIOCMGET: 3437631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 3445731Sroot break; 3457631Ssam 346170Sbill default: 3478568Sroot return (ENOTTY); 348170Sbill } 3498568Sroot return (0); 35017Sbill } 3515731Sroot 3525731Sroot dmtodz(bits) 3535731Sroot register int bits; 3545731Sroot { 3555731Sroot register int b; 3565731Sroot 3575731Sroot b = (bits >>1) & 0370; 3585731Sroot if (bits & DML_ST) b |= DZ_ST; 3595731Sroot if (bits & DML_RTS) b |= DZ_RTS; 3605731Sroot if (bits & DML_DTR) b |= DZ_DTR; 3615731Sroot if (bits & DML_LE) b |= DZ_LE; 3625731Sroot return(b); 3635731Sroot } 3645731Sroot 3655731Sroot dztodm(bits) 3665731Sroot register int bits; 3675731Sroot { 3685731Sroot register int b; 3695731Sroot 3705731Sroot b = (bits << 1) & 0360; 3715731Sroot if (bits & DZ_DSR) b |= DML_DSR; 3725731Sroot if (bits & DZ_DTR) b |= DML_DTR; 3735731Sroot if (bits & DZ_ST) b |= DML_ST; 3745731Sroot if (bits & DZ_RTS) b |= DML_RTS; 3755731Sroot return(b); 3765731Sroot } 37717Sbill 3782395Swnj dzparam(unit) 3792395Swnj register int unit; 38017Sbill { 38117Sbill register struct tty *tp; 38210019Ssam register struct dzdevice *dzaddr; 3832395Swnj register int lpr; 38417Sbill 3852395Swnj tp = &dz_tty[unit]; 3862395Swnj dzaddr = dzpdma[unit].p_addr; 387*16191Skarels if (dzsilos & (1 << (unit >> 3))) 388*16191Skarels dzaddr->dzcsr = DZ_IEN | DZ_SAE; 389*16191Skarels else 390*16191Skarels dzaddr->dzcsr = DZ_IEN; 3912395Swnj dzact |= (1<<(unit>>3)); 39217Sbill if (tp->t_ispeed == 0) { 3936157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 39417Sbill return; 39517Sbill } 3962395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 3979551Ssam if (tp->t_flags & (RAW|LITOUT)) 39817Sbill lpr |= BITS8; 39917Sbill else 40017Sbill lpr |= (BITS7|PENABLE); 40117Sbill if ((tp->t_flags & EVENP) == 0) 40217Sbill lpr |= OPAR; 4032469Swnj if (tp->t_ispeed == B110) 4042469Swnj lpr |= TWOSB; 40517Sbill dzaddr->dzlpr = lpr; 40617Sbill } 40717Sbill 40817Sbill dzxint(tp) 4092395Swnj register struct tty *tp; 41017Sbill { 41117Sbill register struct pdma *dp; 412*16191Skarels register dz, unit; 41317Sbill 4142395Swnj dp = (struct pdma *)tp->t_addr; 4155407Swnj tp->t_state &= ~TS_BUSY; 4165407Swnj if (tp->t_state & TS_FLUSH) 4175407Swnj tp->t_state &= ~TS_FLUSH; 4185731Sroot else { 419281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4205731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4215731Sroot } 42217Sbill if (tp->t_line) 42317Sbill (*linesw[tp->t_line].l_start)(tp); 42417Sbill else 42517Sbill dzstart(tp); 4265731Sroot dz = minor(tp->t_dev) >> 3; 4275731Sroot unit = minor(tp->t_dev) & 7; 4285407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4295731Sroot if (dp->p_addr->dzcsr & DZ_32) 4305731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4315731Sroot else 4325731Sroot dp->p_addr->dztcr &= ~(1<<unit); 43317Sbill } 43417Sbill 43517Sbill dzstart(tp) 4362395Swnj register struct tty *tp; 43717Sbill { 43817Sbill register struct pdma *dp; 43910019Ssam register struct dzdevice *dzaddr; 4402395Swnj register int cc; 4415731Sroot int s, dz, unit; 44217Sbill 4432395Swnj dp = (struct pdma *)tp->t_addr; 44417Sbill dzaddr = dp->p_addr; 4452395Swnj s = spl5(); 4465407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 44717Sbill goto out; 4485407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 4495407Swnj if (tp->t_state&TS_ASLEEP) { 4505407Swnj tp->t_state &= ~TS_ASLEEP; 4515407Swnj wakeup((caddr_t)&tp->t_outq); 4525407Swnj } 4535407Swnj if (tp->t_wsel) { 4545407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 4555407Swnj tp->t_wsel = 0; 4565407Swnj tp->t_state &= ~TS_WCOLL; 4575407Swnj } 45817Sbill } 45917Sbill if (tp->t_outq.c_cc == 0) 46017Sbill goto out; 4619551Ssam if (tp->t_flags & (RAW|LITOUT)) 46217Sbill cc = ndqb(&tp->t_outq, 0); 46317Sbill else { 46417Sbill cc = ndqb(&tp->t_outq, 0200); 46517Sbill if (cc == 0) { 46617Sbill cc = getc(&tp->t_outq); 4672469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 4685407Swnj tp->t_state |= TS_TIMEOUT; 46917Sbill goto out; 47017Sbill } 47117Sbill } 4725407Swnj tp->t_state |= TS_BUSY; 47317Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 47417Sbill dp->p_end += cc; 4755731Sroot dz = minor(tp->t_dev) >> 3; 4765731Sroot unit = minor(tp->t_dev) & 7; 4775731Sroot if (dzaddr->dzcsr & DZ_32) 4785731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 4795731Sroot else 4805731Sroot dzaddr->dztcr |= (1<<unit); 4812395Swnj out: 4822395Swnj splx(s); 48317Sbill } 48417Sbill 48517Sbill /* 48617Sbill * Stop output on a line. 48717Sbill */ 48817Sbill /*ARGSUSED*/ 48917Sbill dzstop(tp, flag) 4902395Swnj register struct tty *tp; 49117Sbill { 49217Sbill register struct pdma *dp; 49317Sbill register int s; 49417Sbill 4952395Swnj dp = (struct pdma *)tp->t_addr; 4962457Swnj s = spl5(); 4975407Swnj if (tp->t_state & TS_BUSY) { 49817Sbill dp->p_end = dp->p_mem; 4995407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5005407Swnj tp->t_state |= TS_FLUSH; 50117Sbill } 50217Sbill splx(s); 50317Sbill } 50417Sbill 5055731Sroot dzmctl(dev, bits, how) 5065731Sroot dev_t dev; 5075731Sroot int bits, how; 50817Sbill { 50910019Ssam register struct dzdevice *dzaddr; 5105731Sroot register int unit, mbits; 5115731Sroot int b, s; 5125731Sroot 5135731Sroot unit = minor(dev); 5145731Sroot b = 1<<(unit&7); 5152395Swnj dzaddr = dzpdma[unit].p_addr; 5165731Sroot s = spl5(); 5175731Sroot if (dzaddr->dzcsr & DZ_32) { 5185731Sroot dzwait(dzaddr) 5195731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5205731Sroot dzaddr->dzlcs = unit&7; 5215731Sroot DELAY(100); 5225731Sroot dzwait(dzaddr) 5235731Sroot DELAY(100); 5245731Sroot mbits = dzaddr->dzlcs; 5255731Sroot mbits &= 0177770; 5265731Sroot } else { 5275731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5285731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5295731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5305731Sroot } 5315731Sroot switch (how) { 5325731Sroot case DMSET: 5335731Sroot mbits = bits; 5345731Sroot break; 5355731Sroot 5365731Sroot case DMBIS: 5375731Sroot mbits |= bits; 5385731Sroot break; 5395731Sroot 5405731Sroot case DMBIC: 5415731Sroot mbits &= ~bits; 5425731Sroot break; 5435731Sroot 5445731Sroot case DMGET: 5455731Sroot (void) splx(s); 5465731Sroot return(mbits); 5475731Sroot } 5485731Sroot if (dzaddr->dzcsr & DZ_32) { 5495731Sroot mbits |= DZ_ACK|(unit&7); 5505731Sroot dzaddr->dzlcs = mbits; 5515731Sroot } else { 5525731Sroot if (mbits & DZ_DTR) 5535731Sroot dzaddr->dzdtr |= b; 5545731Sroot else 5555731Sroot dzaddr->dzdtr &= ~b; 5565731Sroot } 5575731Sroot (void) splx(s); 5585731Sroot return(mbits); 55917Sbill } 56017Sbill 561*16191Skarels int dztransitions, dzfasttimers; /*DEBUG*/ 56217Sbill dzscan() 56317Sbill { 56417Sbill register i; 56510019Ssam register struct dzdevice *dzaddr; 56617Sbill register bit; 56717Sbill register struct tty *tp; 5685731Sroot register car; 569*16191Skarels int olddzsilos = dzsilos; 570*16191Skarels int dztimer(); 57117Sbill 57217Sbill for (i = 0; i < dz_cnt ; i++) { 57317Sbill dzaddr = dzpdma[i].p_addr; 5742627Swnj if (dzaddr == 0) 5752627Swnj continue; 57617Sbill tp = &dz_tty[i]; 57717Sbill bit = 1<<(i&07); 5785731Sroot car = 0; 5795731Sroot if (dzsoftCAR[i>>3]&bit) 5805731Sroot car = 1; 5815731Sroot else if (dzaddr->dzcsr & DZ_32) { 5825731Sroot dzaddr->dzlcs = i&07; 5835731Sroot dzwait(dzaddr); 5845731Sroot car = dzaddr->dzlcs & DZ_CD; 5855731Sroot } else 5865731Sroot car = dzaddr->dzmsr&bit; 5875731Sroot if (car) { 58817Sbill /* carrier present */ 5895407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 59017Sbill wakeup((caddr_t)&tp->t_rawq); 5915407Swnj tp->t_state |= TS_CARR_ON; 59217Sbill } 59317Sbill } else { 5945407Swnj if ((tp->t_state&TS_CARR_ON) && 5959551Ssam (tp->t_flags&NOHANG) == 0) { 59617Sbill /* carrier lost */ 5975407Swnj if (tp->t_state&TS_ISOPEN) { 598170Sbill gsignal(tp->t_pgrp, SIGHUP); 599205Sbill gsignal(tp->t_pgrp, SIGCONT); 600170Sbill dzaddr->dzdtr &= ~bit; 60112777Ssam ttyflush(tp, FREAD|FWRITE); 602170Sbill } 6035407Swnj tp->t_state &= ~TS_CARR_ON; 60417Sbill } 60517Sbill } 60617Sbill } 607*16191Skarels for (i = 0; i < NDZ; i++) { 608*16191Skarels ave(dzrate[i], dzchars[i], 8); 609*16191Skarels if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) { 610*16191Skarels dzpdma[i].p_addr->dzcsr = DZ_IEN | DZ_SAE; 611*16191Skarels dzsilos |= (1 << i); 612*16191Skarels dztransitions++; /*DEBUG*/ 613*16191Skarels } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) { 614*16191Skarels dzpdma[i].p_addr->dzcsr = DZ_IEN; 615*16191Skarels dzsilos &= ~(1 << i); 616*16191Skarels } 617*16191Skarels dzchars[i] = 0; 618*16191Skarels } 619*16191Skarels if (dzsilos && !olddzsilos) 620*16191Skarels timeout(dztimer, (caddr_t)0, dztimerintvl); 621*16191Skarels timeout(dzscan, (caddr_t)0, hz); 62217Sbill } 623119Sbill 624119Sbill dztimer() 625119Sbill { 6268160Sroot register int dz; 627*16191Skarels register int s; 628119Sbill 629*16191Skarels if (dzsilos == 0) 630*16191Skarels return; 631*16191Skarels s = spl5(); 632*16191Skarels dzfasttimers++; /*DEBUG*/ 6332645Swnj for (dz = 0; dz < NDZ; dz++) 634*16191Skarels if (dzsilos & (1 << dz)) 635*16191Skarels dzrint(dz); 6368160Sroot splx(s); 637*16191Skarels timeout(dztimer, (caddr_t) 0, dztimerintvl); 638119Sbill } 639281Sbill 640281Sbill /* 641281Sbill * Reset state of driver if UBA reset was necessary. 642301Sbill * Reset parameters and restart transmission on open lines. 643281Sbill */ 6442395Swnj dzreset(uban) 6452422Skre int uban; 646281Sbill { 6472395Swnj register int unit; 648281Sbill register struct tty *tp; 6492976Swnj register struct uba_device *ui; 650281Sbill 6512645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6522422Skre ui = dzinfo[unit >> 3]; 6532422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6542422Skre continue; 6552923Swnj if (unit%8 == 0) 6562923Swnj printf(" dz%d", unit>>3); 6572395Swnj tp = &dz_tty[unit]; 6585407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6592395Swnj dzparam(unit); 6606157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 6615407Swnj tp->t_state &= ~TS_BUSY; 662301Sbill dzstart(tp); 663281Sbill } 664281Sbill } 665281Sbill } 6661562Sbill #endif 667