xref: /csrg-svn/sys/vax/uba/dz.c (revision 10869)
1*10869Ssam /*	dz.c	4.50	83/02/10	*/
217Sbill 
31935Swnj #include "dz.h"
42645Swnj #if NDZ > 0
517Sbill /*
610019Ssam  *  DZ-11/DZ-32 Driver
72469Swnj  *
82469Swnj  * This driver mimics dh.c; see it for explanation of common code.
917Sbill  */
102731Swnj #include "bk.h"
119773Ssam 
129773Ssam #include "../machine/pte.h"
139773Ssam 
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"
28*10869Ssam #include "../h/kernel.h"
29145Sbill 
308474Sroot #include "../vaxuba/pdma.h"
318474Sroot #include "../vaxuba/ubavar.h"
3210019Ssam #include "../vaxuba/dzreg.h"
338474Sroot 
342469Swnj /*
352469Swnj  * Driver information for auto-configuration stuff.
362469Swnj  */
372606Swnj int	dzprobe(), dzattach(), dzrint();
382976Swnj struct	uba_device *dzinfo[NDZ];
392395Swnj u_short	dzstd[] = { 0 };
402395Swnj struct	uba_driver dzdriver =
412606Swnj 	{ dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
422395Swnj 
432645Swnj #define	NDZLINE 	(NDZ*8)
442469Swnj 
452469Swnj int	dzstart(), dzxint(), dzdma();
46114Sbill int	ttrstrt();
472645Swnj struct	tty dz_tty[NDZLINE];
482645Swnj int	dz_cnt = { NDZLINE };
49119Sbill int	dzact;
5017Sbill 
515731Sroot #define dzwait(x)	while (((x)->dzlcs & DZ_ACK) == 0)
525731Sroot 
532469Swnj /*
542469Swnj  * Software copy of dzbrk since it isn't readable
552469Swnj  */
562645Swnj char	dz_brk[NDZ];
572645Swnj char	dzsoftCAR[NDZ];
585731Sroot char	dz_lnen[NDZ];	/* saved line enable bits for DZ32 */
5917Sbill 
602469Swnj /*
615731Sroot  * The dz11 doesn't interrupt on carrier transitions, so
622469Swnj  * we have to use a timer to watch it.
632469Swnj  */
642469Swnj char	dz_timer;		/* timer started? */
652469Swnj 
662469Swnj /*
672469Swnj  * Pdma structures for fast output code
682469Swnj  */
692645Swnj struct	pdma dzpdma[NDZLINE];
702469Swnj 
712395Swnj char	dz_speeds[] =
726814Swnj 	{ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };
7317Sbill 
746616Ssam #ifndef PORTSELECTOR
756616Ssam #define	ISPEED	B300
766616Ssam #define	IFLAGS	(EVENP|ODDP|ECHO)
776616Ssam #else
786616Ssam #define	ISPEED	B4800
796616Ssam #define	IFLAGS	(EVENP|ODDP)
806616Ssam #endif
816616Ssam 
822606Swnj dzprobe(reg)
832395Swnj 	caddr_t reg;
842395Swnj {
852457Swnj 	register int br, cvec;
8610019Ssam 	register struct dzdevice *dzaddr = (struct dzdevice *)reg;
872395Swnj 
882606Swnj #ifdef lint
893102Swnj 	br = 0; cvec = br; br = cvec;
904933Swnj 	dzrint(0); dzxint((struct tty *)0);
912606Swnj #endif
925731Sroot 	dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32;
935731Sroot 	if (dzaddr->dzcsr & DZ_32)
945731Sroot 		dzaddr->dzlnen = 1;
955731Sroot 	else
965731Sroot 		dzaddr->dztcr = 1;		/* enable any line */
972457Swnj 	DELAY(100000);
985731Sroot 	dzaddr->dzcsr = DZ_CLR|DZ_32;		/* reset everything */
992457Swnj 	if (cvec && cvec != 0x200)
1002457Swnj 		cvec -= 4;
10110019Ssam 	return (sizeof (struct dzdevice));
1022395Swnj }
1032395Swnj 
1042606Swnj dzattach(ui)
1052976Swnj 	register struct uba_device *ui;
1062395Swnj {
1072395Swnj 	register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
1082395Swnj 	register struct tty *tp = &dz_tty[ui->ui_unit*8];
1092606Swnj 	register int cntr;
1102645Swnj 	extern dzscan();
1112395Swnj 
1122606Swnj 	for (cntr = 0; cntr < 8; cntr++) {
11310019Ssam 		pdp->p_addr = (struct dzdevice *)ui->ui_addr;
1142395Swnj 		pdp->p_arg = (int)tp;
1152395Swnj 		pdp->p_fcn = dzxint;
1162395Swnj 		pdp++, tp++;
1172395Swnj 	}
1182567Swnj 	dzsoftCAR[ui->ui_unit] = ui->ui_flags;
1192627Swnj 	if (dz_timer == 0) {
1202627Swnj 		dz_timer++;
1212756Swnj 		timeout(dzscan, (caddr_t)0, hz);
1222627Swnj 	}
1232395Swnj }
1242395Swnj 
12517Sbill /*ARGSUSED*/
1262395Swnj dzopen(dev, flag)
1272395Swnj 	dev_t dev;
12817Sbill {
12917Sbill 	register struct tty *tp;
1302395Swnj 	register int unit;
13117Sbill 
1322395Swnj 	unit = minor(dev);
1338568Sroot 	if (unit >= dz_cnt || dzpdma[unit].p_addr == 0)
1348568Sroot 		return (ENXIO);
1352395Swnj 	tp = &dz_tty[unit];
1362395Swnj 	tp->t_addr = (caddr_t)&dzpdma[unit];
13717Sbill 	tp->t_oproc = dzstart;
1385407Swnj 	tp->t_state |= TS_WOPEN;
1395407Swnj 	if ((tp->t_state & TS_ISOPEN) == 0) {
14017Sbill 		ttychars(tp);
1416616Ssam 		tp->t_ospeed = tp->t_ispeed = ISPEED;
1426616Ssam 		tp->t_flags = IFLAGS;
1435407Swnj 		/* tp->t_state |= TS_HUPCLS; */
1442395Swnj 		dzparam(unit);
1458568Sroot 	} else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
1468568Sroot 		return (EBUSY);
1476157Ssam 	(void) dzmctl(dev, DZ_ON, DMSET);
148114Sbill 	(void) spl5();
1495407Swnj 	while ((tp->t_state & TS_CARR_ON) == 0) {
1505407Swnj 		tp->t_state |= TS_WOPEN;
15117Sbill 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
15217Sbill 	}
153114Sbill 	(void) spl0();
1548568Sroot 	return ((*linesw[tp->t_line].l_open)(dev, tp));
15517Sbill }
15617Sbill 
1572395Swnj /*ARGSUSED*/
1582395Swnj dzclose(dev, flag)
1592395Swnj 	dev_t dev;
16017Sbill {
16117Sbill 	register struct tty *tp;
1622395Swnj 	register int unit;
16310019Ssam 	register struct dzdevice *dzaddr;
1646150Ssam 	int dz;
16517Sbill 
1662395Swnj 	unit = minor(dev);
1672395Swnj 	dz = unit >> 3;
1682395Swnj 	tp = &dz_tty[unit];
16917Sbill 	(*linesw[tp->t_line].l_close)(tp);
1705731Sroot 	dzaddr = dzpdma[unit].p_addr;
1715731Sroot 	if (dzaddr->dzcsr&DZ_32)
1726157Ssam 		(void) dzmctl(dev, DZ_BRK, DMBIC);
1735731Sroot 	else
1745731Sroot 		dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
1756842Swnj 	if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0)
1766157Ssam 		(void) dzmctl(dev, DZ_OFF, DMSET);
17717Sbill 	ttyclose(tp);
17817Sbill }
17917Sbill 
1807727Sroot dzread(dev, uio)
1812395Swnj 	dev_t dev;
1827727Sroot 	struct uio *uio;
18317Sbill {
18417Sbill 	register struct tty *tp;
18517Sbill 
1862395Swnj 	tp = &dz_tty[minor(dev)];
1877727Sroot 	return ((*linesw[tp->t_line].l_read)(tp, uio));
18817Sbill }
18917Sbill 
1907833Sroot dzwrite(dev, uio)
1912395Swnj 	dev_t dev;
1927833Sroot 	struct uio *uio;
19317Sbill {
19417Sbill 	register struct tty *tp;
19517Sbill 
1962395Swnj 	tp = &dz_tty[minor(dev)];
1978531Sroot 	return ((*linesw[tp->t_line].l_write)(tp, uio));
19817Sbill }
19917Sbill 
200119Sbill /*ARGSUSED*/
2012395Swnj dzrint(dz)
2022395Swnj 	int dz;
20317Sbill {
20417Sbill 	register struct tty *tp;
20517Sbill 	register int c;
20610019Ssam 	register struct dzdevice *dzaddr;
207119Sbill 	register struct tty *tp0;
2082395Swnj 	register int unit;
2092923Swnj 	int overrun = 0;
21017Sbill 
2112457Swnj 	if ((dzact & (1<<dz)) == 0)
2122457Swnj 		return;
2132457Swnj 	unit = dz * 8;
2142457Swnj 	dzaddr = dzpdma[unit].p_addr;
2152457Swnj 	tp0 = &dz_tty[unit];
2165731Sroot 	dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE);	/* the manual says this song */
2175731Sroot 	dzaddr->dzcsr |= DZ_RIE|DZ_MIE;		/*   and dance is necessary */
2185731Sroot 	while (dzaddr->dzcsr & DZ_MSC) {	/* DZ32 modem change interrupt */
2195731Sroot 		c = dzaddr->dzmtsr;
2205731Sroot 		tp = tp0 + (c&7);
2215731Sroot 		if (tp >= &dz_tty[dz_cnt])
2225731Sroot 			break;
2235731Sroot 		dzaddr->dzlcs = c&7;	/* get status of modem lines */
2245731Sroot 		dzwait(dzaddr);		/* wait for them */
2255731Sroot 		if (c & DZ_CD)		/* carrier status change? */
2265731Sroot 		if (dzaddr->dzlcs & DZ_CD) {	/* carrier up? */
2275731Sroot 			if ((tp->t_state&TS_CARR_ON) == 0) {
2285731Sroot 				wakeup((caddr_t)&tp->t_rawq);
2295731Sroot 				tp->t_state |= TS_CARR_ON;
2305731Sroot 			}
2315731Sroot 		} else {	/* no carrier */
2325731Sroot 			if (tp->t_state&TS_CARR_ON) {
2335731Sroot 				gsignal(tp->t_pgrp, SIGHUP);
2345731Sroot 				gsignal(tp->t_pgrp, SIGCONT);
2355731Sroot 				dzaddr->dzlcs = DZ_ACK|(c&7);
2365731Sroot 				flushtty(tp, FREAD|FWRITE);
2375731Sroot 			}
2385731Sroot 			tp->t_state &= ~TS_CARR_ON;
2395731Sroot 		}
2405731Sroot 	}
2412457Swnj 	while ((c = dzaddr->dzrbuf) < 0) {	/* char present */
2422457Swnj 		tp = tp0 + ((c>>8)&07);
2432457Swnj 		if (tp >= &dz_tty[dz_cnt])
24417Sbill 			continue;
2455407Swnj 		if ((tp->t_state & TS_ISOPEN) == 0) {
2462457Swnj 			wakeup((caddr_t)&tp->t_rawq);
2476616Ssam #ifdef PORTSELECTOR
2486616Ssam 			if ((tp->t_state&TS_WOPEN) == 0)
2496616Ssam #endif
2502457Swnj 			continue;
2512457Swnj 		}
2522469Swnj 		if (c&DZ_FE)
2532457Swnj 			if (tp->t_flags & RAW)
2542469Swnj 				c = 0;
2552457Swnj 			else
2569551Ssam 				c = tp->t_intrc;
2572923Swnj 		if (c&DZ_DO && overrun == 0) {
2585731Sroot 			/* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */
2592923Swnj 			overrun = 1;
2602923Swnj 		}
2612469Swnj 		if (c&DZ_PE)
2622457Swnj 			if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
2632457Swnj 			  || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
26417Sbill 				continue;
2652731Swnj #if NBK > 0
2662457Swnj 		if (tp->t_line == NETLDISC) {
2672457Swnj 			c &= 0177;
2682457Swnj 			BKINPUT(c, tp);
2692457Swnj 		} else
2702731Swnj #endif
2712457Swnj 			(*linesw[tp->t_line].l_rint)(c, tp);
27217Sbill 	}
27317Sbill }
27417Sbill 
27517Sbill /*ARGSUSED*/
2767631Ssam dzioctl(dev, cmd, data, flag)
2772395Swnj 	dev_t dev;
2787631Ssam 	caddr_t data;
27917Sbill {
28017Sbill 	register struct tty *tp;
2812395Swnj 	register int unit = minor(dev);
2822395Swnj 	register int dz = unit >> 3;
28310019Ssam 	register struct dzdevice *dzaddr;
2848568Sroot 	int error;
28517Sbill 
2862395Swnj 	tp = &dz_tty[unit];
2878568Sroot 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
2888568Sroot 	if (error >= 0)
2898568Sroot 		return (error);
2908568Sroot 	error = ttioctl(tp, cmd, data, flag);
2918568Sroot 	if (error >= 0) {
2927631Ssam 		if (cmd == TIOCSETP || cmd == TIOCSETN)
2932395Swnj 			dzparam(unit);
2948568Sroot 		return (error);
2958568Sroot 	}
2968568Sroot 	switch (cmd) {
2972395Swnj 
298170Sbill 	case TIOCSBRK:
2995731Sroot 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
3005731Sroot 		if (dzaddr->dzcsr&DZ_32)
3016157Ssam 			(void) dzmctl(dev, DZ_BRK, DMBIS);
3025731Sroot 		else
3035731Sroot 			dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
304170Sbill 		break;
3057631Ssam 
306170Sbill 	case TIOCCBRK:
3075731Sroot 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
3085731Sroot 		if (dzaddr->dzcsr&DZ_32)
3096157Ssam 			(void) dzmctl(dev, DZ_BRK, DMBIC);
3105731Sroot 		else
3115731Sroot 			dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
312170Sbill 		break;
3137631Ssam 
314170Sbill 	case TIOCSDTR:
3156157Ssam 		(void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
316170Sbill 		break;
3177631Ssam 
318170Sbill 	case TIOCCDTR:
3196157Ssam 		(void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
320170Sbill 		break;
3217631Ssam 
3225731Sroot 	case TIOCMSET:
3237631Ssam 		(void) dzmctl(dev, dmtodz(*(int *)data), DMSET);
3245731Sroot 		break;
3257631Ssam 
3265731Sroot 	case TIOCMBIS:
3277631Ssam 		(void) dzmctl(dev, dmtodz(*(int *)data), DMBIS);
3285731Sroot 		break;
3297631Ssam 
3305731Sroot 	case TIOCMBIC:
3317631Ssam 		(void) dzmctl(dev, dmtodz(*(int *)data), DMBIC);
3325731Sroot 		break;
3337631Ssam 
3345731Sroot 	case TIOCMGET:
3357631Ssam 		*(int *)data = dztodm(dzmctl(dev, 0, DMGET));
3365731Sroot 		break;
3377631Ssam 
338170Sbill 	default:
3398568Sroot 		return (ENOTTY);
340170Sbill 	}
3418568Sroot 	return (0);
34217Sbill }
3435731Sroot 
3445731Sroot dmtodz(bits)
3455731Sroot 	register int bits;
3465731Sroot {
3475731Sroot 	register int b;
3485731Sroot 
3495731Sroot 	b = (bits >>1) & 0370;
3505731Sroot 	if (bits & DML_ST) b |= DZ_ST;
3515731Sroot 	if (bits & DML_RTS) b |= DZ_RTS;
3525731Sroot 	if (bits & DML_DTR) b |= DZ_DTR;
3535731Sroot 	if (bits & DML_LE) b |= DZ_LE;
3545731Sroot 	return(b);
3555731Sroot }
3565731Sroot 
3575731Sroot dztodm(bits)
3585731Sroot 	register int bits;
3595731Sroot {
3605731Sroot 	register int b;
3615731Sroot 
3625731Sroot 	b = (bits << 1) & 0360;
3635731Sroot 	if (bits & DZ_DSR) b |= DML_DSR;
3645731Sroot 	if (bits & DZ_DTR) b |= DML_DTR;
3655731Sroot 	if (bits & DZ_ST) b |= DML_ST;
3665731Sroot 	if (bits & DZ_RTS) b |= DML_RTS;
3675731Sroot 	return(b);
3685731Sroot }
36917Sbill 
3702395Swnj dzparam(unit)
3712395Swnj 	register int unit;
37217Sbill {
37317Sbill 	register struct tty *tp;
37410019Ssam 	register struct dzdevice *dzaddr;
3752395Swnj 	register int lpr;
37617Sbill 
3772395Swnj 	tp = &dz_tty[unit];
3782395Swnj 	dzaddr = dzpdma[unit].p_addr;
37917Sbill 	dzaddr->dzcsr = DZ_IEN;
3802395Swnj 	dzact |= (1<<(unit>>3));
38117Sbill 	if (tp->t_ispeed == 0) {
3826157Ssam 		(void) dzmctl(unit, DZ_OFF, DMSET);	/* hang up line */
38317Sbill 		return;
38417Sbill 	}
3852395Swnj 	lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
3869551Ssam 	if (tp->t_flags & (RAW|LITOUT))
38717Sbill 		lpr |= BITS8;
38817Sbill 	else
38917Sbill 		lpr |= (BITS7|PENABLE);
39017Sbill 	if ((tp->t_flags & EVENP) == 0)
39117Sbill 		lpr |= OPAR;
3922469Swnj 	if (tp->t_ispeed == B110)
3932469Swnj 		lpr |= TWOSB;
39417Sbill 	dzaddr->dzlpr = lpr;
39517Sbill }
39617Sbill 
39717Sbill dzxint(tp)
3982395Swnj 	register struct tty *tp;
39917Sbill {
40017Sbill 	register struct pdma *dp;
4015731Sroot 	register s, dz, unit;
40217Sbill 
4032469Swnj 	s = spl5();		/* block pdma interrupts */
4042395Swnj 	dp = (struct pdma *)tp->t_addr;
4055407Swnj 	tp->t_state &= ~TS_BUSY;
4065407Swnj 	if (tp->t_state & TS_FLUSH)
4075407Swnj 		tp->t_state &= ~TS_FLUSH;
4085731Sroot 	else {
409281Sbill 		ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
4105731Sroot 		dp->p_end = dp->p_mem = tp->t_outq.c_cf;
4115731Sroot 	}
41217Sbill 	if (tp->t_line)
41317Sbill 		(*linesw[tp->t_line].l_start)(tp);
41417Sbill 	else
41517Sbill 		dzstart(tp);
4165731Sroot 	dz = minor(tp->t_dev) >> 3;
4175731Sroot 	unit = minor(tp->t_dev) & 7;
4185407Swnj 	if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
4195731Sroot 		if (dp->p_addr->dzcsr & DZ_32)
4205731Sroot 			dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
4215731Sroot 		else
4225731Sroot 			dp->p_addr->dztcr &= ~(1<<unit);
423145Sbill 	splx(s);
42417Sbill }
42517Sbill 
42617Sbill dzstart(tp)
4272395Swnj 	register struct tty *tp;
42817Sbill {
42917Sbill 	register struct pdma *dp;
43010019Ssam 	register struct dzdevice *dzaddr;
4312395Swnj 	register int cc;
4325731Sroot 	int s, dz, unit;
43317Sbill 
4342395Swnj 	dp = (struct pdma *)tp->t_addr;
43517Sbill 	dzaddr = dp->p_addr;
4362395Swnj 	s = spl5();
4375407Swnj 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
43817Sbill 		goto out;
4395407Swnj 	if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
4405407Swnj 		if (tp->t_state&TS_ASLEEP) {
4415407Swnj 			tp->t_state &= ~TS_ASLEEP;
4425407Swnj 			wakeup((caddr_t)&tp->t_outq);
4435407Swnj 		}
4445407Swnj 		if (tp->t_wsel) {
4455407Swnj 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
4465407Swnj 			tp->t_wsel = 0;
4475407Swnj 			tp->t_state &= ~TS_WCOLL;
4485407Swnj 		}
44917Sbill 	}
45017Sbill 	if (tp->t_outq.c_cc == 0)
45117Sbill 		goto out;
4529551Ssam 	if (tp->t_flags & (RAW|LITOUT))
45317Sbill 		cc = ndqb(&tp->t_outq, 0);
45417Sbill 	else {
45517Sbill 		cc = ndqb(&tp->t_outq, 0200);
45617Sbill 		if (cc == 0) {
45717Sbill 			cc = getc(&tp->t_outq);
4582469Swnj 			timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
4595407Swnj 			tp->t_state |= TS_TIMEOUT;
46017Sbill 			goto out;
46117Sbill 		}
46217Sbill 	}
4635407Swnj 	tp->t_state |= TS_BUSY;
46417Sbill 	dp->p_end = dp->p_mem = tp->t_outq.c_cf;
46517Sbill 	dp->p_end += cc;
4665731Sroot 	dz = minor(tp->t_dev) >> 3;
4675731Sroot 	unit = minor(tp->t_dev) & 7;
4685731Sroot 	if (dzaddr->dzcsr & DZ_32)
4695731Sroot 		dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit));
4705731Sroot 	else
4715731Sroot 		dzaddr->dztcr |= (1<<unit);
4722395Swnj out:
4732395Swnj 	splx(s);
47417Sbill }
47517Sbill 
47617Sbill /*
47717Sbill  * Stop output on a line.
47817Sbill  */
47917Sbill /*ARGSUSED*/
48017Sbill dzstop(tp, flag)
4812395Swnj 	register struct tty *tp;
48217Sbill {
48317Sbill 	register struct pdma *dp;
48417Sbill 	register int s;
48517Sbill 
4862395Swnj 	dp = (struct pdma *)tp->t_addr;
4872457Swnj 	s = spl5();
4885407Swnj 	if (tp->t_state & TS_BUSY) {
48917Sbill 		dp->p_end = dp->p_mem;
4905407Swnj 		if ((tp->t_state&TS_TTSTOP)==0)
4915407Swnj 			tp->t_state |= TS_FLUSH;
49217Sbill 	}
49317Sbill 	splx(s);
49417Sbill }
49517Sbill 
4965731Sroot dzmctl(dev, bits, how)
4975731Sroot 	dev_t dev;
4985731Sroot 	int bits, how;
49917Sbill {
50010019Ssam 	register struct dzdevice *dzaddr;
5015731Sroot 	register int unit, mbits;
5025731Sroot 	int b, s;
5035731Sroot 
5045731Sroot 	unit = minor(dev);
5055731Sroot 	b = 1<<(unit&7);
5062395Swnj 	dzaddr = dzpdma[unit].p_addr;
5075731Sroot 	s = spl5();
5085731Sroot 	if (dzaddr->dzcsr & DZ_32) {
5095731Sroot 		dzwait(dzaddr)
5105731Sroot 		DELAY(100);		/* IS 100 TOO MUCH? */
5115731Sroot 		dzaddr->dzlcs = unit&7;
5125731Sroot 		DELAY(100);
5135731Sroot 		dzwait(dzaddr)
5145731Sroot 		DELAY(100);
5155731Sroot 		mbits = dzaddr->dzlcs;
5165731Sroot 		mbits &= 0177770;
5175731Sroot 	} else {
5185731Sroot 		mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0;
5195731Sroot 		mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0;
5205731Sroot 		mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0;
5215731Sroot 	}
5225731Sroot 	switch (how) {
5235731Sroot 	case DMSET:
5245731Sroot 		mbits = bits;
5255731Sroot 		break;
5265731Sroot 
5275731Sroot 	case DMBIS:
5285731Sroot 		mbits |= bits;
5295731Sroot 		break;
5305731Sroot 
5315731Sroot 	case DMBIC:
5325731Sroot 		mbits &= ~bits;
5335731Sroot 		break;
5345731Sroot 
5355731Sroot 	case DMGET:
5365731Sroot 		(void) splx(s);
5375731Sroot 		return(mbits);
5385731Sroot 	}
5395731Sroot 	if (dzaddr->dzcsr & DZ_32) {
5405731Sroot 		mbits |= DZ_ACK|(unit&7);
5415731Sroot 		dzaddr->dzlcs = mbits;
5425731Sroot 	} else {
5435731Sroot 		if (mbits & DZ_DTR)
5445731Sroot 			dzaddr->dzdtr |= b;
5455731Sroot 		else
5465731Sroot 			dzaddr->dzdtr &= ~b;
5475731Sroot 	}
5485731Sroot 	(void) splx(s);
5495731Sroot 	return(mbits);
55017Sbill }
55117Sbill 
55217Sbill dzscan()
55317Sbill {
55417Sbill 	register i;
55510019Ssam 	register struct dzdevice *dzaddr;
55617Sbill 	register bit;
55717Sbill 	register struct tty *tp;
5585731Sroot 	register car;
55917Sbill 
56017Sbill 	for (i = 0; i < dz_cnt ; i++) {
56117Sbill 		dzaddr = dzpdma[i].p_addr;
5622627Swnj 		if (dzaddr == 0)
5632627Swnj 			continue;
56417Sbill 		tp = &dz_tty[i];
56517Sbill 		bit = 1<<(i&07);
5665731Sroot 		car = 0;
5675731Sroot 		if (dzsoftCAR[i>>3]&bit)
5685731Sroot 			car = 1;
5695731Sroot 		else if (dzaddr->dzcsr & DZ_32) {
5705731Sroot 			dzaddr->dzlcs = i&07;
5715731Sroot 			dzwait(dzaddr);
5725731Sroot 			car = dzaddr->dzlcs & DZ_CD;
5735731Sroot 		} else
5745731Sroot 			car = dzaddr->dzmsr&bit;
5755731Sroot 		if (car) {
57617Sbill 			/* carrier present */
5775407Swnj 			if ((tp->t_state & TS_CARR_ON) == 0) {
57817Sbill 				wakeup((caddr_t)&tp->t_rawq);
5795407Swnj 				tp->t_state |= TS_CARR_ON;
58017Sbill 			}
58117Sbill 		} else {
5825407Swnj 			if ((tp->t_state&TS_CARR_ON) &&
5839551Ssam 			    (tp->t_flags&NOHANG) == 0) {
58417Sbill 				/* carrier lost */
5855407Swnj 				if (tp->t_state&TS_ISOPEN) {
586170Sbill 					gsignal(tp->t_pgrp, SIGHUP);
587205Sbill 					gsignal(tp->t_pgrp, SIGCONT);
588170Sbill 					dzaddr->dzdtr &= ~bit;
589871Sbill 					flushtty(tp, FREAD|FWRITE);
590170Sbill 				}
5915407Swnj 				tp->t_state &= ~TS_CARR_ON;
59217Sbill 			}
59317Sbill 		}
59417Sbill 	}
5952756Swnj 	timeout(dzscan, (caddr_t)0, 2*hz);
59617Sbill }
597119Sbill 
598119Sbill dztimer()
599119Sbill {
6008160Sroot 	register int dz;
6018160Sroot 	register int s = spl5();
602119Sbill 
6032645Swnj 	for (dz = 0; dz < NDZ; dz++)
6042457Swnj 		dzrint(dz);
6058160Sroot 	splx(s);
606119Sbill }
607281Sbill 
608281Sbill /*
609281Sbill  * Reset state of driver if UBA reset was necessary.
610301Sbill  * Reset parameters and restart transmission on open lines.
611281Sbill  */
6122395Swnj dzreset(uban)
6132422Skre 	int uban;
614281Sbill {
6152395Swnj 	register int unit;
616281Sbill 	register struct tty *tp;
6172976Swnj 	register struct uba_device *ui;
618281Sbill 
6192645Swnj 	for (unit = 0; unit < NDZLINE; unit++) {
6202422Skre 		ui = dzinfo[unit >> 3];
6212422Skre 		if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
6222422Skre 			continue;
6232923Swnj 		if (unit%8 == 0)
6242923Swnj 			printf(" dz%d", unit>>3);
6252395Swnj 		tp = &dz_tty[unit];
6265407Swnj 		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
6272395Swnj 			dzparam(unit);
6286157Ssam 			(void) dzmctl(unit, DZ_ON, DMSET);
6295407Swnj 			tp->t_state &= ~TS_BUSY;
630301Sbill 			dzstart(tp);
631281Sbill 		}
632281Sbill 	}
633281Sbill 	dztimer();
634281Sbill }
6351562Sbill #endif
636