fix to silo and bk bug
[unix-history] / usr / src / sys / vax / uba / va.c
index 946e877..cbe9452 100644 (file)
@@ -1,10 +1,9 @@
-/*     va.c    4.7     %G%     */
+/*     va.c    4.10    81/07/08        */
 
 #include "va.h"
 #if NVA > 0
 /*
 
 #include "va.h"
 #if NVA > 0
 /*
- * Benson-Varian matrix printer/plotter
- * dma interface driver
+ * Varian printer plotter
  */
 #include "../h/param.h"
 #include "../h/dir.h"
  */
 #include "../h/param.h"
 #include "../h/dir.h"
 #include "../h/systm.h"
 #include "../h/map.h"
 #include "../h/pte.h"
 #include "../h/systm.h"
 #include "../h/map.h"
 #include "../h/pte.h"
-#include "../h/uba.h"
+#include "../h/ubareg.h"
+#include "../h/ubavar.h"
 #include "../h/vcmd.h"
 
 #include "../h/vcmd.h"
 
-int    vabdp = 1;
-
 unsigned minvaph();
 
 #define        VAPRI   (PZERO-1)
 
 unsigned minvaph();
 
 #define        VAPRI   (PZERO-1)
 
-#define        ushort  unsigned short
-struct varegs {
-       ushort  vaba;
-       short   vawc;
+struct vadevice {
+       u_short vaba;                   /* buffer address */
+       short   vawc;                   /* word count (2's complement) */
        union {
        union {
-               short   Vacsw;
-               struct {
+               short   Vacsw;          /* control status as word */
+               struct {                /* control status as bytes */
                        char Vacsl;
                        char Vacsh;
                } vacsr;
        } vacs;
                        char Vacsl;
                        char Vacsh;
                } vacsr;
        } vacs;
-       short   vadata;
+       short   vadata;                 /* programmed i/o data buffer */
 };
 
 #define        vacsw   vacs.Vacsw
 };
 
 #define        vacsw   vacs.Vacsw
