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