fix to silo and bk bug
[unix-history] / usr / src / sys / vax / uba / dz.c
index 3a0d465..82f40aa 100644 (file)
@@ -1,11 +1,13 @@
-/*     dz.c    4.12    %G%     */
+/*     dz.c    4.29    81/08/31        */
 
 #include "dz.h"
 
 #include "dz.h"
-#if NDZ11 > 0
-#define        DELAY(i)        { register int j = i; while (--j > 0); }
+#if NDZ > 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"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/buf.h"
-#include "../h/uba.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"
 #include "../h/mx.h"
 
 #include "../h/conf.h"
 #include "../h/pdma.h"
 #include "../h/bk.h"
 #include "../h/file.h"
 #include "../h/mx.h"
 
-int    dzcntrlr(), dzslave(), dzrint();
-struct uba_dinfo *dzinfo[NDZ11];
+/*
+ * Driver information for auto-configuration stuff.
+ */
+int    dzprobe(), dzattach(), dzrint();
+struct uba_device *dzinfo[NDZ];
 u_short        dzstd[] = { 0 };
 struct uba_driver dzdriver =
 u_short        dzstd[] = { 0 };
 struct uba_driver dzdriver =
-       { dzcntrlr, dzslave, 0, 0, dzstd, "dz", dzinfo };
+       { dzprobe, 0, dzattach, 0, dzstd, "dz", dzinfo };
 
 
-#define        NDZ     (NDZ11*8)
+#define        NDZLINE         (NDZ*8)
  
  
+/*
+ * Registers and bits
+ */
+
+/* Bits in dzlpr */
 #define        BITS7   020
 #define        BITS8   030
 #define        TWOSB   040
 #define        PENABLE 0100
 #define        OPAR    0200
 #define        BITS7   020
 #define        BITS8   030
 #define        TWOSB   040
 #define        PENABLE 0100
 #define        OPAR    0200
-#define        CLR     020             /* Reset dz */
-#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 */
 
 
-#define        dzlpr   dzrbuf
-#define        dzmsr   dzbrk
-#define        ON      1
-#define        OFF     0
+/* 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    dzdma();
+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];
+
+/*
+ * 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];
 
 
-struct pdma dzpdma[NDZ];
-char   dz_timer;
 char   dz_speeds[] =
        { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
 char   dz_speeds[] =
        { 0,020,021,022,023,024,0,025,026,027,030,032,034,036,0,0 };
-char   dz_brk[NDZ11];
  
  
-dzcntrlr(ui, reg)
-       struct uba_dinfo *ui;
+dzprobe(reg)
        caddr_t reg;
 {
        register int br, cvec;
        register struct device *dzaddr = (struct device *)reg;
 
        caddr_t reg;
 {
        register int br, cvec;
        register struct device *dzaddr = (struct device *)reg;
 
-       dzaddr->dzcsr = TIE|MSE;
+#ifdef lint
+       br = 0; cvec = br; br = cvec;
+#endif
+       dzaddr->dzcsr = DZ_TIE|DZ_MSE;
        dzaddr->dztcr = 1;              /* enable any line */
        DELAY(100000);
        dzaddr->dztcr = 1;              /* enable any line */
        DELAY(100000);
-       dzaddr->dzcsr = CLR;            /* reset everything */
+       dzaddr->dzcsr = DZ_CLR;         /* reset everything */
        if (cvec && cvec != 0x200)
                cvec -= 4;
        return (1);
 }
 
        if (cvec && cvec != 0x200)
                cvec -= 4;
        return (1);
 }
 
-dzslave(ui, reg, slaveno, uban)
-       register struct uba_dinfo *ui;
-       caddr_t reg;
+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 struct pdma *pdp = &dzpdma[ui->ui_unit*8];
        register struct tty *tp = &dz_tty[ui->ui_unit*8];
-       register int cnt;
-       caddr_t cp;
+       register int cntr;
+       extern dzscan();
 
 
-       for (cnt = 0; cnt < 8; cnt++) {
-               pdp->p_addr = (struct device *)reg;
+       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++;
        }
                pdp->p_arg = (int)tp;
                pdp->p_fcn = dzxint;
                pdp++, tp++;
        }