@@ -41,135 +38,171 @@ struct    varegs {
 #define        vacsl   vacs.vacsr.Vacsl
 
 /* vacsw bits */
 #define        vacsl   vacs.vacsr.Vacsl
 
 /* vacsw bits */
-#define        ERROR           0100000         /* Some error has occurred */
-#define        NPRTIMO         01000           /* DMA timeout error */
-#define        NOTREADY        0400            /* Something besides NPRTIMO */
-#define        DONE            0200
-#define        IENABLE         0100            /* Interrupt enable */
-#define        SUPPLIESLOW     04
-#define        BOTOFFORM       02
-#define        BYTEREVERSE     01              /* Reverse byte order in words */
+#define        VA_ERROR        0100000         /* some error has occurred */
+#define        VA_NPRTIMO      0001000         /* DMA timeout error */
+#define        VA_NOTREADY     0000400         /* something besides NPRTIMO */
+#define        VA_DONE         0000200
+#define        VA_IENABLE      0000100         /* interrupt enable */
+#define        VA_SUPPLIESLOW  0000004
+#define        VA_BOTOFFORM    0000002
+#define        VA_BYTEREVERSE  0000001         /* reverse byte order in words */
 
 /* vacsh command bytes */
 
 /* vacsh command bytes */
-#define        VAPLOT          0340
-#define        VAPRINT         0100
-#define        VAPRINTPLOT     0160
-#define        VAAUTOSTEP      0244
-#define        VANOAUTOSTEP    0045            /* unused */
-#define        VAFORMFEED      0263            /* unused */
-#define        VASLEW          0265            /* unused */
-#define        VASTEP          0064            /* unused */
-
-struct {
-       char    va_open;
-       char    va_busy;
-       int     va_state;       /* State: bits are commands in vcmd.h. */
-       int     va_wc;
-       int     va_bufp;
-       struct  buf *va_bp;
-} va11;
-int    va_ubinfo;
-
-struct buf rvabuf;             /* Used by physio for a buffer. */
-
-vaopen()
+#define        VAPLOT          0000340
+#define        VAPRINT         0000100
+#define        VAPRINTPLOT     0000160
+#define        VAAUTOSTEP      0000244
+#define        VANOAUTOSTEP    0000045
+#define        VAFORMFEED      0000263
+#define        VASLEW          0000265
+#define        VASTEP          0000064
+
+struct va_softc {
+       char    sc_openf;
+       char    sc_busy;
+       int     sc_state;
+       int     sc_wc;
+       struct  buf *sc_bp;
+       int     sc_ubinfo;
+} va_softc[NVA];
+
+#define        VAUNIT(dev)     (minor(dev))
+
+struct buf rvabuf[NVA];
+
+int    vaprobe(), vaattach();
+struct uba_device *vadinfo[NVA];
+u_short        vastd[] = { 0764000, 0 };
+struct uba_driver vadriver =
+    { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo };
+
+vaprobe(reg)
+       caddr_t reg;
+{
+       register int br, cvec;          /* value-result */
+       register struct vadevice *vaaddr = (struct vadevice *)reg;
+
+       vaaddr->vacsl = VA_IENABLE;
+       vaaddr->vaba = 0;
+       vaaddr->vacsh = VAPLOT;
+       vaaddr->vacsl = 0;
+       vaaddr->vawc = -1;
+       DELAY(10000);
+       vaaddr->vacsl = 0;
+}
+
+/*ARGSUSED*/
+vaattach(ui)
+       struct uba_device *ui;
+{
+
+}
+
+vaopen(dev)
+       dev_t dev;
 {
 {
+       register struct va_softc *sc;
+       register struct vadevice *vaaddr;
+       register struct uba_device *ui;
 
 
-       if (va11.va_open) {
+       if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
+           (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
                u.u_error = ENXIO;
                return;
        }
                u.u_error = ENXIO;
                return;
        }
-       va11.va_open = 1;
-       VAADDR->vawc = 0;
-       va11.va_wc = 0;
-       va11.va_state = 0;
-       VAADDR->vacsl = IENABLE;
-       vatimo();
-       vacmd(VPRINT);
+       vaaddr = (struct vadevice *)ui->ui_addr;
+       sc->sc_openf = 1;
+       vaaddr->vawc = 0;
+       sc->sc_wc = 0;
+       sc->sc_state = 0;
+       vaaddr->vacsl = VA_IENABLE;
+       vatimo(dev);
+       vacmd(dev, VPRINT);
        if (u.u_error)
        if (u.u_error)
-               vaclose();
+               vaclose(dev);
 }
 
 vastrategy(bp)
        register struct buf *bp;
 {
        register int e;
 }
 
 vastrategy(bp)
        register struct buf *bp;
 {
        register int e;
+       register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)];
+       register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)];
+       register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr;
 
        (void) spl4();
 
        (void) spl4();
-       while (va11.va_busy)
-               sleep((caddr_t)&va11, VAPRI);
-       va11.va_busy = 1;
-       va11.va_bp = bp;
-       va_ubinfo = ubasetup(bp, vabdp);
-       va11.va_bufp = va_ubinfo & 0x3ffff;
-       if (e = vaerror(DONE))
+       while (sc->sc_busy)
+               sleep((caddr_t)sc, VAPRI);
+       sc->sc_busy = 1;
+       sc->sc_bp = bp;
+       sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
+       if (e = vawait(bp->b_dev))
                goto brkout;
                goto brkout;
-       va11.va_wc = -(bp->b_bcount/2);
-       vastart();
-       e = vaerror(DONE);      /* Wait for DMA to complete */
-       va11.va_wc = 0;
-       va11.va_bufp = 0;
-
-       /*
-        * After printing a line of characters, VPRINTPLOT mode essentially
-        * reverts to VPLOT mode, plotting things until a new mode is set.
-        * This change is indicated by sending a VAAUTOSTEP command to
-        * the va.  We also change va_state to reflect this effective
-        * mode change.
-        */
-       if (va11.va_state & VPRINTPLOT) {
-               va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT;
-               VAADDR->vacsh = VAAUTOSTEP;
-               e |= vaerror(DONE);
+       sc->sc_wc = -(bp->b_bcount/2);
+       vastart(bp->b_dev);
+       e = vawait(bp->b_dev);
+       sc->sc_wc = 0;
+       if (sc->sc_state & VPRINTPLOT) {
+               sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
+               vaaddr->vacsh = VAAUTOSTEP;
+               e |= vawait(bp->b_dev);
        }
        (void) spl0();
 brkout:
        }
        (void) spl0();
 brkout:
-       ubarelse(&va_ubinfo);
-       va11.va_bp = 0;
-       va11.va_busy = 0;
+       ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
+       sc->sc_bp = 0;
+       sc->sc_busy = 0;
        iodone(bp);
        if (e)
                u.u_error = EIO;
        iodone(bp);
        if (e)
                u.u_error = EIO;
