1*9551Ssam /* dz.c 4.47 82/12/05 */ 217Sbill 31935Swnj #include "dz.h" 42645Swnj #if NDZ > 0 517Sbill /* 65731Sroot * DZ-11 and DZ32 Driver 72469Swnj * 82469Swnj * This driver mimics dh.c; see it for explanation of common code. 917Sbill */ 102731Swnj #include "bk.h" 1117Sbill #include "../h/param.h" 1217Sbill #include "../h/systm.h" 13*9551Ssam #include "../h/ioctl.h" 1417Sbill #include "../h/tty.h" 1517Sbill #include "../h/dir.h" 1617Sbill #include "../h/user.h" 176157Ssam #include "../h/proc.h" 1817Sbill #include "../h/map.h" 1917Sbill #include "../h/pte.h" 202395Swnj #include "../h/buf.h" 212567Swnj #include "../h/vm.h" 2217Sbill #include "../h/conf.h" 23114Sbill #include "../h/bk.h" 24871Sbill #include "../h/file.h" 257727Sroot #include "../h/uio.h" 26145Sbill 278474Sroot #include "../vaxuba/pdma.h" 288474Sroot #include "../vaxuba/ubavar.h" 298474Sroot 302469Swnj /* 312469Swnj * Driver information for auto-configuration stuff. 322469Swnj */ 332606Swnj int dzprobe(), dzattach(), dzrint(); 342976Swnj struct uba_device *dzinfo[NDZ]; 352395Swnj u_short dzstd[] = { 0 }; 362395Swnj struct uba_driver dzdriver = 372606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 382395Swnj 392645Swnj #define NDZLINE (NDZ*8) 4017Sbill 412469Swnj /* 422469Swnj * Registers and bits 432469Swnj */ 442469Swnj 455731Sroot /* bits in dzlpr */ 465731Sroot #define BITS7 0020 475731Sroot #define BITS8 0030 485731Sroot #define TWOSB 0040 492457Swnj #define PENABLE 0100 502457Swnj #define OPAR 0200 5117Sbill 525731Sroot /* bits in dzrbuf */ 532469Swnj #define DZ_PE 010000 542469Swnj #define DZ_FE 020000 552469Swnj #define DZ_DO 040000 562469Swnj 575731Sroot /* bits in dzcsr */ 585731Sroot #define DZ_32 000001 /* DZ32 mode */ 595731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 605731Sroot #define DZ_CLR 000020 /* Reset dz */ 615731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 625731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 635731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 642469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 652469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 665731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 672469Swnj 685731Sroot /* flags for modem-control */ 695731Sroot #define DZ_ON DZ_DTR 702469Swnj #define DZ_OFF 0 715731Sroot 725731Sroot /* bits in dzlcs */ 735731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 745731Sroot #define DZ_RTS 0010000 /* Request To Send */ 755731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 765731Sroot #define DZ_BRK 0002000 /* Break */ 775731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 785731Sroot #define DZ_LE 0000400 /* Line Enable */ 795731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 805731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 815731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 825731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 835731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8417Sbill 855731Sroot /* bits in dm lsr, copied from dh.c */ 865731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 875731Sroot #define DML_RNG 0000200 /* ring */ 885731Sroot #define DML_CAR 0000100 /* carrier detect */ 895731Sroot #define DML_CTS 0000040 /* clear to send */ 905731Sroot #define DML_SR 0000020 /* secondary receive */ 915731Sroot #define DML_ST 0000010 /* secondary transmit */ 925731Sroot #define DML_RTS 0000004 /* request to send */ 935731Sroot #define DML_DTR 0000002 /* data terminal ready */ 945731Sroot #define DML_LE 0000001 /* line enable */ 955731Sroot 962469Swnj int dzstart(), dzxint(), dzdma(); 97114Sbill int ttrstrt(); 982645Swnj struct tty dz_tty[NDZLINE]; 992645Swnj int dz_cnt = { NDZLINE }; 100119Sbill int dzact; 10117Sbill 10217Sbill struct device { 1035731Sroot short dzcsr; 1045731Sroot short dzrbuf; 1055731Sroot union { 1065731Sroot struct { 1075731Sroot char dztcr0; 1085731Sroot char dzdtr0; 1095731Sroot char dztbuf0; 1105731Sroot char dzbrk0; 1115731Sroot } dz11; 1125731Sroot struct { 1135731Sroot short dzlcs0; 1145731Sroot char dztbuf0; 1155731Sroot char dzlnen0; 1165731Sroot } dz32; 1175731Sroot } dzun; 11817Sbill }; 1195731Sroot 1205731Sroot #define dzlpr dzrbuf 1215731Sroot #define dzmsr dzun.dz11.dzbrk0 1225731Sroot #define dztcr dzun.dz11.dztcr0 1235731Sroot #define dzdtr dzun.dz11.dzdtr0 1245731Sroot #define dztbuf dzun.dz11.dztbuf0 1255731Sroot #define dzlcs dzun.dz32.dzlcs0 1265731Sroot #define dzbrk dzmsr 1275731Sroot #define dzlnen dzun.dz32.dzlnen0 1287406Skre #define dzmtsr dzun.dz32.dztbuf0 1295731Sroot 1305731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1315731Sroot 1322469Swnj /* 1332469Swnj * Software copy of dzbrk since it isn't readable 1342469Swnj */ 1352645Swnj char dz_brk[NDZ]; 1362645Swnj char dzsoftCAR[NDZ]; 1375731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 13817Sbill 1392469Swnj /* 1405731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1412469Swnj * we have to use a timer to watch it. 1422469Swnj */ 1432469Swnj char dz_timer; /* timer started? */ 1442469Swnj 1452469Swnj /* 1462469Swnj * Pdma structures for fast output code 1472469Swnj */ 1482645Swnj struct pdma dzpdma[NDZLINE]; 1492469Swnj 1502395Swnj char dz_speeds[] = 1516814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 15217Sbill 1536616Ssam #ifndef PORTSELECTOR 1546616Ssam #define ISPEED B300 1556616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 1566616Ssam #else 1576616Ssam #define ISPEED B4800 1586616Ssam #define IFLAGS (EVENP|ODDP) 1596616Ssam #endif 1606616Ssam 1612606Swnj dzprobe(reg) 1622395Swnj caddr_t reg; 1632395Swnj { 1642457Swnj register int br, cvec; 1652457Swnj register struct device *dzaddr = (struct device *)reg; 1662395Swnj 1672606Swnj #ifdef lint 1683102Swnj br = 0; cvec = br; br = cvec; 1694933Swnj dzrint(0); dzxint((struct tty *)0); 1702606Swnj #endif 1715731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1725731Sroot if (dzaddr->dzcsr & DZ_32) 1735731Sroot dzaddr->dzlnen = 1; 1745731Sroot else 1755731Sroot dzaddr->dztcr = 1; /* enable any line */ 1762457Swnj DELAY(100000); 1775731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1782457Swnj if (cvec && cvec != 0x200) 1792457Swnj cvec -= 4; 1807406Skre return (sizeof (struct device)); 1812395Swnj } 1822395Swnj 1832606Swnj dzattach(ui) 1842976Swnj register struct uba_device *ui; 1852395Swnj { 1862395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1872395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1882606Swnj register int cntr; 1892645Swnj extern dzscan(); 1902395Swnj 1912606Swnj for (cntr = 0; cntr < 8; cntr++) { 1922606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1932395Swnj pdp->p_arg = (int)tp; 1942395Swnj pdp->p_fcn = dzxint; 1952395Swnj pdp++, tp++; 1962395Swnj } 1972567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1982627Swnj if (dz_timer == 0) { 1992627Swnj dz_timer++; 2002756Swnj timeout(dzscan, (caddr_t)0, hz); 2012627Swnj } 2022395Swnj } 2032395Swnj 20417Sbill /*ARGSUSED*/ 2052395Swnj dzopen(dev, flag) 2062395Swnj dev_t dev; 20717Sbill { 20817Sbill register struct tty *tp; 2092395Swnj register int unit; 21017Sbill 2112395Swnj unit = minor(dev); 2128568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 2138568Sroot return (ENXIO); 2142395Swnj tp = &dz_tty[unit]; 2152395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 21617Sbill tp->t_oproc = dzstart; 2175407Swnj tp->t_state |= TS_WOPEN; 2185407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 21917Sbill ttychars(tp); 2206616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 2216616Ssam tp->t_flags = IFLAGS; 2225407Swnj /* tp->t_state |= TS_HUPCLS; */ 2232395Swnj dzparam(unit); 2248568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 2258568Sroot return (EBUSY); 2266157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 227114Sbill (void) spl5(); 2285407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 2295407Swnj tp->t_state |= TS_WOPEN; 23017Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 23117Sbill } 232114Sbill (void) spl0(); 2338568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp)); 23417Sbill } 23517Sbill 2362395Swnj /*ARGSUSED*/ 2372395Swnj dzclose(dev, flag) 2382395Swnj dev_t dev; 23917Sbill { 24017Sbill register struct tty *tp; 2412395Swnj register int unit; 2425731Sroot register struct device *dzaddr; 2436150Ssam int dz; 24417Sbill 2452395Swnj unit = minor(dev); 2462395Swnj dz = unit >> 3; 2472395Swnj tp = &dz_tty[unit]; 24817Sbill (*linesw[tp->t_line].l_close)(tp); 2495731Sroot dzaddr = dzpdma[unit].p_addr; 2505731Sroot if (dzaddr->dzcsr&DZ_32) 2516157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 2525731Sroot else 2535731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 2546842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 2556157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 25617Sbill ttyclose(tp); 25717Sbill } 25817Sbill 2597727Sroot dzread(dev, uio) 2602395Swnj dev_t dev; 2617727Sroot struct uio *uio; 26217Sbill { 26317Sbill register struct tty *tp; 26417Sbill 2652395Swnj tp = &dz_tty[minor(dev)]; 2667727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 26717Sbill } 26817Sbill 2697833Sroot dzwrite(dev, uio) 2702395Swnj dev_t dev; 2717833Sroot struct uio *uio; 27217Sbill { 27317Sbill register struct tty *tp; 27417Sbill 2752395Swnj tp = &dz_tty[minor(dev)]; 2768531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 27717Sbill } 27817Sbill 279119Sbill /*ARGSUSED*/ 2802395Swnj dzrint(dz) 2812395Swnj int dz; 28217Sbill { 28317Sbill register struct tty *tp; 28417Sbill register int c; 28517Sbill register struct device *dzaddr; 286119Sbill register struct tty *tp0; 2872395Swnj register int unit; 2882923Swnj int overrun = 0; 28917Sbill 2902457Swnj if ((dzact & (1<<dz)) == 0) 2912457Swnj return; 2922457Swnj unit = dz * 8; 2932457Swnj dzaddr = dzpdma[unit].p_addr; 2942457Swnj tp0 = &dz_tty[unit]; 2955731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2965731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2975731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2985731Sroot c = dzaddr->dzmtsr; 2995731Sroot tp = tp0 + (c&7); 3005731Sroot if (tp >= &dz_tty[dz_cnt]) 3015731Sroot break; 3025731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 3035731Sroot dzwait(dzaddr); /* wait for them */ 3045731Sroot if (c & DZ_CD) /* carrier status change? */ 3055731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 3065731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 3075731Sroot wakeup((caddr_t)&tp->t_rawq); 3085731Sroot tp->t_state |= TS_CARR_ON; 3095731Sroot } 3105731Sroot } else { /* no carrier */ 3115731Sroot if (tp->t_state&TS_CARR_ON) { 3125731Sroot gsignal(tp->t_pgrp, SIGHUP); 3135731Sroot gsignal(tp->t_pgrp, SIGCONT); 3145731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3155731Sroot flushtty(tp, FREAD|FWRITE); 3165731Sroot } 3175731Sroot tp->t_state &= ~TS_CARR_ON; 3185731Sroot } 3195731Sroot } 3202457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3212457Swnj tp = tp0 + ((c>>8)&07); 3222457Swnj if (tp >= &dz_tty[dz_cnt]) 32317Sbill continue; 3245407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3252457Swnj wakeup((caddr_t)&tp->t_rawq); 3266616Ssam #ifdef PORTSELECTOR 3276616Ssam if ((tp->t_state&TS_WOPEN) == 0) 3286616Ssam #endif 3292457Swnj continue; 3302457Swnj } 3312469Swnj if (c&DZ_FE) 3322457Swnj if (tp->t_flags & RAW) 3332469Swnj c = 0; 3342457Swnj else 335*9551Ssam c = tp->t_intrc; 3362923Swnj if (c&DZ_DO && overrun == 0) { 3375731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3382923Swnj overrun = 1; 3392923Swnj } 3402469Swnj if (c&DZ_PE) 3412457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3422457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 34317Sbill continue; 3442731Swnj #if NBK > 0 3452457Swnj if (tp->t_line == NETLDISC) { 3462457Swnj c &= 0177; 3472457Swnj BKINPUT(c, tp); 3482457Swnj } else 3492731Swnj #endif 3502457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 35117Sbill } 35217Sbill } 35317Sbill 35417Sbill /*ARGSUSED*/ 3557631Ssam dzioctl(dev, cmd, data, flag) 3562395Swnj dev_t dev; 3577631Ssam caddr_t data; 35817Sbill { 35917Sbill register struct tty *tp; 3602395Swnj register int unit = minor(dev); 3612395Swnj register int dz = unit >> 3; 3625731Sroot register struct device *dzaddr; 3638568Sroot int error; 36417Sbill 3652395Swnj tp = &dz_tty[unit]; 3668568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 3678568Sroot if (error >= 0) 3688568Sroot return (error); 3698568Sroot error = ttioctl(tp, cmd, data, flag); 3708568Sroot if (error >= 0) { 3717631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 3722395Swnj dzparam(unit); 3738568Sroot return (error); 3748568Sroot } 3758568Sroot switch (cmd) { 3762395Swnj 377170Sbill case TIOCSBRK: 3785731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3795731Sroot if (dzaddr->dzcsr&DZ_32) 3806157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3815731Sroot else 3825731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 383170Sbill break; 3847631Ssam 385170Sbill case TIOCCBRK: 3865731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3875731Sroot if (dzaddr->dzcsr&DZ_32) 3886157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3895731Sroot else 3905731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 391170Sbill break; 3927631Ssam 393170Sbill case TIOCSDTR: 3946157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 395170Sbill break; 3967631Ssam 397170Sbill case TIOCCDTR: 3986157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 399170Sbill break; 4007631Ssam 4015731Sroot case TIOCMSET: 4027631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 4035731Sroot break; 4047631Ssam 4055731Sroot case TIOCMBIS: 4067631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 4075731Sroot break; 4087631Ssam 4095731Sroot case TIOCMBIC: 4107631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 4115731Sroot break; 4127631Ssam 4135731Sroot case TIOCMGET: 4147631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 4155731Sroot break; 4167631Ssam 417170Sbill default: 4188568Sroot return (ENOTTY); 419170Sbill } 4208568Sroot return (0); 42117Sbill } 4225731Sroot 4235731Sroot dmtodz(bits) 4245731Sroot register int bits; 4255731Sroot { 4265731Sroot register int b; 4275731Sroot 4285731Sroot b = (bits >>1) & 0370; 4295731Sroot if (bits & DML_ST) b |= DZ_ST; 4305731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4315731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4325731Sroot if (bits & DML_LE) b |= DZ_LE; 4335731Sroot return(b); 4345731Sroot } 4355731Sroot 4365731Sroot dztodm(bits) 4375731Sroot register int bits; 4385731Sroot { 4395731Sroot register int b; 4405731Sroot 4415731Sroot b = (bits << 1) & 0360; 4425731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4435731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4445731Sroot if (bits & DZ_ST) b |= DML_ST; 4455731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4465731Sroot return(b); 4475731Sroot } 44817Sbill 4492395Swnj dzparam(unit) 4502395Swnj register int unit; 45117Sbill { 45217Sbill register struct tty *tp; 45317Sbill register struct device *dzaddr; 4542395Swnj register int lpr; 45517Sbill 4562395Swnj tp = &dz_tty[unit]; 4572395Swnj dzaddr = dzpdma[unit].p_addr; 45817Sbill dzaddr->dzcsr = DZ_IEN; 4592395Swnj dzact |= (1<<(unit>>3)); 46017Sbill if (tp->t_ispeed == 0) { 4616157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 46217Sbill return; 46317Sbill } 4642395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 465*9551Ssam if (tp->t_flags & (RAW|LITOUT)) 46617Sbill lpr |= BITS8; 46717Sbill else 46817Sbill lpr |= (BITS7|PENABLE); 46917Sbill if ((tp->t_flags & EVENP) == 0) 47017Sbill lpr |= OPAR; 4712469Swnj if (tp->t_ispeed == B110) 4722469Swnj lpr |= TWOSB; 47317Sbill dzaddr->dzlpr = lpr; 47417Sbill } 47517Sbill 47617Sbill dzxint(tp) 4772395Swnj register struct tty *tp; 47817Sbill { 47917Sbill register struct pdma *dp; 4805731Sroot register s, dz, unit; 48117Sbill 4822469Swnj s = spl5(); /* block pdma interrupts */ 4832395Swnj dp = (struct pdma *)tp->t_addr; 4845407Swnj tp->t_state &= ~TS_BUSY; 4855407Swnj if (tp->t_state & TS_FLUSH) 4865407Swnj tp->t_state &= ~TS_FLUSH; 4875731Sroot else { 488281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4895731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4905731Sroot } 49117Sbill if (tp->t_line) 49217Sbill (*linesw[tp->t_line].l_start)(tp); 49317Sbill else 49417Sbill dzstart(tp); 4955731Sroot dz = minor(tp->t_dev) >> 3; 4965731Sroot unit = minor(tp->t_dev) & 7; 4975407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4985731Sroot if (dp->p_addr->dzcsr & DZ_32) 4995731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 5005731Sroot else 5015731Sroot dp->p_addr->dztcr &= ~(1<<unit); 502145Sbill splx(s); 50317Sbill } 50417Sbill 50517Sbill dzstart(tp) 5062395Swnj register struct tty *tp; 50717Sbill { 50817Sbill register struct pdma *dp; 50917Sbill register struct device *dzaddr; 5102395Swnj register int cc; 5115731Sroot int s, dz, unit; 51217Sbill 5132395Swnj dp = (struct pdma *)tp->t_addr; 51417Sbill dzaddr = dp->p_addr; 5152395Swnj s = spl5(); 5165407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 51717Sbill goto out; 5185407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5195407Swnj if (tp->t_state&TS_ASLEEP) { 5205407Swnj tp->t_state &= ~TS_ASLEEP; 5215407Swnj wakeup((caddr_t)&tp->t_outq); 5225407Swnj } 5235407Swnj if (tp->t_wsel) { 5245407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5255407Swnj tp->t_wsel = 0; 5265407Swnj tp->t_state &= ~TS_WCOLL; 5275407Swnj } 52817Sbill } 52917Sbill if (tp->t_outq.c_cc == 0) 53017Sbill goto out; 531*9551Ssam if (tp->t_flags & (RAW|LITOUT)) 53217Sbill cc = ndqb(&tp->t_outq, 0); 53317Sbill else { 53417Sbill cc = ndqb(&tp->t_outq, 0200); 53517Sbill if (cc == 0) { 53617Sbill cc = getc(&tp->t_outq); 5372469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5385407Swnj tp->t_state |= TS_TIMEOUT; 53917Sbill goto out; 54017Sbill } 54117Sbill } 5425407Swnj tp->t_state |= TS_BUSY; 54317Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 54417Sbill dp->p_end += cc; 5455731Sroot dz = minor(tp->t_dev) >> 3; 5465731Sroot unit = minor(tp->t_dev) & 7; 5475731Sroot if (dzaddr->dzcsr & DZ_32) 5485731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5495731Sroot else 5505731Sroot dzaddr->dztcr |= (1<<unit); 5512395Swnj out: 5522395Swnj splx(s); 55317Sbill } 55417Sbill 55517Sbill /* 55617Sbill * Stop output on a line. 55717Sbill */ 55817Sbill /*ARGSUSED*/ 55917Sbill dzstop(tp, flag) 5602395Swnj register struct tty *tp; 56117Sbill { 56217Sbill register struct pdma *dp; 56317Sbill register int s; 56417Sbill 5652395Swnj dp = (struct pdma *)tp->t_addr; 5662457Swnj s = spl5(); 5675407Swnj if (tp->t_state & TS_BUSY) { 56817Sbill dp->p_end = dp->p_mem; 5695407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5705407Swnj tp->t_state |= TS_FLUSH; 57117Sbill } 57217Sbill splx(s); 57317Sbill } 57417Sbill 5755731Sroot dzmctl(dev, bits, how) 5765731Sroot dev_t dev; 5775731Sroot int bits, how; 57817Sbill { 57917Sbill register struct device *dzaddr; 5805731Sroot register int unit, mbits; 5815731Sroot int b, s; 5825731Sroot 5835731Sroot unit = minor(dev); 5845731Sroot b = 1<<(unit&7); 5852395Swnj dzaddr = dzpdma[unit].p_addr; 5865731Sroot s = spl5(); 5875731Sroot if (dzaddr->dzcsr & DZ_32) { 5885731Sroot dzwait(dzaddr) 5895731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5905731Sroot dzaddr->dzlcs = unit&7; 5915731Sroot DELAY(100); 5925731Sroot dzwait(dzaddr) 5935731Sroot DELAY(100); 5945731Sroot mbits = dzaddr->dzlcs; 5955731Sroot mbits &= 0177770; 5965731Sroot } else { 5975731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5985731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5995731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 6005731Sroot } 6015731Sroot switch (how) { 6025731Sroot case DMSET: 6035731Sroot mbits = bits; 6045731Sroot break; 6055731Sroot 6065731Sroot case DMBIS: 6075731Sroot mbits |= bits; 6085731Sroot break; 6095731Sroot 6105731Sroot case DMBIC: 6115731Sroot mbits &= ~bits; 6125731Sroot break; 6135731Sroot 6145731Sroot case DMGET: 6155731Sroot (void) splx(s); 6165731Sroot return(mbits); 6175731Sroot } 6185731Sroot if (dzaddr->dzcsr & DZ_32) { 6195731Sroot mbits |= DZ_ACK|(unit&7); 6205731Sroot dzaddr->dzlcs = mbits; 6215731Sroot } else { 6225731Sroot if (mbits & DZ_DTR) 6235731Sroot dzaddr->dzdtr |= b; 6245731Sroot else 6255731Sroot dzaddr->dzdtr &= ~b; 6265731Sroot } 6275731Sroot (void) splx(s); 6285731Sroot return(mbits); 62917Sbill } 63017Sbill 63117Sbill dzscan() 63217Sbill { 63317Sbill register i; 63417Sbill register struct device *dzaddr; 63517Sbill register bit; 63617Sbill register struct tty *tp; 6375731Sroot register car; 63817Sbill 63917Sbill for (i = 0; i < dz_cnt ; i++) { 64017Sbill dzaddr = dzpdma[i].p_addr; 6412627Swnj if (dzaddr == 0) 6422627Swnj continue; 64317Sbill tp = &dz_tty[i]; 64417Sbill bit = 1<<(i&07); 6455731Sroot car = 0; 6465731Sroot if (dzsoftCAR[i>>3]&bit) 6475731Sroot car = 1; 6485731Sroot else if (dzaddr->dzcsr & DZ_32) { 6495731Sroot dzaddr->dzlcs = i&07; 6505731Sroot dzwait(dzaddr); 6515731Sroot car = dzaddr->dzlcs & DZ_CD; 6525731Sroot } else 6535731Sroot car = dzaddr->dzmsr&bit; 6545731Sroot if (car) { 65517Sbill /* carrier present */ 6565407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 65717Sbill wakeup((caddr_t)&tp->t_rawq); 6585407Swnj tp->t_state |= TS_CARR_ON; 65917Sbill } 66017Sbill } else { 6615407Swnj if ((tp->t_state&TS_CARR_ON) && 662*9551Ssam (tp->t_flags&NOHANG) == 0) { 66317Sbill /* carrier lost */ 6645407Swnj if (tp->t_state&TS_ISOPEN) { 665170Sbill gsignal(tp->t_pgrp, SIGHUP); 666205Sbill gsignal(tp->t_pgrp, SIGCONT); 667170Sbill dzaddr->dzdtr &= ~bit; 668871Sbill flushtty(tp, FREAD|FWRITE); 669170Sbill } 6705407Swnj tp->t_state &= ~TS_CARR_ON; 67117Sbill } 67217Sbill } 67317Sbill } 6742756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 67517Sbill } 676119Sbill 677119Sbill dztimer() 678119Sbill { 6798160Sroot register int dz; 6808160Sroot register int s = spl5(); 681119Sbill 6822645Swnj for (dz = 0; dz < NDZ; dz++) 6832457Swnj dzrint(dz); 6848160Sroot splx(s); 685119Sbill } 686281Sbill 687281Sbill /* 688281Sbill * Reset state of driver if UBA reset was necessary. 689301Sbill * Reset parameters and restart transmission on open lines. 690281Sbill */ 6912395Swnj dzreset(uban) 6922422Skre int uban; 693281Sbill { 6942395Swnj register int unit; 695281Sbill register struct tty *tp; 6962976Swnj register struct uba_device *ui; 697281Sbill 6982645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6992422Skre ui = dzinfo[unit >> 3]; 7002422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 7012422Skre continue; 7022923Swnj if (unit%8 == 0) 7032923Swnj printf(" dz%d", unit>>3); 7042395Swnj tp = &dz_tty[unit]; 7055407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 7062395Swnj dzparam(unit); 7076157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 7085407Swnj tp->t_state &= ~TS_BUSY; 709301Sbill dzstart(tp); 710281Sbill } 711281Sbill } 712281Sbill dztimer(); 713281Sbill } 7141562Sbill #endif 715