BSD 4_3_Reno release
[unix-history] / usr / src / sys / vaxuba / dz.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
1c15e888 6 * @(#)dz.c 7.9 (Berkeley) 6/28/90
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 */
52163dab
JB
16#include "param.h"
17#include "systm.h"
18#include "ioctl.h"
19#include "tty.h"
52163dab
JB
20#include "user.h"
21#include "proc.h"
22#include "map.h"
23#include "buf.h"
24#include "vm.h"
25#include "conf.h"
26#include "bkmac.h"
27#include "file.h"
28#include "uio.h"
29#include "kernel.h"
b50ce881 30#include "syslog.h"
d3ebf5ee 31
52163dab
JB
32#include "pdma.h"
33#include "ubavar.h"
34#include "dzreg.h"
1c15e888 35#include "machine/pte.h"
896962b1 36
7e00c42b
BJ
37/*
38 * Driver information for auto-configuration stuff.
39 */
71236e46 40int dzprobe(), dzattach(), dzrint();
6a1a96ff 41struct uba_device *dzinfo[NDZ];
3f3a34c3 42u_short dzstd[] = { 0 };
3f3a34c3 43struct uba_driver dzdriver =
71236e46 44 { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
3f3a34c3 45
a3cb8f60 46#define NDZLINE (NDZ*8)
acd2f01b 47#define FASTTIMER (hz/30) /* rate to drain silos, when in use */
bea90e0b 48
7e00c42b 49int dzstart(), dzxint(), dzdma();
771d8988 50int ttrstrt();
a3cb8f60
BJ
51struct tty dz_tty[NDZLINE];
52int dz_cnt = { NDZLINE };
9dca4f86 53int dzact;
acd2f01b
MK
54int dzsilos; /* mask of dz's with silo in use */
55int dzchars[NDZ]; /* recent input count */
56int dzrate[NDZ]; /* smoothed input count */
57int dztimerintvl; /* time interval for dztimer */
58int dzhighrate = 100; /* silo on if dzchars > dzhighrate */
59int dzlowrate = 75; /* silo off if dzrate < dzlowrate */
5074fa57 60
bea90e0b
BJ
61#define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0)
62
7e00c42b
BJ
63/*
64 * Software copy of dzbrk since it isn't readable
65 */
a3cb8f60
BJ
66char dz_brk[NDZ];
67char dzsoftCAR[NDZ];
bea90e0b 68char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */
5074fa57 69
7e00c42b 70/*
bea90e0b 71 * The dz11 doesn't interrupt on carrier transitions, so
7e00c42b
BJ
72 * we have to use a timer to watch it.
73 */
74char dz_timer; /* timer started? */
75
76/*
77 * Pdma structures for fast output code
78 */
a3cb8f60 79struct pdma dzpdma[NDZLINE];
7e00c42b 80
54766b65
MT
81struct 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};
5074fa57 99
74bfa0d5 100#ifndef PORTSELECTOR
54766b65
MT
101#define ISPEED TTYDEF_SPEED
102#define LFLAG TTYDEF_LFLAG
df07bd9e
SL
103#else
104#define ISPEED B4800
54766b65 105#define LFLAG (TTYDEF_LFLAG&~ECHO)
df07bd9e
SL
106#endif
107
71236e46 108dzprobe(reg)
3f3a34c3
BJ
109 caddr_t reg;
110{
88d5b764 111 register int br, cvec;
4abcd051 112 register struct dzdevice *dzaddr = (struct dzdevice *)reg;
3f3a34c3 113
71236e46 114#ifdef lint
a0eab615 115 br = 0; cvec = br; br = cvec;
89b8a44c 116 dzrint(0); dzxint((struct tty *)0);
71236e46 117#endif
bea90e0b
BJ
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 */
88d5b764 123 DELAY(100000);
bea90e0b 124 dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */
88d5b764
BJ
125 if (cvec && cvec != 0x200)
126 cvec -= 4;
4abcd051 127 return (sizeof (struct dzdevice));
3f3a34c3
BJ
128}
129
71236e46 130dzattach(ui)
6a1a96ff 131 register struct uba_device *ui;
3f3a34c3
BJ
132{
133 register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
134 register struct tty *tp = &dz_tty[ui->ui_unit*8];
71236e46 135 register int cntr;
a3cb8f60 136 extern dzscan();
3f3a34c3 137
71236e46 138 for (cntr = 0; cntr < 8; cntr++) {
4abcd051 139 pdp->p_addr = (struct dzdevice *)ui->ui_addr;
3f3a34c3
BJ
140 pdp->p_arg = (int)tp;
141 pdp->p_fcn = dzxint;
142 pdp++, tp++;
143 }
7e286c72 144 dzsoftCAR[ui->ui_unit] = ui->ui_flags;
be2b272c
BJ
145 if (dz_timer == 0) {
146 dz_timer++;
7780575a 147 timeout(dzscan, (caddr_t)0, hz);
acd2f01b 148 dztimerintvl = FASTTIMER;
be2b272c 149 }
3f3a34c3
BJ
150}
151
5074fa57 152/*ARGSUSED*/
3f3a34c3
BJ
153dzopen(dev, flag)
154 dev_t dev;
5074fa57
BJ
155{
156 register struct tty *tp;
3f3a34c3 157 register int unit;
c376c8e7 158 int error, dzparam();
5074fa57 159
3f3a34c3 160 unit = minor(dev);
7da157da
BJ
161 if (unit >= dz_cnt || dzpdma[unit].p_addr == 0)
162 return (ENXIO);
3f3a34c3
BJ
163 tp = &dz_tty[unit];
164 tp->t_addr = (caddr_t)&dzpdma[unit];
5074fa57 165 tp->t_oproc = dzstart;
54766b65
MT
166 tp->t_param = dzparam;
167 tp->t_dev = dev;
941944c9 168 if ((tp->t_state & TS_ISOPEN) == 0) {
764619a6 169 tp->t_state |= TS_WOPEN;
5074fa57 170 ttychars(tp);
74cd2624
MK
171#ifndef PORTSELECTOR
172 if (tp->t_ispeed == 0) {
54766b65
MT
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
74cd2624 182 }
54766b65
MT
183#endif
184 dzparam(tp, &tp->t_termios);
185 ttsetwater(tp);
7da157da
BJ
186 } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
187 return (EBUSY);
668cc26d 188 (void) dzmctl(dev, DZ_ON, DMSET);
771d8988 189 (void) spl5();
c376c8e7 190 while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
54766b65 191 (tp->t_state & TS_CARR_ON) == 0) {
941944c9 192 tp->t_state |= TS_WOPEN;
764619a6
MT
193 if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
194 ttopen, 0))
c376c8e7 195 break;
5074fa57 196 }
771d8988 197 (void) spl0();
c376c8e7
MK
198 if (error)
199 return (error);
7da157da 200 return ((*linesw[tp->t_line].l_open)(dev, tp));
5074fa57
BJ
201}
202
3f3a34c3
BJ
203/*ARGSUSED*/
204dzclose(dev, flag)
205 dev_t dev;
5074fa57
BJ
206{
207 register struct tty *tp;
3f3a34c3 208 register int unit;
4abcd051 209 register struct dzdevice *dzaddr;
fa627691 210 int dz;
5074fa57 211
3f3a34c3
BJ
212 unit = minor(dev);
213 dz = unit >> 3;
214 tp = &dz_tty[unit];
5074fa57 215 (*linesw[tp->t_line].l_close)(tp);
bea90e0b
BJ
216 dzaddr = dzpdma[unit].p_addr;
217 if (dzaddr->dzcsr&DZ_32)
668cc26d 218 (void) dzmctl(dev, DZ_BRK, DMBIC);
bea90e0b
BJ
219 else
220 dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
54766b65
MT
221 if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN ||
222 (tp->t_state&TS_ISOPEN) == 0)
668cc26d 223 (void) dzmctl(dev, DZ_OFF, DMSET);
c376c8e7 224 return (ttyclose(tp));
5074fa57
BJ
225}
226
54766b65 227dzread(dev, uio, flag)
3f3a34c3 228 dev_t dev;
740e4029 229 struct uio *uio;
5074fa57
BJ
230{
231 register struct tty *tp;
232
3f3a34c3 233 tp = &dz_tty[minor(dev)];
54766b65 234 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
5074fa57
BJ
235}
236
54766b65 237dzwrite(dev, uio, flag)
3f3a34c3 238 dev_t dev;
406ddcbe 239 struct uio *uio;
5074fa57
BJ
240{
241 register struct tty *tp;
242
3f3a34c3 243 tp = &dz_tty[minor(dev)];
54766b65 244 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
5074fa57
BJ
245}
246
9dca4f86 247/*ARGSUSED*/
3f3a34c3
BJ
248dzrint(dz)
249 int dz;
5074fa57
BJ
250{
251 register struct tty *tp;
54766b65 252 register int c, cc;
4abcd051 253 register struct dzdevice *dzaddr;
9dca4f86 254 register struct tty *tp0;
3f3a34c3 255 register int unit;
b19fe459 256 int overrun = 0;
5074fa57 257
88d5b764
BJ
258 if ((dzact & (1<<dz)) == 0)
259 return;
260 unit = dz * 8;
261 dzaddr = dzpdma[unit].p_addr;
262 tp0 = &dz_tty[unit];
bea90e0b
BJ
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? */
74bfa0d5
MK
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);
bea90e0b 278 }
88d5b764 279 while ((c = dzaddr->dzrbuf) < 0) { /* char present */
54766b65 280 cc = c&0xff;
acd2f01b 281 dzchars[dz]++;
88d5b764
BJ
282 tp = tp0 + ((c>>8)&07);
283 if (tp >= &dz_tty[dz_cnt])
284 continue;
941944c9 285 if ((tp->t_state & TS_ISOPEN) == 0) {
88d5b764 286 wakeup((caddr_t)&tp->t_rawq);
df07bd9e
SL
287#ifdef PORTSELECTOR
288 if ((tp->t_state&TS_WOPEN) == 0)
289#endif
74bfa0d5 290 continue;
9dca4f86 291 }
7e00c42b 292 if (c&DZ_FE)
54766b65 293 cc |= TTY_FE;
b19fe459 294 if (c&DZ_DO && overrun == 0) {
283ffc90 295 log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7);
b19fe459
BJ
296 overrun = 1;
297 }
7e00c42b 298 if (c&DZ_PE)
54766b65
MT
299 cc |= TTY_PE;
300 (*linesw[tp->t_line].l_rint)(cc, tp);
5074fa57
BJ
301 }
302}
303
304/*ARGSUSED*/
942f05a9 305dzioctl(dev, cmd, data, flag)
3f3a34c3 306 dev_t dev;
942f05a9 307 caddr_t data;
5074fa57
BJ
308{
309 register struct tty *tp;
3f3a34c3
BJ
310 register int unit = minor(dev);
311 register int dz = unit >> 3;
4abcd051 312 register struct dzdevice *dzaddr;
7da157da 313 int error;
5074fa57 314
3f3a34c3 315 tp = &dz_tty[unit];
7da157da
BJ
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);
54766b65 320 if (error >= 0)
7da157da 321 return (error);
54766b65 322
7da157da 323 switch (cmd) {
3f3a34c3 324
dc44829a 325 case TIOCSBRK:
bea90e0b
BJ
326 dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
327 if (dzaddr->dzcsr&DZ_32)
668cc26d 328 (void) dzmctl(dev, DZ_BRK, DMBIS);
bea90e0b
BJ
329 else
330 dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
dc44829a 331 break;
942f05a9 332
dc44829a 333 case TIOCCBRK:
bea90e0b
BJ
334 dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
335 if (dzaddr->dzcsr&DZ_32)
668cc26d 336 (void) dzmctl(dev, DZ_BRK, DMBIC);
bea90e0b
BJ
337 else
338 dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
dc44829a 339 break;
942f05a9 340
dc44829a 341 case TIOCSDTR:
668cc26d 342 (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
dc44829a 343 break;
942f05a9 344
dc44829a 345 case TIOCCDTR:
668cc26d 346 (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
bea90e0b 347 break;
942f05a9 348
bea90e0b 349 case TIOCMSET:
942f05a9 350 (void) dzmctl(dev, dmtodz(*(int *)data), DMSET);
bea90e0b 351 break;
942f05a9 352
bea90e0b 353 case TIOCMBIS:
942f05a9 354 (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS);
bea90e0b 355 break;
942f05a9 356
bea90e0b 357 case TIOCMBIC:
942f05a9 358 (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC);
bea90e0b 359 break;
942f05a9 360
bea90e0b 361 case TIOCMGET:
942f05a9 362 *(int *)data = dztodm(dzmctl(dev, 0, DMGET));
dc44829a 363 break;
942f05a9 364
dc44829a 365 default:
7da157da 366 return (ENOTTY);
dc44829a 367 }
7da157da 368 return (0);
5074fa57 369}
bea90e0b
BJ
370
371dmtodz(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
384dztodm(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}
5074fa57 396
54766b65 397dzparam(tp, t)
5074fa57 398 register struct tty *tp;
54766b65
MT
399 register struct termios *t;
400{
4abcd051 401 register struct dzdevice *dzaddr;
3f3a34c3 402 register int lpr;
54766b65
MT
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
3f3a34c3 416 dzaddr = dzpdma[unit].p_addr;
acd2f01b
MK
417 if (dzsilos & (1 << (unit >> 3)))
418 dzaddr->dzcsr = DZ_IEN | DZ_SAE;
419 else
420 dzaddr->dzcsr = DZ_IEN;
3f3a34c3 421 dzact |= (1<<(unit>>3));
54766b65 422 if (ospeed == 0) {
668cc26d 423 (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */
5074fa57
BJ
424 return;
425 }
54766b65
MT
426 lpr = (ospeed<<8) | (unit & 07);
427 if ((cflag&CSIZE) == CS7)
428 lpr |= BITS7;
5074fa57 429 else
54766b65
MT
430 lpr |= BITS8;
431 if (cflag&PARENB)
432 lpr |= PENABLE;
433 if (cflag&PARODD)
5074fa57 434 lpr |= OPAR;
54766b65 435 if (cflag&CSTOPB)
7e00c42b 436 lpr |= TWOSB;
5074fa57 437 dzaddr->dzlpr = lpr;
54766b65 438 return 0;
5074fa57
BJ
439}
440
441dzxint(tp)
3f3a34c3 442 register struct tty *tp;
5074fa57
BJ
443{
444 register struct pdma *dp;
acd2f01b 445 register dz, unit;
5074fa57 446
3f3a34c3 447 dp = (struct pdma *)tp->t_addr;
941944c9
BJ
448 tp->t_state &= ~TS_BUSY;
449 if (tp->t_state & TS_FLUSH)
450 tp->t_state &= ~TS_FLUSH;
bea90e0b 451 else {
46014098 452 ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
bea90e0b
BJ
453 dp->p_end = dp->p_mem = tp->t_outq.c_cf;
454 }
5074fa57
BJ
455 if (tp->t_line)
456 (*linesw[tp->t_line].l_start)(tp);
457 else
458 dzstart(tp);
bea90e0b
BJ
459 dz = minor(tp->t_dev) >> 3;
460 unit = minor(tp->t_dev) & 7;
941944c9 461 if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
bea90e0b
BJ
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);
5074fa57
BJ
466}
467
468dzstart(tp)
3f3a34c3 469 register struct tty *tp;
5074fa57
BJ
470{
471 register struct pdma *dp;
4abcd051 472 register struct dzdevice *dzaddr;
3f3a34c3 473 register int cc;
bea90e0b 474 int s, dz, unit;
5074fa57 475
3f3a34c3 476 dp = (struct pdma *)tp->t_addr;
5074fa57 477 dzaddr = dp->p_addr;
3f3a34c3 478 s = spl5();
941944c9 479 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
5074fa57 480 goto out;
54766b65 481 if (tp->t_outq.c_cc <= tp->t_lowat) {
941944c9
BJ
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 }
5074fa57
BJ
491 }
492 if (tp->t_outq.c_cc == 0)
493 goto out;
21a85e60 494 if (tp->t_flags & (RAW|LITOUT))
5074fa57
BJ
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);
7e00c42b 500 timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
941944c9 501 tp->t_state |= TS_TIMEOUT;
5074fa57
BJ
502 goto out;
503 }
504 }
941944c9 505 tp->t_state |= TS_BUSY;
5074fa57
BJ
506 dp->p_end = dp->p_mem = tp->t_outq.c_cf;
507 dp->p_end += cc;
bea90e0b
BJ
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);
3f3a34c3
BJ
514out:
515 splx(s);
5074fa57
BJ
516}
517
518/*
519 * Stop output on a line.
5074fa57
BJ
520 */
521/*ARGSUSED*/
522dzstop(tp, flag)
3f3a34c3 523 register struct tty *tp;
5074fa57
BJ
524{
525 register struct pdma *dp;
526 register int s;
527
3f3a34c3 528 dp = (struct pdma *)tp->t_addr;
88d5b764 529 s = spl5();
941944c9 530 if (tp->t_state & TS_BUSY) {
5074fa57 531 dp->p_end = dp->p_mem;
941944c9
BJ
532 if ((tp->t_state&TS_TTSTOP)==0)
533 tp->t_state |= TS_FLUSH;
5074fa57
BJ
534 }
535 splx(s);
536}
537
bea90e0b
BJ
538dzmctl(dev, bits, how)
539 dev_t dev;
540 int bits, how;
5074fa57 541{
4abcd051 542 register struct dzdevice *dzaddr;
bea90e0b
BJ
543 register int unit, mbits;
544 int b, s;
545
546 unit = minor(dev);
547 b = 1<<(unit&7);
3f3a34c3 548 dzaddr = dzpdma[unit].p_addr;
bea90e0b
BJ
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 }
d786ff40
MK
590 if (mbits & DZ_DTR && dzsoftCAR[unit >> 3] & b)
591 dz_tty[unit].t_state |= TS_CARR_ON;
bea90e0b
BJ
592 (void) splx(s);
593 return(mbits);
5074fa57
BJ
594}
595
acd2f01b 596int dztransitions, dzfasttimers; /*DEBUG*/
5074fa57
BJ
597dzscan()
598{
599 register i;
4abcd051 600 register struct dzdevice *dzaddr;
5074fa57
BJ
601 register bit;
602 register struct tty *tp;
bea90e0b 603 register car;
acd2f01b
MK
604 int olddzsilos = dzsilos;
605 int dztimer();
5074fa57
BJ
606
607 for (i = 0; i < dz_cnt ; i++) {
608 dzaddr = dzpdma[i].p_addr;
be2b272c
BJ
609 if (dzaddr == 0)
610 continue;
5074fa57
BJ
611 tp = &dz_tty[i];
612 bit = 1<<(i&07);
bea90e0b
BJ
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) {
5074fa57 623 /* carrier present */
74bfa0d5
MK
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;
5074fa57 629 }
acd2f01b
MK
630 for (i = 0; i < NDZ; i++) {
631 ave(dzrate[i], dzchars[i], 8);
632 if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) {
abca5f3b 633 dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE;
acd2f01b
MK
634 dzsilos |= (1 << i);
635 dztransitions++; /*DEBUG*/
636 } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) {
abca5f3b 637 dzpdma[i << 3].p_addr->dzcsr = DZ_IEN;
acd2f01b
MK
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);
5074fa57 645}
9dca4f86
BJ
646
647dztimer()
648{
aa890753 649 register int dz;
acd2f01b 650 register int s;
9dca4f86 651
acd2f01b
MK
652 if (dzsilos == 0)
653 return;
654 s = spl5();
655 dzfasttimers++; /*DEBUG*/
a3cb8f60 656 for (dz = 0; dz < NDZ; dz++)
acd2f01b
MK
657 if (dzsilos & (1 << dz))
658 dzrint(dz);
aa890753 659 splx(s);
acd2f01b 660 timeout(dztimer, (caddr_t) 0, dztimerintvl);
9dca4f86 661}
46014098
BJ
662
663/*
664 * Reset state of driver if UBA reset was necessary.
0072a3c2 665 * Reset parameters and restart transmission on open lines.
46014098 666 */
3f3a34c3 667dzreset(uban)
5aa9d5ea 668 int uban;
46014098 669{
3f3a34c3 670 register int unit;
46014098 671 register struct tty *tp;
6a1a96ff 672 register struct uba_device *ui;
46014098 673
a3cb8f60 674 for (unit = 0; unit < NDZLINE; unit++) {
5aa9d5ea
RE
675 ui = dzinfo[unit >> 3];
676 if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
677 continue;
b19fe459
BJ
678 if (unit%8 == 0)
679 printf(" dz%d", unit>>3);
3f3a34c3 680 tp = &dz_tty[unit];
941944c9 681 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
3f3a34c3 682 dzparam(unit);
668cc26d 683 (void) dzmctl(unit, DZ_ON, DMSET);
941944c9 684 tp->t_state &= ~TS_BUSY;
0072a3c2 685 dzstart(tp);
46014098
BJ
686 }
687 }
46014098 688}
a5cc519e 689#endif