1*6150Ssam /* dz.c 4.34 82/03/12 */ 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" 1317Sbill #include "../h/tty.h" 1417Sbill #include "../h/dir.h" 1517Sbill #include "../h/user.h" 1617Sbill #include "../h/map.h" 1717Sbill #include "../h/pte.h" 182395Swnj #include "../h/buf.h" 192567Swnj #include "../h/vm.h" 202976Swnj #include "../h/ubavar.h" 2117Sbill #include "../h/conf.h" 2217Sbill #include "../h/pdma.h" 23114Sbill #include "../h/bk.h" 24871Sbill #include "../h/file.h" 25145Sbill 262469Swnj /* 272469Swnj * Driver information for auto-configuration stuff. 282469Swnj */ 292606Swnj int dzprobe(), dzattach(), dzrint(); 302976Swnj struct uba_device *dzinfo[NDZ]; 312395Swnj u_short dzstd[] = { 0 }; 322395Swnj struct uba_driver dzdriver = 332606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 342395Swnj 352645Swnj #define NDZLINE (NDZ*8) 3617Sbill 372469Swnj /* 382469Swnj * Registers and bits 392469Swnj */ 402469Swnj 415731Sroot /* bits in dzlpr */ 425731Sroot #define BITS7 0020 435731Sroot #define BITS8 0030 445731Sroot #define TWOSB 0040 452457Swnj #define PENABLE 0100 462457Swnj #define OPAR 0200 4717Sbill 485731Sroot /* bits in dzrbuf */ 492469Swnj #define DZ_PE 010000 502469Swnj #define DZ_FE 020000 512469Swnj #define DZ_DO 040000 522469Swnj 535731Sroot /* bits in dzcsr */ 545731Sroot #define DZ_32 000001 /* DZ32 mode */ 555731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 565731Sroot #define DZ_CLR 000020 /* Reset dz */ 575731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 585731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 595731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 602469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 612469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 625731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 632469Swnj 645731Sroot /* flags for modem-control */ 655731Sroot #define DZ_ON DZ_DTR 662469Swnj #define DZ_OFF 0 675731Sroot 685731Sroot /* bits in dzlcs */ 695731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 705731Sroot #define DZ_RTS 0010000 /* Request To Send */ 715731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 725731Sroot #define DZ_BRK 0002000 /* Break */ 735731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 745731Sroot #define DZ_LE 0000400 /* Line Enable */ 755731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 765731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 775731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 785731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 795731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8017Sbill 815731Sroot /* bits in dm lsr, copied from dh.c */ 825731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 835731Sroot #define DML_RNG 0000200 /* ring */ 845731Sroot #define DML_CAR 0000100 /* carrier detect */ 855731Sroot #define DML_CTS 0000040 /* clear to send */ 865731Sroot #define DML_SR 0000020 /* secondary receive */ 875731Sroot #define DML_ST 0000010 /* secondary transmit */ 885731Sroot #define DML_RTS 0000004 /* request to send */ 895731Sroot #define DML_DTR 0000002 /* data terminal ready */ 905731Sroot #define DML_LE 0000001 /* line enable */ 915731Sroot 922469Swnj int dzstart(), dzxint(), dzdma(); 93114Sbill int ttrstrt(); 942645Swnj struct tty dz_tty[NDZLINE]; 952645Swnj int dz_cnt = { NDZLINE }; 96119Sbill int dzact; 9717Sbill 9817Sbill struct device { 995731Sroot short dzcsr; 1005731Sroot short dzrbuf; 1015731Sroot union { 1025731Sroot struct { 1035731Sroot char dztcr0; 1045731Sroot char dzdtr0; 1055731Sroot char dztbuf0; 1065731Sroot char dzbrk0; 1075731Sroot } dz11; 1085731Sroot struct { 1095731Sroot short dzlcs0; 1105731Sroot char dztbuf0; 1115731Sroot char dzlnen0; 1125731Sroot } dz32; 1135731Sroot } dzun; 11417Sbill }; 1155731Sroot 1165731Sroot #define dzlpr dzrbuf 1175731Sroot #define dzmsr dzun.dz11.dzbrk0 1185731Sroot #define dztcr dzun.dz11.dztcr0 1195731Sroot #define dzdtr dzun.dz11.dzdtr0 1205731Sroot #define dztbuf dzun.dz11.dztbuf0 1215731Sroot #define dzlcs dzun.dz32.dzlcs0 1225731Sroot #define dzbrk dzmsr 1235731Sroot #define dzlnen dzun.dz32.dzlnen0 1245731Sroot #define dzmtsr dzun.dz32.dztbuf0; 1255731Sroot 1265731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1275731Sroot 1282469Swnj /* 1292469Swnj * Software copy of dzbrk since it isn't readable 1302469Swnj */ 1312645Swnj char dz_brk[NDZ]; 1322645Swnj char dzsoftCAR[NDZ]; 1335731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 13417Sbill 1352469Swnj /* 1365731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1372469Swnj * we have to use a timer to watch it. 1382469Swnj */ 1392469Swnj char dz_timer; /* timer started? */ 1402469Swnj 1412469Swnj /* 1422469Swnj * Pdma structures for fast output code 1432469Swnj */ 1442645Swnj struct pdma dzpdma[NDZLINE]; 1452469Swnj 1462395Swnj char dz_speeds[] = 1472395Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 }; 14817Sbill 1492606Swnj dzprobe(reg) 1502395Swnj caddr_t reg; 1512395Swnj { 1522457Swnj register int br, cvec; 1532457Swnj register struct device *dzaddr = (struct device *)reg; 1542395Swnj 1552606Swnj #ifdef lint 1563102Swnj br = 0; cvec = br; br = cvec; 1574933Swnj dzrint(0); dzxint((struct tty *)0); 1582606Swnj #endif 1595731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1605731Sroot if (dzaddr->dzcsr & DZ_32) 1615731Sroot dzaddr->dzlnen = 1; 1625731Sroot else 1635731Sroot dzaddr->dztcr = 1; /* enable any line */ 1642457Swnj DELAY(100000); 1655731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1662457Swnj if (cvec && cvec != 0x200) 1672457Swnj cvec -= 4; 1682457Swnj return (1); 1692395Swnj } 1702395Swnj 1712606Swnj dzattach(ui) 1722976Swnj register struct uba_device *ui; 1732395Swnj { 1742395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1752395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1762606Swnj register int cntr; 1772645Swnj extern dzscan(); 1782395Swnj 1792606Swnj for (cntr = 0; cntr < 8; cntr++) { 1802606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1812395Swnj pdp->p_arg = (int)tp; 1822395Swnj pdp->p_fcn = dzxint; 1832395Swnj pdp++, tp++; 1842395Swnj } 1852567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1862627Swnj if (dz_timer == 0) { 1872627Swnj dz_timer++; 1882756Swnj timeout(dzscan, (caddr_t)0, hz); 1892627Swnj } 1902395Swnj } 1912395Swnj 19217Sbill /*ARGSUSED*/ 1932395Swnj dzopen(dev, flag) 1942395Swnj dev_t dev; 19517Sbill { 19617Sbill register struct tty *tp; 1972395Swnj register int unit; 19817Sbill 1992395Swnj unit = minor(dev); 2002395Swnj if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { 20117Sbill u.u_error = ENXIO; 20217Sbill return; 20317Sbill } 2042395Swnj tp = &dz_tty[unit]; 2052395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 20617Sbill tp->t_oproc = dzstart; 2075407Swnj tp->t_state |= TS_WOPEN; 2085407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 20917Sbill ttychars(tp); 2102469Swnj tp->t_ospeed = tp->t_ispeed = B300; 21117Sbill tp->t_flags = ODDP|EVENP|ECHO; 2125407Swnj /* tp->t_state |= TS_HUPCLS; */ 2132395Swnj dzparam(unit); 2145407Swnj } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { 21517Sbill u.u_error = EBUSY; 21617Sbill return; 21717Sbill } 2185731Sroot dzmctl(dev, DZ_ON, DMSET); 219114Sbill (void) spl5(); 2205407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 2215407Swnj tp->t_state |= TS_WOPEN; 22217Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 22317Sbill } 224114Sbill (void) spl0(); 2252395Swnj (*linesw[tp->t_line].l_open)(dev, tp); 22617Sbill } 22717Sbill 2282395Swnj /*ARGSUSED*/ 2292395Swnj dzclose(dev, flag) 2302395Swnj dev_t dev; 23117Sbill { 23217Sbill register struct tty *tp; 2332395Swnj register int unit; 2345731Sroot register struct device *dzaddr; 235*6150Ssam int dz; 23617Sbill 2372395Swnj unit = minor(dev); 2382395Swnj dz = unit >> 3; 2392395Swnj tp = &dz_tty[unit]; 24017Sbill (*linesw[tp->t_line].l_close)(tp); 2415731Sroot dzaddr = dzpdma[unit].p_addr; 2425731Sroot if (dzaddr->dzcsr&DZ_32) 2435731Sroot dzmctl(dev, DZ_BRK, DMBIC); 2445731Sroot else 2455731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 2465731Sroot if ((tp->t_state&TS_HUPCLS) || (tp->t_state&TS_ISOPEN) == 0) 2475731Sroot dzmctl(dev, DZ_OFF, DMSET); 24817Sbill ttyclose(tp); 24917Sbill } 25017Sbill 2512395Swnj dzread(dev) 2522395Swnj dev_t dev; 25317Sbill { 25417Sbill register struct tty *tp; 25517Sbill 2562395Swnj tp = &dz_tty[minor(dev)]; 25717Sbill (*linesw[tp->t_line].l_read)(tp); 25817Sbill } 25917Sbill 2602395Swnj dzwrite(dev) 2612395Swnj dev_t dev; 26217Sbill { 26317Sbill register struct tty *tp; 26417Sbill 2652395Swnj tp = &dz_tty[minor(dev)]; 26617Sbill (*linesw[tp->t_line].l_write)(tp); 26717Sbill } 26817Sbill 269119Sbill /*ARGSUSED*/ 2702395Swnj dzrint(dz) 2712395Swnj int dz; 27217Sbill { 27317Sbill register struct tty *tp; 27417Sbill register int c; 27517Sbill register struct device *dzaddr; 276119Sbill register struct tty *tp0; 2772395Swnj register int unit; 2782923Swnj int overrun = 0; 27917Sbill 2802457Swnj if ((dzact & (1<<dz)) == 0) 2812457Swnj return; 2822457Swnj unit = dz * 8; 2832457Swnj dzaddr = dzpdma[unit].p_addr; 2842457Swnj tp0 = &dz_tty[unit]; 2855731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2865731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2875731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2885731Sroot c = dzaddr->dzmtsr; 2895731Sroot tp = tp0 + (c&7); 2905731Sroot if (tp >= &dz_tty[dz_cnt]) 2915731Sroot break; 2925731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2935731Sroot dzwait(dzaddr); /* wait for them */ 2945731Sroot if (c & DZ_CD) /* carrier status change? */ 2955731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2965731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2975731Sroot wakeup((caddr_t)&tp->t_rawq); 2985731Sroot tp->t_state |= TS_CARR_ON; 2995731Sroot } 3005731Sroot } else { /* no carrier */ 3015731Sroot if (tp->t_state&TS_CARR_ON) { 3025731Sroot gsignal(tp->t_pgrp, SIGHUP); 3035731Sroot gsignal(tp->t_pgrp, SIGCONT); 3045731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3055731Sroot flushtty(tp, FREAD|FWRITE); 3065731Sroot } 3075731Sroot tp->t_state &= ~TS_CARR_ON; 3085731Sroot } 3095731Sroot } 3102457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3112457Swnj tp = tp0 + ((c>>8)&07); 3122457Swnj if (tp >= &dz_tty[dz_cnt]) 31317Sbill continue; 3145407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3152457Swnj wakeup((caddr_t)&tp->t_rawq); 3162457Swnj continue; 3172457Swnj } 3182469Swnj if (c&DZ_FE) 3192457Swnj if (tp->t_flags & RAW) 3202469Swnj c = 0; 3212457Swnj else 3222457Swnj c = tun.t_intrc; 3232923Swnj if (c&DZ_DO && overrun == 0) { 3245731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3252923Swnj overrun = 1; 3262923Swnj } 3272469Swnj if (c&DZ_PE) 3282457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3292457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 33017Sbill continue; 3312731Swnj #if NBK > 0 3322457Swnj if (tp->t_line == NETLDISC) { 3332457Swnj c &= 0177; 3342457Swnj BKINPUT(c, tp); 3352457Swnj } else 3362731Swnj #endif 3372457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 33817Sbill } 33917Sbill } 34017Sbill 34117Sbill /*ARGSUSED*/ 34217Sbill dzioctl(dev, cmd, addr, flag) 3432395Swnj dev_t dev; 3442395Swnj caddr_t addr; 34517Sbill { 34617Sbill register struct tty *tp; 3472395Swnj register int unit = minor(dev); 3482395Swnj register int dz = unit >> 3; 3495731Sroot register struct device *dzaddr; 3505731Sroot int temp; 35117Sbill 3522395Swnj tp = &dz_tty[unit]; 353114Sbill cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 354114Sbill if (cmd == 0) 355114Sbill return; 3561896Swnj if (ttioctl(tp, cmd, addr, flag)) { 35717Sbill if (cmd==TIOCSETP || cmd==TIOCSETN) 3582395Swnj dzparam(unit); 359170Sbill } else switch(cmd) { 3602395Swnj 361170Sbill case TIOCSBRK: 3625731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3635731Sroot if (dzaddr->dzcsr&DZ_32) 3645731Sroot dzmctl(dev, DZ_BRK, DMBIS); 3655731Sroot else 3665731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 367170Sbill break; 368170Sbill case TIOCCBRK: 3695731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3705731Sroot if (dzaddr->dzcsr&DZ_32) 3715731Sroot dzmctl(dev, DZ_BRK, DMBIC); 3725731Sroot else 3735731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 374170Sbill break; 375170Sbill case TIOCSDTR: 3765731Sroot dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 377170Sbill break; 378170Sbill case TIOCCDTR: 3795731Sroot dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 380170Sbill break; 3815731Sroot case TIOCMSET: 3825731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3835731Sroot u.u_error = EFAULT; 3845731Sroot else 3855731Sroot dzmctl(dev, dmtodz(temp), DMSET); 3865731Sroot break; 3875731Sroot case TIOCMBIS: 3885731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3895731Sroot u.u_error = EFAULT; 3905731Sroot else 3915731Sroot dzmctl(dev, dmtodz(temp), DMBIS); 3925731Sroot break; 3935731Sroot case TIOCMBIC: 3945731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3955731Sroot u.u_error = EFAULT; 3965731Sroot else 3975731Sroot dzmctl(dev, dmtodz(temp), DMBIC); 3985731Sroot break; 3995731Sroot case TIOCMGET: 4005731Sroot temp = dztodm(dzmctl(dev, 0, DMGET)); 4015731Sroot if (copyout((caddr_t) &temp, addr, sizeof(temp))) 4025731Sroot u.u_error = EFAULT; 4035731Sroot break; 404170Sbill default: 40517Sbill u.u_error = ENOTTY; 406170Sbill } 40717Sbill } 4085731Sroot 4095731Sroot dmtodz(bits) 4105731Sroot register int bits; 4115731Sroot { 4125731Sroot register int b; 4135731Sroot 4145731Sroot b = (bits >>1) & 0370; 4155731Sroot if (bits & DML_ST) b |= DZ_ST; 4165731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4175731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4185731Sroot if (bits & DML_LE) b |= DZ_LE; 4195731Sroot return(b); 4205731Sroot } 4215731Sroot 4225731Sroot dztodm(bits) 4235731Sroot register int bits; 4245731Sroot { 4255731Sroot register int b; 4265731Sroot 4275731Sroot b = (bits << 1) & 0360; 4285731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4295731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4305731Sroot if (bits & DZ_ST) b |= DML_ST; 4315731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4325731Sroot return(b); 4335731Sroot } 43417Sbill 4352395Swnj dzparam(unit) 4362395Swnj register int unit; 43717Sbill { 43817Sbill register struct tty *tp; 43917Sbill register struct device *dzaddr; 4402395Swnj register int lpr; 44117Sbill 4422395Swnj tp = &dz_tty[unit]; 4432395Swnj dzaddr = dzpdma[unit].p_addr; 44417Sbill dzaddr->dzcsr = DZ_IEN; 4452395Swnj dzact |= (1<<(unit>>3)); 44617Sbill if (tp->t_ispeed == 0) { 4475731Sroot dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 44817Sbill return; 44917Sbill } 4502395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4512296Swnj if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) 45217Sbill lpr |= BITS8; 45317Sbill else 45417Sbill lpr |= (BITS7|PENABLE); 45517Sbill if ((tp->t_flags & EVENP) == 0) 45617Sbill lpr |= OPAR; 4572469Swnj if (tp->t_ispeed == B110) 4582469Swnj lpr |= TWOSB; 45917Sbill dzaddr->dzlpr = lpr; 46017Sbill } 46117Sbill 46217Sbill dzxint(tp) 4632395Swnj register struct tty *tp; 46417Sbill { 46517Sbill register struct pdma *dp; 4665731Sroot register s, dz, unit; 46717Sbill 4682469Swnj s = spl5(); /* block pdma interrupts */ 4692395Swnj dp = (struct pdma *)tp->t_addr; 4705407Swnj tp->t_state &= ~TS_BUSY; 4715407Swnj if (tp->t_state & TS_FLUSH) 4725407Swnj tp->t_state &= ~TS_FLUSH; 4735731Sroot else { 474281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4755731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4765731Sroot } 47717Sbill if (tp->t_line) 47817Sbill (*linesw[tp->t_line].l_start)(tp); 47917Sbill else 48017Sbill dzstart(tp); 4815731Sroot dz = minor(tp->t_dev) >> 3; 4825731Sroot unit = minor(tp->t_dev) & 7; 4835407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4845731Sroot if (dp->p_addr->dzcsr & DZ_32) 4855731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4865731Sroot else 4875731Sroot dp->p_addr->dztcr &= ~(1<<unit); 488145Sbill splx(s); 48917Sbill } 49017Sbill 49117Sbill dzstart(tp) 4922395Swnj register struct tty *tp; 49317Sbill { 49417Sbill register struct pdma *dp; 49517Sbill register struct device *dzaddr; 4962395Swnj register int cc; 4975731Sroot int s, dz, unit; 49817Sbill 4992395Swnj dp = (struct pdma *)tp->t_addr; 50017Sbill dzaddr = dp->p_addr; 5012395Swnj s = spl5(); 5025407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 50317Sbill goto out; 5045407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5055407Swnj if (tp->t_state&TS_ASLEEP) { 5065407Swnj tp->t_state &= ~TS_ASLEEP; 5075407Swnj wakeup((caddr_t)&tp->t_outq); 5085407Swnj } 5095407Swnj if (tp->t_wsel) { 5105407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5115407Swnj tp->t_wsel = 0; 5125407Swnj tp->t_state &= ~TS_WCOLL; 5135407Swnj } 51417Sbill } 51517Sbill if (tp->t_outq.c_cc == 0) 51617Sbill goto out; 5175731Sroot if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) 51817Sbill cc = ndqb(&tp->t_outq, 0); 51917Sbill else { 52017Sbill cc = ndqb(&tp->t_outq, 0200); 52117Sbill if (cc == 0) { 52217Sbill cc = getc(&tp->t_outq); 5232469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5245407Swnj tp->t_state |= TS_TIMEOUT; 52517Sbill goto out; 52617Sbill } 52717Sbill } 5285407Swnj tp->t_state |= TS_BUSY; 52917Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 53017Sbill dp->p_end += cc; 5315731Sroot dz = minor(tp->t_dev) >> 3; 5325731Sroot unit = minor(tp->t_dev) & 7; 5335731Sroot if (dzaddr->dzcsr & DZ_32) 5345731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5355731Sroot else 5365731Sroot dzaddr->dztcr |= (1<<unit); 5372395Swnj out: 5382395Swnj splx(s); 53917Sbill } 54017Sbill 54117Sbill /* 54217Sbill * Stop output on a line. 54317Sbill */ 54417Sbill /*ARGSUSED*/ 54517Sbill dzstop(tp, flag) 5462395Swnj register struct tty *tp; 54717Sbill { 54817Sbill register struct pdma *dp; 54917Sbill register int s; 55017Sbill 5512395Swnj dp = (struct pdma *)tp->t_addr; 5522457Swnj s = spl5(); 5535407Swnj if (tp->t_state & TS_BUSY) { 55417Sbill dp->p_end = dp->p_mem; 5555407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5565407Swnj tp->t_state |= TS_FLUSH; 55717Sbill } 55817Sbill splx(s); 55917Sbill } 56017Sbill 5615731Sroot dzmctl(dev, bits, how) 5625731Sroot dev_t dev; 5635731Sroot int bits, how; 56417Sbill { 56517Sbill register struct device *dzaddr; 5665731Sroot register int unit, mbits; 5675731Sroot int b, s; 5685731Sroot 5695731Sroot unit = minor(dev); 5705731Sroot b = 1<<(unit&7); 5712395Swnj dzaddr = dzpdma[unit].p_addr; 5725731Sroot s = spl5(); 5735731Sroot if (dzaddr->dzcsr & DZ_32) { 5745731Sroot dzwait(dzaddr) 5755731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5765731Sroot dzaddr->dzlcs = unit&7; 5775731Sroot DELAY(100); 5785731Sroot dzwait(dzaddr) 5795731Sroot DELAY(100); 5805731Sroot mbits = dzaddr->dzlcs; 5815731Sroot mbits &= 0177770; 5825731Sroot } else { 5835731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5845731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5855731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5865731Sroot } 5875731Sroot switch (how) { 5885731Sroot case DMSET: 5895731Sroot mbits = bits; 5905731Sroot break; 5915731Sroot 5925731Sroot case DMBIS: 5935731Sroot mbits |= bits; 5945731Sroot break; 5955731Sroot 5965731Sroot case DMBIC: 5975731Sroot mbits &= ~bits; 5985731Sroot break; 5995731Sroot 6005731Sroot case DMGET: 6015731Sroot (void) splx(s); 6025731Sroot return(mbits); 6035731Sroot } 6045731Sroot if (dzaddr->dzcsr & DZ_32) { 6055731Sroot mbits |= DZ_ACK|(unit&7); 6065731Sroot dzaddr->dzlcs = mbits; 6075731Sroot } else { 6085731Sroot if (mbits & DZ_DTR) 6095731Sroot dzaddr->dzdtr |= b; 6105731Sroot else 6115731Sroot dzaddr->dzdtr &= ~b; 6125731Sroot } 6135731Sroot (void) splx(s); 6145731Sroot return(mbits); 61517Sbill } 61617Sbill 61717Sbill dzscan() 61817Sbill { 61917Sbill register i; 62017Sbill register struct device *dzaddr; 62117Sbill register bit; 62217Sbill register struct tty *tp; 6235731Sroot register car; 62417Sbill 62517Sbill for (i = 0; i < dz_cnt ; i++) { 62617Sbill dzaddr = dzpdma[i].p_addr; 6272627Swnj if (dzaddr == 0) 6282627Swnj continue; 62917Sbill tp = &dz_tty[i]; 63017Sbill bit = 1<<(i&07); 6315731Sroot car = 0; 6325731Sroot if (dzsoftCAR[i>>3]&bit) 6335731Sroot car = 1; 6345731Sroot else if (dzaddr->dzcsr & DZ_32) { 6355731Sroot dzaddr->dzlcs = i&07; 6365731Sroot dzwait(dzaddr); 6375731Sroot car = dzaddr->dzlcs & DZ_CD; 6385731Sroot } else 6395731Sroot car = dzaddr->dzmsr&bit; 6405731Sroot if (car) { 64117Sbill /* carrier present */ 6425407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 64317Sbill wakeup((caddr_t)&tp->t_rawq); 6445407Swnj tp->t_state |= TS_CARR_ON; 64517Sbill } 64617Sbill } else { 6475407Swnj if ((tp->t_state&TS_CARR_ON) && 6482469Swnj (tp->t_local&LNOHANG)==0) { 64917Sbill /* carrier lost */ 6505407Swnj if (tp->t_state&TS_ISOPEN) { 651170Sbill gsignal(tp->t_pgrp, SIGHUP); 652205Sbill gsignal(tp->t_pgrp, SIGCONT); 653170Sbill dzaddr->dzdtr &= ~bit; 654871Sbill flushtty(tp, FREAD|FWRITE); 655170Sbill } 6565407Swnj tp->t_state &= ~TS_CARR_ON; 65717Sbill } 65817Sbill } 65917Sbill } 6602756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 66117Sbill } 662119Sbill 663119Sbill dztimer() 664119Sbill { 6652457Swnj int dz; 666119Sbill 6672645Swnj for (dz = 0; dz < NDZ; dz++) 6682457Swnj dzrint(dz); 669119Sbill } 670281Sbill 671281Sbill /* 672281Sbill * Reset state of driver if UBA reset was necessary. 673301Sbill * Reset parameters and restart transmission on open lines. 674281Sbill */ 6752395Swnj dzreset(uban) 6762422Skre int uban; 677281Sbill { 6782395Swnj register int unit; 679281Sbill register struct tty *tp; 6802976Swnj register struct uba_device *ui; 681281Sbill 6822645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6832422Skre ui = dzinfo[unit >> 3]; 6842422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6852422Skre continue; 6862923Swnj if (unit%8 == 0) 6872923Swnj printf(" dz%d", unit>>3); 6882395Swnj tp = &dz_tty[unit]; 6895407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6902395Swnj dzparam(unit); 6915731Sroot dzmctl(unit, DZ_ON, DMSET); 6925407Swnj tp->t_state &= ~TS_BUSY; 693301Sbill dzstart(tp); 694281Sbill } 695281Sbill } 696281Sbill dztimer(); 697281Sbill } 6981562Sbill #endif 699