123326Smckusick /*
229219Smckusick * Copyright (c) 1982, 1986 Regents of the University of California.
323326Smckusick * All rights reserved. The Berkeley software License Agreement
423326Smckusick * specifies the terms and conditions for redistribution.
523326Smckusick *
6*49759Smarc * @(#)dz.c 7.14 (Berkeley) 05/16/91
723326Smckusick */
817Sbill
91935Swnj #include "dz.h"
102645Swnj #if NDZ > 0
1117Sbill /*
1210019Ssam * DZ-11/DZ-32 Driver
132469Swnj *
142469Swnj * This driver mimics dh.c; see it for explanation of common code.
1517Sbill */
1645804Sbostic #include "sys/param.h"
1745804Sbostic #include "sys/systm.h"
1845804Sbostic #include "sys/ioctl.h"
1945804Sbostic #include "sys/tty.h"
2045804Sbostic #include "sys/user.h"
2145804Sbostic #include "sys/proc.h"
2245804Sbostic #include "sys/map.h"
2345804Sbostic #include "sys/buf.h"
2445804Sbostic #include "sys/vm.h"
2545804Sbostic #include "sys/conf.h"
2645804Sbostic #include "sys/file.h"
2745804Sbostic #include "sys/uio.h"
2845804Sbostic #include "sys/kernel.h"
2945804Sbostic #include "sys/syslog.h"
30145Sbill
3117123Sbloom #include "pdma.h"
3217123Sbloom #include "ubavar.h"
3317123Sbloom #include "dzreg.h"
3445804Sbostic #include "../include/pte.h"
358474Sroot
362469Swnj /*
372469Swnj * Driver information for auto-configuration stuff.
382469Swnj */
392606Swnj int dzprobe(), dzattach(), dzrint();
402976Swnj struct uba_device *dzinfo[NDZ];
412395Swnj u_short dzstd[] = { 0 };
422395Swnj struct uba_driver dzdriver =
432606Swnj { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
442395Swnj
452645Swnj #define NDZLINE (NDZ*8)
4616191Skarels #define FASTTIMER (hz/30) /* rate to drain silos, when in use */
472469Swnj
482469Swnj int dzstart(), dzxint(), dzdma();
49114Sbill int ttrstrt();
502645Swnj struct tty dz_tty[NDZLINE];
512645Swnj int dz_cnt = { NDZLINE };
52119Sbill int dzact;
5316191Skarels int dzsilos; /* mask of dz's with silo in use */
5416191Skarels int dzchars[NDZ]; /* recent input count */
5516191Skarels int dzrate[NDZ]; /* smoothed input count */
5616191Skarels int dztimerintvl; /* time interval for dztimer */
5716191Skarels int dzhighrate = 100; /* silo on if dzchars > dzhighrate */
5816191Skarels int dzlowrate = 75; /* silo off if dzrate < dzlowrate */
5917Sbill
605731Sroot #define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0)
615731Sroot
622469Swnj /*
632469Swnj * Software copy of dzbrk since it isn't readable
642469Swnj */
652645Swnj char dz_brk[NDZ];
662645Swnj char dzsoftCAR[NDZ];
675731Sroot char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */
6817Sbill
692469Swnj /*
705731Sroot * The dz11 doesn't interrupt on carrier transitions, so
712469Swnj * we have to use a timer to watch it.
722469Swnj */
732469Swnj char dz_timer; /* timer started? */
742469Swnj
752469Swnj /*
762469Swnj * Pdma structures for fast output code
772469Swnj */
782645Swnj struct pdma dzpdma[NDZLINE];
792469Swnj
8039061Smarc struct speedtab dzspeedtab[] = {
8139061Smarc 0, 0,
8239061Smarc 50, 020,
8339061Smarc 75, 021,
8439061Smarc 110, 022,
8539061Smarc 134, 023,
8639061Smarc 150, 024,
8739061Smarc 300, 025,
8839061Smarc 600, 026,
8939061Smarc 1200, 027,
9039061Smarc 1800, 030,
9139061Smarc 2400, 032,
9239061Smarc 4800, 034,
9339061Smarc 9600, 036,
9439061Smarc 19200, 037,
9539061Smarc EXTA, 037,
9639061Smarc -1, -1
9739061Smarc };
9817Sbill
9925397Skarels #ifndef PORTSELECTOR
10039061Smarc #define ISPEED TTYDEF_SPEED
10139061Smarc #define LFLAG TTYDEF_LFLAG
1026616Ssam #else
1036616Ssam #define ISPEED B4800
10439061Smarc #define LFLAG (TTYDEF_LFLAG&~ECHO)
1056616Ssam #endif
1066616Ssam
dzprobe(reg)1072606Swnj dzprobe(reg)
1082395Swnj caddr_t reg;
1092395Swnj {
1102457Swnj register int br, cvec;
11110019Ssam register struct dzdevice *dzaddr = (struct dzdevice *)reg;
1122395Swnj
1132606Swnj #ifdef lint
1143102Swnj br = 0; cvec = br; br = cvec;
1154933Swnj dzrint(0); dzxint((struct tty *)0);
1162606Swnj #endif
1175731Sroot dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32;
1185731Sroot if (dzaddr->dzcsr & DZ_32)
1195731Sroot dzaddr->dzlnen = 1;
1205731Sroot else
1215731Sroot dzaddr->dztcr = 1; /* enable any line */
1222457Swnj DELAY(100000);
1235731Sroot dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */
1242457Swnj if (cvec && cvec != 0x200)
1252457Swnj cvec -= 4;
12610019Ssam return (sizeof (struct dzdevice));
1272395Swnj }
1282395Swnj
dzattach(ui)1292606Swnj dzattach(ui)
1302976Swnj register struct uba_device *ui;
1312395Swnj {
1322395Swnj register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
1332395Swnj register struct tty *tp = &dz_tty[ui->ui_unit*8];
1342606Swnj register int cntr;
1352645Swnj extern dzscan();
1362395Swnj
1372606Swnj for (cntr = 0; cntr < 8; cntr++) {
13810019Ssam pdp->p_addr = (struct dzdevice *)ui->ui_addr;
1392395Swnj pdp->p_arg = (int)tp;
1402395Swnj pdp->p_fcn = dzxint;
1412395Swnj pdp++, tp++;
1422395Swnj }
1432567Swnj dzsoftCAR[ui->ui_unit] = ui->ui_flags;
1442627Swnj if (dz_timer == 0) {
1452627Swnj dz_timer++;
1462756Swnj timeout(dzscan, (caddr_t)0, hz);
14716191Skarels dztimerintvl = FASTTIMER;
1482627Swnj }
1492395Swnj }
1502395Swnj
15117Sbill /*ARGSUSED*/
dzopen(dev,flag)1522395Swnj dzopen(dev, flag)
1532395Swnj dev_t dev;
15417Sbill {
15517Sbill register struct tty *tp;
1562395Swnj register int unit;
15747687Smckusick int error = 0, dzparam();
15817Sbill
1592395Swnj unit = minor(dev);
1608568Sroot if (unit >= dz_cnt || dzpdma[unit].p_addr == 0)
1618568Sroot return (ENXIO);
1622395Swnj tp = &dz_tty[unit];
1632395Swnj tp->t_addr = (caddr_t)&dzpdma[unit];
16417Sbill tp->t_oproc = dzstart;
16539061Smarc tp->t_param = dzparam;
16639061Smarc tp->t_dev = dev;
1675407Swnj if ((tp->t_state & TS_ISOPEN) == 0) {
16844393Smarc tp->t_state |= TS_WOPEN;
16917Sbill ttychars(tp);
17027050Skarels #ifndef PORTSELECTOR
17127050Skarels if (tp->t_ispeed == 0) {
17239061Smarc #endif
17339061Smarc tp->t_iflag = TTYDEF_IFLAG;
17439061Smarc tp->t_oflag = TTYDEF_OFLAG;
17539061Smarc tp->t_cflag = TTYDEF_CFLAG;
17639061Smarc tp->t_lflag = LFLAG;
17739061Smarc tp->t_ispeed = tp->t_ospeed = ISPEED;
17839061Smarc #ifdef PORTSELECTOR
17939061Smarc tp->t_cflag |= HUPCL;
18039061Smarc #else
18127050Skarels }
18239061Smarc #endif
18339061Smarc dzparam(tp, &tp->t_termios);
18439061Smarc ttsetwater(tp);
1858568Sroot } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
1868568Sroot return (EBUSY);
1876157Ssam (void) dzmctl(dev, DZ_ON, DMSET);
188114Sbill (void) spl5();
18940725Skarels while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
19039061Smarc (tp->t_state & TS_CARR_ON) == 0) {
1915407Swnj tp->t_state |= TS_WOPEN;
19244393Smarc if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
19344393Smarc ttopen, 0))
19440725Skarels break;
19517Sbill }
196114Sbill (void) spl0();
19740725Skarels if (error)
19840725Skarels return (error);
1998568Sroot return ((*linesw[tp->t_line].l_open)(dev, tp));
20017Sbill }
20117Sbill
2022395Swnj /*ARGSUSED*/
dzclose(dev,flag,mode,p)203*49759Smarc dzclose(dev, flag, mode, p)
2042395Swnj dev_t dev;
205*49759Smarc int flag, mode;
206*49759Smarc struct proc *p;
20717Sbill {
20817Sbill register struct tty *tp;
2092395Swnj register int unit;
21010019Ssam register struct dzdevice *dzaddr;
2116150Ssam int dz;
21217Sbill
2132395Swnj unit = minor(dev);
2142395Swnj dz = unit >> 3;
2152395Swnj tp = &dz_tty[unit];
216*49759Smarc (*linesw[tp->t_line].l_close)(tp, flag);
2175731Sroot dzaddr = dzpdma[unit].p_addr;
2185731Sroot if (dzaddr->dzcsr&DZ_32)
2196157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC);
2205731Sroot else
2215731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
22239061Smarc if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN ||
22339061Smarc (tp->t_state&TS_ISOPEN) == 0)
2246157Ssam (void) dzmctl(dev, DZ_OFF, DMSET);
22540725Skarels return (ttyclose(tp));
22617Sbill }
22717Sbill
dzread(dev,uio,flag)22839061Smarc dzread(dev, uio, flag)
2292395Swnj dev_t dev;
2307727Sroot struct uio *uio;
23117Sbill {
23217Sbill register struct tty *tp;
23317Sbill
2342395Swnj tp = &dz_tty[minor(dev)];
23539061Smarc return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
23617Sbill }
23717Sbill
dzwrite(dev,uio,flag)23839061Smarc dzwrite(dev, uio, flag)
2392395Swnj dev_t dev;
2407833Sroot struct uio *uio;
24117Sbill {
24217Sbill register struct tty *tp;
24317Sbill
2442395Swnj tp = &dz_tty[minor(dev)];
24539061Smarc return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
24617Sbill }
24717Sbill
248119Sbill /*ARGSUSED*/
dzrint(dz)2492395Swnj dzrint(dz)
2502395Swnj int dz;
25117Sbill {
25217Sbill register struct tty *tp;
25339061Smarc register int c, cc;
25410019Ssam register struct dzdevice *dzaddr;
255119Sbill register struct tty *tp0;
2562395Swnj register int unit;
2572923Swnj int overrun = 0;
25817Sbill
2592457Swnj if ((dzact & (1<<dz)) == 0)
2602457Swnj return;
2612457Swnj unit = dz * 8;
2622457Swnj dzaddr = dzpdma[unit].p_addr;
2632457Swnj tp0 = &dz_tty[unit];
2645731Sroot dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */
2655731Sroot dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */
2665731Sroot while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */
2675731Sroot c = dzaddr->dzmtsr;
2685731Sroot tp = tp0 + (c&7);
2695731Sroot if (tp >= &dz_tty[dz_cnt])
2705731Sroot break;
2715731Sroot dzaddr->dzlcs = c&7; /* get status of modem lines */
2725731Sroot dzwait(dzaddr); /* wait for them */
2735731Sroot if (c & DZ_CD) /* carrier status change? */
2745731Sroot if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */
27525397Skarels /* carrier present */
27625397Skarels (void)(*linesw[tp->t_line].l_modem)(tp, 1);
27725397Skarels } else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
27825397Skarels dzaddr->dzlcs = DZ_ACK|(c&7);
2795731Sroot }
2802457Swnj while ((c = dzaddr->dzrbuf) < 0) { /* char present */
28139061Smarc cc = c&0xff;
28216191Skarels dzchars[dz]++;
2832457Swnj tp = tp0 + ((c>>8)&07);
2842457Swnj if (tp >= &dz_tty[dz_cnt])
28517Sbill continue;
2865407Swnj if ((tp->t_state & TS_ISOPEN) == 0) {
2872457Swnj wakeup((caddr_t)&tp->t_rawq);
2886616Ssam #ifdef PORTSELECTOR
2896616Ssam if ((tp->t_state&TS_WOPEN) == 0)
2906616Ssam #endif
29125397Skarels continue;
2922457Swnj }
2932469Swnj if (c&DZ_FE)
29439061Smarc cc |= TTY_FE;
2952923Swnj if (c&DZ_DO && overrun == 0) {
29624843Seric log(LOG_WARNING, "dz%d,%d: silo overflow\n", dz, (c>>8)&7);
2972923Swnj overrun = 1;
2982923Swnj }
2992469Swnj if (c&DZ_PE)
30039061Smarc cc |= TTY_PE;
30139061Smarc (*linesw[tp->t_line].l_rint)(cc, tp);
30217Sbill }
30317Sbill }
30417Sbill
30517Sbill /*ARGSUSED*/
dzioctl(dev,cmd,data,flag)3067631Ssam dzioctl(dev, cmd, data, flag)
3072395Swnj dev_t dev;
3087631Ssam caddr_t data;
30917Sbill {
31017Sbill register struct tty *tp;
3112395Swnj register int unit = minor(dev);
3122395Swnj register int dz = unit >> 3;
31310019Ssam register struct dzdevice *dzaddr;
3148568Sroot int error;
31517Sbill
3162395Swnj tp = &dz_tty[unit];
3178568Sroot error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
3188568Sroot if (error >= 0)
3198568Sroot return (error);
3208568Sroot error = ttioctl(tp, cmd, data, flag);
32139061Smarc if (error >= 0)
3228568Sroot return (error);
32339061Smarc
3248568Sroot switch (cmd) {
3252395Swnj
326170Sbill case TIOCSBRK:
3275731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
3285731Sroot if (dzaddr->dzcsr&DZ_32)
3296157Ssam (void) dzmctl(dev, DZ_BRK, DMBIS);
3305731Sroot else
3315731Sroot dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
332170Sbill break;
3337631Ssam
334170Sbill case TIOCCBRK:
3355731Sroot dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
3365731Sroot if (dzaddr->dzcsr&DZ_32)
3376157Ssam (void) dzmctl(dev, DZ_BRK, DMBIC);
3385731Sroot else
3395731Sroot dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
340170Sbill break;
3417631Ssam
342170Sbill case TIOCSDTR:
3436157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
344170Sbill break;
3457631Ssam
346170Sbill case TIOCCDTR:
3476157Ssam (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
348170Sbill break;
3497631Ssam
3505731Sroot case TIOCMSET:
3517631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMSET);
3525731Sroot break;
3537631Ssam
3545731Sroot case TIOCMBIS:
3557631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIS);
3565731Sroot break;
3577631Ssam
3585731Sroot case TIOCMBIC:
3597631Ssam (void) dzmctl(dev, dmtodz(*(int *)data), DMBIC);
3605731Sroot break;
3617631Ssam
3625731Sroot case TIOCMGET:
3637631Ssam *(int *)data = dztodm(dzmctl(dev, 0, DMGET));
3645731Sroot break;
3657631Ssam
366170Sbill default:
3678568Sroot return (ENOTTY);
368170Sbill }
3698568Sroot return (0);
37017Sbill }
3715731Sroot
dmtodz(bits)3725731Sroot dmtodz(bits)
3735731Sroot register int bits;
3745731Sroot {
3755731Sroot register int b;
3765731Sroot
3775731Sroot b = (bits >>1) & 0370;
3785731Sroot if (bits & DML_ST) b |= DZ_ST;
3795731Sroot if (bits & DML_RTS) b |= DZ_RTS;
3805731Sroot if (bits & DML_DTR) b |= DZ_DTR;
3815731Sroot if (bits & DML_LE) b |= DZ_LE;
3825731Sroot return(b);
3835731Sroot }
3845731Sroot
dztodm(bits)3855731Sroot dztodm(bits)
3865731Sroot register int bits;
3875731Sroot {
3885731Sroot register int b;
3895731Sroot
3905731Sroot b = (bits << 1) & 0360;
3915731Sroot if (bits & DZ_DSR) b |= DML_DSR;
3925731Sroot if (bits & DZ_DTR) b |= DML_DTR;
3935731Sroot if (bits & DZ_ST) b |= DML_ST;
3945731Sroot if (bits & DZ_RTS) b |= DML_RTS;
3955731Sroot return(b);
3965731Sroot }
39717Sbill
dzparam(tp,t)39839061Smarc dzparam(tp, t)
39939061Smarc register struct tty *tp;
40039061Smarc register struct termios *t;
40117Sbill {
40210019Ssam register struct dzdevice *dzaddr;
4032395Swnj register int lpr;
40439061Smarc register int cflag = t->c_cflag;
40539061Smarc int unit = minor(tp->t_dev);
40639061Smarc int ospeed = ttspeedtab(t->c_ospeed, dzspeedtab);
40739061Smarc
40839061Smarc /* check requested parameters */
40939061Smarc if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
41039061Smarc (cflag&CSIZE) == CS5 || (cflag&CSIZE) == CS6)
41139061Smarc return(EINVAL);
41239061Smarc /* and copy to tty */
41339061Smarc tp->t_ispeed = t->c_ispeed;
41439061Smarc tp->t_ospeed = t->c_ospeed;
41539061Smarc tp->t_cflag = cflag;
41639061Smarc
4172395Swnj dzaddr = dzpdma[unit].p_addr;
41816191Skarels if (dzsilos & (1 << (unit >> 3)))
41916191Skarels dzaddr->dzcsr = DZ_IEN | DZ_SAE;
42016191Skarels else
42116191Skarels dzaddr->dzcsr = DZ_IEN;
4222395Swnj dzact |= (1<<(unit>>3));
42347286Sbostic if (ospeed == 0)
4246157Ssam (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */
42547286Sbostic else {
42647286Sbostic lpr = (ospeed<<8) | (unit & 07);
42747286Sbostic if ((cflag&CSIZE) == CS7)
42847286Sbostic lpr |= BITS7;
42947286Sbostic else
43047286Sbostic lpr |= BITS8;
43147286Sbostic if (cflag&PARENB)
43247286Sbostic lpr |= PENABLE;
43347286Sbostic if (cflag&PARODD)
43447286Sbostic lpr |= OPAR;
43547286Sbostic if (cflag&CSTOPB)
43647286Sbostic lpr |= TWOSB;
43747286Sbostic dzaddr->dzlpr = lpr;
43817Sbill }
43947286Sbostic return(0);
44017Sbill }
44117Sbill
dzxint(tp)44217Sbill dzxint(tp)
4432395Swnj register struct tty *tp;
44417Sbill {
44517Sbill register struct pdma *dp;
44616191Skarels register dz, unit;
44717Sbill
4482395Swnj dp = (struct pdma *)tp->t_addr;
4495407Swnj tp->t_state &= ~TS_BUSY;
4505407Swnj if (tp->t_state & TS_FLUSH)
4515407Swnj tp->t_state &= ~TS_FLUSH;
4525731Sroot else {
453281Sbill ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
4545731Sroot dp->p_end = dp->p_mem = tp->t_outq.c_cf;
4555731Sroot }
45617Sbill if (tp->t_line)
45717Sbill (*linesw[tp->t_line].l_start)(tp);
45817Sbill else
45917Sbill dzstart(tp);
4605731Sroot dz = minor(tp->t_dev) >> 3;
4615731Sroot unit = minor(tp->t_dev) & 7;
4625407Swnj if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
4635731Sroot if (dp->p_addr->dzcsr & DZ_32)
4645731Sroot dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
4655731Sroot else
4665731Sroot dp->p_addr->dztcr &= ~(1<<unit);
46717Sbill }
46817Sbill
dzstart(tp)46917Sbill dzstart(tp)
4702395Swnj register struct tty *tp;
47117Sbill {
47217Sbill register struct pdma *dp;
47310019Ssam register struct dzdevice *dzaddr;
4742395Swnj register int cc;
4755731Sroot int s, dz, unit;
47617Sbill
4772395Swnj dp = (struct pdma *)tp->t_addr;
47817Sbill dzaddr = dp->p_addr;
4792395Swnj s = spl5();
4805407Swnj if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
48117Sbill goto out;
48239061Smarc if (tp->t_outq.c_cc <= tp->t_lowat) {
4835407Swnj if (tp->t_state&TS_ASLEEP) {
4845407Swnj tp->t_state &= ~TS_ASLEEP;
4855407Swnj wakeup((caddr_t)&tp->t_outq);
4865407Swnj }
4875407Swnj if (tp->t_wsel) {
4885407Swnj selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
4895407Swnj tp->t_wsel = 0;
4905407Swnj tp->t_state &= ~TS_WCOLL;
4915407Swnj }
49217Sbill }
49317Sbill if (tp->t_outq.c_cc == 0)
49417Sbill goto out;
4959551Ssam if (tp->t_flags & (RAW|LITOUT))
49617Sbill cc = ndqb(&tp->t_outq, 0);
49717Sbill else {
49817Sbill cc = ndqb(&tp->t_outq, 0200);
49917Sbill if (cc == 0) {
50017Sbill cc = getc(&tp->t_outq);
5012469Swnj timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
5025407Swnj tp->t_state |= TS_TIMEOUT;
50317Sbill goto out;
50417Sbill }
50517Sbill }
5065407Swnj tp->t_state |= TS_BUSY;
50717Sbill dp->p_end = dp->p_mem = tp->t_outq.c_cf;
50817Sbill dp->p_end += cc;
5095731Sroot dz = minor(tp->t_dev) >> 3;
5105731Sroot unit = minor(tp->t_dev) & 7;
5115731Sroot if (dzaddr->dzcsr & DZ_32)
5125731Sroot dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit));
5135731Sroot else
5145731Sroot dzaddr->dztcr |= (1<<unit);
5152395Swnj out:
5162395Swnj splx(s);
51717Sbill }
51817Sbill
51917Sbill /*
52017Sbill * Stop output on a line.
52117Sbill */
52217Sbill /*ARGSUSED*/
dzstop(tp,flag)52317Sbill dzstop(tp, flag)
5242395Swnj register struct tty *tp;
52517Sbill {
52617Sbill register struct pdma *dp;
52717Sbill register int s;
52817Sbill
5292395Swnj dp = (struct pdma *)tp->t_addr;
5302457Swnj s = spl5();
5315407Swnj if (tp->t_state & TS_BUSY) {
53217Sbill dp->p_end = dp->p_mem;
5335407Swnj if ((tp->t_state&TS_TTSTOP)==0)
5345407Swnj tp->t_state |= TS_FLUSH;
53517Sbill }
53617Sbill splx(s);
53717Sbill }
53817Sbill
dzmctl(dev,bits,how)5395731Sroot dzmctl(dev, bits, how)
5405731Sroot dev_t dev;
5415731Sroot int bits, how;
54217Sbill {
54310019Ssam register struct dzdevice *dzaddr;
5445731Sroot register int unit, mbits;
5455731Sroot int b, s;
5465731Sroot
5475731Sroot unit = minor(dev);
5485731Sroot b = 1<<(unit&7);
5492395Swnj dzaddr = dzpdma[unit].p_addr;
5505731Sroot s = spl5();
5515731Sroot if (dzaddr->dzcsr & DZ_32) {
5525731Sroot dzwait(dzaddr)
5535731Sroot DELAY(100); /* IS 100 TOO MUCH? */
5545731Sroot dzaddr->dzlcs = unit&7;
5555731Sroot DELAY(100);
5565731Sroot dzwait(dzaddr)
5575731Sroot DELAY(100);
5585731Sroot mbits = dzaddr->dzlcs;
5595731Sroot mbits &= 0177770;
5605731Sroot } else {
5615731Sroot mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0;
5625731Sroot mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0;
5635731Sroot mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0;
5645731Sroot }
5655731Sroot switch (how) {
5665731Sroot case DMSET:
5675731Sroot mbits = bits;
5685731Sroot break;
5695731Sroot
5705731Sroot case DMBIS:
5715731Sroot mbits |= bits;
5725731Sroot break;
5735731Sroot
5745731Sroot case DMBIC:
5755731Sroot mbits &= ~bits;
5765731Sroot break;
5775731Sroot
5785731Sroot case DMGET:
5795731Sroot (void) splx(s);
5805731Sroot return(mbits);
5815731Sroot }
5825731Sroot if (dzaddr->dzcsr & DZ_32) {
5835731Sroot mbits |= DZ_ACK|(unit&7);
5845731Sroot dzaddr->dzlcs = mbits;
5855731Sroot } else {
5865731Sroot if (mbits & DZ_DTR)
5875731Sroot dzaddr->dzdtr |= b;
5885731Sroot else
5895731Sroot dzaddr->dzdtr &= ~b;
5905731Sroot }
59130387Skarels if (mbits & DZ_DTR && dzsoftCAR[unit >> 3] & b)
59230387Skarels dz_tty[unit].t_state |= TS_CARR_ON;
5935731Sroot (void) splx(s);
5945731Sroot return(mbits);
59517Sbill }
59617Sbill
59716191Skarels int dztransitions, dzfasttimers; /*DEBUG*/
dzscan()59817Sbill dzscan()
59917Sbill {
60017Sbill register i;
60110019Ssam register struct dzdevice *dzaddr;
60217Sbill register bit;
60317Sbill register struct tty *tp;
6045731Sroot register car;
60516191Skarels int olddzsilos = dzsilos;
60616191Skarels int dztimer();
60717Sbill
60817Sbill for (i = 0; i < dz_cnt ; i++) {
60917Sbill dzaddr = dzpdma[i].p_addr;
6102627Swnj if (dzaddr == 0)
6112627Swnj continue;
61217Sbill tp = &dz_tty[i];
61317Sbill bit = 1<<(i&07);
6145731Sroot car = 0;
6155731Sroot if (dzsoftCAR[i>>3]&bit)
6165731Sroot car = 1;
6175731Sroot else if (dzaddr->dzcsr & DZ_32) {
6185731Sroot dzaddr->dzlcs = i&07;
6195731Sroot dzwait(dzaddr);
6205731Sroot car = dzaddr->dzlcs & DZ_CD;
6215731Sroot } else
6225731Sroot car = dzaddr->dzmsr&bit;
6235731Sroot if (car) {
62417Sbill /* carrier present */
62525397Skarels if ((tp->t_state & TS_CARR_ON) == 0)
62625397Skarels (void)(*linesw[tp->t_line].l_modem)(tp, 1);
62725397Skarels } else if ((tp->t_state&TS_CARR_ON) &&
62825397Skarels (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
62925397Skarels dzaddr->dzdtr &= ~bit;
63017Sbill }
63116191Skarels for (i = 0; i < NDZ; i++) {
63216191Skarels ave(dzrate[i], dzchars[i], 8);
63316191Skarels if (dzchars[i] > dzhighrate && ((dzsilos & (1 << i)) == 0)) {
63416397Ssam dzpdma[i << 3].p_addr->dzcsr = DZ_IEN | DZ_SAE;
63516191Skarels dzsilos |= (1 << i);
63616191Skarels dztransitions++; /*DEBUG*/
63716191Skarels } else if ((dzsilos & (1 << i)) && (dzrate[i] < dzlowrate)) {
63816397Ssam dzpdma[i << 3].p_addr->dzcsr = DZ_IEN;
63916191Skarels dzsilos &= ~(1 << i);
64016191Skarels }
64116191Skarels dzchars[i] = 0;
64216191Skarels }
64316191Skarels if (dzsilos && !olddzsilos)
64416191Skarels timeout(dztimer, (caddr_t)0, dztimerintvl);
64516191Skarels timeout(dzscan, (caddr_t)0, hz);
64617Sbill }
647119Sbill
dztimer()648119Sbill dztimer()
649119Sbill {
6508160Sroot register int dz;
65116191Skarels register int s;
652119Sbill
65316191Skarels if (dzsilos == 0)
65416191Skarels return;
65516191Skarels s = spl5();
65616191Skarels dzfasttimers++; /*DEBUG*/
6572645Swnj for (dz = 0; dz < NDZ; dz++)
65816191Skarels if (dzsilos & (1 << dz))
65916191Skarels dzrint(dz);
6608160Sroot splx(s);
66116191Skarels timeout(dztimer, (caddr_t) 0, dztimerintvl);
662119Sbill }
663281Sbill
664281Sbill /*
665281Sbill * Reset state of driver if UBA reset was necessary.
666301Sbill * Reset parameters and restart transmission on open lines.
667281Sbill */
dzreset(uban)6682395Swnj dzreset(uban)
6692422Skre int uban;
670281Sbill {
6712395Swnj register int unit;
672281Sbill register struct tty *tp;
6732976Swnj register struct uba_device *ui;
674281Sbill
6752645Swnj for (unit = 0; unit < NDZLINE; unit++) {
6762422Skre ui = dzinfo[unit >> 3];
6772422Skre if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
6782422Skre continue;
6792923Swnj if (unit%8 == 0)
6802923Swnj printf(" dz%d", unit>>3);
6812395Swnj tp = &dz_tty[unit];
6825407Swnj if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
6832395Swnj dzparam(unit);
6846157Ssam (void) dzmctl(unit, DZ_ON, DMSET);
6855407Swnj tp->t_state &= ~TS_BUSY;
686301Sbill dzstart(tp);
687281Sbill }
688281Sbill }
689281Sbill }
6901562Sbill #endif
691