new version which doesn't get hung up
[unix-history] / usr / src / sys / vax / uba / dz.c
index 52080ff..5eaa4d5 100644 (file)
@@ -1,10 +1,14 @@
-/*     dz.c    4.    %G%     */
+/*     dz.c    4.19    %G%     */
 
 #include "dz.h"
 
 #include "dz.h"
-#if NDZ11 > 0
+#if NDZ > 0
+#define        DELAY(i)        { register int j = i; while (--j > 0); }
 /*
  *  DZ-11 Driver
 /*
  *  DZ-11 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/param.h"
 #include "../h/systm.h"
 #include "../h/tty.h"
@@ -12,6 +16,8 @@
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/user.h"
 #include "../h/map.h"
 #include "../h/pte.h"
+#include "../h/buf.h"
+#include "../h/vm.h"
 #include "../h/uba.h"
 #include "../h/conf.h"
 #include "../h/pdma.h"
 #include "../h/uba.h"
 #include "../h/conf.h"
 #include "../h/pdma.h"
 #include "../h/mx.h"
 
 /*
 #include "../h/mx.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 NDZ    (NDZ11*8)
-#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_dinfo *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   020
+#define        BITS8   030
+#define        TWOSB   040
+#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_CLR  020             /* Reset dz */
+#define        DZ_MSE  040             /* Master Scan Enable */
+#define        DZ_RIE  0100            /* Receiver Interrupt Enable */
+#define        DZ_SAE  010000          /* Silo Alarm Enable */
+#define        DZ_TIE  040000          /* Transmit Interrupt Enable */
+#define        DZ_IEN  (DZ_MSE+DZ_RIE+DZ_TIE+DZ_SAE)
+
+/* Flags for modem-control */
+#define        DZ_ON   1
+#define        DZ_OFF  0
  
  
-int    dzstart();
-int    dzxint();
+int    dzstart(), dzxint(), dzdma();
 int    ttrstrt();
 int    ttrstrt();
-struct tty dz_tty[NDZ];
-int    dz_cnt = { NDZ };
+struct tty dz_tty[NDZLINE];
+int    dz_cnt = { NDZLINE };
 int    dzact;
 
 struct device {
 int    dzact;
 
 struct device {
-       short   dzcsr;
-       short   dzrbuf;
-       char    dztcr;
-       char    dzdtr;
-       char    dztbuf;
-       char    dzbrk;
+       short   dzcsr;          /* control-status register */
+       short   dzrbuf;         /* receiver buffer */
+#define        dzlpr   dzrbuf          /* line parameter reg is write of dzrbuf */
+       char    dztcr;          /* transmit control register */
+       char    dzdtr;          /* data terminal ready */
+       char    dztbuf;         /* transmit buffer */
+       char    dzbrk;          /* break control */
+#define        dzmsr   dzbrk           /* modem status register */
 };
 };
+/*
+ * Software copy of dzbrk since it isn't readable
+ */
+char   dz_brk[NDZ];
+char   dzsoftCAR[NDZ];
 
 
-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,
-#if NDZ11 >= 2
-       (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,
-#endif
-#if NDZ11 >= 3
-       (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
-#if NDZ11 >= 4
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[24], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[25], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[26], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[27], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[28], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[29], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[30], dzxint,
-       (struct device *)(DZADDR+030), NULL, NULL, (int)&dz_tty[31], dzxint,
-#endif
-};
-char   dz_timer;
-char   dz_speeds[] = {
-       0, 020 , 021 , 022 , 023 , 024 , 0, 025,
-       026 , 027 , 030 , 032 , 034 , 036 , 0 , 0,
-};
-char dz_brk[NDZ11];
+/*
+ * The dz 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,0,0 };
  
  
+dzprobe(reg)
+       caddr_t reg;
+{
+       register int br, cvec;
+       register struct device *dzaddr = (struct device *)reg;
+
+#ifdef lint
+       br = 0; br = cvec; cvec = br;
+#endif
+       dzaddr->dzcsr = DZ_TIE|DZ_MSE;
+       dzaddr->dztcr = 1;              /* enable any line */
+       DELAY(100000);
+       dzaddr->dzcsr = DZ_CLR;         /* reset everything */
+       if (cvec && cvec != 0x200)
+               cvec -= 4;
+       return (1);
+}
+
+dzattach(ui)
+       register struct uba_dinfo *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);
+       }
+       return (1);
+}
+
 /*ARGSUSED*/
 /*ARGSUSED*/
