1*23326Smckusick /* 2*23326Smckusick * Copyright (c) 1982 Regents of the University of California. 3*23326Smckusick * All rights reserved. The Berkeley software License Agreement 4*23326Smckusick * specifies the terms and conditions for redistribution. 5*23326Smckusick * 6*23326Smckusick * @(#)dz.c 6.7 (Berkeley) 06/08/85 7*23326Smckusick */ 817Sbill 91935Swnj #include "dz.h" 102645Swnj #if NDZ > 0 1117Sbill /* 1210019Ssam * DZ-11/DZ-32 Driver 132469Swnj * 142469Swnj * This driver mimics dh.c; see it for explanation of common code. 1517Sbill */ 162731Swnj #include "bk.h" 179773Ssam 189773Ssam #include "../machine/pte.h" 199773Ssam 2017123Sbloom #include "param.h" 2117123Sbloom #include "systm.h" 2217123Sbloom #include "ioctl.h" 2317123Sbloom #include "tty.h" 2417123Sbloom #include "dir.h" 2517123Sbloom #include "user.h" 2617123Sbloom #include "proc.h" 2717123Sbloom #include "map.h" 2817123Sbloom #include "buf.h" 2917123Sbloom #include "vm.h" 3017123Sbloom #include "conf.h" 3117123Sbloom #include "bkmac.h" 3217123Sbloom #include "file.h" 3317123Sbloom #include "uio.h" 3417123Sbloom #include "kernel.h" 3518313Sralph #include "syslog.h" 36145Sbill 3717123Sbloom #include "pdma.h" 3817123Sbloom #include "ubavar.h" 3917123Sbloom #include "dzreg.h" 408474Sroot 412469Swnj /* 422469Swnj * Driver information for auto-configuration stuff. 432469Swnj */ 442606Swnj int dzprobe(), dzattach(), dzrint(); 452976Swnj struct uba_device *dzinfo[NDZ]; 462395Swnj u_short dzstd[] = { 0 }; 472395Swnj struct uba_driver dzdriver = 482606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 492395Swnj 502645Swnj #define NDZLINE (NDZ*8) 5116191Skarels #define FASTTIMER (hz/30) /* rate to drain silos, when in use */ 522469Swnj 532469Swnj int dzstart(), dzxint(), dzdma(); 54114Sbill int ttrstrt(); 552645Swnj struct tty dz_tty[NDZLINE]; 562645Swnj int dz_cnt = { NDZLINE }; 57119Sbill int dzact; 5816191Skarels int dzsilos; /* mask of dz's with silo in use */ 5916191Skarels int dzchars[NDZ]; /* recent input count */ 6016191Skarels int dzrate[NDZ]; /* smoothed input count */ 6116191Skarels int dztimerintvl; /* time interval for dztimer */ 6216191Skarels int dzhighrate = 100; /* silo on if dzchars > dzhighrate */ 6316191Skarels int dzlowrate = 75; /* silo off if dzrate < dzlowrate */ 6417Sbill 655731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 665731Sroot 672469Swnj /* 682469Swnj * Software copy of dzbrk since it isn't readable 692469Swnj */ 702645Swnj char dz_brk[NDZ]; 712645Swnj char dzsoftCAR[NDZ]; 725731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 7317Sbill 742469Swnj /* 755731Sroot * The dz11 doesn't interrupt on carrier transitions, so 762469Swnj * we have to use a timer to watch it. 772469Swnj */ 782469Swnj char dz_timer; /* timer started? */ 792469Swnj 802469Swnj /* 812469Swnj * Pdma structures for fast output code 822469Swnj */ 832645Swnj struct pdma dzpdma[NDZLINE]; 842469Swnj 852395Swnj char dz_speeds[] = 866814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 8717Sbill 886616Ssam #ifndef PORTSELECTOR 896616Ssam #define ISPEED B300 906616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 916616Ssam #else 926616Ssam #define ISPEED B4800 936616Ssam #define IFLAGS (EVENP|ODDP) 946616Ssam #endif 956616Ssam 962606Swnj dzprobe(reg) 972395Swnj caddr_t reg; 982395Swnj { 992457Swnj register int br, cvec; 10010019Ssam register struct dzdevice *dzaddr = (struct dzdevice *)reg; 1012395Swnj 1022606Swnj #ifdef lint 1033102Swnj br = 0; cvec = br; br = cvec; 1044933Swnj dzrint(0); dzxint((struct tty *)0); 1052606Swnj #endif 1065731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1075731Sroot if (dzaddr->dzcsr & DZ_32) 1085731Sroot dzaddr->dzlnen = 1; 1095731Sroot else 1105731Sroot dzaddr->dztcr = 1; /* enable any line */ 1112457Swnj DELAY(100000); 1125731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1132457Swnj if (cvec && cvec != 0x200) 1142457Swnj cvec -= 4; 11510019Ssam return (sizeof (struct dzdevice)); 1162395Swnj } 1172395Swnj 1182606Swnj dzattach(ui) 1192976Swnj register struct uba_device *ui; 1202395Swnj { 1212395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1222395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1232606Swnj register int cntr; 1242645Swnj extern dzscan(); 1252395Swnj 1262606Swnj for (cntr = 0; cntr < 8; cntr++) { 12710019Ssam pdp->p_addr = (struct dzdevice *)ui->ui_addr; 1282395Swnj pdp->p_arg = (int)tp; 1292395Swnj pdp->p_fcn = dzxint; 1302395Swnj pdp++, tp++; 1312395Swnj } 1322567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1332627Swnj if (dz_timer == 0) { 1342627Swnj dz_timer++; 1352756Swnj timeout(dzscan, (caddr_t)0, hz); 13616191Skarels dztimerintvl = FASTTIMER; 1372627Swnj } 1382395Swnj } 1392395Swnj 14017Sbill /*ARGSUSED*/ 1412395Swnj dzopen(dev, flag) 1422395Swnj dev_t dev; 14317Sbill { 14417Sbill register struct tty *tp; 1452395Swnj register int unit; 14617Sbill 1472395Swnj unit = minor(dev); 1488568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 1498568Sroot return (ENXIO); 1502395Swnj tp = &dz_tty[unit]; 1512395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 15217Sbill tp->t_oproc = dzstart; 1535407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 15417Sbill ttychars(tp); 1556616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 1566616Ssam tp->t_flags = IFLAGS; 1575407Swnj /* tp->t_state |= TS_HUPCLS; */ 1582395Swnj dzparam(unit); 1598568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 1608568Sroot return (EBUSY); 1616157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 162114Sbill (void) spl5(); 1635407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 1645407Swnj tp->t_state |= TS_WOPEN; 16517Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 16617Sbill } 167114Sbill (void) spl0(); 1688568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 16917Sbill } 17017Sbill 1712395Swnj /*ARGSUSED*/ 1722395Swnj dzclose(dev, flag) 1732395Swnj dev_t dev; 17417Sbill { 17517Sbill register struct tty *tp; 1762395Swnj register int unit; 17710019Ssam register struct dzdevice *dzaddr; 1786150Ssam int dz; 17917Sbill 1802395Swnj unit = minor(dev); 1812395Swnj dz = unit >> 3; 1822395Swnj tp = &dz_tty[unit]; 18317Sbill (*linesw[tp->t_line].l_close)(tp); 1845731Sroot dzaddr = dzpdma[unit].p_addr; 1855731Sroot if (dzaddr->dzcsr&DZ_32) 1866157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 1875731Sroot else 1885731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 1896842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 1906157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 19117Sbill ttyclose(tp); 19217Sbill } 19317Sbill 1947727Sroot dzread(dev, uio) 1952395Swnj dev_t dev; 1967727Sroot struct uio *uio; 19717Sbill { 19817Sbill register struct tty *tp; 19917Sbill 2002395Swnj tp = &dz_tty[minor(dev)]; 2017727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 20217Sbill } 20317Sbill 2047833Sroot dzwrite(dev, uio) 2052395Swnj dev_t dev; 2067833Sroot struct uio *uio; 20717Sbill { 20817Sbill register struct tty *tp; 20917Sbill 2102395Swnj tp = &dz_tty[minor(dev)]; 2118531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 21217Sbill } 21317Sbill 214119Sbill /*ARGSUSED*/ 2152395Swnj dzrint(dz) 2162395Swnj int dz; 21717Sbill { 21817Sbill register struct tty *tp; 21917Sbill register int c; 22010019Ssam register struct dzdevice *dzaddr; 221119Sbill register struct tty *tp0; 2222395Swnj register int unit; 2232923Swnj int overrun = 0; 22417Sbill 2252457Swnj if ((dzact & (1<<dz)) == 0) 2262457Swnj return; 2272457Swnj unit = dz * 8; 2282457Swnj dzaddr = dzpdma[unit].p_addr; 2292457Swnj tp0 = &dz_tty[unit]; 2305731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2315731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2325731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2335731Sroot c = dzaddr->dzmtsr; 2345731Sroot tp = tp0 + (c&7); 2355731Sroot if (tp >= &dz_tty[dz_cnt]) 2365731Sroot break; 2375731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2385731Sroot dzwait(dzaddr); /* wait for them */ 2395731Sroot if (c & DZ_CD) /* carrier status change? */ 2405731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2415731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2425731Sroot wakeup((caddr_t)&tp->t_rawq); 2435731Sroot tp->t_state |= TS_CARR_ON; 2445731Sroot } 2455731Sroot } else { /* no carrier */ 2465731Sroot if (tp->t_state&TS_CARR_ON) { 2475731Sroot gsignal(tp->t_pgrp, SIGHUP); 2485731Sroot gsignal(tp->t_pgrp, SIGCONT); 2495731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 25012777Ssam ttyflush(tp, FREAD|FWRITE); 2515731Sroot } 2525731Sroot tp->t_state &= ~TS_CARR_ON; 2535731Sroot } 2545731Sroot } 2552457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 25616191Skarels dzchars[dz]++; 2572457Swnj tp = tp0 + ((c>>8)&07); 2582457Swnj if (tp >= &dz_tty[dz_cnt]) 25917Sbill continue; 2605407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 2612457Swnj wakeup((caddr_t)&tp->t_rawq); 2626616Ssam #ifdef PORTSELECTOR 2636616Ssam if ((tp->t_state&TS_WOPEN) == 0) 2646616Ssam #endif 2652457Swnj continue; 2662457Swnj } 2672469Swnj if (c&DZ_FE) 2682457Swnj if (tp->t_flags & RAW) 2692469Swnj c = 0; 2702457Swnj else 2719551Ssam c = tp->t_intrc; 2722923Swnj if (c&DZ_DO && overrun == 0) { 27318313Sralph log(KERN_RECOV, "dz%d,%d: silo overflow\n", dz, (c>>8)&7); 2742923Swnj overrun = 1; 2752923Swnj } 2762469Swnj if (c&DZ_PE) 2772457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 2782457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 27917Sbill continue; 2802731Swnj #if NBK > 0 2812457Swnj if (tp->t_line == NETLDISC) { 2822457Swnj c &= 0177; 2832457Swnj BKINPUT(c, tp); 2842457Swnj } else 2852731Swnj #endif 2862457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 28717Sbill } 28817Sbill } 28917Sbill 29017Sbill /*ARGSUSED*/ 2917631Ssam dzioctl(dev, cmd, data, flag) 2922395Swnj dev_t dev; 2937631Ssam caddr_t data; 29417Sbill { 29517Sbill register struct tty *tp; 2962395Swnj register int unit = minor(dev); 2972395Swnj register int dz = unit >> 3; 29810019Ssam register struct dzdevice *dzaddr; 2998568Sroot int error; 30017Sbill 3012395Swnj tp = &dz_tty[unit]; 3028568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 3038568Sroot if (error >= 0) 3048568Sroot return (error); 3058568Sroot error = ttioctl(tp, cmd, data, flag); 3068568Sroot if (error >= 0) { 30717563Sbloom if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLBIS || 30817563Sbloom cmd == TIOCLBIC || cmd == TIOCLSET) 3092395Swnj dzparam(unit); 3108568Sroot return (error); 3118568Sroot } 3128568Sroot switch (cmd) { 3132395Swnj 314170Sbill case TIOCSBRK: 3155731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3165731Sroot if (dzaddr->dzcsr&DZ_32) 3176157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3185731Sroot else 3195731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 320170Sbill break; 3217631Ssam 322170Sbill case TIOCCBRK: 3235731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3245731Sroot if (dzaddr->dzcsr&DZ_32) 3256157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3265731Sroot else 3275731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 328170Sbill break; 3297631Ssam 330170Sbill case TIOCSDTR: 3316157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 332170Sbill break; 3337631Ssam 334170Sbill case TIOCCDTR: 3356157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 336170Sbill break; 3377631Ssam 3385731Sroot case TIOCMSET: 3397631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 3405731Sroot break; 3417631Ssam 3425731Sroot case TIOCMBIS: 3437631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 3445731Sroot break; 3457631Ssam 3465731Sroot case TIOCMBIC: 3477631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 3485731Sroot break; 3497631Ssam 3505731Sroot case TIOCMGET: 3517631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 3525731Sroot break; 3537631Ssam 354170Sbill default: 3558568Sroot return (ENOTTY); 356170Sbill } 3578568Sroot return (0); 35817Sbill } 3595731Sroot 3605731Sroot dmtodz(bits) 3615731Sroot register int bits; 3625731Sroot { 3635731Sroot register int b; 3645731Sroot 3655731Sroot b = (bits >>1) & 0370; 3665731Sroot if (bits & DML_ST) b |= DZ_ST; 3675731Sroot if (bits & DML_RTS) b |= DZ_RTS; 3685731Sroot if (bits & DML_DTR) b |= DZ_DTR; 3695731Sroot if (bits & DML_LE) b |= DZ_LE; 3705731Sroot return(b); 3715731Sroot } 3725731Sroot 3735731Sroot dztodm(bits) 3745731Sroot register int bits; 3755731Sroot { 3765731Sroot register int b; 3775731Sroot 3785731Sroot b = (bits << 1) & 0360; 3795731Sroot if (bits & DZ_DSR) b |= DML_DSR; 3805731Sroot if (bits & DZ_DTR) b |= DML_DTR; 3815731Sroot if (bits & DZ_ST) b |= DML_ST; 3825731Sroot if (bits & DZ_RTS) b |= DML_RTS; 3835731Sroot return(b); 3845731Sroot } 38517Sbill 3862395Swnj dzparam(unit) 3872395Swnj register int unit; 38817Sbill { 38917Sbill register struct tty *tp; 39010019Ssam register struct dzdevice *dzaddr; 3912395Swnj register int lpr; 39217Sbill 3932395Swnj tp = &dz_tty[unit]; 3942395Swnj dzaddr = dzpdma[unit].p_addr; 39516191Skarels if (dzsilos & (1 << (unit >> 3))) 39616191Skarels dzaddr->dzcsr = DZ_IEN | DZ_SAE; 39716191Skarels else 39816191Skarels dzaddr->dzcsr = DZ_IEN; 3992395Swnj dzact |= (1<<(unit>>3)); 40017Sbill if (tp->t_ispeed == 0) { 4016157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 40217Sbill return; 40317Sbill } 4042395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4059551Ssam if (tp->t_flags & (RAW|LITOUT)) 40617Sbill lpr |= BITS8; 40717Sbill else 40817Sbill lpr |= (BITS7|PENABLE); 40917Sbill if ((tp->t_flags & EVENP) == 0) 41017Sbill lpr |= OPAR; 4112469Swnj if (tp->t_ispeed == B110) 4122469Swnj lpr |= TWOSB; 41317Sbill dzaddr->dzlpr = lpr; 41417Sbill } 41517Sbill 41617Sbill dzxint(tp) 4172395Swnj register struct tty *tp; 41817Sbill { 41917Sbill register struct pdma *dp; 42016191Skarels register dz, unit; 42117Sbill 4222395Swnj dp = (struct pdma *)tp->t_addr; 4235407Swnj tp->t_state &= ~TS_BUSY; 4245407Swnj if (tp->t_state & TS_FLUSH) 4255407Swnj tp->t_state &= ~TS_FLUSH; 4265731Sroot else { 427281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4285731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4295731Sroot } 43017Sbill if (tp->t_line) 43117Sbill (*linesw[tp->t_line].l_start)(tp); 43217Sbill else 43317Sbill dzstart(tp); 4345731Sroot dz = minor(tp->t_dev) >> 3; 4355731Sroot unit = minor(tp->t_dev) & 7; 4365407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4375731Sroot if (dp->p_addr->dzcsr & DZ_32) 4385731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4395731Sroot else 4405731Sroot dp->p_addr->dztcr &= ~(1<<unit); 44117Sbill } 44217Sbill 44317Sbill dzstart(tp) 4442395Swnj register struct tty *tp; 44517Sbill { 44617Sbill register struct pdma *dp; 44710019Ssam register struct dzdevice *dzaddr; 4482395Swnj register int cc; 4495731Sroot int s, dz, unit; 45017Sbill 4512395Swnj dp = (struct pdma *)tp->t_addr; 45217Sbill dzaddr = dp->p_addr; 4532395Swnj s = spl5(); 4545407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 45517Sbill goto out; 4565407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 4575407Swnj if (tp->t_state&TS_ASLEEP) { 4585407Swnj tp->t_state &= ~TS_ASLEEP; 4595407Swnj wakeup((caddr_t)&tp->t_outq); 4605407Swnj } 4615407Swnj if (tp->t_wsel) { 4625407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 4635407Swnj tp->t_wsel = 0; 4645407Swnj tp->t_state &= ~TS_WCOLL; 4655407Swnj } 46617Sbill } 46717Sbill if (tp->t_outq.c_cc == 0) 46817Sbill goto out; 4699551Ssam if (tp->t_flags & (RAW|LITOUT)) 47017Sbill cc = ndqb(&tp->t_outq, 0); 47117Sbill else { 47217Sbill cc = ndqb(&tp->t_outq, 0200); 47317Sbill if (cc == 0) { 47417Sbill cc = getc(&tp->t_outq); 4752469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 4765407Swnj tp->t_state |= TS_TIMEOUT; 47717Sbill goto out; 47817Sbill } 47917Sbill } 4805407Swnj tp->t_state |= TS_BUSY; 48117Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 48217Sbill dp->p_end += cc; 4835731Sroot dz = minor(tp->t_dev) >> 3; 4845731Sroot unit = minor(tp->t_dev) & 7; 4855731Sroot if (dzaddr->dzcsr & DZ_32) 4865731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 4875731Sroot else 4885731Sroot dzaddr->dztcr |= (1<<unit); 4892395Swnj out: 4902395Swnj splx(s); 49117Sbill } 49217Sbill 49317Sbill /* 49417Sbill * Stop output on a line. 49517Sbill */ 49617Sbill /*ARGSUSED*/ 49717Sbill dzstop(tp, flag) 4982395Swnj register struct tty *tp; 49917Sbill { 50017Sbill register struct pdma *dp; 50117Sbill register int s; 50217Sbill 5032395Swnj dp = (struct pdma *)tp->t_addr; 5042457Swnj s = spl5(); 5055407Swnj if (tp->t_state & TS_BUSY) { 50617Sbill dp->p_end = dp->p_mem; 5075407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5085407Swnj tp->t_state |= TS_FLUSH; 50917Sbill } 51017Sbill splx(s); 51117Sbill } 51217Sbill 5135731Sroot dzmctl(dev, bits, how) 5145731Sroot dev_t dev; 5155731Sroot int bits, how; 51617Sbill { 51710019Ssam register struct dzdevice *dzaddr; 5185731Sroot register int unit, mbits; 5195731Sroot int b, s; 5205731Sroot 5215731Sroot unit = minor(dev); 5225731Sroot b = 1<<(unit&7); 5232395Swnj dzaddr = dzpdma[unit].p_addr; 5245731Sroot s = spl5(); 5255731Sroot if (dzaddr->dzcsr & DZ_32) { 5265731Sroot dzwait(dzaddr) 5275731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5285731Sroot dzaddr->dzlcs = unit&7; 5295731Sroot DELAY(100); 5305731Sroot dzwait(dzaddr) 5315731Sroot DELAY(100); 5325731Sroot mbits = dzaddr->dzlcs; 5335731Sroot mbits &= 0177770; 5345731Sroot } else { 5355731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5365731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5375731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5385731Sroot } 5395731Sroot switch (how) { 5405731Sroot case DMSET: 5415731Sroot mbits = bits; 5425731Sroot break; 5435731Sroot 5445731Sroot case DMBIS: 5455731Sroot mbits |= bits; 5465731Sroot break; 5475731Sroot 5485731Sroot case DMBIC: 5495731Sroot mbits &= ~bits; 5505731Sroot break; 5515731Sroot 5525731Sroot case DMGET: 5535731Sroot (void) splx(s); 5545731Sroot return(mbits); 5555731Sroot } 5565731Sroot if (dzaddr->dzcsr & DZ_32) { 5575731Sroot mbits |= DZ_ACK|(unit&7); 5585731Sroot dzaddr->dzlcs = mbits; 5595731Sroot } else { 5605731Sroot if (mbits & DZ_DTR) 5615731Sroot dzaddr->dzdtr |= b; 5625731Sroot else 5635731Sroot dzaddr->dzdtr &= ~b; 5645731Sroot } 5655731Sroot (void) splx(s); 5665731Sroot return(mbits); 56717Sbill } 56817Sbill 56916191Skarels int dztransitions, dzfasttimers; /*DEBUG*/ 57017Sbill dzscan() 57117Sbill { 57217Sbill register i; 57310019Ssam register struct dzdevice *dzaddr; 57417Sbill register bit; 57517Sbill register struct tty *tp; 5765731Sroot register car; 57716191Skarels int olddzsilos = dzsilos; 57816191Skarels int dztimer(); 57917Sbill 58017Sbill for (i = 0; i < dz_cnt ; i++) { 58117Sbill dzaddr = dzpdma[i].p_addr; 5822627Swnj if (dzaddr == 0) 5832627Swnj continue; 58417Sbill tp = &dz_tty[i]; 58517Sbill bit = 1<<(i&07); 5865731Sroot car = 0; 5875731Sroot if (dzsoftCAR[i>>3]&bit) 5885731Sroot car = 1; 5895731Sroot else if (dzaddr->dzcsr & DZ_32) { 5905731Sroot dzaddr->dzlcs = i&07; 5915731Sroot dzwait(dzaddr); 5925731Sroot car = dzaddr->dzlcs & DZ_CD; 5935731Sroot } else 5945731Sroot car = dzaddr->dzmsr&bit; 5955731Sroot if (car) { 59617Sbill /* carrier present */ 5975407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 59817Sbill wakeup((caddr_t)&tp->t_rawq); 5995407Swnj tp->t_state |= TS_CARR_ON; 60017Sbill } 60117Sbill } else { 6025407Swnj if ((tp->t_state&TS_CARR_ON) && 6039551Ssam (tp->t_flags&NOHANG) == 0) { 60417Sbill /* carrier lost */ 6055407Swnj if (tp->t_state&TS_ISOPEN) { 606170Sbill gsignal(tp->t_pgrp, SIGHUP); 607205Sbill gsignal(tp->t_pgrp, SIGCONT); 608170Sbill dzaddr->dzdtr &= ~bit; 60912777Ssam ttyflush(tp, FREAD|FWRITE); 610170Sbill } 6115407Swnj tp->t_state &= ~TS_CARR_ON; 61217Sbill } 61317Sbill } 61417Sbill } 61516191Skarels for (i = 0; i < NDZ; i++) { 61616191Skarels ave(dzrate[i], dzchars[i], 8); 61716191Skarels if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) { 61816397Ssam dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE; 61916191Skarels dzsilos |= (1 << i); 62016191Skarels dztransitions++; /*DEBUG*/ 62116191Skarels } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) { 62216397Ssam dzpdma[i << 3].p_addr->dzcsr = DZ_IEN; 62316191Skarels dzsilos &= ~(1 << i); 62416191Skarels } 62516191Skarels dzchars[i] = 0; 62616191Skarels } 62716191Skarels if (dzsilos && !olddzsilos) 62816191Skarels timeout(dztimer, (caddr_t)0, dztimerintvl); 62916191Skarels timeout(dzscan, (caddr_t)0, hz); 63017Sbill } 631119Sbill 632119Sbill dztimer() 633119Sbill { 6348160Sroot register int dz; 63516191Skarels register int s; 636119Sbill 63716191Skarels if (dzsilos == 0) 63816191Skarels return; 63916191Skarels s = spl5(); 64016191Skarels dzfasttimers++; /*DEBUG*/ 6412645Swnj for (dz = 0; dz < NDZ; dz++) 64216191Skarels if (dzsilos & (1 << dz)) 64316191Skarels dzrint(dz); 6448160Sroot splx(s); 64516191Skarels timeout(dztimer, (caddr_t) 0, dztimerintvl); 646119Sbill } 647281Sbill 648281Sbill /* 649281Sbill * Reset state of driver if UBA reset was necessary. 650301Sbill * Reset parameters and restart transmission on open lines. 651281Sbill */ 6522395Swnj dzreset(uban) 6532422Skre int uban; 654281Sbill { 6552395Swnj register int unit; 656281Sbill register struct tty *tp; 6572976Swnj register struct uba_device *ui; 658281Sbill 6592645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6602422Skre ui = dzinfo[unit >> 3]; 6612422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6622422Skre continue; 6632923Swnj if (unit%8 == 0) 6642923Swnj printf(" dz%d", unit>>3); 6652395Swnj tp = &dz_tty[unit]; 6665407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6672395Swnj dzparam(unit); 6686157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 6695407Swnj tp->t_state &= ~TS_BUSY; 670301Sbill dzstart(tp); 671281Sbill } 672281Sbill } 673281Sbill } 6741562Sbill #endif 675