1*3183Swnj /* va.c 4.9 81/03/10 */ 241Sbill 31938Swnj #include "va.h" 41564Sbill #if NVA > 0 51564Sbill /* 6*3183Swnj * Varian printer plotter 71564Sbill */ 841Sbill #include "../h/param.h" 941Sbill #include "../h/dir.h" 1041Sbill #include "../h/user.h" 1141Sbill #include "../h/buf.h" 1241Sbill #include "../h/systm.h" 1341Sbill #include "../h/map.h" 1441Sbill #include "../h/pte.h" 15*3183Swnj #include "../h/ubareg.h" 16*3183Swnj #include "../h/ubavar.h" 1741Sbill #include "../h/vcmd.h" 1841Sbill 19287Sbill unsigned minvaph(); 2041Sbill 2141Sbill #define VAPRI (PZERO-1) 2241Sbill 23*3183Swnj struct vadevice { 24*3183Swnj u_short vaba; /* buffer address */ 25*3183Swnj short vawc; /* word count (2's complement) */ 2641Sbill union { 27*3183Swnj short Vacsw; /* control status as word */ 28*3183Swnj struct { /* control status as bytes */ 29287Sbill char Vacsl; 30287Sbill char Vacsh; 31287Sbill } vacsr; 32287Sbill } vacs; 33*3183Swnj short vadata; /* programmed i/o data buffer */ 3441Sbill }; 3541Sbill 36287Sbill #define vacsw vacs.Vacsw 37287Sbill #define vacsh vacs.vacsr.Vacsh 38287Sbill #define vacsl vacs.vacsr.Vacsl 39287Sbill 40287Sbill /* vacsw bits */ 41*3183Swnj #define VA_ERROR 0100000 /* some error has occurred */ 42*3183Swnj #define VA_NPRTIMO 0001000 /* DMA timeout error */ 43*3183Swnj #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ 44*3183Swnj #define VA_DONE 0000200 45*3183Swnj #define VA_IENABLE 0000100 /* interrupt enable */ 46*3183Swnj #define VA_SUPPLIESLOW 0000004 47*3183Swnj #define VA_BOTOFFORM 0000002 48*3183Swnj #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ 4941Sbill 50287Sbill /* vacsh command bytes */ 51*3183Swnj #define VAPLOT 0000340 52*3183Swnj #define VAPRINT 0000100 53*3183Swnj #define VAPRINTPLOT 0000160 54*3183Swnj #define VAAUTOSTEP 0000244 55*3183Swnj #define VANOAUTOSTEP 0000045 56*3183Swnj #define VAFORMFEED 0000263 57*3183Swnj #define VASLEW 0000265 58*3183Swnj #define VASTEP 0000064 5941Sbill 60*3183Swnj struct va_softc { 61*3183Swnj char sc_openf; 62*3183Swnj char sc_busy; 63*3183Swnj int sc_state; 64*3183Swnj int sc_wc; 65*3183Swnj struct buf *sc_bp; 66*3183Swnj int sc_ubinfo; 67*3183Swnj } va_softc[NVA]; 6841Sbill 69*3183Swnj struct uba_device *vadinfo[NVA]; 7041Sbill 71*3183Swnj #define VAUNIT(dev) (minor(dev)) 72*3183Swnj 73*3183Swnj struct buf rvabuf[NVA]; 74*3183Swnj 75*3183Swnj int vaprobe(), vaattach(); 76*3183Swnj struct uba_device *vadinfo[NVA]; 77*3183Swnj u_short vastd[] = { 0764000, 0 }; 78*3183Swnj struct uba_driver vadriver = 79*3183Swnj { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; 80*3183Swnj 81*3183Swnj vaprobe(reg) 82*3183Swnj caddr_t reg; 8341Sbill { 84*3183Swnj register int br, cvec; /* value-result */ 85*3183Swnj register struct vadevice *vaaddr = (struct vadevice *)reg; 8641Sbill 87*3183Swnj vaaddr->vacsl = VA_IENABLE; 88*3183Swnj vaaddr->vaba = 0; 89*3183Swnj vaaddr->vacsh = VAPLOT; 90*3183Swnj vaaddr->vacsl = 0; 91*3183Swnj vaaddr->vawc = -1; 92*3183Swnj DELAY(10000); 93*3183Swnj vaaddr->vacsl = 0; 94*3183Swnj } 95*3183Swnj 96*3183Swnj /*ARGSUSED*/ 97*3183Swnj vaattach(ui) 98*3183Swnj struct uba_device *ui; 99*3183Swnj { 100*3183Swnj 101*3183Swnj } 102*3183Swnj 103*3183Swnj vaopen(dev) 104*3183Swnj dev_t dev; 105*3183Swnj { 106*3183Swnj register struct va_softc *sc; 107*3183Swnj register struct vadevice *vaaddr; 108*3183Swnj register struct uba_device *ui; 109*3183Swnj 110*3183Swnj if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || 111*3183Swnj (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { 11241Sbill u.u_error = ENXIO; 11341Sbill return; 11441Sbill } 115*3183Swnj vaaddr = (struct vadevice *)ui->ui_addr; 116*3183Swnj sc->sc_openf = 1; 117*3183Swnj vaaddr->vawc = 0; 118*3183Swnj sc->sc_wc = 0; 119*3183Swnj sc->sc_state = 0; 120*3183Swnj vaaddr->vacsl = VA_IENABLE; 121*3183Swnj vatimo(dev); 122*3183Swnj vacmd(dev, VPRINT); 12341Sbill if (u.u_error) 124*3183Swnj vaclose(dev); 12541Sbill } 12641Sbill 12741Sbill vastrategy(bp) 12841Sbill register struct buf *bp; 12941Sbill { 13041Sbill register int e; 131*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; 132*3183Swnj register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; 133*3183Swnj register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; 13441Sbill 135133Sbill (void) spl4(); 136*3183Swnj while (sc->sc_busy) 137*3183Swnj sleep((caddr_t)sc, VAPRI); 138*3183Swnj sc->sc_busy = 1; 139*3183Swnj sc->sc_bp = bp; 140*3183Swnj sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); 141*3183Swnj if (e = vawait(bp->b_dev)) 14241Sbill goto brkout; 143*3183Swnj sc->sc_wc = -(bp->b_bcount/2); 144*3183Swnj vastart(bp->b_dev); 145*3183Swnj e = vawait(bp->b_dev); 146*3183Swnj sc->sc_wc = 0; 147*3183Swnj if (sc->sc_state & VPRINTPLOT) { 148*3183Swnj sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; 149*3183Swnj vaaddr->vacsh = VAAUTOSTEP; 150*3183Swnj e |= vawait(bp->b_dev); 15141Sbill } 152133Sbill (void) spl0(); 15341Sbill brkout: 154*3183Swnj ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 155*3183Swnj sc->sc_bp = 0; 156*3183Swnj sc->sc_busy = 0; 15741Sbill iodone(bp); 15841Sbill if (e) 15941Sbill u.u_error = EIO; 160*3183Swnj wakeup((caddr_t)sc); 16141Sbill } 16241Sbill 16341Sbill int vablock = 16384; 16441Sbill 16541Sbill unsigned 16641Sbill minvaph(bp) 167*3183Swnj struct buf *bp; 16841Sbill { 169*3183Swnj 17041Sbill if (bp->b_bcount > vablock) 17141Sbill bp->b_bcount = vablock; 17241Sbill } 17341Sbill 17441Sbill /*ARGSUSED*/ 17541Sbill vawrite(dev) 176*3183Swnj dev_t dev; 17741Sbill { 178*3183Swnj 179*3183Swnj physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph); 18041Sbill } 18141Sbill 182*3183Swnj vawait(dev) 183*3183Swnj dev_t dev; 18441Sbill { 185*3183Swnj register struct vadevice *vaaddr = 186*3183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 18741Sbill register int e; 18841Sbill 189*3183Swnj while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) 190*3183Swnj sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); 191*3183Swnj if (e & VA_NPRTIMO) 192*3183Swnj printf("va%d: npr timeout\n", VAUNIT(dev)); 193*3183Swnj return (e & VA_ERROR); 19441Sbill } 19541Sbill 196*3183Swnj vastart(dev) 197*3183Swnj dev_t; 19841Sbill { 199*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 200*3183Swnj register struct vadevice *vaaddr = 201*3183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 202*3183Swnj 203*3183Swnj if (sc->sc_wc == 0) 20441Sbill return; 205*3183Swnj vaaddr->vaba = sc->sc_ubinfo; 206*3183Swnj vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; 207*3183Swnj vaaddr->vawc = sc->sc_wc; 20841Sbill } 20941Sbill 21041Sbill /*ARGSUSED*/ 21141Sbill vaioctl(dev, cmd, addr, flag) 21241Sbill register caddr_t addr; 21341Sbill { 21441Sbill register int vcmd; 215*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 21641Sbill 21741Sbill switch (cmd) { 21841Sbill 21941Sbill case VGETSTATE: 220*3183Swnj (void) suword(addr, sc->sc_state); 22141Sbill return; 22241Sbill 22341Sbill case VSETSTATE: 22441Sbill vcmd = fuword(addr); 22541Sbill if (vcmd == -1) { 22641Sbill u.u_error = EFAULT; 22741Sbill return; 22841Sbill } 229*3183Swnj vacmd(dev, vcmd); 23041Sbill return; 23141Sbill 23241Sbill default: 233*3183Swnj u.u_error = ENOTTY; 23441Sbill return; 23541Sbill } 23641Sbill } 23741Sbill 238*3183Swnj vacmd(dev, vcmd) 239*3183Swnj dev_t dev; 240*3183Swnj int vcmd; 24141Sbill { 242*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 243*3183Swnj register struct vadevice *vaaddr = 244*3183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 245*3183Swnj 246133Sbill (void) spl4(); 247*3183Swnj (void) vawait(dev); 24841Sbill switch (vcmd) { 24941Sbill 25041Sbill case VPLOT: 25141Sbill /* Must turn on plot AND autostep modes. */ 252*3183Swnj vaaddr->vacsh = VAPLOT; 253*3183Swnj if (vawait(dev)) 25441Sbill u.u_error = EIO; 255*3183Swnj vaaddr->vacsh = VAAUTOSTEP; 25641Sbill break; 25741Sbill 25841Sbill case VPRINT: 259*3183Swnj vaaddr->vacsh = VAPRINT; 26041Sbill break; 26141Sbill 26241Sbill case VPRINTPLOT: 263*3183Swnj vaaddr->vacsh = VAPRINTPLOT; 26441Sbill break; 26541Sbill } 266*3183Swnj sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; 267*3183Swnj if (vawait(dev)) 26841Sbill u.u_error = EIO; 269133Sbill (void) spl0(); 27041Sbill } 27141Sbill 272*3183Swnj vatimo(dev) 273*3183Swnj dev_t dev; 27441Sbill { 275*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 276*3183Swnj 277*3183Swnj if (sc->sc_openf) 278*3183Swnj timeout(vatimo, (caddr_t)dev, hz/10); 279*3183Swnj vaintr(dev); 28041Sbill } 28141Sbill 28241Sbill /*ARGSUSED*/ 28341Sbill vaintr(dev) 284*3183Swnj dev_t dev; 28541Sbill { 286*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 287*3183Swnj 288*3183Swnj wakeup((caddr_t)sc); 28941Sbill } 29041Sbill 291*3183Swnj vaclose(dev) 292*3183Swnj dev_t dev; 29341Sbill { 294*3183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 295*3183Swnj register struct vadevice *vaaddr = 296*3183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 29741Sbill 298*3183Swnj sc->sc_openf = 0; 299*3183Swnj sc->sc_busy = 0; 300*3183Swnj sc->sc_state = 0; 301*3183Swnj sc->sc_ubinfo = 0; 302*3183Swnj vaaddr->vacsl = 0; 30341Sbill } 304287Sbill 305*3183Swnj vareset(uban) 306*3183Swnj int uban; 307287Sbill { 308*3183Swnj register int va11; 309*3183Swnj register struct uba_device *ui; 310*3183Swnj register struct va_softc *sc = va_softc; 311*3183Swnj register struct vadevice *vaaddr; 312287Sbill 313*3183Swnj for (va11 = 0; va11 < NVA; va11++, sc++) { 314*3183Swnj if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || 315*3183Swnj ui->ui_ubanum != uban || sc->sc_openf == 0) 316*3183Swnj continue; 317*3183Swnj printf(" va%d", va11); 318*3183Swnj vaaddr = (struct vadevice *)ui->ui_addr; 319*3183Swnj vaaddr->vacsl = VA_IENABLE; 320*3183Swnj if (sc->sc_state & VPLOT) { 321*3183Swnj vaaddr->vacsh = VAPLOT; 322*3183Swnj DELAY(10000); 323*3183Swnj vaaddr->vacsh = VAAUTOSTEP; 324*3183Swnj } else if (sc->sc_state & VPRINTPLOT) 325*3183Swnj vaaddr->vacsh = VPRINTPLOT; 326*3183Swnj else 327*3183Swnj vaaddr->vacsh = VAPRINTPLOT; 328287Sbill DELAY(10000); 329*3183Swnj if (sc->sc_busy == 0) 330*3183Swnj continue; 331*3183Swnj if (sc->sc_ubinfo) { 332*3183Swnj printf("<%d>", (sc->sc_ubinfo>>28)&0xf); 333*3183Swnj ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 334*3183Swnj } 335*3183Swnj sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); 336*3183Swnj sc->sc_wc = -(sc->sc_bp->b_bcount/2); 337*3183Swnj vastart(sc->sc_bp->b_dev); 338287Sbill } 339287Sbill } 3401564Sbill #endif 341