1*7727Sroot /* dz.c 4.41 82/08/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" 166157Ssam #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" 26*7727Sroot #include "../h/uio.h" 27145Sbill 282469Swnj /* 292469Swnj * Driver information for auto-configuration stuff. 302469Swnj */ 312606Swnj int dzprobe(), dzattach(), dzrint(); 322976Swnj struct uba_device *dzinfo[NDZ]; 332395Swnj u_short dzstd[] = { 0 }; 342395Swnj struct uba_driver dzdriver = 352606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 362395Swnj 372645Swnj #define NDZLINE (NDZ*8) 3817Sbill 392469Swnj /* 402469Swnj * Registers and bits 412469Swnj */ 422469Swnj 435731Sroot /* bits in dzlpr */ 445731Sroot #define BITS7 0020 455731Sroot #define BITS8 0030 465731Sroot #define TWOSB 0040 472457Swnj #define PENABLE 0100 482457Swnj #define OPAR 0200 4917Sbill 505731Sroot /* bits in dzrbuf */ 512469Swnj #define DZ_PE 010000 522469Swnj #define DZ_FE 020000 532469Swnj #define DZ_DO 040000 542469Swnj 555731Sroot /* bits in dzcsr */ 565731Sroot #define DZ_32 000001 /* DZ32 mode */ 575731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 585731Sroot #define DZ_CLR 000020 /* Reset dz */ 595731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 605731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 615731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 622469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 632469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 645731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 652469Swnj 665731Sroot /* flags for modem-control */ 675731Sroot #define DZ_ON DZ_DTR 682469Swnj #define DZ_OFF 0 695731Sroot 705731Sroot /* bits in dzlcs */ 715731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 725731Sroot #define DZ_RTS 0010000 /* Request To Send */ 735731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 745731Sroot #define DZ_BRK 0002000 /* Break */ 755731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 765731Sroot #define DZ_LE 0000400 /* Line Enable */ 775731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 785731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 795731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 805731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 815731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8217Sbill 835731Sroot /* bits in dm lsr, copied from dh.c */ 845731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 855731Sroot #define DML_RNG 0000200 /* ring */ 865731Sroot #define DML_CAR 0000100 /* carrier detect */ 875731Sroot #define DML_CTS 0000040 /* clear to send */ 885731Sroot #define DML_SR 0000020 /* secondary receive */ 895731Sroot #define DML_ST 0000010 /* secondary transmit */ 905731Sroot #define DML_RTS 0000004 /* request to send */ 915731Sroot #define DML_DTR 0000002 /* data terminal ready */ 925731Sroot #define DML_LE 0000001 /* line enable */ 935731Sroot 942469Swnj int dzstart(), dzxint(), dzdma(); 95114Sbill int ttrstrt(); 962645Swnj struct tty dz_tty[NDZLINE]; 972645Swnj int dz_cnt = { NDZLINE }; 98119Sbill int dzact; 9917Sbill 10017Sbill struct device { 1015731Sroot short dzcsr; 1025731Sroot short dzrbuf; 1035731Sroot union { 1045731Sroot struct { 1055731Sroot char dztcr0; 1065731Sroot char dzdtr0; 1075731Sroot char dztbuf0; 1085731Sroot char dzbrk0; 1095731Sroot } dz11; 1105731Sroot struct { 1115731Sroot short dzlcs0; 1125731Sroot char dztbuf0; 1135731Sroot char dzlnen0; 1145731Sroot } dz32; 1155731Sroot } dzun; 11617Sbill }; 1175731Sroot 1185731Sroot #define dzlpr dzrbuf 1195731Sroot #define dzmsr dzun.dz11.dzbrk0 1205731Sroot #define dztcr dzun.dz11.dztcr0 1215731Sroot #define dzdtr dzun.dz11.dzdtr0 1225731Sroot #define dztbuf dzun.dz11.dztbuf0 1235731Sroot #define dzlcs dzun.dz32.dzlcs0 1245731Sroot #define dzbrk dzmsr 1255731Sroot #define dzlnen dzun.dz32.dzlnen0 1267406Skre #define dzmtsr dzun.dz32.dztbuf0 1275731Sroot 1285731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1295731Sroot 1302469Swnj /* 1312469Swnj * Software copy of dzbrk since it isn't readable 1322469Swnj */ 1332645Swnj char dz_brk[NDZ]; 1342645Swnj char dzsoftCAR[NDZ]; 1355731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 13617Sbill 1372469Swnj /* 1385731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1392469Swnj * we have to use a timer to watch it. 1402469Swnj */ 1412469Swnj char dz_timer; /* timer started? */ 1422469Swnj 1432469Swnj /* 1442469Swnj * Pdma structures for fast output code 1452469Swnj */ 1462645Swnj struct pdma dzpdma[NDZLINE]; 1472469Swnj 1482395Swnj char dz_speeds[] = 1496814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 15017Sbill 1516616Ssam #ifndef PORTSELECTOR 1526616Ssam #define ISPEED B300 1536616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 1546616Ssam #else 1556616Ssam #define ISPEED B4800 1566616Ssam #define IFLAGS (EVENP|ODDP) 1576616Ssam #endif 1586616Ssam 1592606Swnj dzprobe(reg) 1602395Swnj caddr_t reg; 1612395Swnj { 1622457Swnj register int br, cvec; 1632457Swnj register struct device *dzaddr = (struct device *)reg; 1642395Swnj 1652606Swnj #ifdef lint 1663102Swnj br = 0; cvec = br; br = cvec; 1674933Swnj dzrint(0); dzxint((struct tty *)0); 1682606Swnj #endif 1695731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1705731Sroot if (dzaddr->dzcsr & DZ_32) 1715731Sroot dzaddr->dzlnen = 1; 1725731Sroot else 1735731Sroot dzaddr->dztcr = 1; /* enable any line */ 1742457Swnj DELAY(100000); 1755731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1762457Swnj if (cvec && cvec != 0x200) 1772457Swnj cvec -= 4; 1787406Skre return (sizeof (struct device)); 1792395Swnj } 1802395Swnj 1812606Swnj dzattach(ui) 1822976Swnj register struct uba_device *ui; 1832395Swnj { 1842395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1852395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1862606Swnj register int cntr; 1872645Swnj extern dzscan(); 1882395Swnj 1892606Swnj for (cntr = 0; cntr < 8; cntr++) { 1902606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1912395Swnj pdp->p_arg = (int)tp; 1922395Swnj pdp->p_fcn = dzxint; 1932395Swnj pdp++, tp++; 1942395Swnj } 1952567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1962627Swnj if (dz_timer == 0) { 1972627Swnj dz_timer++; 1982756Swnj timeout(dzscan, (caddr_t)0, hz); 1992627Swnj } 2002395Swnj } 2012395Swnj 20217Sbill /*ARGSUSED*/ 2032395Swnj dzopen(dev, flag) 2042395Swnj dev_t dev; 20517Sbill { 20617Sbill register struct tty *tp; 2072395Swnj register int unit; 20817Sbill 2092395Swnj unit = minor(dev); 2102395Swnj if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { 21117Sbill u.u_error = ENXIO; 21217Sbill return; 21317Sbill } 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); 2245407Swnj } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { 22517Sbill u.u_error = EBUSY; 22617Sbill return; 22717Sbill } 2286157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 229114Sbill (void) spl5(); 2305407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 2315407Swnj tp->t_state |= TS_WOPEN; 23217Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 23317Sbill } 234114Sbill (void) spl0(); 2352395Swnj (*linesw[tp->t_line].l_open)(dev, tp); 23617Sbill } 23717Sbill 2382395Swnj /*ARGSUSED*/ 2392395Swnj dzclose(dev, flag) 2402395Swnj dev_t dev; 24117Sbill { 24217Sbill register struct tty *tp; 2432395Swnj register int unit; 2445731Sroot register struct device *dzaddr; 2456150Ssam int dz; 24617Sbill 2472395Swnj unit = minor(dev); 2482395Swnj dz = unit >> 3; 2492395Swnj tp = &dz_tty[unit]; 25017Sbill (*linesw[tp->t_line].l_close)(tp); 2515731Sroot dzaddr = dzpdma[unit].p_addr; 2525731Sroot if (dzaddr->dzcsr&DZ_32) 2536157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 2545731Sroot else 2555731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 2566842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 2576157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 25817Sbill ttyclose(tp); 25917Sbill } 26017Sbill 261*7727Sroot dzread(dev, uio) 2622395Swnj dev_t dev; 263*7727Sroot struct uio *uio; 26417Sbill { 26517Sbill register struct tty *tp; 26617Sbill 2672395Swnj tp = &dz_tty[minor(dev)]; 268*7727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 26917Sbill } 27017Sbill 2712395Swnj dzwrite(dev) 2722395Swnj dev_t dev; 27317Sbill { 27417Sbill register struct tty *tp; 27517Sbill 2762395Swnj tp = &dz_tty[minor(dev)]; 27717Sbill (*linesw[tp->t_line].l_write)(tp); 27817Sbill } 27917Sbill 280119Sbill /*ARGSUSED*/ 2812395Swnj dzrint(dz) 2822395Swnj int dz; 28317Sbill { 28417Sbill register struct tty *tp; 28517Sbill register int c; 28617Sbill register struct device *dzaddr; 287119Sbill register struct tty *tp0; 2882395Swnj register int unit; 2892923Swnj int overrun = 0; 29017Sbill 2912457Swnj if ((dzact & (1<<dz)) == 0) 2922457Swnj return; 2932457Swnj unit = dz * 8; 2942457Swnj dzaddr = dzpdma[unit].p_addr; 2952457Swnj tp0 = &dz_tty[unit]; 2965731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2975731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2985731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 2995731Sroot c = dzaddr->dzmtsr; 3005731Sroot tp = tp0 + (c&7); 3015731Sroot if (tp >= &dz_tty[dz_cnt]) 3025731Sroot break; 3035731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 3045731Sroot dzwait(dzaddr); /* wait for them */ 3055731Sroot if (c & DZ_CD) /* carrier status change? */ 3065731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 3075731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 3085731Sroot wakeup((caddr_t)&tp->t_rawq); 3095731Sroot tp->t_state |= TS_CARR_ON; 3105731Sroot } 3115731Sroot } else { /* no carrier */ 3125731Sroot if (tp->t_state&TS_CARR_ON) { 3135731Sroot gsignal(tp->t_pgrp, SIGHUP); 3145731Sroot gsignal(tp->t_pgrp, SIGCONT); 3155731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3165731Sroot flushtty(tp, FREAD|FWRITE); 3175731Sroot } 3185731Sroot tp->t_state &= ~TS_CARR_ON; 3195731Sroot } 3205731Sroot } 3212457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3222457Swnj tp = tp0 + ((c>>8)&07); 3232457Swnj if (tp >= &dz_tty[dz_cnt]) 32417Sbill continue; 3255407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3262457Swnj wakeup((caddr_t)&tp->t_rawq); 3276616Ssam #ifdef PORTSELECTOR 3286616Ssam if ((tp->t_state&TS_WOPEN) == 0) 3296616Ssam #endif 3302457Swnj continue; 3312457Swnj } 3322469Swnj if (c&DZ_FE) 3332457Swnj if (tp->t_flags & RAW) 3342469Swnj c = 0; 3352457Swnj else 3362457Swnj c = tun.t_intrc; 3372923Swnj if (c&DZ_DO && overrun == 0) { 3385731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3392923Swnj overrun = 1; 3402923Swnj } 3412469Swnj if (c&DZ_PE) 3422457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3432457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 34417Sbill continue; 3452731Swnj #if NBK > 0 3462457Swnj if (tp->t_line == NETLDISC) { 3472457Swnj c &= 0177; 3482457Swnj BKINPUT(c, tp); 3492457Swnj } else 3502731Swnj #endif 3512457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 35217Sbill } 35317Sbill } 35417Sbill 35517Sbill /*ARGSUSED*/ 3567631Ssam dzioctl(dev, cmd, data, flag) 3572395Swnj dev_t dev; 3587631Ssam caddr_t data; 35917Sbill { 36017Sbill register struct tty *tp; 3612395Swnj register int unit = minor(dev); 3622395Swnj register int dz = unit >> 3; 3635731Sroot register struct device *dzaddr; 36417Sbill 3652395Swnj tp = &dz_tty[unit]; 3667631Ssam cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 367114Sbill if (cmd == 0) 368114Sbill return; 3697631Ssam if (ttioctl(tp, cmd, data, flag)) { 3707631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 3712395Swnj dzparam(unit); 372170Sbill } else switch(cmd) { 3732395Swnj 374170Sbill case TIOCSBRK: 3755731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3765731Sroot if (dzaddr->dzcsr&DZ_32) 3776157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3785731Sroot else 3795731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 380170Sbill break; 3817631Ssam 382170Sbill case TIOCCBRK: 3835731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3845731Sroot if (dzaddr->dzcsr&DZ_32) 3856157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3865731Sroot else 3875731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 388170Sbill break; 3897631Ssam 390170Sbill case TIOCSDTR: 3916157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 392170Sbill break; 3937631Ssam 394170Sbill case TIOCCDTR: 3956157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 396170Sbill break; 3977631Ssam 3985731Sroot case TIOCMSET: 3997631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 4005731Sroot break; 4017631Ssam 4025731Sroot case TIOCMBIS: 4037631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 4045731Sroot break; 4057631Ssam 4065731Sroot case TIOCMBIC: 4077631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 4085731Sroot break; 4097631Ssam 4105731Sroot case TIOCMGET: 4117631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 4125731Sroot break; 4137631Ssam 414170Sbill default: 41517Sbill u.u_error = ENOTTY; 416170Sbill } 41717Sbill } 4185731Sroot 4195731Sroot dmtodz(bits) 4205731Sroot register int bits; 4215731Sroot { 4225731Sroot register int b; 4235731Sroot 4245731Sroot b = (bits >>1) & 0370; 4255731Sroot if (bits & DML_ST) b |= DZ_ST; 4265731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4275731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4285731Sroot if (bits & DML_LE) b |= DZ_LE; 4295731Sroot return(b); 4305731Sroot } 4315731Sroot 4325731Sroot dztodm(bits) 4335731Sroot register int bits; 4345731Sroot { 4355731Sroot register int b; 4365731Sroot 4375731Sroot b = (bits << 1) & 0360; 4385731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4395731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4405731Sroot if (bits & DZ_ST) b |= DML_ST; 4415731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4425731Sroot return(b); 4435731Sroot } 44417Sbill 4452395Swnj dzparam(unit) 4462395Swnj register int unit; 44717Sbill { 44817Sbill register struct tty *tp; 44917Sbill register struct device *dzaddr; 4502395Swnj register int lpr; 45117Sbill 4522395Swnj tp = &dz_tty[unit]; 4532395Swnj dzaddr = dzpdma[unit].p_addr; 45417Sbill dzaddr->dzcsr = DZ_IEN; 4552395Swnj dzact |= (1<<(unit>>3)); 45617Sbill if (tp->t_ispeed == 0) { 4576157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 45817Sbill return; 45917Sbill } 4602395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4612296Swnj if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) 46217Sbill lpr |= BITS8; 46317Sbill else 46417Sbill lpr |= (BITS7|PENABLE); 46517Sbill if ((tp->t_flags & EVENP) == 0) 46617Sbill lpr |= OPAR; 4672469Swnj if (tp->t_ispeed == B110) 4682469Swnj lpr |= TWOSB; 46917Sbill dzaddr->dzlpr = lpr; 47017Sbill } 47117Sbill 47217Sbill dzxint(tp) 4732395Swnj register struct tty *tp; 47417Sbill { 47517Sbill register struct pdma *dp; 4765731Sroot register s, dz, unit; 47717Sbill 4782469Swnj s = spl5(); /* block pdma interrupts */ 4792395Swnj dp = (struct pdma *)tp->t_addr; 4805407Swnj tp->t_state &= ~TS_BUSY; 4815407Swnj if (tp->t_state & TS_FLUSH) 4825407Swnj tp->t_state &= ~TS_FLUSH; 4835731Sroot else { 484281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4855731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4865731Sroot } 48717Sbill if (tp->t_line) 48817Sbill (*linesw[tp->t_line].l_start)(tp); 48917Sbill else 49017Sbill dzstart(tp); 4915731Sroot dz = minor(tp->t_dev) >> 3; 4925731Sroot unit = minor(tp->t_dev) & 7; 4935407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4945731Sroot if (dp->p_addr->dzcsr & DZ_32) 4955731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4965731Sroot else 4975731Sroot dp->p_addr->dztcr &= ~(1<<unit); 498145Sbill splx(s); 49917Sbill } 50017Sbill 50117Sbill dzstart(tp) 5022395Swnj register struct tty *tp; 50317Sbill { 50417Sbill register struct pdma *dp; 50517Sbill register struct device *dzaddr; 5062395Swnj register int cc; 5075731Sroot int s, dz, unit; 50817Sbill 5092395Swnj dp = (struct pdma *)tp->t_addr; 51017Sbill dzaddr = dp->p_addr; 5112395Swnj s = spl5(); 5125407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 51317Sbill goto out; 5145407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5155407Swnj if (tp->t_state&TS_ASLEEP) { 5165407Swnj tp->t_state &= ~TS_ASLEEP; 5175407Swnj wakeup((caddr_t)&tp->t_outq); 5185407Swnj } 5195407Swnj if (tp->t_wsel) { 5205407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5215407Swnj tp->t_wsel = 0; 5225407Swnj tp->t_state &= ~TS_WCOLL; 5235407Swnj } 52417Sbill } 52517Sbill if (tp->t_outq.c_cc == 0) 52617Sbill goto out; 5275731Sroot if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) 52817Sbill cc = ndqb(&tp->t_outq, 0); 52917Sbill else { 53017Sbill cc = ndqb(&tp->t_outq, 0200); 53117Sbill if (cc == 0) { 53217Sbill cc = getc(&tp->t_outq); 5332469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5345407Swnj tp->t_state |= TS_TIMEOUT; 53517Sbill goto out; 53617Sbill } 53717Sbill } 5385407Swnj tp->t_state |= TS_BUSY; 53917Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 54017Sbill dp->p_end += cc; 5415731Sroot dz = minor(tp->t_dev) >> 3; 5425731Sroot unit = minor(tp->t_dev) & 7; 5435731Sroot if (dzaddr->dzcsr & DZ_32) 5445731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5455731Sroot else 5465731Sroot dzaddr->dztcr |= (1<<unit); 5472395Swnj out: 5482395Swnj splx(s); 54917Sbill } 55017Sbill 55117Sbill /* 55217Sbill * Stop output on a line. 55317Sbill */ 55417Sbill /*ARGSUSED*/ 55517Sbill dzstop(tp, flag) 5562395Swnj register struct tty *tp; 55717Sbill { 55817Sbill register struct pdma *dp; 55917Sbill register int s; 56017Sbill 5612395Swnj dp = (struct pdma *)tp->t_addr; 5622457Swnj s = spl5(); 5635407Swnj if (tp->t_state & TS_BUSY) { 56417Sbill dp->p_end = dp->p_mem; 5655407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5665407Swnj tp->t_state |= TS_FLUSH; 56717Sbill } 56817Sbill splx(s); 56917Sbill } 57017Sbill 5715731Sroot dzmctl(dev, bits, how) 5725731Sroot dev_t dev; 5735731Sroot int bits, how; 57417Sbill { 57517Sbill register struct device *dzaddr; 5765731Sroot register int unit, mbits; 5775731Sroot int b, s; 5785731Sroot 5795731Sroot unit = minor(dev); 5805731Sroot b = 1<<(unit&7); 5812395Swnj dzaddr = dzpdma[unit].p_addr; 5825731Sroot s = spl5(); 5835731Sroot if (dzaddr->dzcsr & DZ_32) { 5845731Sroot dzwait(dzaddr) 5855731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5865731Sroot dzaddr->dzlcs = unit&7; 5875731Sroot DELAY(100); 5885731Sroot dzwait(dzaddr) 5895731Sroot DELAY(100); 5905731Sroot mbits = dzaddr->dzlcs; 5915731Sroot mbits &= 0177770; 5925731Sroot } else { 5935731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5945731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5955731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5965731Sroot } 5975731Sroot switch (how) { 5985731Sroot case DMSET: 5995731Sroot mbits = bits; 6005731Sroot break; 6015731Sroot 6025731Sroot case DMBIS: 6035731Sroot mbits |= bits; 6045731Sroot break; 6055731Sroot 6065731Sroot case DMBIC: 6075731Sroot mbits &= ~bits; 6085731Sroot break; 6095731Sroot 6105731Sroot case DMGET: 6115731Sroot (void) splx(s); 6125731Sroot return(mbits); 6135731Sroot } 6145731Sroot if (dzaddr->dzcsr & DZ_32) { 6155731Sroot mbits |= DZ_ACK|(unit&7); 6165731Sroot dzaddr->dzlcs = mbits; 6175731Sroot } else { 6185731Sroot if (mbits & DZ_DTR) 6195731Sroot dzaddr->dzdtr |= b; 6205731Sroot else 6215731Sroot dzaddr->dzdtr &= ~b; 6225731Sroot } 6235731Sroot (void) splx(s); 6245731Sroot return(mbits); 62517Sbill } 62617Sbill 62717Sbill dzscan() 62817Sbill { 62917Sbill register i; 63017Sbill register struct device *dzaddr; 63117Sbill register bit; 63217Sbill register struct tty *tp; 6335731Sroot register car; 63417Sbill 63517Sbill for (i = 0; i < dz_cnt ; i++) { 63617Sbill dzaddr = dzpdma[i].p_addr; 6372627Swnj if (dzaddr == 0) 6382627Swnj continue; 63917Sbill tp = &dz_tty[i]; 64017Sbill bit = 1<<(i&07); 6415731Sroot car = 0; 6425731Sroot if (dzsoftCAR[i>>3]&bit) 6435731Sroot car = 1; 6445731Sroot else if (dzaddr->dzcsr & DZ_32) { 6455731Sroot dzaddr->dzlcs = i&07; 6465731Sroot dzwait(dzaddr); 6475731Sroot car = dzaddr->dzlcs & DZ_CD; 6485731Sroot } else 6495731Sroot car = dzaddr->dzmsr&bit; 6505731Sroot if (car) { 65117Sbill /* carrier present */ 6525407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 65317Sbill wakeup((caddr_t)&tp->t_rawq); 6545407Swnj tp->t_state |= TS_CARR_ON; 65517Sbill } 65617Sbill } else { 6575407Swnj if ((tp->t_state&TS_CARR_ON) && 6582469Swnj (tp->t_local&LNOHANG)==0) { 65917Sbill /* carrier lost */ 6605407Swnj if (tp->t_state&TS_ISOPEN) { 661170Sbill gsignal(tp->t_pgrp, SIGHUP); 662205Sbill gsignal(tp->t_pgrp, SIGCONT); 663170Sbill dzaddr->dzdtr &= ~bit; 664871Sbill flushtty(tp, FREAD|FWRITE); 665170Sbill } 6665407Swnj tp->t_state &= ~TS_CARR_ON; 66717Sbill } 66817Sbill } 66917Sbill } 6702756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 67117Sbill } 672119Sbill 673119Sbill dztimer() 674119Sbill { 6752457Swnj int dz; 676119Sbill 6772645Swnj for (dz = 0; dz < NDZ; dz++) 6782457Swnj dzrint(dz); 679119Sbill } 680281Sbill 681281Sbill /* 682281Sbill * Reset state of driver if UBA reset was necessary. 683301Sbill * Reset parameters and restart transmission on open lines. 684281Sbill */ 6852395Swnj dzreset(uban) 6862422Skre int uban; 687281Sbill { 6882395Swnj register int unit; 689281Sbill register struct tty *tp; 6902976Swnj register struct uba_device *ui; 691281Sbill 6922645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6932422Skre ui = dzinfo[unit >> 3]; 6942422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6952422Skre continue; 6962923Swnj if (unit%8 == 0) 6972923Swnj printf(" dz%d", unit>>3); 6982395Swnj tp = &dz_tty[unit]; 6995407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 7002395Swnj dzparam(unit); 7016157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 7025407Swnj tp->t_state &= ~TS_BUSY; 703301Sbill dzstart(tp); 704281Sbill } 705281Sbill } 706281Sbill dztimer(); 707281Sbill } 7081562Sbill #endif 709