-dzopen(d, flag)
+dzopen(dev, flag)
+       dev_t dev;
 {
        register struct tty *tp;
 {
        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;
        }
                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) {
                ttychars(tp);
        tp->t_oproc = dzstart;
        tp->t_iproc = NULL;
        tp->t_state |= WOPEN;
        if ((tp->t_state & ISOPEN) == 0) {
                ttychars(tp);
-               tp->t_ospeed = tp->t_ispeed = SSPEED;
+               tp->t_ospeed = tp->t_ispeed = B300;
                tp->t_flags = ODDP|EVENP|ECHO;
                tp->t_flags = ODDP|EVENP|ECHO;
-               /*tp->t_state |= HUPCLS;*/
-               dzparam(dev);
+               /* tp->t_state |= HUPCLS; */
+               dzparam(unit);
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
-       dzmodem(dev, ON);
+       dzmodem(unit, DZ_ON);
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= WOPEN;
                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        }
        (void) spl0();
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= 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 struct tty *tp;
-       register dev;
+       register int unit;
+       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);
        (*linesw[tp->t_line].l_close)(tp);
-       /*
-        * Turn the break bit off in case it was left on by a TIOCSBRK
-        * but not turned off by TIOCCBRK
-        */
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-               (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07)));
+           (dz_brk[dz] &= ~(1 << (unit&07)));
        if (tp->t_state & HUPCLS)
        if (tp->t_state & HUPCLS)
-               dzmodem(dev, OFF);
+               dzmodem(unit, DZ_OFF);
        ttyclose(tp);
 }
  
        ttyclose(tp);
 }
  
-dzread(d)
+dzread(dev)
+       dev_t dev;
 {
        register struct tty *tp;
  
 {
        register struct tty *tp;
  
-       tp = &dz_tty[minor(d)];
+       tp = &dz_tty[minor(dev)];
        (*linesw[tp->t_line].l_read)(tp);
 }
  
        (*linesw[tp->t_line].l_read)(tp);
 }
  
-dzwrite(d)
+dzwrite(dev)
+       dev_t dev;
 {
        register struct tty *tp;
  
 {
        register struct tty *tp;
  
-       tp = &dz_tty[minor(d)];
+       tp = &dz_tty[minor(dev)];
        (*linesw[tp->t_line].l_write)(tp);
 }
  
 /*ARGSUSED*/
        (*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;
 {
        register struct tty *tp;
        register int c;
        register struct device *dzaddr;
        register struct tty *tp0;
-       int s;
+       register int unit;
  
  
-       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)
+       if ((dzact & (1<<dz)) == 0)
+               return;
+       unit = dz * 8;
+       dzaddr = dzpdma[unit].p_addr;
+       tp0 = &dz_tty[unit];
+       while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
+               tp = tp0 + ((c>>8)&07);
+               if (tp >= &dz_tty[dz_cnt])
                        continue;
                        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) {
-                               wakeup((caddr_t)&tp->t_rawq);
+               if ((tp->t_state & ISOPEN) == 0) {
+                       wakeup((caddr_t)&tp->t_rawq);
+                       continue;
+               }
+               if (c&DZ_FE)
+                       if (tp->t_flags & RAW)
+                               c = 0;
+                       else
+                               c = tun.t_intrc;
+               if (c&DZ_DO)
+                       printf("o");
+               if (c&DZ_PE)    
+                       if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
+                         || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
                                continue;
                                continue;
-                       }
-                       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;
+#if NBK > 0
+               if (tp->t_line == NETLDISC) {
+                       c &= 0177;
+                       BKINPUT(c, tp);
+               } else
 #endif
 #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);
-               }
+                       (*linesw[tp->t_line].l_rint)(c, tp);
        }
        }
-       splx(s);
 }
  
 /*ARGSUSED*/
 dzioctl(dev, cmd, addr, flag)
 }
  
 /*ARGSUSED*/
 dzioctl(dev, cmd, addr, flag)
-caddr_t addr;
-dev_t dev;
+       dev_t dev;
+       caddr_t addr;
 {
        register struct tty *tp;
 {
        register struct tty *tp;
+       register int unit = minor(dev);
+       register int dz = unit >> 3;
  
  
-       tp = &dz_tty[minor(dev)];
+       tp = &dz_tty[unit];
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd == 0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP || cmd==TIOCSETN)
        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        if (cmd == 0)
                return;
        if (ttioctl(tp, cmd, addr, flag)) {
                if (cmd==TIOCSETP || cmd==TIOCSETN)
-                       dzparam(minor(dev));
+                       dzparam(unit);
        } else switch(cmd) {
        } else switch(cmd) {
+
        case TIOCSBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
        case TIOCSBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-                       (dz_brk[minor(dev)>>3] |= 1 << (dev&07));
+                       (dz_brk[dz] |= 1 << (unit&07));
                break;
        case TIOCCBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
                break;
        case TIOCCBRK:
                ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
-                       (dz_brk[minor(dev)>>3] &= ~(1 << (dev&07)));
+                       (dz_brk[dz] &= ~(1 << (unit&07)));
                break;
        case TIOCSDTR:
                break;
        case TIOCSDTR:
-               dzmodem(minor(dev), ON);
+               dzmodem(unit, DZ_ON);
                break;
        case TIOCCDTR:
                break;
        case TIOCCDTR:
-               dzmodem(minor(dev), OFF);
+               dzmodem(unit, DZ_OFF);
                break;
        default:
                u.u_error = ENOTTY;
        }
 }
  
                break;
        default:
                u.u_error = ENOTTY;
        }
 }
  
