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