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