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