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