-       wakeup((caddr_t)&va11);
+       wakeup((caddr_t)sc);
 }
 
 int    vablock = 16384;
 
 unsigned
 minvaph(bp)
 }
 
 int    vablock = 16384;
 
 unsigned
 minvaph(bp)
-struct buf *bp;
+       struct buf *bp;
 {
 {
+
        if (bp->b_bcount > vablock)
                bp->b_bcount = vablock;
 }
 
 /*ARGSUSED*/
 vawrite(dev)
        if (bp->b_bcount > vablock)
                bp->b_bcount = vablock;
 }
 
 /*ARGSUSED*/
 vawrite(dev)
+       dev_t dev;
 {
 {
-       physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph);
+
+       physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph);
 }
 
 }
 
-/*
- * Vaerror waits until bit or ERROR gets set, then returns non-zero if
- * if it was ERROR that was set.
- */
-vaerror(bit)
+vawait(dev)
+       dev_t dev;
 {
 {
+       register struct vadevice *vaaddr =
+           (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
        register int e;
 
        register int e;
 
-       while ((e = VAADDR->vacsw & (bit|ERROR)) == 0)
-               sleep((caddr_t)&va11, VAPRI);
-       return (e & ERROR);
+       while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0)
+               sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI);
+       if (e & VA_NPRTIMO)
+               printf("va%d: npr timeout\n", VAUNIT(dev));
+       return (e & VA_ERROR);
 }
 
 }
 
