xref: /original-bsd/sys/vax/uba/dz.c (revision 0b685140)
1 /*	dz.c	4.33	82/02/08	*/
2 
3 #include "dz.h"
4 #if NDZ > 0
5 /*
6  *  DZ-11 and DZ32 Driver
7  *
8  * This driver mimics dh.c; see it for explanation of common code.
9  */
10 #include "bk.h"
11 #include "../h/param.h"
12 #include "../h/systm.h"
13 #include "../h/tty.h"
14 #include "../h/dir.h"
15 #include "../h/user.h"
16 #include "../h/map.h"
17 #include "../h/pte.h"
18 #include "../h/buf.h"
19 #include "../h/vm.h"
20 #include "../h/ubavar.h"
21 #include "../h/conf.h"
22 #include "../h/pdma.h"
23 #include "../h/bk.h"
24 #include "../h/file.h"
25 
26 /*
27  * Driver information for auto-configuration stuff.
28  */
29 int	dzprobe(), dzattach(), dzrint();
30 struct	uba_device *dzinfo[NDZ];
31 u_short	dzstd[] = { 0 };
32 struct	uba_driver dzdriver =
33 	{ dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
34 
35 #define	NDZLINE 	(NDZ*8)
36 
37 /*
38  * Registers and bits
39  */
40 
41 /* bits in dzlpr */
42 #define	BITS7	0020
43 #define	BITS8	0030
44 #define	TWOSB	0040
45 #define	PENABLE	0100
46 #define	OPAR	0200
47 
48 /* bits in dzrbuf */
49 #define	DZ_PE	010000
50 #define	DZ_FE	020000
51 #define	DZ_DO	040000
52 
53 /* bits in dzcsr */
54 #define	DZ_32	000001		/* DZ32 mode */
55 #define	DZ_MIE	000002		/* Modem Interrupt Enable */
56 #define	DZ_CLR	000020		/* Reset dz */
57 #define	DZ_MSE	000040		/* Master Scan Enable */
58 #define	DZ_RIE	000100		/* Receiver Interrupt Enable */
59 #define DZ_MSC	004000		/* Modem Status Change */
60 #define	DZ_SAE	010000		/* Silo Alarm Enable */
61 #define	DZ_TIE	040000		/* Transmit Interrupt Enable */
62 #define	DZ_IEN	(DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE)
63 
64 /* flags for modem-control */
65 #define	DZ_ON	DZ_DTR
66 #define	DZ_OFF	0
67 
68 /* bits in dzlcs */
69 #define DZ_ACK	0100000		/* ACK bit in dzlcs */
70 #define DZ_RTS	0010000		/* Request To Send */
71 #define	DZ_ST	0004000		/* Secondary Transmit */
72 #define	DZ_BRK	0002000		/* Break */
73 #define DZ_DTR	0001000		/* Data Terminal Ready */
74 #define	DZ_LE	0000400		/* Line Enable */
75 #define	DZ_DSR	0000200		/* Data Set Ready */
76 #define	DZ_RI	0000100		/* Ring Indicate */
77 #define DZ_CD	0000040		/* Carrier Detect */
78 #define	DZ_CTS	0000020		/* Clear To Send */
79 #define	DZ_SR	0000010		/* Secondary Receive */
80 
81 /* bits in dm lsr, copied from dh.c */
82 #define	DML_DSR		0000400		/* data set ready, not a real DM bit */
83 #define	DML_RNG		0000200		/* ring */
84 #define	DML_CAR		0000100		/* carrier detect */
85 #define	DML_CTS		0000040		/* clear to send */
86 #define	DML_SR		0000020		/* secondary receive */
87 #define	DML_ST		0000010		/* secondary transmit */
88 #define	DML_RTS		0000004		/* request to send */
89 #define	DML_DTR		0000002		/* data terminal ready */
90 #define	DML_LE		0000001		/* line enable */
91 
92 int	dzstart(), dzxint(), dzdma();
93 int	ttrstrt();
94 struct	tty dz_tty[NDZLINE];
95 int	dz_cnt = { NDZLINE };
96 int	dzact;
97 
98 struct device {
99 	short dzcsr;
100 	short dzrbuf;
101 	union {
102 		struct {
103 			char	dztcr0;
104 			char	dzdtr0;
105 			char	dztbuf0;
106 			char	dzbrk0;
107 		} dz11;
108 		struct {
109 			short	dzlcs0;
110 			char	dztbuf0;
111 			char	dzlnen0;
112 		} dz32;
113 	} dzun;
114 };
115 
116 #define dzlpr	dzrbuf
117 #define dzmsr	dzun.dz11.dzbrk0
118 #define dztcr	dzun.dz11.dztcr0
119 #define dzdtr	dzun.dz11.dzdtr0
120 #define dztbuf	dzun.dz11.dztbuf0
121 #define dzlcs	dzun.dz32.dzlcs0
122 #define	dzbrk	dzmsr
123 #define dzlnen	dzun.dz32.dzlnen0
124 #define dzmtsr	dzun.dz32.dztbuf0;
125 
126 #define dzwait(x)	while (((x)->dzlcs & DZ_ACK) == 0)
127 
128 /*
129  * Software copy of dzbrk since it isn't readable
130  */
131 char	dz_brk[NDZ];
132 char	dzsoftCAR[NDZ];
133 char	dz_lnen[NDZ];	/* saved line enable bits for DZ32 */
134 
135 /*
136  * The dz11 doesn't interrupt on carrier transitions, so
137  * we have to use a timer to watch it.
138  */
139 char	dz_timer;		/* timer started? */
140 
141 /*
142  * Pdma structures for fast output code
143  */
144 struct	pdma dzpdma[NDZLINE];
145 
146 char	dz_speeds[] =
147 	{ 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
148 
149 dzprobe(reg)
150 	caddr_t reg;
151 {
152 	register int br, cvec;
153 	register struct device *dzaddr = (struct device *)reg;
154 
155 #ifdef lint
156 	br = 0; cvec = br; br = cvec;
157 	dzrint(0); dzxint((struct tty *)0);
158 #endif
159 	dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32;
160 	if (dzaddr->dzcsr & DZ_32)
161 		dzaddr->dzlnen = 1;
162 	else
163 		dzaddr->dztcr = 1;		/* enable any line */
164 	DELAY(100000);
165 	dzaddr->dzcsr = DZ_CLR|DZ_32;		/* reset everything */
166 	if (cvec && cvec != 0x200)
167 		cvec -= 4;
168 	return (1);
169 }
170 
171 dzattach(ui)
172 	register struct uba_device *ui;
173 {
174 	register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
175 	register struct tty *tp = &dz_tty[ui->ui_unit*8];
176 	register int cntr;
177 	extern dzscan();
178 
179 	for (cntr = 0; cntr < 8; cntr++) {
180 		pdp->p_addr = (struct device *)ui->ui_addr;
181 		pdp->p_arg = (int)tp;
182 		pdp->p_fcn = dzxint;
183 		pdp++, tp++;
184 	}
185 	dzsoftCAR[ui->ui_unit] = ui->ui_flags;
186 	if (dz_timer == 0) {
187 		dz_timer++;
188 		timeout(dzscan, (caddr_t)0, hz);
189 	}
190 }
191 
192 /*ARGSUSED*/
193 dzopen(dev, flag)
194 	dev_t dev;
195 {
196 	register struct tty *tp;
197 	register int unit;
198 
199 	unit = minor(dev);
200 	if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
201 		u.u_error = ENXIO;
202 		return;
203 	}
204 	tp = &dz_tty[unit];
205 	tp->t_addr = (caddr_t)&dzpdma[unit];
206 	tp->t_oproc = dzstart;
207 	tp->t_state |= TS_WOPEN;
208 	if ((tp->t_state & TS_ISOPEN) == 0) {
209 		ttychars(tp);
210 		tp->t_ospeed = tp->t_ispeed = B300;
211 		tp->t_flags = ODDP|EVENP|ECHO;
212 		/* tp->t_state |= TS_HUPCLS; */
213 		dzparam(unit);
214 	} else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) {
215 		u.u_error = EBUSY;
216 		return;
217 	}
218 	dzmctl(dev, DZ_ON, DMSET);
219 	(void) spl5();
220 	while ((tp->t_state & TS_CARR_ON) == 0) {
221 		tp->t_state |= TS_WOPEN;
222 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
223 	}
224 	(void) spl0();
225 	(*linesw[tp->t_line].l_open)(dev, tp);
226 }
227 
228 /*ARGSUSED*/
229 dzclose(dev, flag)
230 	dev_t dev;
231 {
232 	register struct tty *tp;
233 	register int unit;
234 	register struct device *dzaddr;
235 	int dz, s;
236 
237 	unit = minor(dev);
238 	dz = unit >> 3;
239 	tp = &dz_tty[unit];
240 	(*linesw[tp->t_line].l_close)(tp);
241 	dzaddr = dzpdma[unit].p_addr;
242 	if (dzaddr->dzcsr&DZ_32)
243 		dzmctl(dev, DZ_BRK, DMBIC);
244 	else
245 		dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
246 	if ((tp->t_state&TS_HUPCLS) || (tp->t_state&TS_ISOPEN) == 0)
247 		dzmctl(dev, DZ_OFF, DMSET);
248 	ttyclose(tp);
249 }
250 
251 dzread(dev)
252 	dev_t dev;
253 {
254 	register struct tty *tp;
255 
256 	tp = &dz_tty[minor(dev)];
257 	(*linesw[tp->t_line].l_read)(tp);
258 }
259 
260 dzwrite(dev)
261 	dev_t dev;
262 {
263 	register struct tty *tp;
264 
265 	tp = &dz_tty[minor(dev)];
266 	(*linesw[tp->t_line].l_write)(tp);
267 }
268 
269 /*ARGSUSED*/
270 dzrint(dz)
271 	int dz;
272 {
273 	register struct tty *tp;
274 	register int c;
275 	register struct device *dzaddr;
276 	register struct tty *tp0;
277 	register int unit;
278 	int overrun = 0;
279 
280 	if ((dzact & (1<<dz)) == 0)
281 		return;
282 	unit = dz * 8;
283 	dzaddr = dzpdma[unit].p_addr;
284 	tp0 = &dz_tty[unit];
285 	dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE);	/* the manual says this song */
286 	dzaddr->dzcsr |= DZ_RIE|DZ_MIE;		/*   and dance is necessary */
287 	while (dzaddr->dzcsr & DZ_MSC) {	/* DZ32 modem change interrupt */
288 		c = dzaddr->dzmtsr;
289 		tp = tp0 + (c&7);
290 		if (tp >= &dz_tty[dz_cnt])
291 			break;
292 		dzaddr->dzlcs = c&7;	/* get status of modem lines */
293 		dzwait(dzaddr);		/* wait for them */
294 		if (c & DZ_CD)		/* carrier status change? */
295 		if (dzaddr->dzlcs & DZ_CD) {	/* carrier up? */
296 			if ((tp->t_state&TS_CARR_ON) == 0) {
297 				wakeup((caddr_t)&tp->t_rawq);
298 				tp->t_state |= TS_CARR_ON;
299 			}
300 		} else {	/* no carrier */
301 			if (tp->t_state&TS_CARR_ON) {
302 				gsignal(tp->t_pgrp, SIGHUP);
303 				gsignal(tp->t_pgrp, SIGCONT);
304 				dzaddr->dzlcs = DZ_ACK|(c&7);
305 				flushtty(tp, FREAD|FWRITE);
306 			}
307 			tp->t_state &= ~TS_CARR_ON;
308 		}
309 	}
310 	while ((c = dzaddr->dzrbuf) < 0) {	/* char present */
311 		tp = tp0 + ((c>>8)&07);
312 		if (tp >= &dz_tty[dz_cnt])
313 			continue;
314 		if ((tp->t_state & TS_ISOPEN) == 0) {
315 			wakeup((caddr_t)&tp->t_rawq);
316 			continue;
317 		}
318 		if (c&DZ_FE)
319 			if (tp->t_flags & RAW)
320 				c = 0;
321 			else
322 				c = tun.t_intrc;
323 		if (c&DZ_DO && overrun == 0) {
324 			/* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */
325 			overrun = 1;
326 		}
327 		if (c&DZ_PE)
328 			if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
329 			  || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
330 				continue;
331 #if NBK > 0
332 		if (tp->t_line == NETLDISC) {
333 			c &= 0177;
334 			BKINPUT(c, tp);
335 		} else
336 #endif
337 			(*linesw[tp->t_line].l_rint)(c, tp);
338 	}
339 }
340 
341 /*ARGSUSED*/
342 dzioctl(dev, cmd, addr, flag)
343 	dev_t dev;
344 	caddr_t addr;
345 {
346 	register struct tty *tp;
347 	register int unit = minor(dev);
348 	register int dz = unit >> 3;
349 	register struct device *dzaddr;
350 	int temp;
351 
352 	tp = &dz_tty[unit];
353 	cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
354 	if (cmd == 0)
355 		return;
356 	if (ttioctl(tp, cmd, addr, flag)) {
357 		if (cmd==TIOCSETP || cmd==TIOCSETN)
358 			dzparam(unit);
359 	} else switch(cmd) {
360 
361 	case TIOCSBRK:
362 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
363 		if (dzaddr->dzcsr&DZ_32)
364 			dzmctl(dev, DZ_BRK, DMBIS);
365 		else
366 			dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
367 		break;
368 	case TIOCCBRK:
369 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
370 		if (dzaddr->dzcsr&DZ_32)
371 			dzmctl(dev, DZ_BRK, DMBIC);
372 		else
373 			dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
374 		break;
375 	case TIOCSDTR:
376 		dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
377 		break;
378 	case TIOCCDTR:
379 		dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
380 		break;
381 	case TIOCMSET:
382 		if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
383 			u.u_error = EFAULT;
384 		else
385 			dzmctl(dev, dmtodz(temp), DMSET);
386 		break;
387 	case TIOCMBIS:
388 		if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
389 			u.u_error = EFAULT;
390 		else
391 			dzmctl(dev, dmtodz(temp), DMBIS);
392 		break;
393 	case TIOCMBIC:
394 		if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
395 			u.u_error = EFAULT;
396 		else
397 			dzmctl(dev, dmtodz(temp), DMBIC);
398 		break;
399 	case TIOCMGET:
400 		temp = dztodm(dzmctl(dev, 0, DMGET));
401 		if (copyout((caddr_t) &temp, addr, sizeof(temp)))
402 			u.u_error = EFAULT;
403 		break;
404 	default:
405 		u.u_error = ENOTTY;
406 	}
407 }
408 
409 dmtodz(bits)
410 	register int bits;
411 {
412 	register int b;
413 
414 	b = (bits >>1) & 0370;
415 	if (bits & DML_ST) b |= DZ_ST;
416 	if (bits & DML_RTS) b |= DZ_RTS;
417 	if (bits & DML_DTR) b |= DZ_DTR;
418 	if (bits & DML_LE) b |= DZ_LE;
419 	return(b);
420 }
421 
422 dztodm(bits)
423 	register int bits;
424 {
425 	register int b;
426 
427 	b = (bits << 1) & 0360;
428 	if (bits & DZ_DSR) b |= DML_DSR;
429 	if (bits & DZ_DTR) b |= DML_DTR;
430 	if (bits & DZ_ST) b |= DML_ST;
431 	if (bits & DZ_RTS) b |= DML_RTS;
432 	return(b);
433 }
434 
435 dzparam(unit)
436 	register int unit;
437 {
438 	register struct tty *tp;
439 	register struct device *dzaddr;
440 	register int lpr;
441 
442 	tp = &dz_tty[unit];
443 	dzaddr = dzpdma[unit].p_addr;
444 	dzaddr->dzcsr = DZ_IEN;
445 	dzact |= (1<<(unit>>3));
446 	if (tp->t_ispeed == 0) {
447 		dzmctl(unit, DZ_OFF, DMSET);	/* hang up line */
448 		return;
449 	}
450 	lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
451 	if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
452 		lpr |= BITS8;
453 	else
454 		lpr |= (BITS7|PENABLE);
455 	if ((tp->t_flags & EVENP) == 0)
456 		lpr |= OPAR;
457 	if (tp->t_ispeed == B110)
458 		lpr |= TWOSB;
459 	dzaddr->dzlpr = lpr;
460 }
461 
462 dzxint(tp)
463 	register struct tty *tp;
464 {
465 	register struct pdma *dp;
466 	register s, dz, unit;
467 
468 	s = spl5();		/* block pdma interrupts */
469 	dp = (struct pdma *)tp->t_addr;
470 	tp->t_state &= ~TS_BUSY;
471 	if (tp->t_state & TS_FLUSH)
472 		tp->t_state &= ~TS_FLUSH;
473 	else {
474 		ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
475 		dp->p_end = dp->p_mem = tp->t_outq.c_cf;
476 	}
477 	if (tp->t_line)
478 		(*linesw[tp->t_line].l_start)(tp);
479 	else
480 		dzstart(tp);
481 	dz = minor(tp->t_dev) >> 3;
482 	unit = minor(tp->t_dev) & 7;
483 	if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
484 		if (dp->p_addr->dzcsr & DZ_32)
485 			dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
486 		else
487 			dp->p_addr->dztcr &= ~(1<<unit);
488 	splx(s);
489 }
490 
491 dzstart(tp)
492 	register struct tty *tp;
493 {
494 	register struct pdma *dp;
495 	register struct device *dzaddr;
496 	register int cc;
497 	int s, dz, unit;
498 
499 	dp = (struct pdma *)tp->t_addr;
500 	dzaddr = dp->p_addr;
501 	s = spl5();
502 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
503 		goto out;
504 	if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
505 		if (tp->t_state&TS_ASLEEP) {
506 			tp->t_state &= ~TS_ASLEEP;
507 			wakeup((caddr_t)&tp->t_outq);
508 		}
509 		if (tp->t_wsel) {
510 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
511 			tp->t_wsel = 0;
512 			tp->t_state &= ~TS_WCOLL;
513 		}
514 	}
515 	if (tp->t_outq.c_cc == 0)
516 		goto out;
517 	if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
518 		cc = ndqb(&tp->t_outq, 0);
519 	else {
520 		cc = ndqb(&tp->t_outq, 0200);
521 		if (cc == 0) {
522 			cc = getc(&tp->t_outq);
523 			timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
524 			tp->t_state |= TS_TIMEOUT;
525 			goto out;
526 		}
527 	}
528 	tp->t_state |= TS_BUSY;
529 	dp->p_end = dp->p_mem = tp->t_outq.c_cf;
530 	dp->p_end += cc;
531 	dz = minor(tp->t_dev) >> 3;
532 	unit = minor(tp->t_dev) & 7;
533 	if (dzaddr->dzcsr & DZ_32)
534 		dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit));
535 	else
536 		dzaddr->dztcr |= (1<<unit);
537 out:
538 	splx(s);
539 }
540 
541 /*
542  * Stop output on a line.
543  */
544 /*ARGSUSED*/
545 dzstop(tp, flag)
546 	register struct tty *tp;
547 {
548 	register struct pdma *dp;
549 	register int s;
550 
551 	dp = (struct pdma *)tp->t_addr;
552 	s = spl5();
553 	if (tp->t_state & TS_BUSY) {
554 		dp->p_end = dp->p_mem;
555 		if ((tp->t_state&TS_TTSTOP)==0)
556 			tp->t_state |= TS_FLUSH;
557 	}
558 	splx(s);
559 }
560 
561 dzmctl(dev, bits, how)
562 	dev_t dev;
563 	int bits, how;
564 {
565 	register struct device *dzaddr;
566 	register int unit, mbits;
567 	int b, s;
568 
569 	unit = minor(dev);
570 	b = 1<<(unit&7);
571 	dzaddr = dzpdma[unit].p_addr;
572 	s = spl5();
573 	if (dzaddr->dzcsr & DZ_32) {
574 		dzwait(dzaddr)
575 		DELAY(100);		/* IS 100 TOO MUCH? */
576 		dzaddr->dzlcs = unit&7;
577 		DELAY(100);
578 		dzwait(dzaddr)
579 		DELAY(100);
580 		mbits = dzaddr->dzlcs;
581 		mbits &= 0177770;
582 	} else {
583 		mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0;
584 		mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0;
585 		mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0;
586 	}
587 	switch (how) {
588 	case DMSET:
589 		mbits = bits;
590 		break;
591 
592 	case DMBIS:
593 		mbits |= bits;
594 		break;
595 
596 	case DMBIC:
597 		mbits &= ~bits;
598 		break;
599 
600 	case DMGET:
601 		(void) splx(s);
602 		return(mbits);
603 	}
604 	if (dzaddr->dzcsr & DZ_32) {
605 		mbits |= DZ_ACK|(unit&7);
606 		dzaddr->dzlcs = mbits;
607 	} else {
608 		if (mbits & DZ_DTR)
609 			dzaddr->dzdtr |= b;
610 		else
611 			dzaddr->dzdtr &= ~b;
612 	}
613 	(void) splx(s);
614 	return(mbits);
615 }
616 
617 dzscan()
618 {
619 	register i;
620 	register struct device *dzaddr;
621 	register bit;
622 	register struct tty *tp;
623 	register car;
624 
625 	for (i = 0; i < dz_cnt ; i++) {
626 		dzaddr = dzpdma[i].p_addr;
627 		if (dzaddr == 0)
628 			continue;
629 		tp = &dz_tty[i];
630 		bit = 1<<(i&07);
631 		car = 0;
632 		if (dzsoftCAR[i>>3]&bit)
633 			car = 1;
634 		else if (dzaddr->dzcsr & DZ_32) {
635 			dzaddr->dzlcs = i&07;
636 			dzwait(dzaddr);
637 			car = dzaddr->dzlcs & DZ_CD;
638 		} else
639 			car = dzaddr->dzmsr&bit;
640 		if (car) {
641 			/* carrier present */
642 			if ((tp->t_state & TS_CARR_ON) == 0) {
643 				wakeup((caddr_t)&tp->t_rawq);
644 				tp->t_state |= TS_CARR_ON;
645 			}
646 		} else {
647 			if ((tp->t_state&TS_CARR_ON) &&
648 			    (tp->t_local&LNOHANG)==0) {
649 				/* carrier lost */
650 				if (tp->t_state&TS_ISOPEN) {
651 					gsignal(tp->t_pgrp, SIGHUP);
652 					gsignal(tp->t_pgrp, SIGCONT);
653 					dzaddr->dzdtr &= ~bit;
654 					flushtty(tp, FREAD|FWRITE);
655 				}
656 				tp->t_state &= ~TS_CARR_ON;
657 			}
658 		}
659 	}
660 	timeout(dzscan, (caddr_t)0, 2*hz);
661 }
662 
663 dztimer()
664 {
665 	int dz;
666 
667 	for (dz = 0; dz < NDZ; dz++)
668 		dzrint(dz);
669 }
670 
671 /*
672  * Reset state of driver if UBA reset was necessary.
673  * Reset parameters and restart transmission on open lines.
674  */
675 dzreset(uban)
676 	int uban;
677 {
678 	register int unit;
679 	register struct tty *tp;
680 	register struct uba_device *ui;
681 
682 	for (unit = 0; unit < NDZLINE; unit++) {
683 		ui = dzinfo[unit >> 3];
684 		if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
685 			continue;
686 		if (unit%8 == 0)
687 			printf(" dz%d", unit>>3);
688 		tp = &dz_tty[unit];
689 		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
690 			dzparam(unit);
691 			dzmctl(unit, DZ_ON, DMSET);
692 			tp->t_state &= ~TS_BUSY;
693 			dzstart(tp);
694 		}
695 	}
696 	dztimer();
697 }
698 #endif
699