-       return (1);
+       dzsoftCAR[ui->ui_unit] = ui->ui_flags;
+       if (dz_timer == 0) {
+               dz_timer++;
+               timeout(dzscan, (caddr_t)0, hz);
+       }
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -113,17 +144,12 @@ dzopen(dev, flag)
 {
        register struct tty *tp;
        register int unit;
 {
        register struct tty *tp;
        register int unit;
-       extern dzscan();
  
        unit = minor(dev);
        if (unit >= dz_cnt || dzpdma[unit].p_addr == 0) {
                u.u_error = ENXIO;
                return;
        }
  
        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[unit];
        tp->t_addr = (caddr_t)&dzpdma[unit];
        tp->t_oproc = dzstart;
        tp = &dz_tty[unit];
        tp->t_addr = (caddr_t)&dzpdma[unit];
        tp->t_oproc = dzstart;
@@ -131,15 +157,15 @@ dzopen(dev, flag)
        tp->t_state |= WOPEN;
        if ((tp->t_state & ISOPEN) == 0) {
                ttychars(tp);
        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;*/
+               /* tp->t_state |= HUPCLS; */
                dzparam(unit);
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
                dzparam(unit);
        } else if (tp->t_state&XCLUDE && u.u_uid != 0) {
                u.u_error = EBUSY;
                return;
        }
-       dzmodem(unit, ON);
+       dzmodem(unit, DZ_ON);
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= WOPEN;
        (void) spl5();
        while ((tp->t_state & CARR_ON) == 0) {
                tp->t_state |= WOPEN;
@@ -164,7 +190,7 @@ dzclose(dev, flag)
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
            (dz_brk[dz] &= ~(1 << (unit&07)));
        if (tp->t_state & HUPCLS)
        ((struct pdma *)(tp->t_addr))->p_addr->dzbrk =
            (dz_brk[dz] &= ~(1 << (unit&07)));
        if (tp->t_state & HUPCLS)
-               dzmodem(unit, OFF);
+               dzmodem(unit, DZ_OFF);
        ttyclose(tp);
 }
  
        ttyclose(tp);
 }
  
@@ -195,7 +221,7 @@ dzrint(dz)
        register struct device *dzaddr;
        register struct tty *tp0;
        register int unit;
        register struct device *dzaddr;
        register struct tty *tp0;
        register int unit;
-       int s;
+       int overrun = 0;
  
        if ((dzact & (1<<dz)) == 0)
                return;
  
        if ((dzact & (1<<dz)) == 0)
                return;
@@ -210,23 +236,25 @@ dzrint(dz)
                        wakeup((caddr_t)&tp->t_rawq);
                        continue;
                }
                        wakeup((caddr_t)&tp->t_rawq);
                        continue;
                }
-               if (c&FRERROR)
-                       /* framing error = break */
+               if (c&DZ_FE)
                        if (tp->t_flags & RAW)
                        if (tp->t_flags & RAW)
-                               c = 0;          /* null for getty */
+                               c = 0;
                        else
                                c = tun.t_intrc;
                        else
                                c = tun.t_intrc;
-               if (c&OVERRUN)
-                       printf("o");
-               if (c&PERROR)   
-                       /* parity error */
+               if (c&DZ_DO && overrun == 0) {
+                       printf("dz%d: silo overflow\n", dz);
+                       overrun = 1;
+               }
+               if (c&DZ_PE)    
                        if (((tp->t_flags & (EVENP|ODDP)) == EVENP)
                          || ((tp->t_flags & (EVENP|ODDP)) == ODDP))
                                continue;
                        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
                if (tp->t_line == NETLDISC) {
                        c &= 0177;
                        BKINPUT(c, tp);
                } else
+#endif
                        (*linesw[tp->t_line].l_rint)(c, tp);
        }
 }
                        (*linesw[tp->t_line].l_rint)(c, tp);
        }
 }
@@ -258,10 +286,10 @@ dzioctl(dev, cmd, addr, flag)
                        (dz_brk[dz] &= ~(1 << (unit&07)));
                break;
        case TIOCSDTR:
                        (dz_brk[dz] &= ~(1 << (unit&07)));
                break;
        case TIOCSDTR:
-               dzmodem(unit, ON);
+               dzmodem(unit, DZ_ON);
                break;
        case TIOCCDTR:
                break;
        case TIOCCDTR:
-               dzmodem(unit, OFF);
+               dzmodem(unit, DZ_OFF);
                break;
        default:
                u.u_error = ENOTTY;
                break;
        default:
                u.u_error = ENOTTY;
