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