1*6157Ssam /* dz.c 4.35 82/03/13 */ 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" 16*6157Ssam #include "../h/proc.h" 1717Sbill #include "../h/map.h" 1817Sbill #include "../h/pte.h" 192395Swnj #include "../h/buf.h" 202567Swnj #include "../h/vm.h" 212976Swnj #include "../h/ubavar.h" 2217Sbill #include "../h/conf.h" 2317Sbill #include "../h/pdma.h" 24114Sbill #include "../h/bk.h" 25871Sbill #include "../h/file.h" 26145Sbill 272469Swnj /* 282469Swnj * Driver information for auto-configuration stuff. 292469Swnj */ 302606Swnj int dzprobe(), dzattach(), dzrint(); 312976Swnj struct uba_device *dzinfo[NDZ]; 322395Swnj u_short dzstd[] = { 0 }; 332395Swnj struct uba_driver dzdriver = 342606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 352395Swnj 362645Swnj #define NDZLINE (NDZ*8) 3717Sbill 382469Swnj /* 392469Swnj * Registers and bits 402469Swnj */ 412469Swnj 425731Sroot /* bits in dzlpr */ 435731Sroot #define BITS7 0020 445731Sroot #define BITS8 0030 455731Sroot #define TWOSB 0040 462457Swnj #define PENABLE 0100 472457Swnj #define OPAR 0200 4817Sbill 495731Sroot /* bits in dzrbuf */ 502469Swnj #define DZ_PE 010000 512469Swnj #define DZ_FE 020000 522469Swnj #define DZ_DO 040000 532469Swnj 545731Sroot /* bits in dzcsr */ 555731Sroot #define DZ_32 000001 /* DZ32 mode */ 565731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 575731Sroot #define DZ_CLR 000020 /* Reset dz */ 585731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 595731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 605731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 612469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 622469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 635731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 642469Swnj 655731Sroot /* flags for modem-control */ 665731Sroot #define DZ_ON DZ_DTR 672469Swnj #define DZ_OFF 0 685731Sroot 695731Sroot /* bits in dzlcs */ 705731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 715731Sroot #define DZ_RTS 0010000 /* Request To Send */ 725731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 735731Sroot #define DZ_BRK 0002000 /* Break */ 745731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 755731Sroot #define DZ_LE 0000400 /* Line Enable */ 765731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 775731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 785731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 795731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 805731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8117Sbill 825731Sroot /* bits in dm lsr, copied from dh.c */ 835731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 845731Sroot #define DML_RNG 0000200 /* ring */ 855731Sroot #define DML_CAR 0000100 /* carrier detect */ 865731Sroot #define DML_CTS 0000040 /* clear to send */ 875731Sroot #define DML_SR 0000020 /* secondary receive */ 885731Sroot #define DML_ST 0000010 /* secondary transmit */ 895731Sroot #define DML_RTS 0000004 /* request to send */ 905731Sroot #define DML_DTR 0000002 /* data terminal ready */ 915731Sroot #define DML_LE 0000001 /* line enable */ 925731Sroot 932469Swnj int dzstart(), dzxint(), dzdma(); 94114Sbill int ttrstrt(); 952645Swnj struct tty dz_tty[NDZLINE]; 962645Swnj int dz_cnt = { NDZLINE }; 97119Sbill int dzact; 9817Sbill 9917Sbill struct device { 1005731Sroot short dzcsr; 1015731Sroot short dzrbuf; 1025731Sroot union { 1035731Sroot struct { 1045731Sroot char dztcr0; 1055731Sroot char dzdtr0; 1065731Sroot char dztbuf0; 1075731Sroot char dzbrk0; 1085731Sroot } dz11; 1095731Sroot struct { 1105731Sroot short dzlcs0; 1115731Sroot char dztbuf0; 1125731Sroot char dzlnen0; 1135731Sroot } dz32; 1145731Sroot } dzun; 11517Sbill }; 1165731Sroot 1175731Sroot #define dzlpr dzrbuf 1185731Sroot #define dzmsr dzun.dz11.dzbrk0 1195731Sroot #define dztcr dzun.dz11.dztcr0 1205731Sroot #define dzdtr dzun.dz11.dzdtr0 1215731Sroot #define dztbuf dzun.dz11.dztbuf0 1225731Sroot #define dzlcs dzun.dz32.dzlcs0 1235731Sroot #define dzbrk dzmsr 1245731Sroot #define dzlnen dzun.dz32.dzlnen0 1255731Sroot #define dzmtsr dzun.dz32.dztbuf0; 1265731Sroot 1275731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1285731Sroot 1292469Swnj /* 1302469Swnj * Software copy of dzbrk since it isn't readable 1312469Swnj */ 1322645Swnj char dz_brk[NDZ]; 1332645Swnj char dzsoftCAR[NDZ]; 1345731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 13517Sbill 1362469Swnj /* 1375731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1382469Swnj * we have to use a timer to watch it. 1392469Swnj */ 1402469Swnj char dz_timer; /* timer started? */ 1412469Swnj 1422469Swnj /* 1432469Swnj * Pdma structures for fast output code 1442469Swnj */ 1452645Swnj struct pdma dzpdma[NDZLINE]; 1462469Swnj 1472395Swnj char dz_speeds[] = 1482395Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 }; 14917Sbill 1502606Swnj dzprobe(reg) 1512395Swnj caddr_t reg; 1522395Swnj { 1532457Swnj register int br, cvec; 1542457Swnj register struct device *dzaddr = (struct device *)reg; 1552395Swnj 1562606Swnj #ifdef lint 1573102Swnj br = 0; cvec = br; br = cvec; 1584933Swnj dzrint(0); dzxint((struct tty *)0); 1592606Swnj #endif 1605731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1615731Sroot if (dzaddr->dzcsr & DZ_32) 1625731Sroot dzaddr->dzlnen = 1; 1635731Sroot else 1645731Sroot dzaddr->dztcr = 1; /* enable any line */ 1652457Swnj DELAY(100000); 1665731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1672457Swnj if (cvec && cvec != 0x200) 1682457Swnj cvec -= 4; 1692457Swnj return (1); 1702395Swnj } 1712395Swnj 1722606Swnj dzattach(ui) 1732976Swnj register struct uba_device *ui; 1742395Swnj { 1752395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1762395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1772606Swnj register int cntr; 1782645Swnj extern dzscan(); 1792395Swnj 1802606Swnj for (cntr = 0; cntr < 8; cntr++) { 1812606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1822395Swnj pdp->p_arg = (int)tp; 1832395Swnj pdp->p_fcn = dzxint; 1842395Swnj pdp++, tp++; 1852395Swnj } 1862567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1872627Swnj if (dz_timer == 0) { 1882627Swnj dz_timer++; 1892756Swnj timeout(dzscan, (caddr_t)0, hz); 1902627Swnj } 1912395Swnj } 1922395Swnj 19317Sbill /*ARGSUSED*/ 1942395Swnj dzopen(dev, flag) 1952395Swnj dev_t dev; 19617Sbill { 19717Sbill register struct tty *tp; 1982395Swnj register int unit; 19917Sbill 2002395Swnj unit = minor(dev); 2012395Swnj if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { 20217Sbill u.u_error = ENXIO; 20317Sbill return; 20417Sbill } 2052395Swnj tp = &dz_tty[unit]; 2062395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 20717Sbill tp->t_oproc = dzstart; 2085407Swnj tp->t_state |= TS_WOPEN; 2095407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 21017Sbill ttychars(tp); 2112469Swnj tp->t_ospeed = tp->t_ispeed = B300; 21217Sbill tp->t_flags = ODDP|EVENP|ECHO; 2135407Swnj /* tp->t_state |= TS_HUPCLS; */ 2142395Swnj dzparam(unit); 2155407Swnj } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { 21617Sbill u.u_error = EBUSY; 21717Sbill return; 21817Sbill } 219*6157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 220114Sbill (void) spl5(); 2215407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 2225407Swnj tp->t_state |= TS_WOPEN; 22317Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 22417Sbill } 225114Sbill (void) spl0(); 2262395Swnj (*linesw[tp->t_line].l_open)(dev, tp); 22717Sbill } 22817Sbill 2292395Swnj /*ARGSUSED*/ 2302395Swnj dzclose(dev, flag) 2312395Swnj dev_t dev; 23217Sbill { 23317Sbill register struct tty *tp; 2342395Swnj register int unit; 2355731Sroot register struct device *dzaddr; 2366150Ssam int dz; 23717Sbill 2382395Swnj unit = minor(dev); 2392395Swnj dz = unit >> 3; 2402395Swnj tp = &dz_tty[unit]; 24117Sbill (*linesw[tp->t_line].l_close)(tp); 2425731Sroot dzaddr = dzpdma[unit].p_addr; 2435731Sroot if (dzaddr->dzcsr&DZ_32) 244*6157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 2455731Sroot else 2465731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 2475731Sroot if ((tp->t_state&TS_HUPCLS) || (tp->t_state&TS_ISOPEN) == 0) 248*6157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 24917Sbill ttyclose(tp); 25017Sbill } 25117Sbill 2522395Swnj dzread(dev) 2532395Swnj dev_t dev; 25417Sbill { 25517Sbill register struct tty *tp; 25617Sbill 2572395Swnj tp = &dz_tty[minor(dev)]; 25817Sbill (*linesw[tp->t_line].l_read)(tp); 25917Sbill } 26017Sbill 2612395Swnj dzwrite(dev) 2622395Swnj dev_t dev; 26317Sbill { 26417Sbill register struct tty *tp; 26517Sbill 2662395Swnj tp = &dz_tty[minor(dev)]; 26717Sbill (*linesw[tp->t_line].l_write)(tp); 26817Sbill } 26917Sbill 270119Sbill /*ARGSUSED*/ 2712395Swnj dzrint(dz) 2722395Swnj int dz; 27317Sbill { 27417Sbill register struct tty *tp; 27517Sbill register int c; 27617Sbill register struct device *dzaddr; 277119Sbill register struct tty *tp0; 2782395Swnj register int unit; 2792923Swnj int overrun = 0; 28017Sbill 2812457Swnj if ((dzact & (1<<dz)) == 0) 2822457Swnj return; 2832457Swnj unit = dz * 8; 2842457Swnj dzaddr = dzpdma[unit].p_addr; 2852457Swnj tp0 = &dz_tty[unit]; 2865731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2875731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2885731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2895731Sroot c = dzaddr->dzmtsr; 2905731Sroot tp = tp0 + (c&7); 2915731Sroot if (tp >= &dz_tty[dz_cnt]) 2925731Sroot break; 2935731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 2945731Sroot dzwait(dzaddr); /* wait for them */ 2955731Sroot if (c & DZ_CD) /* carrier status change? */ 2965731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 2975731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 2985731Sroot wakeup((caddr_t)&tp->t_rawq); 2995731Sroot tp->t_state |= TS_CARR_ON; 3005731Sroot } 3015731Sroot } else { /* no carrier */ 3025731Sroot if (tp->t_state&TS_CARR_ON) { 3035731Sroot gsignal(tp->t_pgrp, SIGHUP); 3045731Sroot gsignal(tp->t_pgrp, SIGCONT); 3055731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3065731Sroot flushtty(tp, FREAD|FWRITE); 3075731Sroot } 3085731Sroot tp->t_state &= ~TS_CARR_ON; 3095731Sroot } 3105731Sroot } 3112457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3122457Swnj tp = tp0 + ((c>>8)&07); 3132457Swnj if (tp >= &dz_tty[dz_cnt]) 31417Sbill continue; 3155407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3162457Swnj wakeup((caddr_t)&tp->t_rawq); 3172457Swnj continue; 3182457Swnj } 3192469Swnj if (c&DZ_FE) 3202457Swnj if (tp->t_flags & RAW) 3212469Swnj c = 0; 3222457Swnj else 3232457Swnj c = tun.t_intrc; 3242923Swnj if (c&DZ_DO && overrun == 0) { 3255731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3262923Swnj overrun = 1; 3272923Swnj } 3282469Swnj if (c&DZ_PE) 3292457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3302457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 33117Sbill continue; 3322731Swnj #if NBK > 0 3332457Swnj if (tp->t_line == NETLDISC) { 3342457Swnj c &= 0177; 3352457Swnj BKINPUT(c, tp); 3362457Swnj } else 3372731Swnj #endif 3382457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 33917Sbill } 34017Sbill } 34117Sbill 34217Sbill /*ARGSUSED*/ 34317Sbill dzioctl(dev, cmd, addr, flag) 3442395Swnj dev_t dev; 3452395Swnj caddr_t addr; 34617Sbill { 34717Sbill register struct tty *tp; 3482395Swnj register int unit = minor(dev); 3492395Swnj register int dz = unit >> 3; 3505731Sroot register struct device *dzaddr; 3515731Sroot int temp; 35217Sbill 3532395Swnj tp = &dz_tty[unit]; 354114Sbill cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); 355114Sbill if (cmd == 0) 356114Sbill return; 3571896Swnj if (ttioctl(tp, cmd, addr, flag)) { 35817Sbill if (cmd==TIOCSETP || cmd==TIOCSETN) 3592395Swnj dzparam(unit); 360170Sbill } else switch(cmd) { 3612395Swnj 362170Sbill case TIOCSBRK: 3635731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3645731Sroot if (dzaddr->dzcsr&DZ_32) 365*6157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3665731Sroot else 3675731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 368170Sbill break; 369170Sbill case TIOCCBRK: 3705731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3715731Sroot if (dzaddr->dzcsr&DZ_32) 372*6157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3735731Sroot else 3745731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 375170Sbill break; 376170Sbill case TIOCSDTR: 377*6157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 378170Sbill break; 379170Sbill case TIOCCDTR: 380*6157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 381170Sbill break; 3825731Sroot case TIOCMSET: 3835731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3845731Sroot u.u_error = EFAULT; 3855731Sroot else 386*6157Ssam (void) dzmctl(dev, dmtodz(temp), DMSET); 3875731Sroot break; 3885731Sroot case TIOCMBIS: 3895731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3905731Sroot u.u_error = EFAULT; 3915731Sroot else 392*6157Ssam (void) dzmctl(dev, dmtodz(temp), DMBIS); 3935731Sroot break; 3945731Sroot case TIOCMBIC: 3955731Sroot if (copyin(addr, (caddr_t) &temp, sizeof(temp))) 3965731Sroot u.u_error = EFAULT; 3975731Sroot else 398*6157Ssam (void) dzmctl(dev, dmtodz(temp), DMBIC); 3995731Sroot break; 4005731Sroot case TIOCMGET: 4015731Sroot temp = dztodm(dzmctl(dev, 0, DMGET)); 4025731Sroot if (copyout((caddr_t) &temp, addr, sizeof(temp))) 4035731Sroot u.u_error = EFAULT; 4045731Sroot break; 405170Sbill default: 40617Sbill u.u_error = ENOTTY; 407170Sbill } 40817Sbill } 4095731Sroot 4105731Sroot dmtodz(bits) 4115731Sroot register int bits; 4125731Sroot { 4135731Sroot register int b; 4145731Sroot 4155731Sroot b = (bits >>1) & 0370; 4165731Sroot if (bits & DML_ST) b |= DZ_ST; 4175731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4185731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4195731Sroot if (bits & DML_LE) b |= DZ_LE; 4205731Sroot return(b); 4215731Sroot } 4225731Sroot 4235731Sroot dztodm(bits) 4245731Sroot register int bits; 4255731Sroot { 4265731Sroot register int b; 4275731Sroot 4285731Sroot b = (bits << 1) & 0360; 4295731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4305731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4315731Sroot if (bits & DZ_ST) b |= DML_ST; 4325731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4335731Sroot return(b); 4345731Sroot } 43517Sbill 4362395Swnj dzparam(unit) 4372395Swnj register int unit; 43817Sbill { 43917Sbill register struct tty *tp; 44017Sbill register struct device *dzaddr; 4412395Swnj register int lpr; 44217Sbill 4432395Swnj tp = &dz_tty[unit]; 4442395Swnj dzaddr = dzpdma[unit].p_addr; 44517Sbill dzaddr->dzcsr = DZ_IEN; 4462395Swnj dzact |= (1<<(unit>>3)); 44717Sbill if (tp->t_ispeed == 0) { 448*6157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 44917Sbill return; 45017Sbill } 4512395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4522296Swnj if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) 45317Sbill lpr |= BITS8; 45417Sbill else 45517Sbill lpr |= (BITS7|PENABLE); 45617Sbill if ((tp->t_flags & EVENP) == 0) 45717Sbill lpr |= OPAR; 4582469Swnj if (tp->t_ispeed == B110) 4592469Swnj lpr |= TWOSB; 46017Sbill dzaddr->dzlpr = lpr; 46117Sbill } 46217Sbill 46317Sbill dzxint(tp) 4642395Swnj register struct tty *tp; 46517Sbill { 46617Sbill register struct pdma *dp; 4675731Sroot register s, dz, unit; 46817Sbill 4692469Swnj s = spl5(); /* block pdma interrupts */ 4702395Swnj dp = (struct pdma *)tp->t_addr; 4715407Swnj tp->t_state &= ~TS_BUSY; 4725407Swnj if (tp->t_state & TS_FLUSH) 4735407Swnj tp->t_state &= ~TS_FLUSH; 4745731Sroot else { 475281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4765731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4775731Sroot } 47817Sbill if (tp->t_line) 47917Sbill (*linesw[tp->t_line].l_start)(tp); 48017Sbill else 48117Sbill dzstart(tp); 4825731Sroot dz = minor(tp->t_dev) >> 3; 4835731Sroot unit = minor(tp->t_dev) & 7; 4845407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4855731Sroot if (dp->p_addr->dzcsr & DZ_32) 4865731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4875731Sroot else 4885731Sroot dp->p_addr->dztcr &= ~(1<<unit); 489145Sbill splx(s); 49017Sbill } 49117Sbill 49217Sbill dzstart(tp) 4932395Swnj register struct tty *tp; 49417Sbill { 49517Sbill register struct pdma *dp; 49617Sbill register struct device *dzaddr; 4972395Swnj register int cc; 4985731Sroot int s, dz, unit; 49917Sbill 5002395Swnj dp = (struct pdma *)tp->t_addr; 50117Sbill dzaddr = dp->p_addr; 5022395Swnj s = spl5(); 5035407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 50417Sbill goto out; 5055407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5065407Swnj if (tp->t_state&TS_ASLEEP) { 5075407Swnj tp->t_state &= ~TS_ASLEEP; 5085407Swnj wakeup((caddr_t)&tp->t_outq); 5095407Swnj } 5105407Swnj if (tp->t_wsel) { 5115407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5125407Swnj tp->t_wsel = 0; 5135407Swnj tp->t_state &= ~TS_WCOLL; 5145407Swnj } 51517Sbill } 51617Sbill if (tp->t_outq.c_cc == 0) 51717Sbill goto out; 5185731Sroot if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) 51917Sbill cc = ndqb(&tp->t_outq, 0); 52017Sbill else { 52117Sbill cc = ndqb(&tp->t_outq, 0200); 52217Sbill if (cc == 0) { 52317Sbill cc = getc(&tp->t_outq); 5242469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5255407Swnj tp->t_state |= TS_TIMEOUT; 52617Sbill goto out; 52717Sbill } 52817Sbill } 5295407Swnj tp->t_state |= TS_BUSY; 53017Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 53117Sbill dp->p_end += cc; 5325731Sroot dz = minor(tp->t_dev) >> 3; 5335731Sroot unit = minor(tp->t_dev) & 7; 5345731Sroot if (dzaddr->dzcsr & DZ_32) 5355731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5365731Sroot else 5375731Sroot dzaddr->dztcr |= (1<<unit); 5382395Swnj out: 5392395Swnj splx(s); 54017Sbill } 54117Sbill 54217Sbill /* 54317Sbill * Stop output on a line. 54417Sbill */ 54517Sbill /*ARGSUSED*/ 54617Sbill dzstop(tp, flag) 5472395Swnj register struct tty *tp; 54817Sbill { 54917Sbill register struct pdma *dp; 55017Sbill register int s; 55117Sbill 5522395Swnj dp = (struct pdma *)tp->t_addr; 5532457Swnj s = spl5(); 5545407Swnj if (tp->t_state & TS_BUSY) { 55517Sbill dp->p_end = dp->p_mem; 5565407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5575407Swnj tp->t_state |= TS_FLUSH; 55817Sbill } 55917Sbill splx(s); 56017Sbill } 56117Sbill 5625731Sroot dzmctl(dev, bits, how) 5635731Sroot dev_t dev; 5645731Sroot int bits, how; 56517Sbill { 56617Sbill register struct device *dzaddr; 5675731Sroot register int unit, mbits; 5685731Sroot int b, s; 5695731Sroot 5705731Sroot unit = minor(dev); 5715731Sroot b = 1<<(unit&7); 5722395Swnj dzaddr = dzpdma[unit].p_addr; 5735731Sroot s = spl5(); 5745731Sroot if (dzaddr->dzcsr & DZ_32) { 5755731Sroot dzwait(dzaddr) 5765731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5775731Sroot dzaddr->dzlcs = unit&7; 5785731Sroot DELAY(100); 5795731Sroot dzwait(dzaddr) 5805731Sroot DELAY(100); 5815731Sroot mbits = dzaddr->dzlcs; 5825731Sroot mbits &= 0177770; 5835731Sroot } else { 5845731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5855731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5865731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5875731Sroot } 5885731Sroot switch (how) { 5895731Sroot case DMSET: 5905731Sroot mbits = bits; 5915731Sroot break; 5925731Sroot 5935731Sroot case DMBIS: 5945731Sroot mbits |= bits; 5955731Sroot break; 5965731Sroot 5975731Sroot case DMBIC: 5985731Sroot mbits &= ~bits; 5995731Sroot break; 6005731Sroot 6015731Sroot case DMGET: 6025731Sroot (void) splx(s); 6035731Sroot return(mbits); 6045731Sroot } 6055731Sroot if (dzaddr->dzcsr & DZ_32) { 6065731Sroot mbits |= DZ_ACK|(unit&7); 6075731Sroot dzaddr->dzlcs = mbits; 6085731Sroot } else { 6095731Sroot if (mbits & DZ_DTR) 6105731Sroot dzaddr->dzdtr |= b; 6115731Sroot else 6125731Sroot dzaddr->dzdtr &= ~b; 6135731Sroot } 6145731Sroot (void) splx(s); 6155731Sroot return(mbits); 61617Sbill } 61717Sbill 61817Sbill dzscan() 61917Sbill { 62017Sbill register i; 62117Sbill register struct device *dzaddr; 62217Sbill register bit; 62317Sbill register struct tty *tp; 6245731Sroot register car; 62517Sbill 62617Sbill for (i = 0; i < dz_cnt ; i++) { 62717Sbill dzaddr = dzpdma[i].p_addr; 6282627Swnj if (dzaddr == 0) 6292627Swnj continue; 63017Sbill tp = &dz_tty[i]; 63117Sbill bit = 1<<(i&07); 6325731Sroot car = 0; 6335731Sroot if (dzsoftCAR[i>>3]&bit) 6345731Sroot car = 1; 6355731Sroot else if (dzaddr->dzcsr & DZ_32) { 6365731Sroot dzaddr->dzlcs = i&07; 6375731Sroot dzwait(dzaddr); 6385731Sroot car = dzaddr->dzlcs & DZ_CD; 6395731Sroot } else 6405731Sroot car = dzaddr->dzmsr&bit; 6415731Sroot if (car) { 64217Sbill /* carrier present */ 6435407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 64417Sbill wakeup((caddr_t)&tp->t_rawq); 6455407Swnj tp->t_state |= TS_CARR_ON; 64617Sbill } 64717Sbill } else { 6485407Swnj if ((tp->t_state&TS_CARR_ON) && 6492469Swnj (tp->t_local&LNOHANG)==0) { 65017Sbill /* carrier lost */ 6515407Swnj if (tp->t_state&TS_ISOPEN) { 652170Sbill gsignal(tp->t_pgrp, SIGHUP); 653205Sbill gsignal(tp->t_pgrp, SIGCONT); 654170Sbill dzaddr->dzdtr &= ~bit; 655871Sbill flushtty(tp, FREAD|FWRITE); 656170Sbill } 6575407Swnj tp->t_state &= ~TS_CARR_ON; 65817Sbill } 65917Sbill } 66017Sbill } 6612756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 66217Sbill } 663119Sbill 664119Sbill dztimer() 665119Sbill { 6662457Swnj int dz; 667119Sbill 6682645Swnj for (dz = 0; dz < NDZ; dz++) 6692457Swnj dzrint(dz); 670119Sbill } 671281Sbill 672281Sbill /* 673281Sbill * Reset state of driver if UBA reset was necessary. 674301Sbill * Reset parameters and restart transmission on open lines. 675281Sbill */ 6762395Swnj dzreset(uban) 6772422Skre int uban; 678281Sbill { 6792395Swnj register int unit; 680281Sbill register struct tty *tp; 6812976Swnj register struct uba_device *ui; 682281Sbill 6832645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6842422Skre ui = dzinfo[unit >> 3]; 6852422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6862422Skre continue; 6872923Swnj if (unit%8 == 0) 6882923Swnj printf(" dz%d", unit>>3); 6892395Swnj tp = &dz_tty[unit]; 6905407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 6912395Swnj dzparam(unit); 692*6157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 6935407Swnj tp->t_state &= ~TS_BUSY; 694301Sbill dzstart(tp); 695281Sbill } 696281Sbill } 697281Sbill dztimer(); 698281Sbill } 6991562Sbill #endif 700