1*8474Sroot /* dz.c 4.44 82/10/10 */ 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" 2117Sbill #include "../h/conf.h" 22114Sbill #include "../h/bk.h" 23871Sbill #include "../h/file.h" 247727Sroot #include "../h/uio.h" 25145Sbill 26*8474Sroot #include "../vaxuba/pdma.h" 27*8474Sroot #include "../vaxuba/ubavar.h" 28*8474Sroot 292469Swnj /* 302469Swnj * Driver information for auto-configuration stuff. 312469Swnj */ 322606Swnj int dzprobe(), dzattach(), dzrint(); 332976Swnj struct uba_device *dzinfo[NDZ]; 342395Swnj u_short dzstd[] = { 0 }; 352395Swnj struct uba_driver dzdriver = 362606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 372395Swnj 382645Swnj #define NDZLINE (NDZ*8) 3917Sbill 402469Swnj /* 412469Swnj * Registers and bits 422469Swnj */ 432469Swnj 445731Sroot /* bits in dzlpr */ 455731Sroot #define BITS7 0020 465731Sroot #define BITS8 0030 475731Sroot #define TWOSB 0040 482457Swnj #define PENABLE 0100 492457Swnj #define OPAR 0200 5017Sbill 515731Sroot /* bits in dzrbuf */ 522469Swnj #define DZ_PE 010000 532469Swnj #define DZ_FE 020000 542469Swnj #define DZ_DO 040000 552469Swnj 565731Sroot /* bits in dzcsr */ 575731Sroot #define DZ_32 000001 /* DZ32 mode */ 585731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 595731Sroot #define DZ_CLR 000020 /* Reset dz */ 605731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 615731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 625731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 632469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 642469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 655731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 662469Swnj 675731Sroot /* flags for modem-control */ 685731Sroot #define DZ_ON DZ_DTR 692469Swnj #define DZ_OFF 0 705731Sroot 715731Sroot /* bits in dzlcs */ 725731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 735731Sroot #define DZ_RTS 0010000 /* Request To Send */ 745731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 755731Sroot #define DZ_BRK 0002000 /* Break */ 765731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 775731Sroot #define DZ_LE 0000400 /* Line Enable */ 785731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 795731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 805731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 815731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 825731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8317Sbill 845731Sroot /* bits in dm lsr, copied from dh.c */ 855731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 865731Sroot #define DML_RNG 0000200 /* ring */ 875731Sroot #define DML_CAR 0000100 /* carrier detect */ 885731Sroot #define DML_CTS 0000040 /* clear to send */ 895731Sroot #define DML_SR 0000020 /* secondary receive */ 905731Sroot #define DML_ST 0000010 /* secondary transmit */ 915731Sroot #define DML_RTS 0000004 /* request to send */ 925731Sroot #define DML_DTR 0000002 /* data terminal ready */ 935731Sroot #define DML_LE 0000001 /* line enable */ 945731Sroot 952469Swnj int dzstart(), dzxint(), dzdma(); 96114Sbill int ttrstrt(); 972645Swnj struct tty dz_tty[NDZLINE]; 982645Swnj int dz_cnt = { NDZLINE }; 99119Sbill int dzact; 10017Sbill 10117Sbill struct device { 1025731Sroot short dzcsr; 1035731Sroot short dzrbuf; 1045731Sroot union { 1055731Sroot struct { 1065731Sroot char dztcr0; 1075731Sroot char dzdtr0; 1085731Sroot char dztbuf0; 1095731Sroot char dzbrk0; 1105731Sroot } dz11; 1115731Sroot struct { 1125731Sroot short dzlcs0; 1135731Sroot char dztbuf0; 1145731Sroot char dzlnen0; 1155731Sroot } dz32; 1165731Sroot } dzun; 11717Sbill }; 1185731Sroot 1195731Sroot #define dzlpr dzrbuf 1205731Sroot #define dzmsr dzun.dz11.dzbrk0 1215731Sroot #define dztcr dzun.dz11.dztcr0 1225731Sroot #define dzdtr dzun.dz11.dzdtr0 1235731Sroot #define dztbuf dzun.dz11.dztbuf0 1245731Sroot #define dzlcs dzun.dz32.dzlcs0 1255731Sroot #define dzbrk dzmsr 1265731Sroot #define dzlnen dzun.dz32.dzlnen0 1277406Skre #define dzmtsr dzun.dz32.dztbuf0 1285731Sroot 1295731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1305731Sroot 1312469Swnj /* 1322469Swnj * Software copy of dzbrk since it isn't readable 1332469Swnj */ 1342645Swnj char dz_brk[NDZ]; 1352645Swnj char dzsoftCAR[NDZ]; 1365731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 13717Sbill 1382469Swnj /* 1395731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1402469Swnj * we have to use a timer to watch it. 1412469Swnj */ 1422469Swnj char dz_timer; /* timer started? */ 1432469Swnj 1442469Swnj /* 1452469Swnj * Pdma structures for fast output code 1462469Swnj */ 1472645Swnj struct pdma dzpdma[NDZLINE]; 1482469Swnj 1492395Swnj char dz_speeds[] = 1506814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 15117Sbill 1526616Ssam #ifndef PORTSELECTOR 1536616Ssam #define ISPEED B300 1546616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 1556616Ssam #else 1566616Ssam #define ISPEED B4800 1576616Ssam #define IFLAGS (EVENP|ODDP) 1586616Ssam #endif 1596616Ssam 1602606Swnj dzprobe(reg) 1612395Swnj caddr_t reg; 1622395Swnj { 1632457Swnj register int br, cvec; 1642457Swnj register struct device *dzaddr = (struct device *)reg; 1652395Swnj 1662606Swnj #ifdef lint 1673102Swnj br = 0; cvec = br; br = cvec; 1684933Swnj dzrint(0); dzxint((struct tty *)0); 1692606Swnj #endif 1705731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1715731Sroot if (dzaddr->dzcsr & DZ_32) 1725731Sroot dzaddr->dzlnen = 1; 1735731Sroot else 1745731Sroot dzaddr->dztcr = 1; /* enable any line */ 1752457Swnj DELAY(100000); 1765731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1772457Swnj if (cvec && cvec != 0x200) 1782457Swnj cvec -= 4; 1797406Skre return (sizeof (struct device)); 1802395Swnj } 1812395Swnj 1822606Swnj dzattach(ui) 1832976Swnj register struct uba_device *ui; 1842395Swnj { 1852395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1862395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1872606Swnj register int cntr; 1882645Swnj extern dzscan(); 1892395Swnj 1902606Swnj for (cntr = 0; cntr < 8; cntr++) { 1912606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1922395Swnj pdp->p_arg = (int)tp; 1932395Swnj pdp->p_fcn = dzxint; 1942395Swnj pdp++, tp++; 1952395Swnj } 1962567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 1972627Swnj if (dz_timer == 0) { 1982627Swnj dz_timer++; 1992756Swnj timeout(dzscan, (caddr_t)0, hz); 2002627Swnj } 2012395Swnj } 2022395Swnj 20317Sbill /*ARGSUSED*/ 2042395Swnj dzopen(dev, flag) 2052395Swnj dev_t dev; 20617Sbill { 20717Sbill register struct tty *tp; 2082395Swnj register int unit; 20917Sbill 2102395Swnj unit = minor(dev); 2112395Swnj if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { 21217Sbill u.u_error = ENXIO; 21317Sbill return; 21417Sbill } 2152395Swnj tp = &dz_tty[unit]; 2162395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 21717Sbill tp->t_oproc = dzstart; 2185407Swnj tp->t_state |= TS_WOPEN; 2195407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 22017Sbill ttychars(tp); 2216616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 2226616Ssam tp->t_flags = IFLAGS; 2235407Swnj /* tp->t_state |= TS_HUPCLS; */ 2242395Swnj dzparam(unit); 2255407Swnj } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { 22617Sbill u.u_error = EBUSY; 22717Sbill return; 22817Sbill } 2296157Ssam (void) dzmctl(dev, DZ_ON, DMSET); 230114Sbill (void) spl5(); 2315407Swnj while ((tp->t_state & TS_CARR_ON) == 0) { 2325407Swnj tp->t_state |= TS_WOPEN; 23317Sbill sleep((caddr_t)&tp->t_rawq, TTIPRI); 23417Sbill } 235114Sbill (void) spl0(); 2362395Swnj (*linesw[tp->t_line].l_open)(dev, tp); 23717Sbill } 23817Sbill 2392395Swnj /*ARGSUSED*/ 2402395Swnj dzclose(dev, flag) 2412395Swnj dev_t dev; 24217Sbill { 24317Sbill register struct tty *tp; 2442395Swnj register int unit; 2455731Sroot register struct device *dzaddr; 2466150Ssam int dz; 24717Sbill 2482395Swnj unit = minor(dev); 2492395Swnj dz = unit >> 3; 2502395Swnj tp = &dz_tty[unit]; 25117Sbill (*linesw[tp->t_line].l_close)(tp); 2525731Sroot dzaddr = dzpdma[unit].p_addr; 2535731Sroot if (dzaddr->dzcsr&DZ_32) 2546157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 2555731Sroot else 2565731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 2576842Swnj if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) 2586157Ssam (void) dzmctl(dev, DZ_OFF, DMSET); 25917Sbill ttyclose(tp); 26017Sbill } 26117Sbill 2627727Sroot dzread(dev, uio) 2632395Swnj dev_t dev; 2647727Sroot struct uio *uio; 26517Sbill { 26617Sbill register struct tty *tp; 26717Sbill 2682395Swnj tp = &dz_tty[minor(dev)]; 2697727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 27017Sbill } 27117Sbill 2727833Sroot dzwrite(dev, uio) 2732395Swnj dev_t dev; 2747833Sroot struct uio *uio; 27517Sbill { 27617Sbill register struct tty *tp; 27717Sbill 2782395Swnj tp = &dz_tty[minor(dev)]; 2797833Sroot (*linesw[tp->t_line].l_write)(tp, uio); 28017Sbill } 28117Sbill 282119Sbill /*ARGSUSED*/ 2832395Swnj dzrint(dz) 2842395Swnj int dz; 28517Sbill { 28617Sbill register struct tty *tp; 28717Sbill register int c; 28817Sbill register struct device *dzaddr; 289119Sbill register struct tty *tp0; 2902395Swnj register int unit; 2912923Swnj int overrun = 0; 29217Sbill 2932457Swnj if ((dzact & (1<<dz)) == 0) 2942457Swnj return; 2952457Swnj unit = dz * 8; 2962457Swnj dzaddr = dzpdma[unit].p_addr; 2972457Swnj tp0 = &dz_tty[unit]; 2985731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2995731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 3005731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 3015731Sroot c = dzaddr->dzmtsr; 3025731Sroot tp = tp0 + (c&7); 3035731Sroot if (tp >= &dz_tty[dz_cnt]) 3045731Sroot break; 3055731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 3065731Sroot dzwait(dzaddr); /* wait for them */ 3075731Sroot if (c & DZ_CD) /* carrier status change? */ 3085731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 3095731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 3105731Sroot wakeup((caddr_t)&tp->t_rawq); 3115731Sroot tp->t_state |= TS_CARR_ON; 3125731Sroot } 3135731Sroot } else { /* no carrier */ 3145731Sroot if (tp->t_state&TS_CARR_ON) { 3155731Sroot gsignal(tp->t_pgrp, SIGHUP); 3165731Sroot gsignal(tp->t_pgrp, SIGCONT); 3175731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3185731Sroot flushtty(tp, FREAD|FWRITE); 3195731Sroot } 3205731Sroot tp->t_state &= ~TS_CARR_ON; 3215731Sroot } 3225731Sroot } 3232457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3242457Swnj tp = tp0 + ((c>>8)&07); 3252457Swnj if (tp >= &dz_tty[dz_cnt]) 32617Sbill continue; 3275407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3282457Swnj wakeup((caddr_t)&tp->t_rawq); 3296616Ssam #ifdef PORTSELECTOR 3306616Ssam if ((tp->t_state&TS_WOPEN) == 0) 3316616Ssam #endif 3322457Swnj continue; 3332457Swnj } 3342469Swnj if (c&DZ_FE) 3352457Swnj if (tp->t_flags & RAW) 3362469Swnj c = 0; 3372457Swnj else 3382457Swnj c = tun.t_intrc; 3392923Swnj if (c&DZ_DO && overrun == 0) { 3405731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3412923Swnj overrun = 1; 3422923Swnj } 3432469Swnj if (c&DZ_PE) 3442457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3452457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 34617Sbill continue; 3472731Swnj #if NBK > 0 3482457Swnj if (tp->t_line == NETLDISC) { 3492457Swnj c &= 0177; 3502457Swnj BKINPUT(c, tp); 3512457Swnj } else 3522731Swnj #endif 3532457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 35417Sbill } 35517Sbill } 35617Sbill 35717Sbill /*ARGSUSED*/ 3587631Ssam dzioctl(dev, cmd, data, flag) 3592395Swnj dev_t dev; 3607631Ssam caddr_t data; 36117Sbill { 36217Sbill register struct tty *tp; 3632395Swnj register int unit = minor(dev); 3642395Swnj register int dz = unit >> 3; 3655731Sroot register struct device *dzaddr; 36617Sbill 3672395Swnj tp = &dz_tty[unit]; 3687631Ssam cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 369114Sbill if (cmd == 0) 370114Sbill return; 3717631Ssam if (ttioctl(tp, cmd, data, flag)) { 3727631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 3732395Swnj dzparam(unit); 374170Sbill } else switch(cmd) { 3752395Swnj 376170Sbill case TIOCSBRK: 3775731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3785731Sroot if (dzaddr->dzcsr&DZ_32) 3796157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3805731Sroot else 3815731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 382170Sbill break; 3837631Ssam 384170Sbill case TIOCCBRK: 3855731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3865731Sroot if (dzaddr->dzcsr&DZ_32) 3876157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3885731Sroot else 3895731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 390170Sbill break; 3917631Ssam 392170Sbill case TIOCSDTR: 3936157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 394170Sbill break; 3957631Ssam 396170Sbill case TIOCCDTR: 3976157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 398170Sbill break; 3997631Ssam 4005731Sroot case TIOCMSET: 4017631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 4025731Sroot break; 4037631Ssam 4045731Sroot case TIOCMBIS: 4057631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 4065731Sroot break; 4077631Ssam 4085731Sroot case TIOCMBIC: 4097631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 4105731Sroot break; 4117631Ssam 4125731Sroot case TIOCMGET: 4137631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 4145731Sroot break; 4157631Ssam 416170Sbill default: 41717Sbill u.u_error = ENOTTY; 418170Sbill } 41917Sbill } 4205731Sroot 4215731Sroot dmtodz(bits) 4225731Sroot register int bits; 4235731Sroot { 4245731Sroot register int b; 4255731Sroot 4265731Sroot b = (bits >>1) & 0370; 4275731Sroot if (bits & DML_ST) b |= DZ_ST; 4285731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4295731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4305731Sroot if (bits & DML_LE) b |= DZ_LE; 4315731Sroot return(b); 4325731Sroot } 4335731Sroot 4345731Sroot dztodm(bits) 4355731Sroot register int bits; 4365731Sroot { 4375731Sroot register int b; 4385731Sroot 4395731Sroot b = (bits << 1) & 0360; 4405731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4415731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4425731Sroot if (bits & DZ_ST) b |= DML_ST; 4435731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4445731Sroot return(b); 4455731Sroot } 44617Sbill 4472395Swnj dzparam(unit) 4482395Swnj register int unit; 44917Sbill { 45017Sbill register struct tty *tp; 45117Sbill register struct device *dzaddr; 4522395Swnj register int lpr; 45317Sbill 4542395Swnj tp = &dz_tty[unit]; 4552395Swnj dzaddr = dzpdma[unit].p_addr; 45617Sbill dzaddr->dzcsr = DZ_IEN; 4572395Swnj dzact |= (1<<(unit>>3)); 45817Sbill if (tp->t_ispeed == 0) { 4596157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 46017Sbill return; 46117Sbill } 4622395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4632296Swnj if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) 46417Sbill lpr |= BITS8; 46517Sbill else 46617Sbill lpr |= (BITS7|PENABLE); 46717Sbill if ((tp->t_flags & EVENP) == 0) 46817Sbill lpr |= OPAR; 4692469Swnj if (tp->t_ispeed == B110) 4702469Swnj lpr |= TWOSB; 47117Sbill dzaddr->dzlpr = lpr; 47217Sbill } 47317Sbill 47417Sbill dzxint(tp) 4752395Swnj register struct tty *tp; 47617Sbill { 47717Sbill register struct pdma *dp; 4785731Sroot register s, dz, unit; 47917Sbill 4802469Swnj s = spl5(); /* block pdma interrupts */ 4812395Swnj dp = (struct pdma *)tp->t_addr; 4825407Swnj tp->t_state &= ~TS_BUSY; 4835407Swnj if (tp->t_state & TS_FLUSH) 4845407Swnj tp->t_state &= ~TS_FLUSH; 4855731Sroot else { 486281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4875731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4885731Sroot } 48917Sbill if (tp->t_line) 49017Sbill (*linesw[tp->t_line].l_start)(tp); 49117Sbill else 49217Sbill dzstart(tp); 4935731Sroot dz = minor(tp->t_dev) >> 3; 4945731Sroot unit = minor(tp->t_dev) & 7; 4955407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 4965731Sroot if (dp->p_addr->dzcsr & DZ_32) 4975731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 4985731Sroot else 4995731Sroot dp->p_addr->dztcr &= ~(1<<unit); 500145Sbill splx(s); 50117Sbill } 50217Sbill 50317Sbill dzstart(tp) 5042395Swnj register struct tty *tp; 50517Sbill { 50617Sbill register struct pdma *dp; 50717Sbill register struct device *dzaddr; 5082395Swnj register int cc; 5095731Sroot int s, dz, unit; 51017Sbill 5112395Swnj dp = (struct pdma *)tp->t_addr; 51217Sbill dzaddr = dp->p_addr; 5132395Swnj s = spl5(); 5145407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 51517Sbill goto out; 5165407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5175407Swnj if (tp->t_state&TS_ASLEEP) { 5185407Swnj tp->t_state &= ~TS_ASLEEP; 5195407Swnj wakeup((caddr_t)&tp->t_outq); 5205407Swnj } 5215407Swnj if (tp->t_wsel) { 5225407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5235407Swnj tp->t_wsel = 0; 5245407Swnj tp->t_state &= ~TS_WCOLL; 5255407Swnj } 52617Sbill } 52717Sbill if (tp->t_outq.c_cc == 0) 52817Sbill goto out; 5295731Sroot if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) 53017Sbill cc = ndqb(&tp->t_outq, 0); 53117Sbill else { 53217Sbill cc = ndqb(&tp->t_outq, 0200); 53317Sbill if (cc == 0) { 53417Sbill cc = getc(&tp->t_outq); 5352469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5365407Swnj tp->t_state |= TS_TIMEOUT; 53717Sbill goto out; 53817Sbill } 53917Sbill } 5405407Swnj tp->t_state |= TS_BUSY; 54117Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 54217Sbill dp->p_end += cc; 5435731Sroot dz = minor(tp->t_dev) >> 3; 5445731Sroot unit = minor(tp->t_dev) & 7; 5455731Sroot if (dzaddr->dzcsr & DZ_32) 5465731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5475731Sroot else 5485731Sroot dzaddr->dztcr |= (1<<unit); 5492395Swnj out: 5502395Swnj splx(s); 55117Sbill } 55217Sbill 55317Sbill /* 55417Sbill * Stop output on a line. 55517Sbill */ 55617Sbill /*ARGSUSED*/ 55717Sbill dzstop(tp, flag) 5582395Swnj register struct tty *tp; 55917Sbill { 56017Sbill register struct pdma *dp; 56117Sbill register int s; 56217Sbill 5632395Swnj dp = (struct pdma *)tp->t_addr; 5642457Swnj s = spl5(); 5655407Swnj if (tp->t_state & TS_BUSY) { 56617Sbill dp->p_end = dp->p_mem; 5675407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5685407Swnj tp->t_state |= TS_FLUSH; 56917Sbill } 57017Sbill splx(s); 57117Sbill } 57217Sbill 5735731Sroot dzmctl(dev, bits, how) 5745731Sroot dev_t dev; 5755731Sroot int bits, how; 57617Sbill { 57717Sbill register struct device *dzaddr; 5785731Sroot register int unit, mbits; 5795731Sroot int b, s; 5805731Sroot 5815731Sroot unit = minor(dev); 5825731Sroot b = 1<<(unit&7); 5832395Swnj dzaddr = dzpdma[unit].p_addr; 5845731Sroot s = spl5(); 5855731Sroot if (dzaddr->dzcsr & DZ_32) { 5865731Sroot dzwait(dzaddr) 5875731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5885731Sroot dzaddr->dzlcs = unit&7; 5895731Sroot DELAY(100); 5905731Sroot dzwait(dzaddr) 5915731Sroot DELAY(100); 5925731Sroot mbits = dzaddr->dzlcs; 5935731Sroot mbits &= 0177770; 5945731Sroot } else { 5955731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 5965731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 5975731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 5985731Sroot } 5995731Sroot switch (how) { 6005731Sroot case DMSET: 6015731Sroot mbits = bits; 6025731Sroot break; 6035731Sroot 6045731Sroot case DMBIS: 6055731Sroot mbits |= bits; 6065731Sroot break; 6075731Sroot 6085731Sroot case DMBIC: 6095731Sroot mbits &= ~bits; 6105731Sroot break; 6115731Sroot 6125731Sroot case DMGET: 6135731Sroot (void) splx(s); 6145731Sroot return(mbits); 6155731Sroot } 6165731Sroot if (dzaddr->dzcsr & DZ_32) { 6175731Sroot mbits |= DZ_ACK|(unit&7); 6185731Sroot dzaddr->dzlcs = mbits; 6195731Sroot } else { 6205731Sroot if (mbits & DZ_DTR) 6215731Sroot dzaddr->dzdtr |= b; 6225731Sroot else 6235731Sroot dzaddr->dzdtr &= ~b; 6245731Sroot } 6255731Sroot (void) splx(s); 6265731Sroot return(mbits); 62717Sbill } 62817Sbill 62917Sbill dzscan() 63017Sbill { 63117Sbill register i; 63217Sbill register struct device *dzaddr; 63317Sbill register bit; 63417Sbill register struct tty *tp; 6355731Sroot register car; 63617Sbill 63717Sbill for (i = 0; i < dz_cnt ; i++) { 63817Sbill dzaddr = dzpdma[i].p_addr; 6392627Swnj if (dzaddr == 0) 6402627Swnj continue; 64117Sbill tp = &dz_tty[i]; 64217Sbill bit = 1<<(i&07); 6435731Sroot car = 0; 6445731Sroot if (dzsoftCAR[i>>3]&bit) 6455731Sroot car = 1; 6465731Sroot else if (dzaddr->dzcsr & DZ_32) { 6475731Sroot dzaddr->dzlcs = i&07; 6485731Sroot dzwait(dzaddr); 6495731Sroot car = dzaddr->dzlcs & DZ_CD; 6505731Sroot } else 6515731Sroot car = dzaddr->dzmsr&bit; 6525731Sroot if (car) { 65317Sbill /* carrier present */ 6545407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 65517Sbill wakeup((caddr_t)&tp->t_rawq); 6565407Swnj tp->t_state |= TS_CARR_ON; 65717Sbill } 65817Sbill } else { 6595407Swnj if ((tp->t_state&TS_CARR_ON) && 6602469Swnj (tp->t_local&LNOHANG)==0) { 66117Sbill /* carrier lost */ 6625407Swnj if (tp->t_state&TS_ISOPEN) { 663170Sbill gsignal(tp->t_pgrp, SIGHUP); 664205Sbill gsignal(tp->t_pgrp, SIGCONT); 665170Sbill dzaddr->dzdtr &= ~bit; 666871Sbill flushtty(tp, FREAD|FWRITE); 667170Sbill } 6685407Swnj tp->t_state &= ~TS_CARR_ON; 66917Sbill } 67017Sbill } 67117Sbill } 6722756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 67317Sbill } 674119Sbill 675119Sbill dztimer() 676119Sbill { 6778160Sroot register int dz; 6788160Sroot register int s = spl5(); 679119Sbill 6802645Swnj for (dz = 0; dz < NDZ; dz++) 6812457Swnj dzrint(dz); 6828160Sroot splx(s); 683119Sbill } 684281Sbill 685281Sbill /* 686281Sbill * Reset state of driver if UBA reset was necessary. 687301Sbill * Reset parameters and restart transmission on open lines. 688281Sbill */ 6892395Swnj dzreset(uban) 6902422Skre int uban; 691281Sbill { 6922395Swnj register int unit; 693281Sbill register struct tty *tp; 6942976Swnj register struct uba_device *ui; 695281Sbill 6962645Swnj for (unit = 0; unit < NDZLINE; unit++) { 6972422Skre ui = dzinfo[unit >> 3]; 6982422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 6992422Skre continue; 7002923Swnj if (unit%8 == 0) 7012923Swnj printf(" dz%d", unit>>3); 7022395Swnj tp = &dz_tty[unit]; 7035407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 7042395Swnj dzparam(unit); 7056157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 7065407Swnj tp->t_state &= ~TS_BUSY; 707301Sbill dzstart(tp); 708281Sbill } 709281Sbill } 710281Sbill dztimer(); 711281Sbill } 7121562Sbill #endif 713