xref: /original-bsd/sys/vax/uba/dz.c (revision de3f5c4e)
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.13 (Berkeley) 05/09/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)
204 	dev_t dev;
205 {
206 	register struct tty *tp;
207 	register int unit;
208 	register struct dzdevice *dzaddr;
209 	int dz;
210 
211 	unit = minor(dev);
212 	dz = unit >> 3;
213 	tp = &dz_tty[unit];
214 	(*linesw[tp->t_line].l_close)(tp);
215 	dzaddr = dzpdma[unit].p_addr;
216 	if (dzaddr->dzcsr&DZ_32)
217 		(void) dzmctl(dev, DZ_BRK, DMBIC);
218 	else
219 		dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
220 	if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN ||
221 	    (tp->t_state&TS_ISOPEN) == 0)
222 		(void) dzmctl(dev, DZ_OFF, DMSET);
223 	return (ttyclose(tp));
224 }
225 
226 dzread(dev, uio, flag)
227 	dev_t dev;
228 	struct uio *uio;
229 {
230 	register struct tty *tp;
231 
232 	tp = &dz_tty[minor(dev)];
233 	return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
234 }
235 
236 dzwrite(dev, uio, flag)
237 	dev_t dev;
238 	struct uio *uio;
239 {
240 	register struct tty *tp;
241 
242 	tp = &dz_tty[minor(dev)];
243 	return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
244 }
245 
246 /*ARGSUSED*/
247 dzrint(dz)
248 	int dz;
249 {
250 	register struct tty *tp;
251 	register int c, cc;
252 	register struct dzdevice *dzaddr;
253 	register struct tty *tp0;
254 	register int unit;
255 	int overrun = 0;
256 
257 	if ((dzact & (1<<dz)) == 0)
258 		return;
259 	unit = dz * 8;
260 	dzaddr = dzpdma[unit].p_addr;
261 	tp0 = &dz_tty[unit];
262 	dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE);	/* the manual says this song */
263 	dzaddr->dzcsr |= DZ_RIE|DZ_MIE;		/*   and dance is necessary */
264 	while (dzaddr->dzcsr & DZ_MSC) {	/* DZ32 modem change interrupt */
265 		c = dzaddr->dzmtsr;
266 		tp = tp0 + (c&7);
267 		if (tp >= &dz_tty[dz_cnt])
268 			break;
269 		dzaddr->dzlcs = c&7;	/* get status of modem lines */
270 		dzwait(dzaddr);		/* wait for them */
271 		if (c & DZ_CD)		/* carrier status change? */
272 		if (dzaddr->dzlcs & DZ_CD) {	/* carrier up? */
273 			/* carrier present */
274 			(void)(*linesw[tp->t_line].l_modem)(tp, 1);
275 		} else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
276 			dzaddr->dzlcs = DZ_ACK|(c&7);
277 	}
278 	while ((c = dzaddr->dzrbuf) < 0) {	/* char present */
279 		cc = c&0xff;
280 		dzchars[dz]++;
281 		tp = tp0 + ((c>>8)&07);
282 		if (tp >= &dz_tty[dz_cnt])
283 			continue;
284 		if ((tp->t_state & TS_ISOPEN) == 0) {
285 			wakeup((caddr_t)&tp->t_rawq);
286 #ifdef PORTSELECTOR
287 			if ((tp->t_state&TS_WOPEN) == 0)
288 #endif
289 				continue;
290 		}
291 		if (c&DZ_FE)
292 			cc |= TTY_FE;
293 		if (c&DZ_DO && overrun == 0) {
294 			log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7);
295 			overrun = 1;
296 		}
297 		if (c&DZ_PE)
298 			cc |= TTY_PE;
299 		(*linesw[tp->t_line].l_rint)(cc, tp);
300 	}
301 }
302 
303 /*ARGSUSED*/
304 dzioctl(dev, cmd, data, flag)
305 	dev_t dev;
306 	caddr_t data;
307 {
308 	register struct tty *tp;
309 	register int unit = minor(dev);
310 	register int dz = unit >> 3;
311 	register struct dzdevice *dzaddr;
312 	int error;
313 
314 	tp = &dz_tty[unit];
315 	error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
316 	if (error >= 0)
317 		return (error);
318 	error = ttioctl(tp, cmd, data, flag);
319 	if (error >= 0)
320 		return (error);
321 
322 	switch (cmd) {
323 
324 	case TIOCSBRK:
325 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
326 		if (dzaddr->dzcsr&DZ_32)
327 			(void) dzmctl(dev, DZ_BRK, DMBIS);
328 		else
329 			dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
330 		break;
331 
332 	case TIOCCBRK:
333 		dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
334 		if (dzaddr->dzcsr&DZ_32)
335 			(void) dzmctl(dev, DZ_BRK, DMBIC);
336 		else
337 			dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
338 		break;
339 
340 	case TIOCSDTR:
341 		(void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
342 		break;
343 
344 	case TIOCCDTR:
345 		(void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
346 		break;
347 
348 	case TIOCMSET:
349 		(void) dzmctl(dev, dmtodz(*(int *)data), DMSET);
350 		break;
351 
352 	case TIOCMBIS:
353 		(void) dzmctl(dev, dmtodz(*(int *)data), DMBIS);
354 		break;
355 
356 	case TIOCMBIC:
357 		(void) dzmctl(dev, dmtodz(*(int *)data), DMBIC);
358 		break;
359 
360 	case TIOCMGET:
361 		*(int *)data = dztodm(dzmctl(dev, 0, DMGET));
362 		break;
363 
364 	default:
365 		return (ENOTTY);
366 	}
367 	return (0);
368 }
369 
370 dmtodz(bits)
371 	register int bits;
372 {
373 	register int b;
374 
375 	b = (bits >>1) & 0370;
376 	if (bits & DML_ST) b |= DZ_ST;
377 	if (bits & DML_RTS) b |= DZ_RTS;
378 	if (bits & DML_DTR) b |= DZ_DTR;
379 	if (bits & DML_LE) b |= DZ_LE;
380 	return(b);
381 }
382 
383 dztodm(bits)
384 	register int bits;
385 {
386 	register int b;
387 
388 	b = (bits << 1) & 0360;
389 	if (bits & DZ_DSR) b |= DML_DSR;
390 	if (bits & DZ_DTR) b |= DML_DTR;
391 	if (bits & DZ_ST) b |= DML_ST;
392 	if (bits & DZ_RTS) b |= DML_RTS;
393 	return(b);
394 }
395 
396 dzparam(tp, t)
397 	register struct tty *tp;
398 	register struct termios *t;
399 {
400 	register struct dzdevice *dzaddr;
401 	register int lpr;
402 	register int cflag = t->c_cflag;
403 	int unit = minor(tp->t_dev);
404 	int ospeed = ttspeedtab(t->c_ospeed, dzspeedtab);
405 
406 	/* check requested parameters */
407         if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
408             (cflag&CSIZE) == CS5 || (cflag&CSIZE) == CS6)
409                 return(EINVAL);
410         /* and copy to tty */
411         tp->t_ispeed = t->c_ispeed;
412         tp->t_ospeed = t->c_ospeed;
413         tp->t_cflag = cflag;
414 
415 	dzaddr = dzpdma[unit].p_addr;
416 	if (dzsilos & (1 << (unit >> 3)))
417 		dzaddr->dzcsr = DZ_IEN | DZ_SAE;
418 	else
419 		dzaddr->dzcsr = DZ_IEN;
420 	dzact |= (1<<(unit>>3));
421 	if (ospeed == 0)
422 		(void) dzmctl(unit, DZ_OFF, DMSET);	/* hang up line */
423 	else {
424 		lpr = (ospeed<<8) | (unit & 07);
425 		if ((cflag&CSIZE) == CS7)
426 			lpr |= BITS7;
427 		else
428 			lpr |= BITS8;
429 		if (cflag&PARENB)
430 			lpr |= PENABLE;
431 		if (cflag&PARODD)
432 			lpr |= OPAR;
433 		if (cflag&CSTOPB)
434 			lpr |= TWOSB;
435 		dzaddr->dzlpr = lpr;
436 	}
437 	return(0);
438 }
439 
440 dzxint(tp)
441 	register struct tty *tp;
442 {
443 	register struct pdma *dp;
444 	register dz, unit;
445 
446 	dp = (struct pdma *)tp->t_addr;
447 	tp->t_state &= ~TS_BUSY;
448 	if (tp->t_state & TS_FLUSH)
449 		tp->t_state &= ~TS_FLUSH;
450 	else {
451 		ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
452 		dp->p_end = dp->p_mem = tp->t_outq.c_cf;
453 	}
454 	if (tp->t_line)
455 		(*linesw[tp->t_line].l_start)(tp);
456 	else
457 		dzstart(tp);
458 	dz = minor(tp->t_dev) >> 3;
459 	unit = minor(tp->t_dev) & 7;
460 	if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
461 		if (dp->p_addr->dzcsr & DZ_32)
462 			dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
463 		else
464 			dp->p_addr->dztcr &= ~(1<<unit);
465 }
466 
467 dzstart(tp)
468 	register struct tty *tp;
469 {
470 	register struct pdma *dp;
471 	register struct dzdevice *dzaddr;
472 	register int cc;
473 	int s, dz, unit;
474 
475 	dp = (struct pdma *)tp->t_addr;
476 	dzaddr = dp->p_addr;
477 	s = spl5();
478 	if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
479 		goto out;
480 	if (tp->t_outq.c_cc <= tp->t_lowat) {
481 		if (tp->t_state&TS_ASLEEP) {
482 			tp->t_state &= ~TS_ASLEEP;
483 			wakeup((caddr_t)&tp->t_outq);
484 		}
485 		if (tp->t_wsel) {
486 			selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
487 			tp->t_wsel = 0;
488 			tp->t_state &= ~TS_WCOLL;
489 		}
490 	}
491 	if (tp->t_outq.c_cc == 0)
492 		goto out;
493 	if (tp->t_flags & (RAW|LITOUT))
494 		cc = ndqb(&tp->t_outq, 0);
495 	else {
496 		cc = ndqb(&tp->t_outq, 0200);
497 		if (cc == 0) {
498 			cc = getc(&tp->t_outq);
499 			timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
500 			tp->t_state |= TS_TIMEOUT;
501 			goto out;
502 		}
503 	}
504 	tp->t_state |= TS_BUSY;
505 	dp->p_end = dp->p_mem = tp->t_outq.c_cf;
506 	dp->p_end += cc;
507 	dz = minor(tp->t_dev) >> 3;
508 	unit = minor(tp->t_dev) & 7;
509 	if (dzaddr->dzcsr & DZ_32)
510 		dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit));
511 	else
512 		dzaddr->dztcr |= (1<<unit);
513 out:
514 	splx(s);
515 }
516 
517 /*
518  * Stop output on a line.
519  */
520 /*ARGSUSED*/
521 dzstop(tp, flag)
522 	register struct tty *tp;
523 {
524 	register struct pdma *dp;
525 	register int s;
526 
527 	dp = (struct pdma *)tp->t_addr;
528 	s = spl5();
529 	if (tp->t_state & TS_BUSY) {
530 		dp->p_end = dp->p_mem;
531 		if ((tp->t_state&TS_TTSTOP)==0)
532 			tp->t_state |= TS_FLUSH;
533 	}
534 	splx(s);
535 }
536 
537 dzmctl(dev, bits, how)
538 	dev_t dev;
539 	int bits, how;
540 {
541 	register struct dzdevice *dzaddr;
542 	register int unit, mbits;
543 	int b, s;
544 
545 	unit = minor(dev);
546 	b = 1<<(unit&7);
547 	dzaddr = dzpdma[unit].p_addr;
548 	s = spl5();
549 	if (dzaddr->dzcsr & DZ_32) {
550 		dzwait(dzaddr)
551 		DELAY(100);		/* IS 100 TOO MUCH? */
552 		dzaddr->dzlcs = unit&7;
553 		DELAY(100);
554 		dzwait(dzaddr)
555 		DELAY(100);
556 		mbits = dzaddr->dzlcs;
557 		mbits &= 0177770;
558 	} else {
559 		mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0;
560 		mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0;
561 		mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0;
562 	}
563 	switch (how) {
564 	case DMSET:
565 		mbits = bits;
566 		break;
567 
568 	case DMBIS:
569 		mbits |= bits;
570 		break;
571 
572 	case DMBIC:
573 		mbits &= ~bits;
574 		break;
575 
576 	case DMGET:
577 		(void) splx(s);
578 		return(mbits);
579 	}
580 	if (dzaddr->dzcsr & DZ_32) {
581 		mbits |= DZ_ACK|(unit&7);
582 		dzaddr->dzlcs = mbits;
583 	} else {
584 		if (mbits & DZ_DTR)
585 			dzaddr->dzdtr |= b;
586 		else
587 			dzaddr->dzdtr &= ~b;
588 	}
589 	if (mbits & DZ_DTR && dzsoftCAR[unit >> 3] & b)
590 		dz_tty[unit].t_state |= TS_CARR_ON;
591 	(void) splx(s);
592 	return(mbits);
593 }
594 
595 int dztransitions, dzfasttimers;		/*DEBUG*/
596 dzscan()
597 {
598 	register i;
599 	register struct dzdevice *dzaddr;
600 	register bit;
601 	register struct tty *tp;
602 	register car;
603 	int olddzsilos = dzsilos;
604 	int dztimer();
605 
606 	for (i = 0; i < dz_cnt ; i++) {
607 		dzaddr = dzpdma[i].p_addr;
608 		if (dzaddr == 0)
609 			continue;
610 		tp = &dz_tty[i];
611 		bit = 1<<(i&07);
612 		car = 0;
613 		if (dzsoftCAR[i>>3]&bit)
614 			car = 1;
615 		else if (dzaddr->dzcsr & DZ_32) {
616 			dzaddr->dzlcs = i&07;
617 			dzwait(dzaddr);
618 			car = dzaddr->dzlcs & DZ_CD;
619 		} else
620 			car = dzaddr->dzmsr&bit;
621 		if (car) {
622 			/* carrier present */
623 			if ((tp->t_state & TS_CARR_ON) == 0)
624 				(void)(*linesw[tp->t_line].l_modem)(tp, 1);
625 		} else if ((tp->t_state&TS_CARR_ON) &&
626 		    (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
627 			dzaddr->dzdtr &= ~bit;
628 	}
629 	for (i = 0; i < NDZ; i++) {
630 		ave(dzrate[i], dzchars[i], 8);
631 		if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) {
632 			dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE;
633 			dzsilos |= (1 << i);
634 			dztransitions++;		/*DEBUG*/
635 		} else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) {
636 			dzpdma[i << 3].p_addr->dzcsr = DZ_IEN;
637 			dzsilos &= ~(1 << i);
638 		}
639 		dzchars[i] = 0;
640 	}
641 	if (dzsilos && !olddzsilos)
642 		timeout(dztimer, (caddr_t)0, dztimerintvl);
643 	timeout(dzscan, (caddr_t)0, hz);
644 }
645 
646 dztimer()
647 {
648 	register int dz;
649 	register int s;
650 
651 	if (dzsilos == 0)
652 		return;
653 	s = spl5();
654 	dzfasttimers++;		/*DEBUG*/
655 	for (dz = 0; dz < NDZ; dz++)
656 		if (dzsilos & (1 << dz))
657 		    dzrint(dz);
658 	splx(s);
659 	timeout(dztimer, (caddr_t) 0, dztimerintvl);
660 }
661 
662 /*
663  * Reset state of driver if UBA reset was necessary.
664  * Reset parameters and restart transmission on open lines.
665  */
666 dzreset(uban)
667 	int uban;
668 {
669 	register int unit;
670 	register struct tty *tp;
671 	register struct uba_device *ui;
672 
673 	for (unit = 0; unit < NDZLINE; unit++) {
674 		ui = dzinfo[unit >> 3];
675 		if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
676 			continue;
677 		if (unit%8 == 0)
678 			printf(" dz%d", unit>>3);
679 		tp = &dz_tty[unit];
680 		if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
681 			dzparam(unit);
682 			(void) dzmctl(unit, DZ_ON, DMSET);
683 			tp->t_state &= ~TS_BUSY;
684 			dzstart(tp);
685 		}
686 	}
687 }
688 #endif
689