-dzparam(dev)
+dzparam(unit)
+       register int unit;
 {
        register struct tty *tp;
        register struct device *dzaddr;
 {
        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;
        dzaddr->dzcsr = DZ_IEN;
-       dzact |= (1<<(dev>>3));
+       dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
        if (tp->t_ispeed == 0) {
-               dzmodem(dev, OFF);              /* hang up line */
+               dzmodem(unit, DZ_OFF);          /* hang up line */
                return;
        }
                return;
        }
-       lpr = (dz_speeds[tp->t_ispeed]<<8) | (dev & 07);
-#ifndef IIASA
-       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;
                lpr |= BITS8;
        else
                lpr |= (BITS7|PENABLE);
        if ((tp->t_flags & EVENP) == 0)
                lpr |= OPAR;
-#else IIASA
-       if ((tp->t_flags & (EVENP|ODDP)) == (EVENP|ODDP))
-               lpr |= BITS8;
-       else if (tp->t_flags & EVENP)
-               lpr |= (BITS7|PENABLE);
-       else if (tp->t_flags & ODDP)
-               lpr |= (BITS7|OPAR|PENABLE);
-       else
-               lpr |= BITS7;
-#endif IIASA
-       if (tp->t_ispeed == 3)
-               lpr |= TWOSB;                   /* 110 baud: 2 stop bits */
+       if (tp->t_ispeed == B110)
+               lpr |= TWOSB;
        dzaddr->dzlpr = lpr;
 }
  
 dzxint(tp)
        dzaddr->dzlpr = lpr;
 }
  
 dzxint(tp)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register s;
 {
        register struct pdma *dp;
        register s;
-       s = spl6();     /* block the clock */
  
  
-       dp = &dzpdma[tp-dz_tty];
+       s = spl5();             /* block pdma interrupts */
+       dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
                tp->t_state &= ~FLUSH;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
                tp->t_state &= ~FLUSH;
@@ -333,21 +340,21 @@ register struct tty *tp;
        else
                dzstart(tp);
        if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
        else
                dzstart(tp);
        if (tp->t_outq.c_cc == 0 || (tp->t_state&BUSY)==0)
-               dp->p_addr->dztcr &= ~(1 << ((tp-dz_tty) % 8));
+               dp->p_addr->dztcr &= ~(1 << (minor(tp->t_dev)&07));
        splx(s);
 }
 
 dzstart(tp)
        splx(s);
 }
 
 dzstart(tp)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register struct device *dzaddr;
 {
        register struct pdma *dp;
        register struct device *dzaddr;
-       register cc;
-       int sps;
+       register int cc;
+       int s;
  
  
-       dp = &dzpdma[tp-dz_tty];
+       dp = (struct pdma *)tp->t_addr;
        dzaddr = dp->p_addr;
        dzaddr = dp->p_addr;
-       sps = spl5();
+       s = spl5();
        if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
                goto out;
        if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
        if (tp->t_state & (TIMEOUT|BUSY|TTSTOP))
                goto out;
        if (tp->t_state&ASLEEP && tp->t_outq.c_cc <= TTLOWAT(tp)) {
@@ -365,7 +372,7 @@ register struct tty *tp;
                cc = ndqb(&tp->t_outq, 0200);
                if (cc == 0) {
                        cc = getc(&tp->t_outq);
                cc = ndqb(&tp->t_outq, 0200);
                if (cc == 0) {
                        cc = getc(&tp->t_outq);
-                       timeout(ttrstrt, (caddr_t)tp, (cc&0177) + 6);
+                       timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
                        tp->t_state |= TIMEOUT;
                        goto out;
                }
                        tp->t_state |= TIMEOUT;
                        goto out;
                }
@@ -373,42 +380,40 @@ register struct tty *tp;
        tp->t_state |= BUSY;
        dp->p_end = dp->p_mem = tp->t_outq.c_cf;
        dp->p_end += cc;
        tp->t_state |= 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);
+       dzaddr->dztcr |= 1 << (minor(tp->t_dev) & 07);  /* force intr */
+out:
+       splx(s);
 }
  
 /*
  * Stop output on a line.
 }
  
 /*
  * Stop output on a line.
- * Assume call is made at spl6.
  */
 /*ARGSUSED*/
 dzstop(tp, flag)
  */
 /*ARGSUSED*/
 dzstop(tp, flag)
