X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/b25a5292decdb3145016542d03c8b0604dc025d1..de59ccc2375aad4c9f0ff41f3291584ead755f15:/usr/src/sys/vax/uba/dz.c?ds=inline diff --git a/usr/src/sys/vax/uba/dz.c b/usr/src/sys/vax/uba/dz.c index 6665dbb1d6..6d0c76d767 100644 --- a/usr/src/sys/vax/uba/dz.c +++ b/usr/src/sys/vax/uba/dz.c @@ -1,415 +1,629 @@ -/* dz.c 3.16 %G% */ +/* dz.c 4.38 82/05/19 */ +#include "dz.h" +#if NDZ > 0 /* - * DZ-11 Driver + * DZ-11 and DZ32 Driver + * + * This driver mimics dh.c; see it for explanation of common code. */ +#include "bk.h" #include "../h/param.h" #include "../h/systm.h" #include "../h/tty.h" #include "../h/dir.h" #include "../h/user.h" +#include "../h/proc.h" #include "../h/map.h" #include "../h/pte.h" -#include "../h/uba.h" +#include "../h/buf.h" +#include "../h/vm.h" +#include "../h/ubavar.h" #include "../h/conf.h" #include "../h/pdma.h" #include "../h/bk.h" #include "../h/file.h" /* - * When running dz's using only SAE (silo alarm) on input - * it is necessary to call dzrint() at clock interrupt time. - * This is unsafe unless spl5()s in tty code are changed to - * spl6()s to block clock interrupts. Note that the dh driver - * currently in use works the same way as the dz, even though - * we could try to more intelligently manage its silo. - * Thus don't take this out if you have no dz's unless you - * change clock.c and dhtimer(). + * Driver information for auto-configuration stuff. */ -#define spl5 spl6 - -#define DZADDR (UBA0_DEV + 0160100) -#ifdef DISTRIB -#define NDZ11 1 -#else -#define NDZ11 4 -#endif -#define NDZ (NDZ11*8) - -#define BITS7 020 -#define BITS8 030 -#define TWOSB 040 -#define PENABLE 0100 -#define OPAR 0200 -#define MSE 040 /* Master Scan Enable */ -#define RIE 0100 /* Receiver Interrupt Enable */ -#define SAE 010000 /* Silo Alarm Enable */ -#define TIE 040000 /* Transmit Interrupt Enable */ -#define DZ_IEN (MSE+RIE+TIE+SAE) -#define PERROR 010000 -#define FRERROR 020000 -#define OVERRUN 040000 -#define SSPEED 7 /* std speed = 300 baud */ +int dzprobe(), dzattach(), dzrint(); +struct uba_device *dzinfo[NDZ]; +u_short dzstd[] = { 0 }; +struct uba_driver dzdriver = + { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo }; +#define NDZLINE (NDZ*8) -#define dzlpr dzrbuf -#define dzmsr dzbrk -#define ON 1 -#define OFF 0 +/* + * Registers and bits + */ + +/* bits in dzlpr */ +#define BITS7 0020 +#define BITS8 0030 +#define TWOSB 0040 +#define PENABLE 0100 +#define OPAR 0200 + +/* bits in dzrbuf */ +#define DZ_PE 010000 +#define DZ_FE 020000 +#define DZ_DO 040000 + +/* bits in dzcsr */ +#define DZ_32 000001 /* DZ32 mode */ +#define DZ_MIE 000002 /* Modem Interrupt Enable */ +#define DZ_CLR 000020 /* Reset dz */ +#define DZ_MSE 000040 /* Master Scan Enable */ +#define DZ_RIE 000100 /* Receiver Interrupt Enable */ +#define DZ_MSC 004000 /* Modem Status Change */ +#define DZ_SAE 010000 /* Silo Alarm Enable */ +#define DZ_TIE 040000 /* Transmit Interrupt Enable */ +#define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE) + +/* flags for modem-control */ +#define DZ_ON DZ_DTR +#define DZ_OFF 0 + +/* bits in dzlcs */ +#define DZ_ACK 0100000 /* ACK bit in dzlcs */ +#define DZ_RTS 0010000 /* Request To Send */ +#define DZ_ST 0004000 /* Secondary Transmit */ +#define DZ_BRK 0002000 /* Break */ +#define DZ_DTR 0001000 /* Data Terminal Ready */ +#define DZ_LE 0000400 /* Line Enable */ +#define DZ_DSR 0000200 /* Data Set Ready */ +#define DZ_RI 0000100 /* Ring Indicate */ +#define DZ_CD 0000040 /* Carrier Detect */ +#define DZ_CTS 0000020 /* Clear To Send */ +#define DZ_SR 0000010 /* Secondary Receive */ -int dzstart(); -int dzxint(); +/* bits in dm lsr, copied from dh.c */ +#define DML_DSR 0000400 /* data set ready, not a real DM bit */ +#define DML_RNG 0000200 /* ring */ +#define DML_CAR 0000100 /* carrier detect */ +#define DML_CTS 0000040 /* clear to send */ +#define DML_SR 0000020 /* secondary receive */ +#define DML_ST 0000010 /* secondary transmit */ +#define DML_RTS 0000004 /* request to send */ +#define DML_DTR 0000002 /* data terminal ready */ +#define DML_LE 0000001 /* line enable */ + +int dzstart(), dzxint(), dzdma(); int ttrstrt(); -struct tty dz_tty[NDZ]; -int dz_cnt = { NDZ }; +struct tty dz_tty[NDZLINE]; +int dz_cnt = { NDZLINE }; int dzact; -int dzinit; struct device { - short dzcsr; - short dzrbuf; - char dztcr; - char dzdtr; - char dztbuf; - char dzbrk; + short dzcsr; + short dzrbuf; + union { + struct { + char dztcr0; + char dzdtr0; + char dztbuf0; + char dzbrk0; + } dz11; + struct { + short dzlcs0; + char dztbuf0; + char dzlnen0; + } dz32; + } dzun; }; -struct pdma dzpdma[] = { - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint, - (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint, -#if NDZ >= 2 - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint, - (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint, -#endif -#if NDZ >= 3 - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint, - (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint, +#define dzlpr dzrbuf +#define dzmsr dzun.dz11.dzbrk0 +#define dztcr dzun.dz11.dztcr0 +#define dzdtr dzun.dz11.dzdtr0 +#define dztbuf dzun.dz11.dztbuf0 +#define dzlcs dzun.dz32.dzlcs0 +#define dzbrk dzmsr +#define dzlnen dzun.dz32.dzlnen0 +#define dzmtsr dzun.dz32.dztbuf0; + +#define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0) + +/* + * Software copy of dzbrk since it isn't readable + */ +char dz_brk[NDZ]; +char dzsoftCAR[NDZ]; +char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */ + +/* + * The dz11 doesn't interrupt on carrier transitions, so + * we have to use a timer to watch it. + */ +char dz_timer; /* timer started? */ + +/* + * Pdma structures for fast output code + */ +struct pdma dzpdma[NDZLINE]; + +char dz_speeds[] = + { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 }; + +#ifndef PORTSELECTOR +#define ISPEED B300 +#define IFLAGS (EVENP|ODDP|ECHO) +#else +#define ISPEED B4800 +#define IFLAGS (EVENP|ODDP) #endif -#if NDZ >= 4 - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint, - (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint, + +dzprobe(reg) + caddr_t reg; +{ + register int br, cvec; + register struct device *dzaddr = (struct device *)reg; + +#ifdef lint + br = 0; cvec = br; br = cvec; + dzrint(0); dzxint((struct tty *)0); #endif -}; -char dz_timer; -char dz_speeds[] = { - 0, 020 , 021 , 022 , 023 , 024 , 0, 025, - 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0, -}; - + dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32; + if (dzaddr->dzcsr & DZ_32) + dzaddr->dzlnen = 1; + else + dzaddr->dztcr = 1; /* enable any line */ + DELAY(100000); + dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */ + if (cvec && cvec != 0x200) + cvec -= 4; + return (1); +} + +dzattach(ui) + register struct uba_device *ui; +{ + register struct pdma *pdp = &dzpdma[ui->ui_unit*8]; + register struct tty *tp = &dz_tty[ui->ui_unit*8]; + register int cntr; + extern dzscan(); + + for (cntr = 0; cntr < 8; cntr++) { + pdp->p_addr = (struct device *)ui->ui_addr; + pdp->p_arg = (int)tp; + pdp->p_fcn = dzxint; + pdp++, tp++; + } + dzsoftCAR[ui->ui_unit] = ui->ui_flags; + if (dz_timer == 0) { + dz_timer++; + timeout(dzscan, (caddr_t)0, hz); + } +} + /*ARGSUSED*/ -dzopen(d, flag) +dzopen(dev, flag) + dev_t dev; { register struct tty *tp; - register dev; - extern dzscan(); + register int unit; - dev = minor(d); - if (dev >= dz_cnt) { + unit = minor(dev); + if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) { u.u_error = ENXIO; return; } - if (dz_timer == 0) { - dz_timer++; - timeout(dzscan, (caddr_t)0, 60); - } - tp = &dz_tty[dev]; - tp->t_addr = (caddr_t)&dzpdma[dev]; + tp = &dz_tty[unit]; + tp->t_addr = (caddr_t)&dzpdma[unit]; tp->t_oproc = dzstart; - tp->t_iproc = NULL; - tp->t_state |= WOPEN; - if ((tp->t_state & ISOPEN) == 0) { + tp->t_state |= TS_WOPEN; + if ((tp->t_state & TS_ISOPEN) == 0) { ttychars(tp); - tp->t_ospeed = tp->t_ispeed = SSPEED; - tp->t_flags = ODDP|EVENP|ECHO; - /*tp->t_state |= HUPCLS;*/ - dzparam(dev); - } else if (tp->t_state&XCLUDE && u.u_uid != 0) { + tp->t_ospeed = tp->t_ispeed = ISPEED; + tp->t_flags = IFLAGS; + /* tp->t_state |= TS_HUPCLS; */ + dzparam(unit); + } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) { u.u_error = EBUSY; return; } - dzmodem(dev, ON); + (void) dzmctl(dev, DZ_ON, DMSET); (void) spl5(); - while ((tp->t_state & CARR_ON) == 0) { - tp->t_state |= WOPEN; + while ((tp->t_state & TS_CARR_ON) == 0) { + tp->t_state |= TS_WOPEN; sleep((caddr_t)&tp->t_rawq, TTIPRI); } (void) spl0(); - (*linesw[tp->t_line].l_open)(d, tp); + (*linesw[tp->t_line].l_open)(dev, tp); } -dzclose(d) +/*ARGSUSED*/ +dzclose(dev, flag) + dev_t dev; { register struct tty *tp; - register dev; + register int unit; + register struct device *dzaddr; + int dz; - dev = minor(d); - tp = &dz_tty[dev]; + unit = minor(dev); + dz = unit >> 3; + tp = &dz_tty[unit]; (*linesw[tp->t_line].l_close)(tp); - if (tp->t_state & HUPCLS) - dzmodem(dev, OFF); + dzaddr = dzpdma[unit].p_addr; + if (dzaddr->dzcsr&DZ_32) + (void) dzmctl(dev, DZ_BRK, DMBIC); + else + dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); + if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0) + (void) dzmctl(dev, DZ_OFF, DMSET); ttyclose(tp); } -dzread(d) +dzread(dev) + dev_t dev; { register struct tty *tp; - tp = &dz_tty[minor(d)]; + tp = &dz_tty[minor(dev)]; (*linesw[tp->t_line].l_read)(tp); } -dzwrite(d) +dzwrite(dev) + dev_t dev; { register struct tty *tp; - tp = &dz_tty[minor(d)]; + tp = &dz_tty[minor(dev)]; (*linesw[tp->t_line].l_write)(tp); } /*ARGSUSED*/ -dzrint(dev) +dzrint(dz) + int dz; { register struct tty *tp; register int c; register struct device *dzaddr; register struct tty *tp0; - int s; + register int unit; + int overrun = 0; - s = spl6(); /* see comment in clock.c */ - /* as long as we are here, service them all */ - for (dev = 0; dev < NDZ; dev += 8) { - if ((dzact & (1<<(dev>>3))) == 0) - continue; - dzaddr = dzpdma[dev].p_addr; - tp0 = &dz_tty[dev]; - while ((c = dzaddr->dzrbuf) < 0) { /* char present */ - tp = tp0 + ((c>>8)&07); - if (tp >= &dz_tty[dz_cnt]) - continue; - if ((tp->t_state & ISOPEN) == 0) { + if ((dzact & (1<dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */ + dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */ + while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */ + c = dzaddr->dzmtsr; + tp = tp0 + (c&7); + if (tp >= &dz_tty[dz_cnt]) + break; + dzaddr->dzlcs = c&7; /* get status of modem lines */ + dzwait(dzaddr); /* wait for them */ + if (c & DZ_CD) /* carrier status change? */ + if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */ + if ((tp->t_state&TS_CARR_ON) == 0) { wakeup((caddr_t)&tp->t_rawq); - continue; + tp->t_state |= TS_CARR_ON; } - if (c&FRERROR) - /* framing error = break */ - if (tp->t_flags & RAW) - c = 0; /* null for getty */ - else -#ifdef IIASA - continue; -#else - c = tun.t_intrc; + } else { /* no carrier */ + if (tp->t_state&TS_CARR_ON) { + gsignal(tp->t_pgrp, SIGHUP); + gsignal(tp->t_pgrp, SIGCONT); + dzaddr->dzlcs = DZ_ACK|(c&7); + flushtty(tp, FREAD|FWRITE); + } + tp->t_state &= ~TS_CARR_ON; + } + } + while ((c = dzaddr->dzrbuf) < 0) { /* char present */ + tp = tp0 + ((c>>8)&07); + if (tp >= &dz_tty[dz_cnt]) + continue; + if ((tp->t_state & TS_ISOPEN) == 0) { + wakeup((caddr_t)&tp->t_rawq); +#ifdef PORTSELECTOR + if ((tp->t_state&TS_WOPEN) == 0) #endif - if (c&OVERRUN) - printf("o"); - if (c&PERROR) - /* parity error */ - if (((tp->t_flags & (EVENP|ODDP)) == EVENP) - || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) - continue; - if (tp->t_line == NETLDISC) { - c &= 0177; - BKINPUT(c, tp); - } else - (*linesw[tp->t_line].l_rint)(c, tp); + continue; + } + if (c&DZ_FE) + if (tp->t_flags & RAW) + c = 0; + else + c = tun.t_intrc; + if (c&DZ_DO && overrun == 0) { + /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */ + overrun = 1; } + if (c&DZ_PE) + if (((tp->t_flags & (EVENP|ODDP)) == EVENP) + || ((tp->t_flags & (EVENP|ODDP)) == ODDP)) + continue; +#if NBK > 0 + if (tp->t_line == NETLDISC) { + c &= 0177; + BKINPUT(c, tp); + } else +#endif + (*linesw[tp->t_line].l_rint)(c, tp); } - splx(s); } /*ARGSUSED*/ dzioctl(dev, cmd, addr, flag) -caddr_t addr; -dev_t dev; + dev_t dev; + caddr_t addr; { register struct tty *tp; - static char dz_brk[NDZ11]; + register int unit = minor(dev); + register int dz = unit >> 3; + register struct device *dzaddr; + int temp; - tp = &dz_tty[minor(dev)]; + tp = &dz_tty[unit]; cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr); if (cmd == 0) return; - if (ttioctl(cmd, tp, addr, dev, flag)) { + if (ttioctl(tp, cmd, addr, flag)) { if (cmd==TIOCSETP || cmd==TIOCSETN) - dzparam(minor(dev)); + dzparam(unit); } else switch(cmd) { + case TIOCSBRK: - ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = - (dz_brk[minor(dev)>>3] |= 1 << (dev&07)); + dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; + if (dzaddr->dzcsr&DZ_32) + (void) dzmctl(dev, DZ_BRK, DMBIS); + else + dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07)); break; case TIOCCBRK: - ((struct pdma *)(tp->t_addr))->p_addr->dzbrk = - (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07))); + dzaddr = ((struct pdma *)(tp->t_addr))->p_addr; + if (dzaddr->dzcsr&DZ_32) + (void) dzmctl(dev, DZ_BRK, DMBIC); + else + dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07))); break; case TIOCSDTR: - dzmodem(minor(dev), ON); + (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS); break; case TIOCCDTR: - dzmodem(minor(dev), OFF); + (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC); + break; + case TIOCMSET: + if (copyin(addr, (caddr_t) &temp, sizeof(temp))) + u.u_error = EFAULT; + else + (void) dzmctl(dev, dmtodz(temp), DMSET); + break; + case TIOCMBIS: + if (copyin(addr, (caddr_t) &temp, sizeof(temp))) + u.u_error = EFAULT; + else + (void) dzmctl(dev, dmtodz(temp), DMBIS); + break; + case TIOCMBIC: + if (copyin(addr, (caddr_t) &temp, sizeof(temp))) + u.u_error = EFAULT; + else + (void) dzmctl(dev, dmtodz(temp), DMBIC); + break; + case TIOCMGET: + temp = dztodm(dzmctl(dev, 0, DMGET)); + if (copyout((caddr_t) &temp, addr, sizeof(temp))) + u.u_error = EFAULT; break; default: u.u_error = ENOTTY; } } + +dmtodz(bits) + register int bits; +{ + register int b; + + b = (bits >>1) & 0370; + if (bits & DML_ST) b |= DZ_ST; + if (bits & DML_RTS) b |= DZ_RTS; + if (bits & DML_DTR) b |= DZ_DTR; + if (bits & DML_LE) b |= DZ_LE; + return(b); +} + +dztodm(bits) + register int bits; +{ + register int b; + + b = (bits << 1) & 0360; + if (bits & DZ_DSR) b |= DML_DSR; + if (bits & DZ_DTR) b |= DML_DTR; + if (bits & DZ_ST) b |= DML_ST; + if (bits & DZ_RTS) b |= DML_RTS; + return(b); +} -dzparam(dev) +dzparam(unit) + register int unit; { register struct tty *tp; register struct device *dzaddr; - register short lpr; + register int lpr; - tp = &dz_tty[dev]; - dzaddr = dzpdma[dev].p_addr; + tp = &dz_tty[unit]; + dzaddr = dzpdma[unit].p_addr; dzaddr->dzcsr = DZ_IEN; - dzact |= (1<<(dev>>3)); + dzact |= (1<<(unit>>3)); if (tp->t_ispeed == 0) { - dzmodem(dev, OFF); /* hang up line */ + (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */ return; } - lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07); -#ifndef IIASA - if (tp->t_flags & RAW) + lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07); + if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW)) lpr |= BITS8; else lpr |= (BITS7|PENABLE); if ((tp->t_flags & EVENP) == 0) lpr |= OPAR; -#else IIASA - if ((tp->t_flags & (EVENP|ODDP)) == (EVENP|ODDP)) - lpr |= BITS8; - else if (tp->t_flags & EVENP) - lpr |= (BITS7|PENABLE); - else if (tp->t_flags & ODDP) - lpr |= (BITS7|OPAR|PENABLE); - else - lpr |= BITS7; -#endif IIASA - if (tp->t_ispeed == 3) - lpr |= TWOSB; /* 110 baud: 2 stop bits */ + if (tp->t_ispeed == B110) + lpr |= TWOSB; dzaddr->dzlpr = lpr; } dzxint(tp) -register struct tty *tp; + register struct tty *tp; { register struct pdma *dp; - register s; - s = spl6(); /* block the clock */ + register s, dz, unit; - dp = &dzpdma[tp-dz_tty]; - tp->t_state &= ~BUSY; - if (tp->t_state & FLUSH) - tp->t_state &= ~FLUSH; - else + s = spl5(); /* block pdma interrupts */ + dp = (struct pdma *)tp->t_addr; + tp->t_state &= ~TS_BUSY; + if (tp->t_state & TS_FLUSH) + tp->t_state &= ~TS_FLUSH; + else { ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf); + dp->p_end = dp->p_mem = tp->t_outq.c_cf; + } if (tp->t_line) (*linesw[tp->t_line].l_start)(tp); else dzstart(tp); - if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0) - dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8)); + dz = minor(tp->t_dev) >> 3; + unit = minor(tp->t_dev) & 7; + if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0) + if (dp->p_addr->dzcsr & DZ_32) + dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<p_addr->dztcr &= ~(1<t_addr; dzaddr = dp->p_addr; - sps = spl5(); - if (tp->t_state & (TIMEOUT|BUSY|TTSTOP)) + s = spl5(); + if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) goto out; - if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) { - tp->t_state &= ~ASLEEP; - if (tp->t_chan) - mcstart(tp->t_chan, (caddr_t)&tp->t_outq); - else + if (tp->t_outq.c_cc <= TTLOWAT(tp)) { + if (tp->t_state&TS_ASLEEP) { + tp->t_state &= ~TS_ASLEEP; wakeup((caddr_t)&tp->t_outq); + } + if (tp->t_wsel) { + selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); + tp->t_wsel = 0; + tp->t_state &= ~TS_WCOLL; + } } if (tp->t_outq.c_cc == 0) goto out; - if (tp->t_flags&RAW) + if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT)) cc = ndqb(&tp->t_outq, 0); else { cc = ndqb(&tp->t_outq, 0200); if (cc == 0) { cc = getc(&tp->t_outq); - timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6); - tp->t_state |= TIMEOUT; + timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6); + tp->t_state |= TS_TIMEOUT; goto out; } } - tp->t_state |= BUSY; + tp->t_state |= TS_BUSY; dp->p_end = dp->p_mem = tp->t_outq.c_cf; dp->p_end += cc; - dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8); - out: - splx(sps); + dz = minor(tp->t_dev) >> 3; + unit = minor(tp->t_dev) & 7; + if (dzaddr->dzcsr & DZ_32) + dzaddr->dzlnen = (dz_lnen[dz] |= (1<dztcr |= (1<t_state & BUSY) { + dp = (struct pdma *)tp->t_addr; + s = spl5(); + if (tp->t_state & TS_BUSY) { dp->p_end = dp->p_mem; - if ((tp->t_state&TTSTOP)==0) { - tp->t_state |= FLUSH; - } + if ((tp->t_state&TS_TTSTOP)==0) + tp->t_state |= TS_FLUSH; } splx(s); } -dzmodem(dev, flag) -register int dev; +dzmctl(dev, bits, how) + dev_t dev; + int bits, how; { register struct device *dzaddr; - register char bit; - - dzaddr = dzpdma[dev].p_addr; - bit = 1<<(dev&07); - if (flag == OFF) - dzaddr->dzdtr &= ~bit; - else - dzaddr->dzdtr |= bit; + register int unit, mbits; + int b, s; + + unit = minor(dev); + b = 1<<(unit&7); + dzaddr = dzpdma[unit].p_addr; + s = spl5(); + if (dzaddr->dzcsr & DZ_32) { + dzwait(dzaddr) + DELAY(100); /* IS 100 TOO MUCH? */ + dzaddr->dzlcs = unit&7; + DELAY(100); + dzwait(dzaddr) + DELAY(100); + mbits = dzaddr->dzlcs; + mbits &= 0177770; + } else { + mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0; + mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0; + mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0; + } + switch (how) { + case DMSET: + mbits = bits; + break; + + case DMBIS: + mbits |= bits; + break; + + case DMBIC: + mbits &= ~bits; + break; + + case DMGET: + (void) splx(s); + return(mbits); + } + if (dzaddr->dzcsr & DZ_32) { + mbits |= DZ_ACK|(unit&7); + dzaddr->dzlcs = mbits; + } else { + if (mbits & DZ_DTR) + dzaddr->dzdtr |= b; + else + dzaddr->dzdtr &= ~b; + } + (void) splx(s); + return(mbits); } dzscan() @@ -418,57 +632,79 @@ dzscan() register struct device *dzaddr; register bit; register struct tty *tp; + register car; for (i = 0; i < dz_cnt ; i++) { dzaddr = dzpdma[i].p_addr; + if (dzaddr == 0) + continue; tp = &dz_tty[i]; bit = 1<<(i&07); - if (dzaddr->dzmsr & bit) { + car = 0; + if (dzsoftCAR[i>>3]&bit) + car = 1; + else if (dzaddr->dzcsr & DZ_32) { + dzaddr->dzlcs = i&07; + dzwait(dzaddr); + car = dzaddr->dzlcs & DZ_CD; + } else + car = dzaddr->dzmsr&bit; + if (car) { /* carrier present */ - if ((tp->t_state & CARR_ON) == 0) { + if ((tp->t_state & TS_CARR_ON) == 0) { wakeup((caddr_t)&tp->t_rawq); - tp->t_state |= CARR_ON; + tp->t_state |= TS_CARR_ON; } } else { - if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) { + if ((tp->t_state&TS_CARR_ON) && + (tp->t_local&LNOHANG)==0) { /* carrier lost */ - if (tp->t_state&ISOPEN) { + if (tp->t_state&TS_ISOPEN) { gsignal(tp->t_pgrp, SIGHUP); gsignal(tp->t_pgrp, SIGCONT); dzaddr->dzdtr &= ~bit; flushtty(tp, FREAD|FWRITE); } - tp->t_state &= ~CARR_ON; + tp->t_state &= ~TS_CARR_ON; } } } - timeout(dzscan, (caddr_t)0, 2*HZ); + timeout(dzscan, (caddr_t)0, 2*hz); } dztimer() { + int dz; - dzrint(0); + for (dz = 0; dz < NDZ; dz++) + dzrint(dz); } /* * Reset state of driver if UBA reset was necessary. * Reset parameters and restart transmission on open lines. */ -dzreset() +dzreset(uban) + int uban; { - int d; + register int unit; register struct tty *tp; + register struct uba_device *ui; - printf(" dz"); - for (d = 0; d < NDZ; d++) { - tp = &dz_tty[d]; - if (tp->t_state & (ISOPEN|WOPEN)) { - dzparam(d); - dzmodem(d, ON); - tp->t_state &= ~BUSY; + for (unit = 0; unit < NDZLINE; unit++) { + ui = dzinfo[unit >> 3]; + if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0) + continue; + if (unit%8 == 0) + printf(" dz%d", unit>>3); + tp = &dz_tty[unit]; + if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { + dzparam(unit); + (void) dzmctl(unit, DZ_ON, DMSET); + tp->t_state &= ~TS_BUSY; dzstart(tp); } } dztimer(); } +#endif