1*12777Ssam /* dz.c 4.51 83/05/27 */ 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) 442469Swnj 452469Swnj int dzstart(), dzxint(), dzdma(); 46114Sbill int ttrstrt(); 472645Swnj struct tty dz_tty[NDZLINE]; 482645Swnj int dz_cnt = { NDZLINE }; 49119Sbill int dzact; 5017Sbill 515731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 525731Sroot 532469Swnj /* 542469Swnj * Software copy of dzbrk since it isn't readable 552469Swnj */ 562645Swnj char dz_brk[NDZ]; 572645Swnj char dzsoftCAR[NDZ]; 585731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 5917Sbill 602469Swnj /* 615731Sroot * The dz11 doesn't interrupt on carrier transitions, so 622469Swnj * we have to use a timer to watch it. 632469Swnj */ 642469Swnj char dz_timer; /* timer started? */ 652469Swnj 662469Swnj /* 672469Swnj * Pdma structures for fast output code 682469Swnj */ 692645Swnj struct pdma dzpdma[NDZLINE]; 702469Swnj 712395Swnj char dz_speeds[] = 726814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 7317Sbill 746616Ssam #ifndef PORTSELECTOR 756616Ssam #define ISPEED B300 766616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 776616Ssam #else 786616Ssam #define ISPEED B4800 796616Ssam #define IFLAGS (EVENP|ODDP) 806616Ssam #endif 816616Ssam 822606Swnj dzprobe(reg) 832395Swnj caddr_t reg; 842395Swnj { 852457Swnj register int br, cvec; 8610019Ssam register struct dzdevice *dzaddr = (struct dzdevice *)reg; 872395Swnj 882606Swnj #ifdef lint 893102Swnj br = 0; cvec = br; br = cvec; 904933Swnj dzrint(0); dzxint((struct tty *)0); 912606Swnj #endif 925731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 935731Sroot if (dzaddr->dzcsr & DZ_32) 945731Sroot dzaddr->dzlnen = 1; 955731Sroot else 965731Sroot dzaddr->dztcr = 1; /* enable any line */ 972457Swnj DELAY(100000); 985731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 992457Swnj if (cvec && cvec != 0x200) 1002457Swnj cvec -= 4; 10110019Ssam return (sizeof (struct dzdevice)); 1022395Swnj } 1032395Swnj 1042606Swnj dzattach(ui) 1052976Swnj register struct uba_device *ui; 1062395Swnj { 1072395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1082395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1092606Swnj register int cntr; 1102645Swnj extern dzscan(); 1112395Swnj 1122606Swnj for (cntr = 0; cntr < 8; cntr++) { 11310019Ssam pdp->p_addr = (struct dzdevice *)ui->ui_addr; 1142395Swnj pdp->p_arg = (int)tp; 1152395Swnj pdp->p_fcn = dzxint; 1162395Swnj pdp++, tp++; 1172395Swnj } 1182567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1192627Swnj if (dz_timer == 0) { 1202627Swnj dz_timer++; 1212756Swnj timeout(dzscan, (caddr_t)0, hz); 1222627Swnj } 1232395Swnj } 1242395Swnj 12517Sbill /*ARGSUSED*/ 1262395Swnj dzopen(dev, flag) 1272395Swnj dev_t dev; 12817Sbill { 12917Sbill register struct tty *tp; 1302395Swnj register int unit; 13117Sbill 1322395Swnj unit = minor(dev); 1338568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 1348568Sroot return (ENXIO); 1352395Swnj tp = &dz_tty[unit]; 1362395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 13717Sbill tp->t_oproc = dzstart; 1385407Swnj tp->t_state |= TS_WOPEN; 1395407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 14017Sbill ttychars(tp); 1416616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 1426616Ssam tp->t_flags = IFLAGS; 1435407Swnj /* tp->t_state |= TS_HUPCLS; */ 1442395Swnj dzparam(unit); 1458568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 1468568Sroot return (EBUSY); 1476157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 148114Sbill (void) spl5(); 1495407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 1505407Swnj tp->t_state |= TS_WOPEN; 15117Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 15217Sbill } 153114Sbill (void) spl0(); 1548568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 15517Sbill } 15617Sbill 1572395Swnj /*ARGSUSED*/ 1582395Swnj dzclose(dev, flag) 1592395Swnj dev_t dev; 16017Sbill { 16117Sbill register struct tty *tp; 1622395Swnj register int unit; 16310019Ssam register struct dzdevice *dzaddr; 1646150Ssam int dz; 16517Sbill 1662395Swnj unit = minor(dev); 1672395Swnj dz = unit >> 3; 1682395Swnj tp = &dz_tty[unit]; 16917Sbill (*linesw[tp->t_line].l_close)(tp); 1705731Sroot dzaddr = dzpdma[unit].p_addr; 1715731Sroot if (dzaddr->dzcsr&DZ_32) 1726157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 1735731Sroot else 1745731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 1756842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 1766157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 17717Sbill ttyclose(tp); 17817Sbill } 17917Sbill 1807727Sroot dzread(dev, uio) 1812395Swnj dev_t dev; 1827727Sroot struct uio *uio; 18317Sbill { 18417Sbill register struct tty *tp; 18517Sbill 1862395Swnj tp = &dz_tty[minor(dev)]; 1877727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 18817Sbill } 18917Sbill 1907833Sroot dzwrite(dev, uio) 1912395Swnj dev_t dev; 1927833Sroot struct uio *uio; 19317Sbill { 19417Sbill register struct tty *tp; 19517Sbill 1962395Swnj tp = &dz_tty[minor(dev)]; 1978531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 19817Sbill } 19917Sbill 200119Sbill /*ARGSUSED*/ 2012395Swnj dzrint(dz) 2022395Swnj int dz; 20317Sbill { 20417Sbill register struct tty *tp; 20517Sbill register int c; 20610019Ssam register struct dzdevice *dzaddr; 207119Sbill register struct tty *tp0; 2082395Swnj register int unit; 2092923Swnj int overrun = 0; 21017Sbill 2112457Swnj if ((dzact & (1<<dz)) == 0) 2122457Swnj return; 2132457Swnj unit = dz * 8; 2142457Swnj dzaddr = dzpdma[unit].p_addr; 2152457Swnj tp0 = &dz_tty[unit]; 2165731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2175731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2185731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2195731Sroot c = dzaddr->dzmtsr; 2205731Sroot tp = tp0 + (c&7); 2215731Sroot if (tp >= &dz_tty[dz_cnt]) 2225731Sroot break; 2235731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2245731Sroot dzwait(dzaddr); /* wait for them */ 2255731Sroot if (c & DZ_CD) /* carrier status change? */ 2265731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2275731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2285731Sroot wakeup((caddr_t)&tp->t_rawq); 2295731Sroot tp->t_state |= TS_CARR_ON; 2305731Sroot } 2315731Sroot } else { /* no carrier */ 2325731Sroot if (tp->t_state&TS_CARR_ON) { 2335731Sroot gsignal(tp->t_pgrp, SIGHUP); 2345731Sroot gsignal(tp->t_pgrp, SIGCONT); 2355731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 236*12777Ssam ttyflush(tp, FREAD|FWRITE); 2375731Sroot } 2385731Sroot tp->t_state &= ~TS_CARR_ON; 2395731Sroot } 2405731Sroot } 2412457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 2422457Swnj tp = tp0 + ((c>>8)&07); 2432457Swnj if (tp >= &dz_tty[dz_cnt]) 24417Sbill continue; 2455407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 2462457Swnj wakeup((caddr_t)&tp->t_rawq); 2476616Ssam #ifdef PORTSELECTOR 2486616Ssam if ((tp->t_state&TS_WOPEN) == 0) 2496616Ssam #endif 2502457Swnj continue; 2512457Swnj } 2522469Swnj if (c&DZ_FE) 2532457Swnj if (tp->t_flags & RAW) 2542469Swnj c = 0; 2552457Swnj else 2569551Ssam c = tp->t_intrc; 2572923Swnj if (c&DZ_DO && overrun == 0) { 2585731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 2592923Swnj overrun = 1; 2602923Swnj } 2612469Swnj if (c&DZ_PE) 2622457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 2632457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 26417Sbill continue; 2652731Swnj #if NBK > 0 2662457Swnj if (tp->t_line == NETLDISC) { 2672457Swnj c &= 0177; 2682457Swnj BKINPUT(c, tp); 2692457Swnj } else 2702731Swnj #endif 2712457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 27217Sbill } 27317Sbill } 27417Sbill 27517Sbill /*ARGSUSED*/ 2767631Ssam dzioctl(dev, cmd, data, flag) 2772395Swnj dev_t dev; 2787631Ssam caddr_t data; 27917Sbill { 28017Sbill register struct tty *tp; 2812395Swnj register int unit = minor(dev); 2822395Swnj register int dz = unit >> 3; 28310019Ssam register struct dzdevice *dzaddr; 2848568Sroot int error; 28517Sbill 2862395Swnj tp = &dz_tty[unit]; 2878568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 2888568Sroot if (error >= 0) 2898568Sroot return (error); 2908568Sroot error = ttioctl(tp, cmd, data, flag); 2918568Sroot if (error >= 0) { 2927631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 2932395Swnj dzparam(unit); 2948568Sroot return (error); 2958568Sroot } 2968568Sroot switch (cmd) { 2972395Swnj 298170Sbill case TIOCSBRK: 2995731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3005731Sroot if (dzaddr->dzcsr&DZ_32) 3016157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3025731Sroot else 3035731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 304170Sbill break; 3057631Ssam 306170Sbill case TIOCCBRK: 3075731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3085731Sroot if (dzaddr->dzcsr&DZ_32) 3096157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3105731Sroot else 3115731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 312170Sbill break; 3137631Ssam 314170Sbill case TIOCSDTR: 3156157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 316170Sbill break; 3177631Ssam 318170Sbill case TIOCCDTR: 3196157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 320170Sbill break; 3217631Ssam 3225731Sroot case TIOCMSET: 3237631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 3245731Sroot break; 3257631Ssam 3265731Sroot case TIOCMBIS: 3277631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 3285731Sroot break; 3297631Ssam 3305731Sroot case TIOCMBIC: 3317631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 3325731Sroot break; 3337631Ssam 3345731Sroot case TIOCMGET: 3357631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 3365731Sroot break; 3377631Ssam 338170Sbill default: 3398568Sroot return (ENOTTY); 340170Sbill } 3418568Sroot return (0); 34217Sbill } 3435731Sroot 3445731Sroot dmtodz(bits) 3455731Sroot register int bits; 3465731Sroot { 3475731Sroot register int b; 3485731Sroot 3495731Sroot b = (bits >>1) & 0370; 3505731Sroot if (bits & DML_ST) b |= DZ_ST; 3515731Sroot if (bits & DML_RTS) b |= DZ_RTS; 3525731Sroot if (bits & DML_DTR) b |= DZ_DTR; 3535731Sroot if (bits & DML_LE) b |= DZ_LE; 3545731Sroot return(b); 3555731Sroot } 3565731Sroot 3575731Sroot dztodm(bits) 3585731Sroot register int bits; 3595731Sroot { 3605731Sroot register int b; 3615731Sroot 3625731Sroot b = (bits << 1) & 0360; 3635731Sroot if (bits & DZ_DSR) b |= DML_DSR; 3645731Sroot if (bits & DZ_DTR) b |= DML_DTR; 3655731Sroot if (bits & DZ_ST) b |= DML_ST; 3665731Sroot if (bits & DZ_RTS) b |= DML_RTS; 3675731Sroot return(b); 3685731Sroot } 36917Sbill 3702395Swnj dzparam(unit) 3712395Swnj register int unit; 37217Sbill { 37317Sbill register struct tty *tp; 37410019Ssam register struct dzdevice *dzaddr; 3752395Swnj register int lpr; 37617Sbill 3772395Swnj tp = &dz_tty[unit]; 3782395Swnj dzaddr = dzpdma[unit].p_addr; 37917Sbill dzaddr->dzcsr = DZ_IEN; 3802395Swnj dzact |= (1<<(unit>>3)); 38117Sbill if (tp->t_ispeed == 0) { 3826157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 38317Sbill return; 38417Sbill } 3852395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 3869551Ssam if (tp->t_flags & (RAW|LITOUT)) 38717Sbill lpr |= BITS8; 38817Sbill else 38917Sbill lpr |= (BITS7|PENABLE); 39017Sbill if ((tp->t_flags & EVENP) == 0) 39117Sbill lpr |= OPAR; 3922469Swnj if (tp->t_ispeed == B110) 3932469Swnj lpr |= TWOSB; 39417Sbill dzaddr->dzlpr = lpr; 39517Sbill } 39617Sbill 39717Sbill dzxint(tp) 3982395Swnj register struct tty *tp; 39917Sbill { 40017Sbill register struct pdma *dp; 4015731Sroot register s, dz, unit; 40217Sbill 4032469Swnj s = spl5(); /* block pdma interrupts */ 4042395Swnj dp = (struct pdma *)tp->t_addr; 4055407Swnj tp->t_state &= ~TS_BUSY; 4065407Swnj if (tp->t_state & TS_FLUSH) 4075407Swnj tp->t_state &= ~TS_FLUSH; 4085731Sroot else { 409281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4105731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4115731Sroot } 41217Sbill if (tp->t_line) 41317Sbill (*linesw[tp->t_line].l_start)(tp); 41417Sbill else 41517Sbill dzstart(tp); 4165731Sroot dz = minor(tp->t_dev) >> 3; 4175731Sroot unit = minor(tp->t_dev) & 7; 4185407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4195731Sroot if (dp->p_addr->dzcsr & DZ_32) 4205731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4215731Sroot else 4225731Sroot dp->p_addr->dztcr &= ~(1<<unit); 423145Sbill splx(s); 42417Sbill } 42517Sbill 42617Sbill dzstart(tp) 4272395Swnj register struct tty *tp; 42817Sbill { 42917Sbill register struct pdma *dp; 43010019Ssam register struct dzdevice *dzaddr; 4312395Swnj register int cc; 4325731Sroot int s, dz, unit; 43317Sbill 4342395Swnj dp = (struct pdma *)tp->t_addr; 43517Sbill dzaddr = dp->p_addr; 4362395Swnj s = spl5(); 4375407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 43817Sbill goto out; 4395407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 4405407Swnj if (tp->t_state&TS_ASLEEP) { 4415407Swnj tp->t_state &= ~TS_ASLEEP; 4425407Swnj wakeup((caddr_t)&tp->t_outq); 4435407Swnj } 4445407Swnj if (tp->t_wsel) { 4455407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 4465407Swnj tp->t_wsel = 0; 4475407Swnj tp->t_state &= ~TS_WCOLL; 4485407Swnj } 44917Sbill } 45017Sbill if (tp->t_outq.c_cc == 0) 45117Sbill goto out; 4529551Ssam if (tp->t_flags & (RAW|LITOUT)) 45317Sbill cc = ndqb(&tp->t_outq, 0); 45417Sbill else { 45517Sbill cc = ndqb(&tp->t_outq, 0200); 45617Sbill if (cc == 0) { 45717Sbill cc = getc(&tp->t_outq); 4582469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 4595407Swnj tp->t_state |= TS_TIMEOUT; 46017Sbill goto out; 46117Sbill } 46217Sbill } 4635407Swnj tp->t_state |= TS_BUSY; 46417Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 46517Sbill dp->p_end += cc; 4665731Sroot dz = minor(tp->t_dev) >> 3; 4675731Sroot unit = minor(tp->t_dev) & 7; 4685731Sroot if (dzaddr->dzcsr & DZ_32) 4695731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 4705731Sroot else 4715731Sroot dzaddr->dztcr |= (1<<unit); 4722395Swnj out: 4732395Swnj splx(s); 47417Sbill } 47517Sbill 47617Sbill /* 47717Sbill * Stop output on a line. 47817Sbill */ 47917Sbill /*ARGSUSED*/ 48017Sbill dzstop(tp, flag) 4812395Swnj register struct tty *tp; 48217Sbill { 48317Sbill register struct pdma *dp; 48417Sbill register int s; 48517Sbill 4862395Swnj dp = (struct pdma *)tp->t_addr; 4872457Swnj s = spl5(); 4885407Swnj if (tp->t_state & TS_BUSY) { 48917Sbill dp->p_end = dp->p_mem; 4905407Swnj if ((tp->t_state&TS_TTSTOP)==0) 4915407Swnj tp->t_state |= TS_FLUSH; 49217Sbill } 49317Sbill splx(s); 49417Sbill } 49517Sbill 4965731Sroot dzmctl(dev, bits, how) 4975731Sroot dev_t dev; 4985731Sroot int bits, how; 49917Sbill { 50010019Ssam register struct dzdevice *dzaddr; 5015731Sroot register int unit, mbits; 5025731Sroot int b, s; 5035731Sroot 5045731Sroot unit = minor(dev); 5055731Sroot b = 1<<(unit&7); 5062395Swnj dzaddr = dzpdma[unit].p_addr; 5075731Sroot s = spl5(); 5085731Sroot if (dzaddr->dzcsr & DZ_32) { 5095731Sroot dzwait(dzaddr) 5105731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5115731Sroot dzaddr->dzlcs = unit&7; 5125731Sroot DELAY(100); 5135731Sroot dzwait(dzaddr) 5145731Sroot DELAY(100); 5155731Sroot mbits = dzaddr->dzlcs; 5165731Sroot mbits &= 0177770; 5175731Sroot } else { 5185731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5195731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5205731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5215731Sroot } 5225731Sroot switch (how) { 5235731Sroot case DMSET: 5245731Sroot mbits = bits; 5255731Sroot break; 5265731Sroot 5275731Sroot case DMBIS: 5285731Sroot mbits |= bits; 5295731Sroot break; 5305731Sroot 5315731Sroot case DMBIC: 5325731Sroot mbits &= ~bits; 5335731Sroot break; 5345731Sroot 5355731Sroot case DMGET: 5365731Sroot (void) splx(s); 5375731Sroot return(mbits); 5385731Sroot } 5395731Sroot if (dzaddr->dzcsr & DZ_32) { 5405731Sroot mbits |= DZ_ACK|(unit&7); 5415731Sroot dzaddr->dzlcs = mbits; 5425731Sroot } else { 5435731Sroot if (mbits & DZ_DTR) 5445731Sroot dzaddr->dzdtr |= b; 5455731Sroot else 5465731Sroot dzaddr->dzdtr &= ~b; 5475731Sroot } 5485731Sroot (void) splx(s); 5495731Sroot return(mbits); 55017Sbill } 55117Sbill 55217Sbill dzscan() 55317Sbill { 55417Sbill register i; 55510019Ssam register struct dzdevice *dzaddr; 55617Sbill register bit; 55717Sbill register struct tty *tp; 5585731Sroot register car; 55917Sbill 56017Sbill for (i = 0; i < dz_cnt ; i++) { 56117Sbill dzaddr = dzpdma[i].p_addr; 5622627Swnj if (dzaddr == 0) 5632627Swnj continue; 56417Sbill tp = &dz_tty[i]; 56517Sbill bit = 1<<(i&07); 5665731Sroot car = 0; 5675731Sroot if (dzsoftCAR[i>>3]&bit) 5685731Sroot car = 1; 5695731Sroot else if (dzaddr->dzcsr & DZ_32) { 5705731Sroot dzaddr->dzlcs = i&07; 5715731Sroot dzwait(dzaddr); 5725731Sroot car = dzaddr->dzlcs & DZ_CD; 5735731Sroot } else 5745731Sroot car = dzaddr->dzmsr&bit; 5755731Sroot if (car) { 57617Sbill /* carrier present */ 5775407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 57817Sbill wakeup((caddr_t)&tp->t_rawq); 5795407Swnj tp->t_state |= TS_CARR_ON; 58017Sbill } 58117Sbill } else { 5825407Swnj if ((tp->t_state&TS_CARR_ON) && 5839551Ssam (tp->t_flags&NOHANG) == 0) { 58417Sbill /* carrier lost */ 5855407Swnj if (tp->t_state&TS_ISOPEN) { 586170Sbill gsignal(tp->t_pgrp, SIGHUP); 587205Sbill gsignal(tp->t_pgrp, SIGCONT); 588170Sbill dzaddr->dzdtr &= ~bit; 589*12777Ssam ttyflush(tp, FREAD|FWRITE); 590170Sbill } 5915407Swnj tp->t_state &= ~TS_CARR_ON; 59217Sbill } 59317Sbill } 59417Sbill } 5952756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 59617Sbill } 597119Sbill 598119Sbill dztimer() 599119Sbill { 6008160Sroot register int dz; 6018160Sroot register int s = spl5(); 602119Sbill 6032645Swnj for (dz = 0; dz < NDZ; dz++) 6042457Swnj dzrint(dz); 6058160Sroot splx(s); 606119Sbill } 607281Sbill 608281Sbill /* 609281Sbill * Reset state of driver if UBA reset was necessary. 610301Sbill * Reset parameters and restart transmission on open lines. 611281Sbill */ 6122395Swnj dzreset(uban) 6132422Skre int uban; 614281Sbill { 6152395Swnj register int unit; 616281Sbill register struct tty *tp; 6172976Swnj register struct uba_device *ui; 618281Sbill 6192645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6202422Skre ui = dzinfo[unit >> 3]; 6212422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6222422Skre continue; 6232923Swnj if (unit%8 == 0) 6242923Swnj printf(" dz%d", unit>>3); 6252395Swnj tp = &dz_tty[unit]; 6265407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6272395Swnj dzparam(unit); 6286157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 6295407Swnj tp->t_state &= ~TS_BUSY; 630301Sbill dzstart(tp); 631281Sbill } 632281Sbill } 633281Sbill dztimer(); 634281Sbill } 6351562Sbill #endif 636