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