1*9773Ssam /* dz.c 4.48 82/12/17 */ 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" 11*9773Ssam 12*9773Ssam #include "../machine/pte.h" 13*9773Ssam 1417Sbill #include "../h/param.h" 1517Sbill #include "../h/systm.h" 169551Ssam #include "../h/ioctl.h" 1717Sbill #include "../h/tty.h" 1817Sbill #include "../h/dir.h" 1917Sbill #include "../h/user.h" 206157Ssam #include "../h/proc.h" 2117Sbill #include "../h/map.h" 222395Swnj #include "../h/buf.h" 232567Swnj #include "../h/vm.h" 2417Sbill #include "../h/conf.h" 25114Sbill #include "../h/bk.h" 26871Sbill #include "../h/file.h" 277727Sroot #include "../h/uio.h" 28145Sbill 298474Sroot #include "../vaxuba/pdma.h" 308474Sroot #include "../vaxuba/ubavar.h" 318474Sroot 322469Swnj /* 332469Swnj * Driver information for auto-configuration stuff. 342469Swnj */ 352606Swnj int dzprobe(), dzattach(), dzrint(); 362976Swnj struct uba_device *dzinfo[NDZ]; 372395Swnj u_short dzstd[] = { 0 }; 382395Swnj struct uba_driver dzdriver = 392606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; 402395Swnj 412645Swnj #define NDZLINE (NDZ*8) 4217Sbill 432469Swnj /* 442469Swnj * Registers and bits 452469Swnj */ 462469Swnj 475731Sroot /* bits in dzlpr */ 485731Sroot #define BITS7 0020 495731Sroot #define BITS8 0030 505731Sroot #define TWOSB 0040 512457Swnj #define PENABLE 0100 522457Swnj #define OPAR 0200 5317Sbill 545731Sroot /* bits in dzrbuf */ 552469Swnj #define DZ_PE 010000 562469Swnj #define DZ_FE 020000 572469Swnj #define DZ_DO 040000 582469Swnj 595731Sroot /* bits in dzcsr */ 605731Sroot #define DZ_32 000001 /* DZ32 mode */ 615731Sroot #define DZ_MIE 000002 /* Modem Interrupt Enable */ 625731Sroot #define DZ_CLR 000020 /* Reset dz */ 635731Sroot #define DZ_MSE 000040 /* Master Scan Enable */ 645731Sroot #define DZ_RIE 000100 /* Receiver Interrupt Enable */ 655731Sroot #define DZ_MSC 004000 /* Modem Status Change */ 662469Swnj #define DZ_SAE 010000 /* Silo Alarm Enable */ 672469Swnj #define DZ_TIE 040000 /* Transmit Interrupt Enable */ 685731Sroot #define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) 692469Swnj 705731Sroot /* flags for modem-control */ 715731Sroot #define DZ_ON DZ_DTR 722469Swnj #define DZ_OFF 0 735731Sroot 745731Sroot /* bits in dzlcs */ 755731Sroot #define DZ_ACK 0100000 /* ACK bit in dzlcs */ 765731Sroot #define DZ_RTS 0010000 /* Request To Send */ 775731Sroot #define DZ_ST 0004000 /* Secondary Transmit */ 785731Sroot #define DZ_BRK 0002000 /* Break */ 795731Sroot #define DZ_DTR 0001000 /* Data Terminal Ready */ 805731Sroot #define DZ_LE 0000400 /* Line Enable */ 815731Sroot #define DZ_DSR 0000200 /* Data Set Ready */ 825731Sroot #define DZ_RI 0000100 /* Ring Indicate */ 835731Sroot #define DZ_CD 0000040 /* Carrier Detect */ 845731Sroot #define DZ_CTS 0000020 /* Clear To Send */ 855731Sroot #define DZ_SR 0000010 /* Secondary Receive */ 8617Sbill 875731Sroot /* bits in dm lsr, copied from dh.c */ 885731Sroot #define DML_DSR 0000400 /* data set ready, not a real DM bit */ 895731Sroot #define DML_RNG 0000200 /* ring */ 905731Sroot #define DML_CAR 0000100 /* carrier detect */ 915731Sroot #define DML_CTS 0000040 /* clear to send */ 925731Sroot #define DML_SR 0000020 /* secondary receive */ 935731Sroot #define DML_ST 0000010 /* secondary transmit */ 945731Sroot #define DML_RTS 0000004 /* request to send */ 955731Sroot #define DML_DTR 0000002 /* data terminal ready */ 965731Sroot #define DML_LE 0000001 /* line enable */ 975731Sroot 982469Swnj int dzstart(), dzxint(), dzdma(); 99114Sbill int ttrstrt(); 1002645Swnj struct tty dz_tty[NDZLINE]; 1012645Swnj int dz_cnt = { NDZLINE }; 102119Sbill int dzact; 10317Sbill 10417Sbill struct device { 1055731Sroot short dzcsr; 1065731Sroot short dzrbuf; 1075731Sroot union { 1085731Sroot struct { 1095731Sroot char dztcr0; 1105731Sroot char dzdtr0; 1115731Sroot char dztbuf0; 1125731Sroot char dzbrk0; 1135731Sroot } dz11; 1145731Sroot struct { 1155731Sroot short dzlcs0; 1165731Sroot char dztbuf0; 1175731Sroot char dzlnen0; 1185731Sroot } dz32; 1195731Sroot } dzun; 12017Sbill }; 1215731Sroot 1225731Sroot #define dzlpr dzrbuf 1235731Sroot #define dzmsr dzun.dz11.dzbrk0 1245731Sroot #define dztcr dzun.dz11.dztcr0 1255731Sroot #define dzdtr dzun.dz11.dzdtr0 1265731Sroot #define dztbuf dzun.dz11.dztbuf0 1275731Sroot #define dzlcs dzun.dz32.dzlcs0 1285731Sroot #define dzbrk dzmsr 1295731Sroot #define dzlnen dzun.dz32.dzlnen0 1307406Skre #define dzmtsr dzun.dz32.dztbuf0 1315731Sroot 1325731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) 1335731Sroot 1342469Swnj /* 1352469Swnj * Software copy of dzbrk since it isn't readable 1362469Swnj */ 1372645Swnj char dz_brk[NDZ]; 1382645Swnj char dzsoftCAR[NDZ]; 1395731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ 14017Sbill 1412469Swnj /* 1425731Sroot * The dz11 doesn't interrupt on carrier transitions, so 1432469Swnj * we have to use a timer to watch it. 1442469Swnj */ 1452469Swnj char dz_timer; /* timer started? */ 1462469Swnj 1472469Swnj /* 1482469Swnj * Pdma structures for fast output code 1492469Swnj */ 1502645Swnj struct pdma dzpdma[NDZLINE]; 1512469Swnj 1522395Swnj char dz_speeds[] = 1536814Swnj { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; 15417Sbill 1556616Ssam #ifndef PORTSELECTOR 1566616Ssam #define ISPEED B300 1576616Ssam #define IFLAGS (EVENP|ODDP|ECHO) 1586616Ssam #else 1596616Ssam #define ISPEED B4800 1606616Ssam #define IFLAGS (EVENP|ODDP) 1616616Ssam #endif 1626616Ssam 1632606Swnj dzprobe(reg) 1642395Swnj caddr_t reg; 1652395Swnj { 1662457Swnj register int br, cvec; 1672457Swnj register struct device *dzaddr = (struct device *)reg; 1682395Swnj 1692606Swnj #ifdef lint 1703102Swnj br = 0; cvec = br; br = cvec; 1714933Swnj dzrint(0); dzxint((struct tty *)0); 1722606Swnj #endif 1735731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; 1745731Sroot if (dzaddr->dzcsr & DZ_32) 1755731Sroot dzaddr->dzlnen = 1; 1765731Sroot else 1775731Sroot dzaddr->dztcr = 1; /* enable any line */ 1782457Swnj DELAY(100000); 1795731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ 1802457Swnj if (cvec && cvec != 0x200) 1812457Swnj cvec -= 4; 1827406Skre return (sizeof (struct device)); 1832395Swnj } 1842395Swnj 1852606Swnj dzattach(ui) 1862976Swnj register struct uba_device *ui; 1872395Swnj { 1882395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; 1892395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8]; 1902606Swnj register int cntr; 1912645Swnj extern dzscan(); 1922395Swnj 1932606Swnj for (cntr = 0; cntr < 8; cntr++) { 1942606Swnj pdp->p_addr = (struct device *)ui->ui_addr; 1952395Swnj pdp->p_arg = (int)tp; 1962395Swnj pdp->p_fcn = dzxint; 1972395Swnj pdp++, tp++; 1982395Swnj } 1992567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags; 2002627Swnj if (dz_timer == 0) { 2012627Swnj dz_timer++; 2022756Swnj timeout(dzscan, (caddr_t)0, hz); 2032627Swnj } 2042395Swnj } 2052395Swnj 20617Sbill /*ARGSUSED*/ 2072395Swnj dzopen(dev, flag) 2082395Swnj dev_t dev; 20917Sbill { 21017Sbill register struct tty *tp; 2112395Swnj register int unit; 21217Sbill 2132395Swnj unit = minor(dev); 2148568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) 2158568Sroot return (ENXIO); 2162395Swnj tp = &dz_tty[unit]; 2172395Swnj tp->t_addr = (caddr_t)&dzpdma[unit]; 21817Sbill tp->t_oproc = dzstart; 2195407Swnj tp->t_state |= TS_WOPEN; 2205407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 22117Sbill ttychars(tp); 2226616Ssam tp->t_ospeed = tp->t_ispeed = ISPEED; 2236616Ssam tp->t_flags = IFLAGS; 2245407Swnj /* tp->t_state |= TS_HUPCLS; */ 2252395Swnj dzparam(unit); 2268568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) 2278568Sroot return (EBUSY); 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(); 2358568Sroot return ((*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 2617727Sroot dzread(dev, uio) 2622395Swnj dev_t dev; 2637727Sroot struct uio *uio; 26417Sbill { 26517Sbill register struct tty *tp; 26617Sbill 2672395Swnj tp = &dz_tty[minor(dev)]; 2687727Sroot return ((*linesw[tp->t_line].l_read)(tp, uio)); 26917Sbill } 27017Sbill 2717833Sroot dzwrite(dev, uio) 2722395Swnj dev_t dev; 2737833Sroot struct uio *uio; 27417Sbill { 27517Sbill register struct tty *tp; 27617Sbill 2772395Swnj tp = &dz_tty[minor(dev)]; 2788531Sroot return ((*linesw[tp->t_line].l_write)(tp, uio)); 27917Sbill } 28017Sbill 281119Sbill /*ARGSUSED*/ 2822395Swnj dzrint(dz) 2832395Swnj int dz; 28417Sbill { 28517Sbill register struct tty *tp; 28617Sbill register int c; 28717Sbill register struct device *dzaddr; 288119Sbill register struct tty *tp0; 2892395Swnj register int unit; 2902923Swnj int overrun = 0; 29117Sbill 2922457Swnj if ((dzact & (1<<dz)) == 0) 2932457Swnj return; 2942457Swnj unit = dz * 8; 2952457Swnj dzaddr = dzpdma[unit].p_addr; 2962457Swnj tp0 = &dz_tty[unit]; 2975731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ 2985731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ 2995731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ 3005731Sroot c = dzaddr->dzmtsr; 3015731Sroot tp = tp0 + (c&7); 3025731Sroot if (tp >= &dz_tty[dz_cnt]) 3035731Sroot break; 3045731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */ 3055731Sroot dzwait(dzaddr); /* wait for them */ 3065731Sroot if (c & DZ_CD) /* carrier status change? */ 3075731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ 3085731Sroot if ((tp->t_state&TS_CARR_ON) == 0) { 3095731Sroot wakeup((caddr_t)&tp->t_rawq); 3105731Sroot tp->t_state |= TS_CARR_ON; 3115731Sroot } 3125731Sroot } else { /* no carrier */ 3135731Sroot if (tp->t_state&TS_CARR_ON) { 3145731Sroot gsignal(tp->t_pgrp, SIGHUP); 3155731Sroot gsignal(tp->t_pgrp, SIGCONT); 3165731Sroot dzaddr->dzlcs = DZ_ACK|(c&7); 3175731Sroot flushtty(tp, FREAD|FWRITE); 3185731Sroot } 3195731Sroot tp->t_state &= ~TS_CARR_ON; 3205731Sroot } 3215731Sroot } 3222457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */ 3232457Swnj tp = tp0 + ((c>>8)&07); 3242457Swnj if (tp >= &dz_tty[dz_cnt]) 32517Sbill continue; 3265407Swnj if ((tp->t_state & TS_ISOPEN) == 0) { 3272457Swnj wakeup((caddr_t)&tp->t_rawq); 3286616Ssam #ifdef PORTSELECTOR 3296616Ssam if ((tp->t_state&TS_WOPEN) == 0) 3306616Ssam #endif 3312457Swnj continue; 3322457Swnj } 3332469Swnj if (c&DZ_FE) 3342457Swnj if (tp->t_flags & RAW) 3352469Swnj c = 0; 3362457Swnj else 3379551Ssam c = tp->t_intrc; 3382923Swnj if (c&DZ_DO && overrun == 0) { 3395731Sroot /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ 3402923Swnj overrun = 1; 3412923Swnj } 3422469Swnj if (c&DZ_PE) 3432457Swnj if (((tp->t_flags & (EVENP|ODDP)) == EVENP) 3442457Swnj || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) 34517Sbill continue; 3462731Swnj #if NBK > 0 3472457Swnj if (tp->t_line == NETLDISC) { 3482457Swnj c &= 0177; 3492457Swnj BKINPUT(c, tp); 3502457Swnj } else 3512731Swnj #endif 3522457Swnj (*linesw[tp->t_line].l_rint)(c, tp); 35317Sbill } 35417Sbill } 35517Sbill 35617Sbill /*ARGSUSED*/ 3577631Ssam dzioctl(dev, cmd, data, flag) 3582395Swnj dev_t dev; 3597631Ssam caddr_t data; 36017Sbill { 36117Sbill register struct tty *tp; 3622395Swnj register int unit = minor(dev); 3632395Swnj register int dz = unit >> 3; 3645731Sroot register struct device *dzaddr; 3658568Sroot int error; 36617Sbill 3672395Swnj tp = &dz_tty[unit]; 3688568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 3698568Sroot if (error >= 0) 3708568Sroot return (error); 3718568Sroot error = ttioctl(tp, cmd, data, flag); 3728568Sroot if (error >= 0) { 3737631Ssam if (cmd == TIOCSETP || cmd == TIOCSETN) 3742395Swnj dzparam(unit); 3758568Sroot return (error); 3768568Sroot } 3778568Sroot switch (cmd) { 3782395Swnj 379170Sbill case TIOCSBRK: 3805731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3815731Sroot if (dzaddr->dzcsr&DZ_32) 3826157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS); 3835731Sroot else 3845731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); 385170Sbill break; 3867631Ssam 387170Sbill case TIOCCBRK: 3885731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; 3895731Sroot if (dzaddr->dzcsr&DZ_32) 3906157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC); 3915731Sroot else 3925731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); 393170Sbill break; 3947631Ssam 395170Sbill case TIOCSDTR: 3966157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); 397170Sbill break; 3987631Ssam 399170Sbill case TIOCCDTR: 4006157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); 401170Sbill break; 4027631Ssam 4035731Sroot case TIOCMSET: 4047631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET); 4055731Sroot break; 4067631Ssam 4075731Sroot case TIOCMBIS: 4087631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS); 4095731Sroot break; 4107631Ssam 4115731Sroot case TIOCMBIC: 4127631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC); 4135731Sroot break; 4147631Ssam 4155731Sroot case TIOCMGET: 4167631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET)); 4175731Sroot break; 4187631Ssam 419170Sbill default: 4208568Sroot return (ENOTTY); 421170Sbill } 4228568Sroot return (0); 42317Sbill } 4245731Sroot 4255731Sroot dmtodz(bits) 4265731Sroot register int bits; 4275731Sroot { 4285731Sroot register int b; 4295731Sroot 4305731Sroot b = (bits >>1) & 0370; 4315731Sroot if (bits & DML_ST) b |= DZ_ST; 4325731Sroot if (bits & DML_RTS) b |= DZ_RTS; 4335731Sroot if (bits & DML_DTR) b |= DZ_DTR; 4345731Sroot if (bits & DML_LE) b |= DZ_LE; 4355731Sroot return(b); 4365731Sroot } 4375731Sroot 4385731Sroot dztodm(bits) 4395731Sroot register int bits; 4405731Sroot { 4415731Sroot register int b; 4425731Sroot 4435731Sroot b = (bits << 1) & 0360; 4445731Sroot if (bits & DZ_DSR) b |= DML_DSR; 4455731Sroot if (bits & DZ_DTR) b |= DML_DTR; 4465731Sroot if (bits & DZ_ST) b |= DML_ST; 4475731Sroot if (bits & DZ_RTS) b |= DML_RTS; 4485731Sroot return(b); 4495731Sroot } 45017Sbill 4512395Swnj dzparam(unit) 4522395Swnj register int unit; 45317Sbill { 45417Sbill register struct tty *tp; 45517Sbill register struct device *dzaddr; 4562395Swnj register int lpr; 45717Sbill 4582395Swnj tp = &dz_tty[unit]; 4592395Swnj dzaddr = dzpdma[unit].p_addr; 46017Sbill dzaddr->dzcsr = DZ_IEN; 4612395Swnj dzact |= (1<<(unit>>3)); 46217Sbill if (tp->t_ispeed == 0) { 4636157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ 46417Sbill return; 46517Sbill } 4662395Swnj lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); 4679551Ssam if (tp->t_flags & (RAW|LITOUT)) 46817Sbill lpr |= BITS8; 46917Sbill else 47017Sbill lpr |= (BITS7|PENABLE); 47117Sbill if ((tp->t_flags & EVENP) == 0) 47217Sbill lpr |= OPAR; 4732469Swnj if (tp->t_ispeed == B110) 4742469Swnj lpr |= TWOSB; 47517Sbill dzaddr->dzlpr = lpr; 47617Sbill } 47717Sbill 47817Sbill dzxint(tp) 4792395Swnj register struct tty *tp; 48017Sbill { 48117Sbill register struct pdma *dp; 4825731Sroot register s, dz, unit; 48317Sbill 4842469Swnj s = spl5(); /* block pdma interrupts */ 4852395Swnj dp = (struct pdma *)tp->t_addr; 4865407Swnj tp->t_state &= ~TS_BUSY; 4875407Swnj if (tp->t_state & TS_FLUSH) 4885407Swnj tp->t_state &= ~TS_FLUSH; 4895731Sroot else { 490281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); 4915731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf; 4925731Sroot } 49317Sbill if (tp->t_line) 49417Sbill (*linesw[tp->t_line].l_start)(tp); 49517Sbill else 49617Sbill dzstart(tp); 4975731Sroot dz = minor(tp->t_dev) >> 3; 4985731Sroot unit = minor(tp->t_dev) & 7; 4995407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) 5005731Sroot if (dp->p_addr->dzcsr & DZ_32) 5015731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit)); 5025731Sroot else 5035731Sroot dp->p_addr->dztcr &= ~(1<<unit); 504145Sbill splx(s); 50517Sbill } 50617Sbill 50717Sbill dzstart(tp) 5082395Swnj register struct tty *tp; 50917Sbill { 51017Sbill register struct pdma *dp; 51117Sbill register struct device *dzaddr; 5122395Swnj register int cc; 5135731Sroot int s, dz, unit; 51417Sbill 5152395Swnj dp = (struct pdma *)tp->t_addr; 51617Sbill dzaddr = dp->p_addr; 5172395Swnj s = spl5(); 5185407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 51917Sbill goto out; 5205407Swnj if (tp->t_outq.c_cc <= TTLOWAT(tp)) { 5215407Swnj if (tp->t_state&TS_ASLEEP) { 5225407Swnj tp->t_state &= ~TS_ASLEEP; 5235407Swnj wakeup((caddr_t)&tp->t_outq); 5245407Swnj } 5255407Swnj if (tp->t_wsel) { 5265407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 5275407Swnj tp->t_wsel = 0; 5285407Swnj tp->t_state &= ~TS_WCOLL; 5295407Swnj } 53017Sbill } 53117Sbill if (tp->t_outq.c_cc == 0) 53217Sbill goto out; 5339551Ssam if (tp->t_flags & (RAW|LITOUT)) 53417Sbill cc = ndqb(&tp->t_outq, 0); 53517Sbill else { 53617Sbill cc = ndqb(&tp->t_outq, 0200); 53717Sbill if (cc == 0) { 53817Sbill cc = getc(&tp->t_outq); 5392469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); 5405407Swnj tp->t_state |= TS_TIMEOUT; 54117Sbill goto out; 54217Sbill } 54317Sbill } 5445407Swnj tp->t_state |= TS_BUSY; 54517Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf; 54617Sbill dp->p_end += cc; 5475731Sroot dz = minor(tp->t_dev) >> 3; 5485731Sroot unit = minor(tp->t_dev) & 7; 5495731Sroot if (dzaddr->dzcsr & DZ_32) 5505731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit)); 5515731Sroot else 5525731Sroot dzaddr->dztcr |= (1<<unit); 5532395Swnj out: 5542395Swnj splx(s); 55517Sbill } 55617Sbill 55717Sbill /* 55817Sbill * Stop output on a line. 55917Sbill */ 56017Sbill /*ARGSUSED*/ 56117Sbill dzstop(tp, flag) 5622395Swnj register struct tty *tp; 56317Sbill { 56417Sbill register struct pdma *dp; 56517Sbill register int s; 56617Sbill 5672395Swnj dp = (struct pdma *)tp->t_addr; 5682457Swnj s = spl5(); 5695407Swnj if (tp->t_state & TS_BUSY) { 57017Sbill dp->p_end = dp->p_mem; 5715407Swnj if ((tp->t_state&TS_TTSTOP)==0) 5725407Swnj tp->t_state |= TS_FLUSH; 57317Sbill } 57417Sbill splx(s); 57517Sbill } 57617Sbill 5775731Sroot dzmctl(dev, bits, how) 5785731Sroot dev_t dev; 5795731Sroot int bits, how; 58017Sbill { 58117Sbill register struct device *dzaddr; 5825731Sroot register int unit, mbits; 5835731Sroot int b, s; 5845731Sroot 5855731Sroot unit = minor(dev); 5865731Sroot b = 1<<(unit&7); 5872395Swnj dzaddr = dzpdma[unit].p_addr; 5885731Sroot s = spl5(); 5895731Sroot if (dzaddr->dzcsr & DZ_32) { 5905731Sroot dzwait(dzaddr) 5915731Sroot DELAY(100); /* IS 100 TOO MUCH? */ 5925731Sroot dzaddr->dzlcs = unit&7; 5935731Sroot DELAY(100); 5945731Sroot dzwait(dzaddr) 5955731Sroot DELAY(100); 5965731Sroot mbits = dzaddr->dzlcs; 5975731Sroot mbits &= 0177770; 5985731Sroot } else { 5995731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; 6005731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; 6015731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; 6025731Sroot } 6035731Sroot switch (how) { 6045731Sroot case DMSET: 6055731Sroot mbits = bits; 6065731Sroot break; 6075731Sroot 6085731Sroot case DMBIS: 6095731Sroot mbits |= bits; 6105731Sroot break; 6115731Sroot 6125731Sroot case DMBIC: 6135731Sroot mbits &= ~bits; 6145731Sroot break; 6155731Sroot 6165731Sroot case DMGET: 6175731Sroot (void) splx(s); 6185731Sroot return(mbits); 6195731Sroot } 6205731Sroot if (dzaddr->dzcsr & DZ_32) { 6215731Sroot mbits |= DZ_ACK|(unit&7); 6225731Sroot dzaddr->dzlcs = mbits; 6235731Sroot } else { 6245731Sroot if (mbits & DZ_DTR) 6255731Sroot dzaddr->dzdtr |= b; 6265731Sroot else 6275731Sroot dzaddr->dzdtr &= ~b; 6285731Sroot } 6295731Sroot (void) splx(s); 6305731Sroot return(mbits); 63117Sbill } 63217Sbill 63317Sbill dzscan() 63417Sbill { 63517Sbill register i; 63617Sbill register struct device *dzaddr; 63717Sbill register bit; 63817Sbill register struct tty *tp; 6395731Sroot register car; 64017Sbill 64117Sbill for (i = 0; i < dz_cnt ; i++) { 64217Sbill dzaddr = dzpdma[i].p_addr; 6432627Swnj if (dzaddr == 0) 6442627Swnj continue; 64517Sbill tp = &dz_tty[i]; 64617Sbill bit = 1<<(i&07); 6475731Sroot car = 0; 6485731Sroot if (dzsoftCAR[i>>3]&bit) 6495731Sroot car = 1; 6505731Sroot else if (dzaddr->dzcsr & DZ_32) { 6515731Sroot dzaddr->dzlcs = i&07; 6525731Sroot dzwait(dzaddr); 6535731Sroot car = dzaddr->dzlcs & DZ_CD; 6545731Sroot } else 6555731Sroot car = dzaddr->dzmsr&bit; 6565731Sroot if (car) { 65717Sbill /* carrier present */ 6585407Swnj if ((tp->t_state & TS_CARR_ON) == 0) { 65917Sbill wakeup((caddr_t)&tp->t_rawq); 6605407Swnj tp->t_state |= TS_CARR_ON; 66117Sbill } 66217Sbill } else { 6635407Swnj if ((tp->t_state&TS_CARR_ON) && 6649551Ssam (tp->t_flags&NOHANG) == 0) { 66517Sbill /* carrier lost */ 6665407Swnj if (tp->t_state&TS_ISOPEN) { 667170Sbill gsignal(tp->t_pgrp, SIGHUP); 668205Sbill gsignal(tp->t_pgrp, SIGCONT); 669170Sbill dzaddr->dzdtr &= ~bit; 670871Sbill flushtty(tp, FREAD|FWRITE); 671170Sbill } 6725407Swnj tp->t_state &= ~TS_CARR_ON; 67317Sbill } 67417Sbill } 67517Sbill } 6762756Swnj timeout(dzscan, (caddr_t)0, 2*hz); 67717Sbill } 678119Sbill 679119Sbill dztimer() 680119Sbill { 6818160Sroot register int dz; 6828160Sroot register int s = spl5(); 683119Sbill 6842645Swnj for (dz = 0; dz < NDZ; dz++) 6852457Swnj dzrint(dz); 6868160Sroot splx(s); 687119Sbill } 688281Sbill 689281Sbill /* 690281Sbill * Reset state of driver if UBA reset was necessary. 691301Sbill * Reset parameters and restart transmission on open lines. 692281Sbill */ 6932395Swnj dzreset(uban) 6942422Skre int uban; 695281Sbill { 6962395Swnj register int unit; 697281Sbill register struct tty *tp; 6982976Swnj register struct uba_device *ui; 699281Sbill 7002645Swnj for (unit = 0; unit < NDZLINE; unit++) { 7012422Skre ui = dzinfo[unit >> 3]; 7022422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) 7032422Skre continue; 7042923Swnj if (unit%8 == 0) 7052923Swnj printf(" dz%d", unit>>3); 7062395Swnj tp = &dz_tty[unit]; 7075407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 7082395Swnj dzparam(unit); 7096157Ssam (void) dzmctl(unit, DZ_ON, DMSET); 7105407Swnj tp->t_state &= ~TS_BUSY; 711301Sbill dzstart(tp); 712281Sbill } 713281Sbill } 714281Sbill dztimer(); 715281Sbill } 7161562Sbill #endif 717