-register struct tty *tp;
+       register struct tty *tp;
 {
        register struct pdma *dp;
        register int s;
 
 {
        register struct pdma *dp;
        register int s;
 
-       dp = &dzpdma[tp-dz_tty];
-       s = spl6();
+       dp = (struct pdma *)tp->t_addr;
+       s = spl5();
        if (tp->t_state & BUSY) {
                dp->p_end = dp->p_mem;
        if (tp->t_state & BUSY) {
                dp->p_end = dp->p_mem;
-               if ((tp->t_state&TTSTOP)==0) {
+               if ((tp->t_state&TTSTOP)==0)
                        tp->t_state |= FLUSH;
                        tp->t_state |= FLUSH;
-               }
        }
        splx(s);
 }
  
        }
        splx(s);
 }
  
-dzmodem(dev, flag)
-register int dev;
+dzmodem(unit, flag)
+       register int unit;
 {
        register struct device *dzaddr;
        register char bit;
  
 {
        register struct device *dzaddr;
        register char bit;
  
-       dzaddr = dzpdma[dev].p_addr;
-       bit = 1<<(dev&07);
-       if (flag == OFF)
+       dzaddr = dzpdma[unit].p_addr;
+       bit = 1<<(unit&07);
+       if (flag == DZ_OFF)
                dzaddr->dzdtr &= ~bit;
        else
                dzaddr->dzdtr |= bit;
                dzaddr->dzdtr &= ~bit;
        else
                dzaddr->dzdtr |= bit;
@@ -423,16 +428,19 @@ dzscan()
  
        for (i = 0; i < dz_cnt ; i++) {
                dzaddr = dzpdma[i].p_addr;
  
        for (i = 0; i < dz_cnt ; i++) {
                dzaddr = dzpdma[i].p_addr;
+               if (dzaddr == 0)
+                       continue;
                tp = &dz_tty[i];
                bit = 1<<(i&07);
                tp = &dz_tty[i];
                bit = 1<<(i&07);
-               if (dzaddr->dzmsr & bit) {
+               if ((dzsoftCAR[i>>3]&bit) || (dzaddr->dzmsr&bit)) {
                        /* carrier present */
                        if ((tp->t_state & CARR_ON) == 0) {
                                wakeup((caddr_t)&tp->t_rawq);
                                tp->t_state |= CARR_ON;
                        }
                } else {
                        /* carrier present */
                        if ((tp->t_state & CARR_ON) == 0) {
                                wakeup((caddr_t)&tp->t_rawq);
                                tp->t_state |= CARR_ON;
                        }
                } else {
-                       if ((tp->t_state&CARR_ON) && (tp->t_local&LNOHANG) == 0) {
+                       if ((tp->t_state&CARR_ON) &&
+                           (tp->t_local&LNOHANG)==0) {
                                /* carrier lost */
                                if (tp->t_state&ISOPEN) {
                                        gsignal(tp->t_pgrp, SIGHUP);
                                /* carrier lost */
                                if (tp->t_state&ISOPEN) {
                                        gsignal(tp->t_pgrp, SIGHUP);
@@ -444,30 +452,41 @@ dzscan()
                        }
                }
        }
                        }
                }
        }
-       timeout(dzscan, (caddr_t)0, 2*HZ);
+       timeout(dzscan, (caddr_t)0, 2*hz);
 }
 
 dztimer()
 {
 }
 
 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.
  */
 }
 
 /*
  * Reset state of driver if UBA reset was necessary.
  * Reset parameters and restart transmission on open lines.
  */
-dzreset()
+dzreset(uban)
+       int uban;
 {
 {
-       int d;
+       register int unit;
        register struct tty *tp;
        register struct tty *tp;
+       register struct uba_dinfo *ui;
+       int any = 0;
 
 
-       printf(" dz");
-       for (d = 0; d < NDZ; d++) {
-               tp = &dz_tty[d];
+       for (unit = 0; unit < NDZLINE; unit++) {
+               ui = dzinfo[unit >> 3];
+               if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
+                       continue;
+               if (any == 0) {
+                       printf(" dz");
+                       any++;
+               }
+               tp = &dz_tty[unit];
                if (tp->t_state & (ISOPEN|WOPEN)) {
                if (tp->t_state & (ISOPEN|WOPEN)) {
-                       dzparam(d);
-                       dzmodem(d, ON);
+                       dzparam(unit);
+                       dzmodem(unit, DZ_ON);
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }