1*10019Ssam /* dz.c 4.49 82/12/30 */ 217Sbill 31935Swnj #include "dz.h" 42645Swnj #if NDZ > 0 517Sbill /* 6*10019Ssam * 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" 28145Sbill 298474Sroot #include "../vaxuba/pdma.h" 308474Sroot #include "../vaxuba/ubavar.h" 31*10019Ssam #include "../vaxuba/dzreg.h" 328474Sroot 332469Swnj /* 342469Swnj * Driver information for auto-configuration stuff. 352469Swnj */ 362606Swnj int dzprobe(), dzattach(), dzrint(); 372976Swnj struct uba_device *dzinfo[NDZ]; 382395Swnj u_short dzstd[] = { 0 }; 392395Swnj struct uba_driver dzdriver = 402606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 412395Swnj 422645Swnj #define NDZLINE (NDZ*8) 432469Swnj 442469Swnj int dzstart(), dzxint(), dzdma(); 45114Sbill int ttrstrt(); 462645Swnj struct tty dz_tty[NDZLINE]; 472645Swnj int dz_cnt = { NDZLINE }; 48119Sbill int dzact; 4917Sbill 505731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 515731Sroot 522469Swnj /* 532469Swnj * Software copy of dzbrk since it isn't readable 542469Swnj */ 552645Swnj char dz_brk[NDZ]; 562645Swnj char dzsoftCAR[NDZ]; 575731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 5817Sbill 592469Swnj /* 605731Sroot * The dz11 doesn't interrupt on carrier transitions, so 612469Swnj * we have to use a timer to watch it. 622469Swnj */ 632469Swnj char dz_timer; /* timer started? */ 642469Swnj 652469Swnj /* 662469Swnj * Pdma structures for fast output code 672469Swnj */ 682645Swnj struct pdma dzpdma[NDZLINE]; 692469Swnj 702395Swnj char dz_speeds[] = 716814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 7217Sbill 736616Ssam #ifndef PORTSELECTOR 746616Ssam #define ISPEED B300 756616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 766616Ssam #else 776616Ssam #define ISPEED B4800 786616Ssam #define IFLAGS (EVENP|ODDP) 796616Ssam #endif 806616Ssam 812606Swnj dzprobe(reg) 822395Swnj caddr_t reg; 832395Swnj { 842457Swnj register int br, cvec; 85*10019Ssam register struct dzdevice *dzaddr = (struct dzdevice *)reg; 862395Swnj 872606Swnj #ifdef lint 883102Swnj br = 0; cvec = br; br = cvec; 894933Swnj dzrint(0); dzxint((struct tty *)0); 902606Swnj #endif 915731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 925731Sroot if (dzaddr->dzcsr & DZ_32) 935731Sroot dzaddr->dzlnen = 1; 945731Sroot else 955731Sroot dzaddr->dztcr = 1; /* enable any line */ 962457Swnj DELAY(100000); 975731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 982457Swnj if (cvec && cvec != 0x200) 992457Swnj cvec -= 4; 100*10019Ssam return (sizeof (struct dzdevice)); 1012395Swnj } 1022395Swnj 1032606Swnj dzattach(ui) 1042976Swnj register struct uba_device *ui; 1052395Swnj { 1062395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1072395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1082606Swnj register int cntr; 1092645Swnj extern dzscan(); 1102395Swnj 1112606Swnj for (cntr = 0; cntr < 8; cntr++) { 112*10019Ssam pdp->p_addr = (struct dzdevice *)ui->ui_addr; 1132395Swnj pdp->p_arg = (int)tp; 1142395Swnj pdp->p_fcn = dzxint; 1152395Swnj pdp++, tp++; 1162395Swnj } 1172567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1182627Swnj if (dz_timer == 0) { 1192627Swnj dz_timer++; 1202756Swnj timeout(dzscan, (caddr_t)0, hz); 1212627Swnj } 1222395Swnj } 1232395Swnj 12417Sbill /*ARGSUSED*/ 1252395Swnj dzopen(dev, flag) 1262395Swnj dev_t dev; 12717Sbill { 12817Sbill register struct tty *tp; 1292395Swnj register int unit; 13017Sbill 1312395Swnj unit = minor(dev); 1328568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 1338568Sroot return (ENXIO); 1342395Swnj tp = &dz_tty[unit]; 1352395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 13617Sbill tp->t_oproc = dzstart; 1375407Swnj tp->t_state |= TS_WOPEN; 1385407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 13917Sbill ttychars(tp); 1406616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 1416616Ssam tp->t_flags = IFLAGS; 1425407Swnj /* tp->t_state |= TS_HUPCLS; */ 1432395Swnj dzparam(unit); 1448568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 1458568Sroot return (EBUSY); 1466157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 147114Sbill (void) spl5(); 1485407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 1495407Swnj tp->t_state |= TS_WOPEN; 15017Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 15117Sbill } 152114Sbill (void) spl0(); 1538568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 15417Sbill } 15517Sbill 1562395Swnj /*ARGSUSED*/ 1572395Swnj dzclose(dev, flag) 1582395Swnj dev_t dev; 15917Sbill { 16017Sbill register struct tty *tp; 1612395Swnj register int unit; 162*10019Ssam register struct dzdevice *dzaddr; 1636150Ssam int dz; 16417Sbill 1652395Swnj unit = minor(dev); 1662395Swnj dz = unit >> 3; 1672395Swnj tp = &dz_tty[unit]; 16817Sbill (*linesw[tp->t_line].l_close)(tp); 1695731Sroot dzaddr = dzpdma[unit].p_addr; 1705731Sroot if (dzaddr->dzcsr&DZ_32) 1716157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 1725731Sroot else 1735731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 1746842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 1756157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 17617Sbill ttyclose(tp); 17717Sbill } 17817Sbill 1797727Sroot dzread(dev, uio) 1802395Swnj dev_t dev; 1817727Sroot struct uio *uio; 18217Sbill { 18317Sbill register struct tty *tp; 18417Sbill 1852395Swnj tp = &dz_tty[minor(dev)]; 1867727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 18717Sbill } 18817Sbill 1897833Sroot dzwrite(dev, uio) 1902395Swnj dev_t dev; 1917833Sroot struct uio *uio; 19217Sbill { 19317Sbill register struct tty *tp; 19417Sbill 1952395Swnj tp = &dz_tty[minor(dev)]; 1968531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 19717Sbill } 19817Sbill 199119Sbill /*ARGSUSED*/ 2002395Swnj dzrint(dz) 2012395Swnj int dz; 20217Sbill { 20317Sbill register struct tty *tp; 20417Sbill register int c; 205*10019Ssam register struct dzdevice *dzaddr; 206119Sbill register struct tty *tp0; 2072395Swnj register int unit; 2082923Swnj int overrun = 0; 20917Sbill 2102457Swnj if ((dzact & (1<<dz)) == 0) 2112457Swnj return; 2122457Swnj unit = dz * 8; 2132457Swnj dzaddr = dzpdma[unit].p_addr; 2142457Swnj tp0 = &dz_tty[unit]; 2155731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2165731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2175731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2185731Sroot c = dzaddr->dzmtsr; 2195731Sroot tp = tp0 + (c&7); 2205731Sroot if (tp >= &dz_tty[dz_cnt]) 2215731Sroot break; 2225731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2235731Sroot dzwait(dzaddr); /* wait for them */ 2245731Sroot if (c & DZ_CD) /* carrier status change? */ 2255731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2265731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2275731Sroot wakeup((caddr_t)&tp->t_rawq); 2285731Sroot tp->t_state |= TS_CARR_ON; 2295731Sroot } 2305731Sroot } else { /* no carrier */ 2315731Sroot if (tp->t_state&TS_CARR_ON) { 2325731Sroot gsignal(tp->t_pgrp, SIGHUP); 2335731Sroot gsignal(tp->t_pgrp, SIGCONT); 2345731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 2355731Sroot flushtty(tp, FREAD|FWRITE); 2365731Sroot } 2375731Sroot tp->t_state &= ~TS_CARR_ON; 2385731Sroot } 2395731Sroot } 2402457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 2412457Swnj tp = tp0 + ((c>>8)&07); 2422457Swnj if (tp >= &dz_tty[dz_cnt]) 24317Sbill continue; 2445407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 2452457Swnj wakeup((caddr_t)&tp->t_rawq); 2466616Ssam #ifdef PORTSELECTOR 2476616Ssam if ((tp->t_state&TS_WOPEN) == 0) 2486616Ssam #endif 2492457Swnj continue; 2502457Swnj } 2512469Swnj if (c&DZ_FE) 2522457Swnj if (tp->t_flags & RAW) 2532469Swnj c = 0; 2542457Swnj else 2559551Ssam c = tp->t_intrc; 2562923Swnj if (c&DZ_DO && overrun == 0) { 2575731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 2582923Swnj overrun = 1; 2592923Swnj } 2602469Swnj if (c&DZ_PE) 2612457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 2622457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 26317Sbill continue; 2642731Swnj #if NBK > 0 2652457Swnj if (tp->t_line == NETLDISC) { 2662457Swnj c &= 0177; 2672457Swnj BKINPUT(c, tp); 2682457Swnj } else 2692731Swnj #endif 2702457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 27117Sbill } 27217Sbill } 27317Sbill 27417Sbill /*ARGSUSED*/ 2757631Ssam dzioctl(dev, cmd, data, flag) 2762395Swnj dev_t dev; 2777631Ssam caddr_t data; 27817Sbill { 27917Sbill register struct tty *tp; 2802395Swnj register int unit = minor(dev); 2812395Swnj register int dz = unit >> 3; 282*10019Ssam register struct dzdevice *dzaddr; 2838568Sroot int error; 28417Sbill 2852395Swnj tp = &dz_tty[unit]; 2868568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 2878568Sroot if (error >= 0) 2888568Sroot return (error); 2898568Sroot error = ttioctl(tp, cmd, data, flag); 2908568Sroot if (error >= 0) { 2917631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 2922395Swnj dzparam(unit); 2938568Sroot return (error); 2948568Sroot } 2958568Sroot switch (cmd) { 2962395Swnj 297170Sbill case TIOCSBRK: 2985731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 2995731Sroot if (dzaddr->dzcsr&DZ_32) 3006157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3015731Sroot else 3025731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 303170Sbill break; 3047631Ssam 305170Sbill case TIOCCBRK: 3065731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3075731Sroot if (dzaddr->dzcsr&DZ_32) 3086157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3095731Sroot else 3105731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 311170Sbill break; 3127631Ssam 313170Sbill case TIOCSDTR: 3146157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 315170Sbill break; 3167631Ssam 317170Sbill case TIOCCDTR: 3186157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 319170Sbill break; 3207631Ssam 3215731Sroot case TIOCMSET: 3227631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 3235731Sroot break; 3247631Ssam 3255731Sroot case TIOCMBIS: 3267631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 3275731Sroot break; 3287631Ssam 3295731Sroot case TIOCMBIC: 3307631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 3315731Sroot break; 3327631Ssam 3335731Sroot case TIOCMGET: 3347631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 3355731Sroot break; 3367631Ssam 337170Sbill default: 3388568Sroot return (ENOTTY); 339170Sbill } 3408568Sroot return (0); 34117Sbill } 3425731Sroot 3435731Sroot dmtodz(bits) 3445731Sroot register int bits; 3455731Sroot { 3465731Sroot register int b; 3475731Sroot 3485731Sroot b = (bits >>1) & 0370; 3495731Sroot if (bits & DML_ST) b |= DZ_ST; 3505731Sroot if (bits & DML_RTS) b |= DZ_RTS; 3515731Sroot if (bits & DML_DTR) b |= DZ_DTR; 3525731Sroot if (bits & DML_LE) b |= DZ_LE; 3535731Sroot return(b); 3545731Sroot } 3555731Sroot 3565731Sroot dztodm(bits) 3575731Sroot register int bits; 3585731Sroot { 3595731Sroot register int b; 3605731Sroot 3615731Sroot b = (bits << 1) & 0360; 3625731Sroot if (bits & DZ_DSR) b |= DML_DSR; 3635731Sroot if (bits & DZ_DTR) b |= DML_DTR; 3645731Sroot if (bits & DZ_ST) b |= DML_ST; 3655731Sroot if (bits & DZ_RTS) b |= DML_RTS; 3665731Sroot return(b); 3675731Sroot } 36817Sbill 3692395Swnj dzparam(unit) 3702395Swnj register int unit; 37117Sbill { 37217Sbill register struct tty *tp; 373*10019Ssam register struct dzdevice *dzaddr; 3742395Swnj register int lpr; 37517Sbill 3762395Swnj tp = &dz_tty[unit]; 3772395Swnj dzaddr = dzpdma[unit].p_addr; 37817Sbill dzaddr->dzcsr = DZ_IEN; 3792395Swnj dzact |= (1<<(unit>>3)); 38017Sbill if (tp->t_ispeed == 0) { 3816157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 38217Sbill return; 38317Sbill } 3842395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 3859551Ssam if (tp->t_flags & (RAW|LITOUT)) 38617Sbill lpr |= BITS8; 38717Sbill else 38817Sbill lpr |= (BITS7|PENABLE); 38917Sbill if ((tp->t_flags & EVENP) == 0) 39017Sbill lpr |= OPAR; 3912469Swnj if (tp->t_ispeed == B110) 3922469Swnj lpr |= TWOSB; 39317Sbill dzaddr->dzlpr = lpr; 39417Sbill } 39517Sbill 39617Sbill dzxint(tp) 3972395Swnj register struct tty *tp; 39817Sbill { 39917Sbill register struct pdma *dp; 4005731Sroot register s, dz, unit; 40117Sbill 4022469Swnj s = spl5(); /* block pdma interrupts */ 4032395Swnj dp = (struct pdma *)tp->t_addr; 4045407Swnj tp->t_state &= ~TS_BUSY; 4055407Swnj if (tp->t_state & TS_FLUSH) 4065407Swnj tp->t_state &= ~TS_FLUSH; 4075731Sroot else { 408281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4095731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4105731Sroot } 41117Sbill if (tp->t_line) 41217Sbill (*linesw[tp->t_line].l_start)(tp); 41317Sbill else 41417Sbill dzstart(tp); 4155731Sroot dz = minor(tp->t_dev) >> 3; 4165731Sroot unit = minor(tp->t_dev) & 7; 4175407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4185731Sroot if (dp->p_addr->dzcsr & DZ_32) 4195731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4205731Sroot else 4215731Sroot dp->p_addr->dztcr &= ~(1<<unit); 422145Sbill splx(s); 42317Sbill } 42417Sbill 42517Sbill dzstart(tp) 4262395Swnj register struct tty *tp; 42717Sbill { 42817Sbill register struct pdma *dp; 429*10019Ssam register struct dzdevice *dzaddr; 4302395Swnj register int cc; 4315731Sroot int s, dz, unit; 43217Sbill 4332395Swnj dp = (struct pdma *)tp->t_addr; 43417Sbill dzaddr = dp->p_addr; 4352395Swnj s = spl5(); 4365407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 43717Sbill goto out; 4385407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 4395407Swnj if (tp->t_state&TS_ASLEEP) { 4405407Swnj tp->t_state &= ~TS_ASLEEP; 4415407Swnj wakeup((caddr_t)&tp->t_outq); 4425407Swnj } 4435407Swnj if (tp->t_wsel) { 4445407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 4455407Swnj tp->t_wsel = 0; 4465407Swnj tp->t_state &= ~TS_WCOLL; 4475407Swnj } 44817Sbill } 44917Sbill if (tp->t_outq.c_cc == 0) 45017Sbill goto out; 4519551Ssam if (tp->t_flags & (RAW|LITOUT)) 45217Sbill cc = ndqb(&tp->t_outq, 0); 45317Sbill else { 45417Sbill cc = ndqb(&tp->t_outq, 0200); 45517Sbill if (cc == 0) { 45617Sbill cc = getc(&tp->t_outq); 4572469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 4585407Swnj tp->t_state |= TS_TIMEOUT; 45917Sbill goto out; 46017Sbill } 46117Sbill } 4625407Swnj tp->t_state |= TS_BUSY; 46317Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 46417Sbill dp->p_end += cc; 4655731Sroot dz = minor(tp->t_dev) >> 3; 4665731Sroot unit = minor(tp->t_dev) & 7; 4675731Sroot if (dzaddr->dzcsr & DZ_32) 4685731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 4695731Sroot else 4705731Sroot dzaddr->dztcr |= (1<<unit); 4712395Swnj out: 4722395Swnj splx(s); 47317Sbill } 47417Sbill 47517Sbill /* 47617Sbill * Stop output on a line. 47717Sbill */ 47817Sbill /*ARGSUSED*/ 47917Sbill dzstop(tp, flag) 4802395Swnj register struct tty *tp; 48117Sbill { 48217Sbill register struct pdma *dp; 48317Sbill register int s; 48417Sbill 4852395Swnj dp = (struct pdma *)tp->t_addr; 4862457Swnj s = spl5(); 4875407Swnj if (tp->t_state & TS_BUSY) { 48817Sbill dp->p_end = dp->p_mem; 4895407Swnj if ((tp->t_state&TS_TTSTOP)==0) 4905407Swnj tp->t_state |= TS_FLUSH; 49117Sbill } 49217Sbill splx(s); 49317Sbill } 49417Sbill 4955731Sroot dzmctl(dev, bits, how) 4965731Sroot dev_t dev; 4975731Sroot int bits, how; 49817Sbill { 499*10019Ssam register struct dzdevice *dzaddr; 5005731Sroot register int unit, mbits; 5015731Sroot int b, s; 5025731Sroot 5035731Sroot unit = minor(dev); 5045731Sroot b = 1<<(unit&7); 5052395Swnj dzaddr = dzpdma[unit].p_addr; 5065731Sroot s = spl5(); 5075731Sroot if (dzaddr->dzcsr & DZ_32) { 5085731Sroot dzwait(dzaddr) 5095731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5105731Sroot dzaddr->dzlcs = unit&7; 5115731Sroot DELAY(100); 5125731Sroot dzwait(dzaddr) 5135731Sroot DELAY(100); 5145731Sroot mbits = dzaddr->dzlcs; 5155731Sroot mbits &= 0177770; 5165731Sroot } else { 5175731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5185731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5195731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5205731Sroot } 5215731Sroot switch (how) { 5225731Sroot case DMSET: 5235731Sroot mbits = bits; 5245731Sroot break; 5255731Sroot 5265731Sroot case DMBIS: 5275731Sroot mbits |= bits; 5285731Sroot break; 5295731Sroot 5305731Sroot case DMBIC: 5315731Sroot mbits &= ~bits; 5325731Sroot break; 5335731Sroot 5345731Sroot case DMGET: 5355731Sroot (void) splx(s); 5365731Sroot return(mbits); 5375731Sroot } 5385731Sroot if (dzaddr->dzcsr & DZ_32) { 5395731Sroot mbits |= DZ_ACK|(unit&7); 5405731Sroot dzaddr->dzlcs = mbits; 5415731Sroot } else { 5425731Sroot if (mbits & DZ_DTR) 5435731Sroot dzaddr->dzdtr |= b; 5445731Sroot else 5455731Sroot dzaddr->dzdtr &= ~b; 5465731Sroot } 5475731Sroot (void) splx(s); 5485731Sroot return(mbits); 54917Sbill } 55017Sbill 55117Sbill dzscan() 55217Sbill { 55317Sbill register i; 554*10019Ssam register struct dzdevice *dzaddr; 55517Sbill register bit; 55617Sbill register struct tty *tp; 5575731Sroot register car; 55817Sbill 55917Sbill for (i = 0; i < dz_cnt ; i++) { 56017Sbill dzaddr = dzpdma[i].p_addr; 5612627Swnj if (dzaddr == 0) 5622627Swnj continue; 56317Sbill tp = &dz_tty[i]; 56417Sbill bit = 1<<(i&07); 5655731Sroot car = 0; 5665731Sroot if (dzsoftCAR[i>>3]&bit) 5675731Sroot car = 1; 5685731Sroot else if (dzaddr->dzcsr & DZ_32) { 5695731Sroot dzaddr->dzlcs = i&07; 5705731Sroot dzwait(dzaddr); 5715731Sroot car = dzaddr->dzlcs & DZ_CD; 5725731Sroot } else 5735731Sroot car = dzaddr->dzmsr&bit; 5745731Sroot if (car) { 57517Sbill /* carrier present */ 5765407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 57717Sbill wakeup((caddr_t)&tp->t_rawq); 5785407Swnj tp->t_state |= TS_CARR_ON; 57917Sbill } 58017Sbill } else { 5815407Swnj if ((tp->t_state&TS_CARR_ON) && 5829551Ssam (tp->t_flags&NOHANG) == 0) { 58317Sbill /* carrier lost */ 5845407Swnj if (tp->t_state&TS_ISOPEN) { 585170Sbill gsignal(tp->t_pgrp, SIGHUP); 586205Sbill gsignal(tp->t_pgrp, SIGCONT); 587170Sbill dzaddr->dzdtr &= ~bit; 588871Sbill flushtty(tp, FREAD|FWRITE); 589170Sbill } 5905407Swnj tp->t_state &= ~TS_CARR_ON; 59117Sbill } 59217Sbill } 59317Sbill } 5942756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 59517Sbill } 596119Sbill 597119Sbill dztimer() 598119Sbill { 5998160Sroot register int dz; 6008160Sroot register int s = spl5(); 601119Sbill 6022645Swnj for (dz = 0; dz < NDZ; dz++) 6032457Swnj dzrint(dz); 6048160Sroot splx(s); 605119Sbill } 606281Sbill 607281Sbill /* 608281Sbill * Reset state of driver if UBA reset was necessary. 609301Sbill * Reset parameters and restart transmission on open lines. 610281Sbill */ 6112395Swnj dzreset(uban) 6122422Skre int uban; 613281Sbill { 6142395Swnj register int unit; 615281Sbill register struct tty *tp; 6162976Swnj register struct uba_device *ui; 617281Sbill 6182645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6192422Skre ui = dzinfo[unit >> 3]; 6202422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6212422Skre continue; 6222923Swnj if (unit%8 == 0) 6232923Swnj printf(" dz%d", unit>>3); 6242395Swnj tp = &dz_tty[unit]; 6255407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6262395Swnj dzparam(unit); 6276157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 6285407Swnj tp->t_state &= ~TS_BUSY; 629301Sbill dzstart(tp); 630281Sbill } 631281Sbill } 632281Sbill dztimer(); 633281Sbill } 6341562Sbill #endif 635