-/* dz.c 3.8 %H% */
+/* dz.c 4.38 82/05/19 */
+#include "dz.h"
+#if NDZ > 0
/*
- * DZ-11 Driver
+ * DZ-11 and DZ32 Driver
+ *
+ * This driver mimics dh.c; see it for explanation of common code.
*/
+#include "bk.h"
#include "../h/param.h"
#include "../h/systm.h"
#include "../h/tty.h"
#include "../h/dir.h"
#include "../h/user.h"
+#include "../h/proc.h"
#include "../h/map.h"
#include "../h/pte.h"
-#include "../h/uba.h"
+#include "../h/buf.h"
+#include "../h/vm.h"
+#include "../h/ubavar.h"
#include "../h/conf.h"
#include "../h/pdma.h"
#include "../h/bk.h"
+#include "../h/file.h"
/*
- * When running dz's using only SAE (silo alarm) on input
- * it is necessary to call dzrint() at clock interrupt time.
- * This is unsafe unless spl5()s in tty code are changed to
- * spl6()s to block clock interrupts. Note that the dh driver
- * currently in use works the same way as the dz, even though
- * we could try to more intelligently manage its silo.
- * Thus don't take this out if you have no dz's unless you
- * change clock.c and dhtimer().
+ * Driver information for auto-configuration stuff.
*/
-#define spl5 spl6
-
-#define DZADDR (UBA0_DEV + 0160100)
-#ifdef ERNIE
-#define NDZ (3*8)
-#else
-#define NDZ (8)
-#endif
-
-#define BITS7 020
-#define BITS8 030
-#define TWOSB 040
-#define PENABLE 0100
-#define OPAR 0200
-#define MSE 040 /* Master Scan Enable */
-#define RIE 0100 /* Receiver Interrupt Enable */
-#define SAE 010000 /* Silo Alarm Enable */
-#define TIE 040000 /* Transmit Interrupt Enable */
-#define DZ_IEN (MSE+RIE+TIE+SAE)
-#define PERROR 010000
-#define FRERROR 020000
-#define OVERRUN 040000
-#define SSPEED 7 /* std speed = 300 baud */
+int dzprobe(), dzattach(), dzrint();
+struct uba_device *dzinfo[NDZ];
+u_short dzstd[] = { 0 };
+struct uba_driver dzdriver =
+ { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
+#define NDZLINE (NDZ*8)
-#define dzlpr dzrbuf
-#define dzmsr dzbrk
-#define ON 1
-#define OFF 0
+/*
+ * Registers and bits
+ */
+
+/* bits in dzlpr */
+#define BITS7 0020
+#define BITS8 0030
+#define TWOSB 0040
+#define PENABLE 0100
+#define OPAR 0200
+
+/* bits in dzrbuf */
+#define DZ_PE 010000
+#define DZ_FE 020000
+#define DZ_DO 040000
+
+/* bits in dzcsr */
+#define DZ_32 000001 /* DZ32 mode */
+#define DZ_MIE 000002 /* Modem Interrupt Enable */
+#define DZ_CLR 000020 /* Reset dz */
+#define DZ_MSE 000040 /* Master Scan Enable */
+#define DZ_RIE 000100 /* Receiver Interrupt Enable */
+#define DZ_MSC 004000 /* Modem Status Change */
+#define DZ_SAE 010000 /* Silo Alarm Enable */
+#define DZ_TIE 040000 /* Transmit Interrupt Enable */
+#define DZ_IEN (DZ_32|DZ_MIE|DZ_MSE|DZ_RIE|DZ_TIE|DZ_SAE)
+
+/* flags for modem-control */
+#define DZ_ON DZ_DTR
+#define DZ_OFF 0
+
+/* bits in dzlcs */
+#define DZ_ACK 0100000 /* ACK bit in dzlcs */
+#define DZ_RTS 0010000 /* Request To Send */
+#define DZ_ST 0004000 /* Secondary Transmit */
+#define DZ_BRK 0002000 /* Break */
+#define DZ_DTR 0001000 /* Data Terminal Ready */
+#define DZ_LE 0000400 /* Line Enable */
+#define DZ_DSR 0000200 /* Data Set Ready */
+#define DZ_RI 0000100 /* Ring Indicate */
+#define DZ_CD 0000040 /* Carrier Detect */
+#define DZ_CTS 0000020 /* Clear To Send */
+#define DZ_SR 0000010 /* Secondary Receive */
-int dzstart();
-int dzxint();
+/* bits in dm lsr, copied from dh.c */
+#define DML_DSR 0000400 /* data set ready, not a real DM bit */
+#define DML_RNG 0000200 /* ring */
+#define DML_CAR 0000100 /* carrier detect */
+#define DML_CTS 0000040 /* clear to send */
+#define DML_SR 0000020 /* secondary receive */
+#define DML_ST 0000010 /* secondary transmit */
+#define DML_RTS 0000004 /* request to send */
+#define DML_DTR 0000002 /* data terminal ready */
+#define DML_LE 0000001 /* line enable */
+
+int dzstart(), dzxint(), dzdma();
int ttrstrt();
-struct tty dz_tty[NDZ];
-int dz_cnt = { NDZ };
+struct tty dz_tty[NDZLINE];
+int dz_cnt = { NDZLINE };
int dzact;
struct device {
- short dzcsr;
- short dzrbuf;
- char dztcr;
- char dzdtr;
- char dztbuf;
- char dzbrk;
+ short dzcsr;
+ short dzrbuf;
+ union {
+ struct {
+ char dztcr0;
+ char dzdtr0;
+ char dztbuf0;
+ char dzbrk0;
+ } dz11;
+ struct {
+ short dzlcs0;
+ char dztbuf0;
+ char dzlnen0;
+ } dz32;
+ } dzun;
};
-struct pdma dzpdma[] = {
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[0], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[1], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[2], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[3], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[4], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[5], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[6], dzxint,
- (struct device *)(DZADDR), NULL, NULL, (int)&dz_tty[7], dzxint,
-#ifdef ERNIE
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[8], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[9], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[10], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[11], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[12], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[13], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[14], dzxint,
- (struct device *)(DZADDR+010), NULL, NULL, (int)&dz_tty[15], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[16], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[17], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[18], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[19], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[20], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[21], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[22], dzxint,
- (struct device *)(DZADDR+020), NULL, NULL, (int)&dz_tty[23], dzxint,
-#endif
-};
-char dz_timer;
-char dz_speeds[] = {
- 0, 020 , 021 , 022 , 023 , 024 , 0, 025,
- 026 , 027 , 030 , 032 , 034 , 036 , 0 , 0,
-};
+#define dzlpr dzrbuf
+#define dzmsr dzun.dz11.dzbrk0
+#define dztcr dzun.dz11.dztcr0
+#define dzdtr dzun.dz11.dzdtr0
+#define dztbuf dzun.dz11.dztbuf0
+#define dzlcs dzun.dz32.dzlcs0
+#define dzbrk dzmsr
+#define dzlnen dzun.dz32.dzlnen0
+#define dzmtsr dzun.dz32.dztbuf0;
+
+#define dzwait(x) while (((x)->dzlcs & DZ_ACK) == 0)
+
+/*
+ * Software copy of dzbrk since it isn't readable
+ */
+char dz_brk[NDZ];
+char dzsoftCAR[NDZ];
+char dz_lnen[NDZ]; /* saved line enable bits for DZ32 */
+
+/*
+ * The dz11 doesn't interrupt on carrier transitions, so
+ * we have to use a timer to watch it.
+ */
+char dz_timer; /* timer started? */
+
+/*
+ * Pdma structures for fast output code
+ */
+struct pdma dzpdma[NDZLINE];
+
+char dz_speeds[] =
+ { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,037,0 };
+#ifndef PORTSELECTOR
+#define ISPEED B300
+#define IFLAGS (EVENP|ODDP|ECHO)
+#else
+#define ISPEED B4800
+#define IFLAGS (EVENP|ODDP)
+#endif
+
+dzprobe(reg)
+ caddr_t reg;
+{
+ register int br, cvec;
+ register struct device *dzaddr = (struct device *)reg;
+
+#ifdef lint
+ br = 0; cvec = br; br = cvec;
+ dzrint(0); dzxint((struct tty *)0);
+#endif
+ dzaddr->dzcsr = DZ_TIE|DZ_MSE|DZ_32;
+ if (dzaddr->dzcsr & DZ_32)
+ dzaddr->dzlnen = 1;
+ else
+ dzaddr->dztcr = 1; /* enable any line */
+ DELAY(100000);
+ dzaddr->dzcsr = DZ_CLR|DZ_32; /* reset everything */
+ if (cvec && cvec != 0x200)
+ cvec -= 4;
+ return (1);
+}
+
+dzattach(ui)
+ register struct uba_device *ui;
+{
+ register struct pdma *pdp = &dzpdma[ui->ui_unit*8];
+ register struct tty *tp = &dz_tty[ui->ui_unit*8];
+ register int cntr;
+ extern dzscan();
+
+ for (cntr = 0; cntr < 8; cntr++) {
+ pdp->p_addr = (struct device *)ui->ui_addr;
+ pdp->p_arg = (int)tp;
+ pdp->p_fcn = dzxint;
+ pdp++, tp++;
+ }
+ dzsoftCAR[ui->ui_unit] = ui->ui_flags;
+ if (dz_timer == 0) {
+ dz_timer++;
+ timeout(dzscan, (caddr_t)0, hz);
+ }
+}
+
/*ARGSUSED*/
-dzopen(d, flag)
+dzopen(dev, flag)
+ dev_t dev;
{
register struct tty *tp;
- register dev;
- extern dzscan();
+ register int unit;
- dev = minor(d);
- if (dev >= dz_cnt) {
+ unit = minor(dev);
+ if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
u.u_error = ENXIO;
return;
}
- if (dz_timer == 0) {
- dz_timer++;
- timeout(dzscan, (caddr_t)0, 60);
- }
- tp = &dz_tty[dev];
- tp->t_addr = (caddr_t)&dzpdma[dev];
+ tp = &dz_tty[unit];
+ tp->t_addr = (caddr_t)&dzpdma[unit];
tp->t_oproc = dzstart;
- tp->t_iproc = NULL;
- tp->t_state |= WOPEN;
- if ((tp->t_state & ISOPEN) == 0) {
+ tp->t_state |= TS_WOPEN;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
ttychars(tp);
- tp->t_ospeed = tp->t_ispeed = SSPEED;
- tp->t_flags = ODDP|EVENP|ECHO;
- /*tp->t_state |= HUPCLS;*/
- dzparam(dev);
- } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
+ tp->t_ospeed = tp->t_ispeed = ISPEED;
+ tp->t_flags = IFLAGS;
+ /* tp->t_state |= TS_HUPCLS; */
+ dzparam(unit);
+ } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0) {
u.u_error = EBUSY;
return;
}
- dzmodem(dev, ON);
+ (void) dzmctl(dev, DZ_ON, DMSET);
(void) spl5();
- while ((tp->t_state & CARR_ON) == 0) {
- tp->t_state |= WOPEN;
+ while ((tp->t_state & TS_CARR_ON) == 0) {
+ tp->t_state |= TS_WOPEN;
sleep((caddr_t)&tp->t_rawq, TTIPRI);
}
(void) spl0();
- (*linesw[tp->t_line].l_open)(d, tp);
+ (*linesw[tp->t_line].l_open)(dev, tp);
}
-dzclose(d)
+/*ARGSUSED*/
+dzclose(dev, flag)
+ dev_t dev;
{
register struct tty *tp;
- register dev;
+ register int unit;
+ register struct device *dzaddr;
+ int dz;
- dev = minor(d);
- tp = &dz_tty[dev];
+ unit = minor(dev);
+ dz = unit >> 3;
+ tp = &dz_tty[unit];
(*linesw[tp->t_line].l_close)(tp);
- if (tp->t_state & HUPCLS)
- dzmodem(dev, OFF);
+ dzaddr = dzpdma[unit].p_addr;
+ if (dzaddr->dzcsr&DZ_32)
+ (void) dzmctl(dev, DZ_BRK, DMBIC);
+ else
+ dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
+ if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN) == 0)
+ (void) dzmctl(dev, DZ_OFF, DMSET);
ttyclose(tp);
}
-dzread(d)
+dzread(dev)
+ dev_t dev;
{
register struct tty *tp;
- tp = &dz_tty[minor(d)];
+ tp = &dz_tty[minor(dev)];
(*linesw[tp->t_line].l_read)(tp);
}
-dzwrite(d)
+dzwrite(dev)
+ dev_t dev;
{
register struct tty *tp;
- tp = &dz_tty[minor(d)];
+ tp = &dz_tty[minor(dev)];
(*linesw[tp->t_line].l_write)(tp);
}
/*ARGSUSED*/
-dzrint(dev)
+dzrint(dz)
+ int dz;
{
register struct tty *tp;
register int c;
register struct device *dzaddr;
register struct tty *tp0;
- int s;
+ register int unit;
+ int overrun = 0;
- s = spl6(); /* see comment in clock.c */
- /* as long as we are here, service them all */
- for (dev = 0; dev < NDZ; dev += 8) {
- if ((dzact & (1<<(dev>>3))) == 0)
- continue;
- dzaddr = dzpdma[dev].p_addr;
- tp0 = &dz_tty[dev];
- while ((c = dzaddr->dzrbuf) < 0) { /* char present */
- tp = tp0 + ((c>>8)&07);
- if (tp >= &dz_tty[dz_cnt])
- continue;
- if ((tp->t_state & ISOPEN) == 0) {
+ if ((dzact & (1<<dz)) == 0)
+ return;
+ unit = dz * 8;
+ dzaddr = dzpdma[unit].p_addr;
+ tp0 = &dz_tty[unit];
+ dzaddr->dzcsr &= ~(DZ_RIE|DZ_MIE); /* the manual says this song */
+ dzaddr->dzcsr |= DZ_RIE|DZ_MIE; /* and dance is necessary */
+ while (dzaddr->dzcsr & DZ_MSC) { /* DZ32 modem change interrupt */
+ c = dzaddr->dzmtsr;
+ tp = tp0 + (c&7);
+ if (tp >= &dz_tty[dz_cnt])
+ break;
+ dzaddr->dzlcs = c&7; /* get status of modem lines */
+ dzwait(dzaddr); /* wait for them */
+ if (c & DZ_CD) /* carrier status change? */
+ if (dzaddr->dzlcs & DZ_CD) { /* carrier up? */
+ if ((tp->t_state&TS_CARR_ON) == 0) {
wakeup((caddr_t)&tp->t_rawq);
- continue;
+ tp->t_state |= TS_CARR_ON;
}
- if (c&FRERROR)
- /* framing error = break */
- if (tp->t_flags & RAW)
- c = 0; /* null for getty */
- else
-#ifdef IIASA
- continue;
-#else
- c = tun.t_intrc;
+ } else { /* no carrier */
+ if (tp->t_state&TS_CARR_ON) {
+ gsignal(tp->t_pgrp, SIGHUP);
+ gsignal(tp->t_pgrp, SIGCONT);
+ dzaddr->dzlcs = DZ_ACK|(c&7);
+ flushtty(tp, FREAD|FWRITE);
+ }
+ tp->t_state &= ~TS_CARR_ON;
+ }
+ }
+ while ((c = dzaddr->dzrbuf) < 0) { /* char present */
+ tp = tp0 + ((c>>8)&07);
+ if (tp >= &dz_tty[dz_cnt])
+ continue;
+ if ((tp->t_state & TS_ISOPEN) == 0) {
+ wakeup((caddr_t)&tp->t_rawq);
+#ifdef PORTSELECTOR
+ if ((tp->t_state&TS_WOPEN) == 0)
#endif
- if (c&OVERRUN)
- printf("o");
- if (c&PERROR)
- /* parity error */
- if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
- || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
- continue;
- if (tp->t_line == NETLDISC) {
- c &= 0177;
- BKINPUT(c, tp);
- } else
- (*linesw[tp->t_line].l_rint)(c, tp);
+ continue;
}
+ if (c&DZ_FE)
+ if (tp->t_flags & RAW)
+ c = 0;
+ else
+ c = tun.t_intrc;
+ if (c&DZ_DO && overrun == 0) {
+ /* printf("dz%d,%d: silo overflow\n", dz, (c>>8)&7); */
+ overrun = 1;
+ }
+ if (c&DZ_PE)
+ if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
+ || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
+ continue;
+#if NBK > 0
+ if (tp->t_line == NETLDISC) {
+ c &= 0177;
+ BKINPUT(c, tp);
+ } else
+#endif
+ (*linesw[tp->t_line].l_rint)(c, tp);
}
- splx(s);
}
/*ARGSUSED*/
dzioctl(dev, cmd, addr, flag)
-caddr_t addr;
-dev_t dev;
+ dev_t dev;
+ caddr_t addr;
{
register struct tty *tp;
+ register int unit = minor(dev);
+ register int dz = unit >> 3;
+ register struct device *dzaddr;
+ int temp;
- tp = &dz_tty[minor(dev)];
+ tp = &dz_tty[unit];
cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
if (cmd == 0)
return;
- if (ttioccomm(cmd, tp, addr, dev)) {
+ if (ttioctl(tp, cmd, addr, flag)) {
if (cmd==TIOCSETP || cmd==TIOCSETN)
- dzparam(minor(dev));
+ dzparam(unit);
} else switch(cmd) {
+
case TIOCSBRK:
- ((struct device *)(tp->t_addr))->dzbrk |= 1 << (dev&07);
+ dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
+ if (dzaddr->dzcsr&DZ_32)
+ (void) dzmctl(dev, DZ_BRK, DMBIS);
+ else
+ dzaddr->dzbrk = (dz_brk[dz] |= 1 << (unit&07));
break;
case TIOCCBRK:
- ((struct device *)(tp->t_addr))->dzbrk &= ~(1 << (dev&07));
+ dzaddr = ((struct pdma *)(tp->t_addr))->p_addr;
+ if (dzaddr->dzcsr&DZ_32)
+ (void) dzmctl(dev, DZ_BRK, DMBIC);
+ else
+ dzaddr->dzbrk = (dz_brk[dz] &= ~(1 << (unit&07)));
break;
case TIOCSDTR:
- dzmodem(dev, ON);
+ (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIS);
break;
case TIOCCDTR:
- dzmodem(dev, OFF);
+ (void) dzmctl(dev, DZ_DTR|DZ_RTS, DMBIC);
+ break;
+ case TIOCMSET:
+ if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
+ u.u_error = EFAULT;
+ else
+ (void) dzmctl(dev, dmtodz(temp), DMSET);
+ break;
+ case TIOCMBIS:
+ if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
+ u.u_error = EFAULT;
+ else
+ (void) dzmctl(dev, dmtodz(temp), DMBIS);
+ break;
+ case TIOCMBIC:
+ if (copyin(addr, (caddr_t) &temp, sizeof(temp)))
+ u.u_error = EFAULT;
+ else
+ (void) dzmctl(dev, dmtodz(temp), DMBIC);
+ break;
+ case TIOCMGET:
+ temp = dztodm(dzmctl(dev, 0, DMGET));
+ if (copyout((caddr_t) &temp, addr, sizeof(temp)))
+ u.u_error = EFAULT;
break;
default:
u.u_error = ENOTTY;
}
}
+
+dmtodz(bits)
+ register int bits;
+{
+ register int b;
+
+ b = (bits >>1) & 0370;
+ if (bits & DML_ST) b |= DZ_ST;
+ if (bits & DML_RTS) b |= DZ_RTS;
+ if (bits & DML_DTR) b |= DZ_DTR;
+ if (bits & DML_LE) b |= DZ_LE;
+ return(b);
+}
+
+dztodm(bits)
+ register int bits;
+{
+ register int b;
+
+ b = (bits << 1) & 0360;
+ if (bits & DZ_DSR) b |= DML_DSR;
+ if (bits & DZ_DTR) b |= DML_DTR;
+ if (bits & DZ_ST) b |= DML_ST;
+ if (bits & DZ_RTS) b |= DML_RTS;
+ return(b);
+}
-dzparam(dev)
+dzparam(unit)
+ register int unit;
{
register struct tty *tp;
register struct device *dzaddr;
- register short lpr;
+ register int lpr;
- tp = &dz_tty[dev];
- dzaddr = dzpdma[dev].p_addr;
+ tp = &dz_tty[unit];
+ dzaddr = dzpdma[unit].p_addr;
dzaddr->dzcsr = DZ_IEN;
- dzact |= (1<<(dev>>3));
+ dzact |= (1<<(unit>>3));
if (tp->t_ispeed == 0) {
- dzmodem(dev, OFF); /* hang up line */
+ (void) dzmctl(unit, DZ_OFF, DMSET); /* hang up line */
return;
}
- lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07);
- if (tp->t_flags & RAW)
+ lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
+ if ((tp->t_local&LLITOUT) || (tp->t_flags&RAW))
lpr |= BITS8;
else
lpr |= (BITS7|PENABLE);
if ((tp->t_flags & EVENP) == 0)
lpr |= OPAR;
- if (tp->t_ispeed == 3)
- lpr |= TWOSB; /* 110 baud: 2 stop bits */
+ if (tp->t_ispeed == B110)
+ lpr |= TWOSB;
dzaddr->dzlpr = lpr;
}
dzxint(tp)
-register struct tty *tp;
+ register struct tty *tp;
{
register struct pdma *dp;
- register s;
- s = spl6(); /* block the clock */
+ register s, dz, unit;
- dp = &dzpdma[tp-dz_tty];
- tp->t_state &= ~BUSY;
- if (tp->t_state & FLUSH)
- tp->t_state &= ~FLUSH;
- else
- ndflush(&tp->t_outq, dp->p_end-tp->t_outq.c_cf);
+ s = spl5(); /* block pdma interrupts */
+ dp = (struct pdma *)tp->t_addr;
+ tp->t_state &= ~TS_BUSY;
+ if (tp->t_state & TS_FLUSH)
+ tp->t_state &= ~TS_FLUSH;
+ else {
+ ndflush(&tp->t_outq, dp->p_mem-tp->t_outq.c_cf);
+ dp->p_end = dp->p_mem = tp->t_outq.c_cf;
+ }
if (tp->t_line)
(*linesw[tp->t_line].l_start)(tp);
else
dzstart(tp);
- if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
- dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8));
+ dz = minor(tp->t_dev) >> 3;
+ unit = minor(tp->t_dev) & 7;
+ if (tp->t_outq.c_cc == 0 || (tp->t_state&TS_BUSY)==0)
+ if (dp->p_addr->dzcsr & DZ_32)
+ dp->p_addr->dzlnen = (dz_lnen[dz] &= ~(1<<unit));
+ else
+ dp->p_addr->dztcr &= ~(1<<unit);
splx(s);
}
dzstart(tp)
-register struct tty *tp;
+ register struct tty *tp;
{
register struct pdma *dp;
register struct device *dzaddr;
- register cc;
- int sps;
+ register int cc;
+ int s, dz, unit;
- dp = &dzpdma[tp-dz_tty];
+ dp = (struct pdma *)tp->t_addr;
dzaddr = dp->p_addr;
- sps = spl5();
- if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
+ s = spl5();
+ if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
goto out;
- if (tp->t_outq.c_cc <= TTLOWAT && tp->t_state&ASLEEP) {
- tp->t_state &= ~ASLEEP;
- if (tp->t_chan)
- mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
- else
+ if (tp->t_outq.c_cc <= TTLOWAT(tp)) {
+ if (tp->t_state&TS_ASLEEP) {
+ tp->t_state &= ~TS_ASLEEP;
wakeup((caddr_t)&tp->t_outq);
+ }
+ if (tp->t_wsel) {
+ selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
+ tp->t_wsel = 0;
+ tp->t_state &= ~TS_WCOLL;
+ }
}
if (tp->t_outq.c_cc == 0)
goto out;
- if (tp->t_flags&RAW)
+ if ((tp->t_flags&RAW) || (tp->t_local&LLITOUT))
cc = ndqb(&tp->t_outq, 0);
else {
cc = ndqb(&tp->t_outq, 0200);
if (cc == 0) {
cc = getc(&tp->t_outq);
- timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6);
- tp->t_state |= TIMEOUT;
+ timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
+ tp->t_state |= TS_TIMEOUT;
goto out;
}
}
- tp->t_state |= BUSY;
+ tp->t_state |= TS_BUSY;
dp->p_end = dp->p_mem = tp->t_outq.c_cf;
dp->p_end += cc;
- dzaddr->dztcr |= 1 << ((tp-dz_tty) % 8);
- out:
- splx(sps);
+ dz = minor(tp->t_dev) >> 3;
+ unit = minor(tp->t_dev) & 7;
+ if (dzaddr->dzcsr & DZ_32)
+ dzaddr->dzlnen = (dz_lnen[dz] |= (1<<unit));
+ else
+ dzaddr->dztcr |= (1<<unit);
+out:
+ splx(s);
}
/*
* Stop output on a line.
- * Assume call is made at spl6.
*/
/*ARGSUSED*/
dzstop(tp, flag)
-register struct tty *tp;
+ register struct tty *tp;
{
register struct pdma *dp;
register int s;
- dp = &dzpdma[tp-dz_tty];
- s = spl6();
- if (tp->t_state & BUSY) {
+ dp = (struct pdma *)tp->t_addr;
+ s = spl5();
+ if (tp->t_state & TS_BUSY) {
dp->p_end = dp->p_mem;
- if ((tp->t_state&TTSTOP)==0) {
- tp->t_state |= FLUSH;
- }
+ if ((tp->t_state&TS_TTSTOP)==0)
+ tp->t_state |= TS_FLUSH;
}
splx(s);
}
-dzmodem(dev, flag)
-register int dev;
+dzmctl(dev, bits, how)
+ dev_t dev;
+ int bits, how;
{
register struct device *dzaddr;
- register char bit;
-
- dzaddr = dzpdma[dev].p_addr;
- bit = 1<<(dev&07);
- if (flag == OFF)
- dzaddr->dzdtr &= ~bit;
- else
- dzaddr->dzdtr |= bit;
+ register int unit, mbits;
+ int b, s;
+
+ unit = minor(dev);
+ b = 1<<(unit&7);
+ dzaddr = dzpdma[unit].p_addr;
+ s = spl5();
+ if (dzaddr->dzcsr & DZ_32) {
+ dzwait(dzaddr)
+ DELAY(100); /* IS 100 TOO MUCH? */
+ dzaddr->dzlcs = unit&7;
+ DELAY(100);
+ dzwait(dzaddr)
+ DELAY(100);
+ mbits = dzaddr->dzlcs;
+ mbits &= 0177770;
+ } else {
+ mbits = (dzaddr->dzdtr & b) ? DZ_DTR : 0;
+ mbits |= (dzaddr->dzmsr & b) ? DZ_CD : 0;
+ mbits |= (dzaddr->dztbuf & b) ? DZ_RI : 0;
+ }
+ switch (how) {
+ case DMSET:
+ mbits = bits;
+ break;
+
+ case DMBIS:
+ mbits |= bits;
+ break;
+
+ case DMBIC:
+ mbits &= ~bits;
+ break;
+
+ case DMGET:
+ (void) splx(s);
+ return(mbits);
+ }
+ if (dzaddr->dzcsr & DZ_32) {
+ mbits |= DZ_ACK|(unit&7);
+ dzaddr->dzlcs = mbits;
+ } else {
+ if (mbits & DZ_DTR)
+ dzaddr->dzdtr |= b;
+ else
+ dzaddr->dzdtr &= ~b;
+ }
+ (void) splx(s);
+ return(mbits);
}
dzscan()
register struct device *dzaddr;
register bit;
register struct tty *tp;
+ register car;
for (i = 0; i < dz_cnt ; i++) {
dzaddr = dzpdma[i].p_addr;
+ if (dzaddr == 0)
+ continue;
tp = &dz_tty[i];
bit = 1<<(i&07);
- if (dzaddr->dzmsr & bit) {
+ car = 0;
+ if (dzsoftCAR[i>>3]&bit)
+ car = 1;
+ else if (dzaddr->dzcsr & DZ_32) {
+ dzaddr->dzlcs = i&07;
+ dzwait(dzaddr);
+ car = dzaddr->dzlcs & DZ_CD;
+ } else
+ car = dzaddr->dzmsr&bit;
+ if (car) {
/* carrier present */
- if ((tp->t_state & CARR_ON) == 0) {
+ if ((tp->t_state & TS_CARR_ON) == 0) {
wakeup((caddr_t)&tp->t_rawq);
- tp->t_state |= CARR_ON;
+ tp->t_state |= TS_CARR_ON;
}
} else {
- if ((tp->t_state & CARR_ON)) {
+ if ((tp->t_state&TS_CARR_ON) &&
+ (tp->t_local&LNOHANG)==0) {
/* carrier lost */
- if (tp->t_state&ISOPEN &&
- (tp->t_local&LNOHANG) == 0) {
+ if (tp->t_state&TS_ISOPEN) {
gsignal(tp->t_pgrp, SIGHUP);
gsignal(tp->t_pgrp, SIGCONT);
dzaddr->dzdtr &= ~bit;
- flushtty(tp);
+ flushtty(tp, FREAD|FWRITE);
}
- tp->t_state &= ~CARR_ON;
+ tp->t_state &= ~TS_CARR_ON;
}
}
}
- timeout(dzscan, (caddr_t)0, 2*HZ);
+ timeout(dzscan, (caddr_t)0, 2*hz);
}
dztimer()
{
+ int dz;
- dzrint(0);
+ for (dz = 0; dz < NDZ; dz++)
+ dzrint(dz);
}
+
+/*
+ * Reset state of driver if UBA reset was necessary.
+ * Reset parameters and restart transmission on open lines.
+ */
+dzreset(uban)
+ int uban;
+{
+ register int unit;
+ register struct tty *tp;
+ register struct uba_device *ui;
+
+ for (unit = 0; unit < NDZLINE; unit++) {
+ ui = dzinfo[unit >> 3];
+ if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
+ continue;
+ if (unit%8 == 0)
+ printf(" dz%d", unit>>3);
+ tp = &dz_tty[unit];
+ if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
+ dzparam(unit);
+ (void) dzmctl(unit, DZ_ON, DMSET);
+ tp->t_state &= ~TS_BUSY;
+ dzstart(tp);
+ }
+ }
+ dztimer();
+}
+#endif