-vastart()
+vastart(dev)
+       dev_t;
 {
 {
-       if (va11.va_wc) {
-               VAADDR->vaba = va11.va_bufp;
-               VAADDR->vacsl = (va11.va_bufp >> 12) & 0x30;
-               VAADDR->vawc = va11.va_wc;
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
+       register struct vadevice *vaaddr =
+           (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
+
+       if (sc->sc_wc == 0)
                return;
                return;
-       }
+       vaaddr->vaba = sc->sc_ubinfo;
+       vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
+       vaaddr->vawc = sc->sc_wc;
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
@@ -177,11 +210,12 @@ vaioctl(dev, cmd, addr, flag)
        register caddr_t addr;
 {
        register int vcmd;
        register caddr_t addr;
 {
        register int vcmd;
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
 
        switch (cmd) {
 
        case VGETSTATE:
 
        switch (cmd) {
 
        case VGETSTATE:
-               (void) suword(addr, va11.va_state);
+               (void) suword(addr, sc->sc_state);
                return;
 
        case VSETSTATE:
                return;
 
        case VSETSTATE:
@@ -190,101 +224,115 @@ vaioctl(dev, cmd, addr, flag)
                        u.u_error = EFAULT;
                        return;
                }
                        u.u_error = EFAULT;
                        return;
                }
-               vacmd(vcmd);
+               vacmd(dev, vcmd);
                return;
 
        default:
                return;
 
        default:
-               u.u_error = ENOTTY;     /* Not a legal ioctl cmd. */
+               u.u_error = ENOTTY;
                return;
        }
 }
 
                return;
        }
 }
 
-/*
- * Send a command code to the va, and wait for it to complete.
- * If an error occurs, u.u_error is set to EIO.
- * In any case, update va11.va_state.
- */
-vacmd(vcmd)
+vacmd(dev, vcmd)
+       dev_t dev;
+       int vcmd;
 {
 {
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
+       register struct vadevice *vaaddr =
+           (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
+
        (void) spl4();
        (void) spl4();
-       (void) vaerror(DONE);           /* Wait for va to be ready */
+       (void) vawait(dev);
        switch (vcmd) {
 
        case VPLOT:
                /* Must turn on plot AND autostep modes. */
        switch (vcmd) {
 
        case VPLOT:
                /* Must turn on plot AND autostep modes. */
-               VAADDR->vacsh = VAPLOT;
-               if (vaerror(DONE))
+               vaaddr->vacsh = VAPLOT;
+               if (vawait(dev))
                        u.u_error = EIO;
                        u.u_error = EIO;
-               VAADDR->vacsh = VAAUTOSTEP;
+               vaaddr->vacsh = VAAUTOSTEP;
                break;
 
        case VPRINT:
                break;
 
        case VPRINT:
-               VAADDR->vacsh = VAPRINT;
+               vaaddr->vacsh = VAPRINT;
                break;
 
        case VPRINTPLOT:
                break;
 
        case VPRINTPLOT:
-               VAADDR->vacsh = VAPRINTPLOT;
+               vaaddr->vacsh = VAPRINTPLOT;
                break;
        }
                break;
        }
-       va11.va_state =
-               (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd;
-
-       if (vaerror(DONE))      /* Wait for command to complete. */
+       sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
+       if (vawait(dev))
                u.u_error = EIO;
        (void) spl0();
 }
 
                u.u_error = EIO;
        (void) spl0();
 }
 
-vatimo()
+vatimo(dev)
+       dev_t dev;
 {
 {
-       if (va11.va_open)
-               timeout(vatimo, (caddr_t)0, hz/10);
-       vaintr(0);
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
+
+       if (sc->sc_openf)
+               timeout(vatimo, (caddr_t)dev, hz/10);
+       vaintr(dev);
 }
 
 /*ARGSUSED*/
 vaintr(dev)
 }
 
 /*ARGSUSED*/
 vaintr(dev)
+       dev_t dev;
 {
 {
-       wakeup((caddr_t)&va11);
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
+
+       wakeup((caddr_t)sc);
 }
 
 }
 
-vaclose()
+vaclose(dev)
+       dev_t dev;
 {
 {
-
-       va11.va_open = 0;
-       va11.va_busy = 0;
-       va11.va_state = 0;
-       va11.va_wc = 0;
-       va11.va_bufp = 0;
-       VAADDR->vacsl = 0;
+       register struct va_softc *sc = &va_softc[VAUNIT(dev)];
+       register struct vadevice *vaaddr =
+           (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
+
+       sc->sc_openf = 0;
+       sc->sc_busy = 0;
+       sc->sc_state = 0;
+       sc->sc_ubinfo = 0;
+       vaaddr->vacsl = 0;
 }
 
 }
 
-vareset()
+vareset(uban)
+       int uban;
 {
 {
-
-       if (va11.va_open == 0)
-               return;
-       printf(" va");
-       VAADDR->vacsl = IENABLE;
-       if (va11.va_state & VPLOT) {
-               VAADDR->vacsh = VAPLOT;
+       register int va11;
+       register struct uba_device *ui;
+       register struct va_softc *sc = va_softc;
+       register struct vadevice *vaaddr;
+
+       for (va11 = 0; va11 < NVA; va11++, sc++) {
+               if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 ||
+                   ui->ui_ubanum != uban || sc->sc_openf == 0)
+                       continue;
+               printf(" va%d", va11);
+               vaaddr = (struct vadevice *)ui->ui_addr;
+               vaaddr->vacsl = VA_IENABLE;
+               if (sc->sc_state & VPLOT) {
+                       vaaddr->vacsh = VAPLOT;
+                       DELAY(10000);
+                       vaaddr->vacsh = VAAUTOSTEP;
+               } else if (sc->sc_state & VPRINTPLOT)
+                       vaaddr->vacsh = VPRINTPLOT;
+               else
+                       vaaddr->vacsh = VAPRINTPLOT;
                DELAY(10000);
                DELAY(10000);
-               VAADDR->vacsh = VAAUTOSTEP;
-       } else if (va11.va_state & VPRINTPLOT)
-               VAADDR->vacsh = VPRINTPLOT;
-       else
-               VAADDR->vacsh = VAPRINTPLOT;
-       DELAY(10000);
-       if (va11.va_busy == 0)
-               return;
-       if (va_ubinfo) {
-               printf("<%d>", (va_ubinfo>>28)&0xf);
-               ubarelse(&va_ubinfo);
+               if (sc->sc_busy == 0)
+                       continue;
+               if (sc->sc_ubinfo) {
+                       printf("<%d>", (sc->sc_ubinfo>>28)&0xf);
+                       ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
+               }
+               sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP);
+               sc->sc_wc = -(sc->sc_bp->b_bcount/2);
+               vastart(sc->sc_bp->b_dev);
        }
        }
-       /* This code belongs in vastart() */
-       va_ubinfo = ubasetup(va11.va_bp, vabdp);
-       va11.va_bufp = va_ubinfo & 0x3ffff;
-       va11.va_wc = (-va11.va_bp->b_bcount/2);
-       /* End badly placed code */
-       vastart();
 }
 #endif
 }
 #endif