@@ -280,7 +308,7 @@ dzparam(unit)
        dzaddr->dzcsr = DZ_IEN;
        dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
        dzaddr->dzcsr = DZ_IEN;
        dzact |= (1<<(unit>>3));
        if (tp->t_ispeed == 0) {
-               dzmodem(unit, OFF);             /* hang up line */
+               dzmodem(unit, DZ_OFF);          /* hang up line */
                return;
        }
        lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
                return;
        }
        lpr = (dz_speeds[tp->t_ispeed]<<8) | (unit & 07);
@@ -290,8 +318,8 @@ dzparam(unit)
                lpr |= (BITS7|PENABLE);
        if ((tp->t_flags & EVENP) == 0)
                lpr |= OPAR;
                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;
 }
  
        dzaddr->dzlpr = lpr;
 }
  
@@ -301,7 +329,7 @@ dzxint(tp)
        register struct pdma *dp;
        register s;
  
        register struct pdma *dp;
        register s;
  
-       s = spl5();
+       s = spl5();             /* block pdma interrupts */
        dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
        dp = (struct pdma *)tp->t_addr;
        tp->t_state &= ~BUSY;
        if (tp->t_state & FLUSH)
@@ -339,13 +367,13 @@ dzstart(tp)
        }
        if (tp->t_outq.c_cc == 0)
                goto out;
        }
        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);
                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);
+                       timeout(ttrstrt, (caddr_t)tp, (cc&0x7f) + 6);
                        tp->t_state |= TIMEOUT;
                        goto out;
                }
                        tp->t_state |= TIMEOUT;
                        goto out;
                }
@@ -353,7 +381,7 @@ dzstart(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 << (minor(tp->t_dev) & 07);
+       dzaddr->dztcr |= 1 << (minor(tp->t_dev) & 07);  /* force intr */
 out:
        splx(s);
 }
 out:
        splx(s);
 }
@@ -386,7 +414,7 @@ dzmodem(unit, flag)
  
        dzaddr = dzpdma[unit].p_addr;
        bit = 1<<(unit&07);
  
        dzaddr = dzpdma[unit].p_addr;
        bit = 1<<(unit&07);
-       if (flag == OFF)
+       if (flag == DZ_OFF)
                dzaddr->dzdtr &= ~bit;
        else
                dzaddr->dzdtr |= bit;
                dzaddr->dzdtr &= ~bit;
        else
                dzaddr->dzdtr |= bit;
@@ -401,20 +429,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);
-#ifdef BERT
-               if (dzaddr->dzmsr & bit || i == 6 || i == 7) {
-#else
-               if (dzaddr->dzmsr & bit) {
-#endif
+               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);
@@ -426,14 +453,14 @@ dzscan()
                        }
                }
        }
                        }
                }
        }
-       timeout(dzscan, (caddr_t)0, 2*HZ);
+       timeout(dzscan, (caddr_t)0, 2*hz);
 }
 
 dztimer()
 {
        int dz;
 
 }
 
 dztimer()
 {
        int dz;
 
-       for (dz = 0; dz < NDZ11; dz++)
+       for (dz = 0; dz < NDZ; dz++)
                dzrint(dz);
 }
 
                dzrint(dz);
 }
 
@@ -446,21 +473,18 @@ dzreset(uban)
 {
        register int unit;
        register struct tty *tp;
 {
        register int unit;
        register struct tty *tp;
-       register struct uba_dinfo *ui;
-       int any = 0;
+       register struct uba_device *ui;
 
 
-       for (unit = 0; unit < NDZ; unit++) {
+       for (unit = 0; unit < NDZLINE; unit++) {
                ui = dzinfo[unit >> 3];
                if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
                        continue;
                ui = dzinfo[unit >> 3];
                if (ui == 0 || ui->ui_ubanum != uban || ui->ui_alive == 0)
                        continue;
-               if (any == 0) {
-                       printf(" dz");
-                       any++;
-               }
+               if (unit%8 == 0)
+                       printf(" dz%d", unit>>3);
                tp = &dz_tty[unit];
                if (tp->t_state & (ISOPEN|WOPEN)) {
                        dzparam(unit);
                tp = &dz_tty[unit];
                if (tp->t_state & (ISOPEN|WOPEN)) {
                        dzparam(unit);
-                       dzmodem(unit, ON);
+                       dzmodem(unit, DZ_ON);
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }
                        tp->t_state &= ~BUSY;
                        dzstart(tp);
                }