1*6432Ssam /* va.c 4.12 82/04/01 */ 241Sbill 31938Swnj #include "va.h" 41564Sbill #if NVA > 0 51564Sbill /* 63183Swnj * 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" 153183Swnj #include "../h/ubareg.h" 163183Swnj #include "../h/ubavar.h" 1741Sbill #include "../h/vcmd.h" 1841Sbill 19287Sbill unsigned minvaph(); 2041Sbill 2141Sbill #define VAPRI (PZERO-1) 2241Sbill 233183Swnj struct vadevice { 243183Swnj u_short vaba; /* buffer address */ 253183Swnj short vawc; /* word count (2's complement) */ 2641Sbill union { 273183Swnj short Vacsw; /* control status as word */ 283183Swnj struct { /* control status as bytes */ 29287Sbill char Vacsl; 30287Sbill char Vacsh; 31287Sbill } vacsr; 32287Sbill } vacs; 333183Swnj 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 */ 413183Swnj #define VA_ERROR 0100000 /* some error has occurred */ 423183Swnj #define VA_NPRTIMO 0001000 /* DMA timeout error */ 433183Swnj #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ 443183Swnj #define VA_DONE 0000200 453183Swnj #define VA_IENABLE 0000100 /* interrupt enable */ 463183Swnj #define VA_SUPPLIESLOW 0000004 473183Swnj #define VA_BOTOFFORM 0000002 483183Swnj #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ 4941Sbill 50287Sbill /* vacsh command bytes */ 513183Swnj #define VAPLOT 0000340 523183Swnj #define VAPRINT 0000100 533183Swnj #define VAPRINTPLOT 0000160 543183Swnj #define VAAUTOSTEP 0000244 553183Swnj #define VANOAUTOSTEP 0000045 563183Swnj #define VAFORMFEED 0000263 573183Swnj #define VASLEW 0000265 583183Swnj #define VASTEP 0000064 5941Sbill 603183Swnj struct va_softc { 613183Swnj char sc_openf; 623183Swnj char sc_busy; 633183Swnj int sc_state; 643183Swnj int sc_wc; 653183Swnj struct buf *sc_bp; 663183Swnj int sc_ubinfo; 673183Swnj } va_softc[NVA]; 6841Sbill 693183Swnj #define VAUNIT(dev) (minor(dev)) 703183Swnj 713183Swnj struct buf rvabuf[NVA]; 723183Swnj 733183Swnj int vaprobe(), vaattach(); 743183Swnj struct uba_device *vadinfo[NVA]; 753183Swnj u_short vastd[] = { 0764000, 0 }; 763183Swnj struct uba_driver vadriver = 773183Swnj { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; 783183Swnj 793183Swnj vaprobe(reg) 803183Swnj caddr_t reg; 8141Sbill { 823183Swnj register int br, cvec; /* value-result */ 833183Swnj register struct vadevice *vaaddr = (struct vadevice *)reg; 8441Sbill 854942Swnj #ifdef lint 864942Swnj br = 0; cvec = br; br = cvec; 874942Swnj vaintr(0); 884942Swnj #endif 893183Swnj vaaddr->vacsl = VA_IENABLE; 903183Swnj vaaddr->vaba = 0; 913183Swnj vaaddr->vacsh = VAPLOT; 923183Swnj vaaddr->vacsl = 0; 933183Swnj vaaddr->vawc = -1; 943183Swnj DELAY(10000); 953183Swnj vaaddr->vacsl = 0; 963183Swnj } 973183Swnj 983183Swnj /*ARGSUSED*/ 993183Swnj vaattach(ui) 1003183Swnj struct uba_device *ui; 1013183Swnj { 1023183Swnj 1033183Swnj } 1043183Swnj 1053183Swnj vaopen(dev) 1063183Swnj dev_t dev; 1073183Swnj { 1083183Swnj register struct va_softc *sc; 1093183Swnj register struct vadevice *vaaddr; 1103183Swnj register struct uba_device *ui; 1113183Swnj 1123183Swnj if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || 1133183Swnj (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { 11441Sbill u.u_error = ENXIO; 11541Sbill return; 11641Sbill } 1173183Swnj vaaddr = (struct vadevice *)ui->ui_addr; 1183183Swnj sc->sc_openf = 1; 1193183Swnj vaaddr->vawc = 0; 1203183Swnj sc->sc_wc = 0; 1213183Swnj sc->sc_state = 0; 1223183Swnj vaaddr->vacsl = VA_IENABLE; 1233183Swnj vatimo(dev); 1243183Swnj vacmd(dev, VPRINT); 12541Sbill if (u.u_error) 1263183Swnj vaclose(dev); 12741Sbill } 12841Sbill 12941Sbill vastrategy(bp) 13041Sbill register struct buf *bp; 13141Sbill { 13241Sbill register int e; 1333183Swnj register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; 1343183Swnj register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; 1353183Swnj register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; 13641Sbill 137133Sbill (void) spl4(); 1383183Swnj while (sc->sc_busy) 1393183Swnj sleep((caddr_t)sc, VAPRI); 1403183Swnj sc->sc_busy = 1; 1413183Swnj sc->sc_bp = bp; 1423183Swnj sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); 1433183Swnj if (e = vawait(bp->b_dev)) 14441Sbill goto brkout; 1453183Swnj sc->sc_wc = -(bp->b_bcount/2); 1463183Swnj vastart(bp->b_dev); 1473183Swnj e = vawait(bp->b_dev); 1483183Swnj sc->sc_wc = 0; 1493183Swnj if (sc->sc_state & VPRINTPLOT) { 1503183Swnj sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; 1513183Swnj vaaddr->vacsh = VAAUTOSTEP; 1523183Swnj e |= vawait(bp->b_dev); 15341Sbill } 154133Sbill (void) spl0(); 15541Sbill brkout: 1563183Swnj ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 1573183Swnj sc->sc_bp = 0; 1583183Swnj sc->sc_busy = 0; 15941Sbill iodone(bp); 16041Sbill if (e) 16141Sbill u.u_error = EIO; 1623183Swnj wakeup((caddr_t)sc); 16341Sbill } 16441Sbill 16541Sbill int vablock = 16384; 16641Sbill 16741Sbill unsigned 16841Sbill minvaph(bp) 1693183Swnj struct buf *bp; 17041Sbill { 1713183Swnj 17241Sbill if (bp->b_bcount > vablock) 17341Sbill bp->b_bcount = vablock; 17441Sbill } 17541Sbill 17641Sbill /*ARGSUSED*/ 17741Sbill vawrite(dev) 1783183Swnj dev_t dev; 17941Sbill { 1803183Swnj 1813183Swnj physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph); 18241Sbill } 18341Sbill 1843183Swnj vawait(dev) 1853183Swnj dev_t dev; 18641Sbill { 1873183Swnj register struct vadevice *vaaddr = 1883183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 18941Sbill register int e; 19041Sbill 1913183Swnj while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) 1923183Swnj sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); 1933183Swnj if (e & VA_NPRTIMO) 1943183Swnj printf("va%d: npr timeout\n", VAUNIT(dev)); 1953183Swnj return (e & VA_ERROR); 19641Sbill } 19741Sbill 1983183Swnj vastart(dev) 1993183Swnj dev_t; 20041Sbill { 2013183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2023183Swnj register struct vadevice *vaaddr = 2033183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 2043183Swnj 2053183Swnj if (sc->sc_wc == 0) 20641Sbill return; 2073183Swnj vaaddr->vaba = sc->sc_ubinfo; 2083183Swnj vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; 2093183Swnj vaaddr->vawc = sc->sc_wc; 21041Sbill } 21141Sbill 21241Sbill /*ARGSUSED*/ 21341Sbill vaioctl(dev, cmd, addr, flag) 21441Sbill register caddr_t addr; 21541Sbill { 21641Sbill register int vcmd; 2173183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 21841Sbill 21941Sbill switch (cmd) { 22041Sbill 22141Sbill case VGETSTATE: 2223183Swnj (void) suword(addr, sc->sc_state); 22341Sbill return; 22441Sbill 22541Sbill case VSETSTATE: 22641Sbill vcmd = fuword(addr); 22741Sbill if (vcmd == -1) { 22841Sbill u.u_error = EFAULT; 22941Sbill return; 23041Sbill } 2313183Swnj vacmd(dev, vcmd); 23241Sbill return; 23341Sbill 23441Sbill default: 2353183Swnj u.u_error = ENOTTY; 23641Sbill return; 23741Sbill } 23841Sbill } 23941Sbill 2403183Swnj vacmd(dev, vcmd) 2413183Swnj dev_t dev; 2423183Swnj int vcmd; 24341Sbill { 2443183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2453183Swnj register struct vadevice *vaaddr = 2463183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 2473183Swnj 248133Sbill (void) spl4(); 2493183Swnj (void) vawait(dev); 25041Sbill switch (vcmd) { 25141Sbill 25241Sbill case VPLOT: 25341Sbill /* Must turn on plot AND autostep modes. */ 2543183Swnj vaaddr->vacsh = VAPLOT; 2553183Swnj if (vawait(dev)) 25641Sbill u.u_error = EIO; 2573183Swnj vaaddr->vacsh = VAAUTOSTEP; 25841Sbill break; 25941Sbill 26041Sbill case VPRINT: 2613183Swnj vaaddr->vacsh = VAPRINT; 26241Sbill break; 26341Sbill 26441Sbill case VPRINTPLOT: 2653183Swnj vaaddr->vacsh = VAPRINTPLOT; 26641Sbill break; 26741Sbill } 2683183Swnj sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; 2693183Swnj if (vawait(dev)) 27041Sbill u.u_error = EIO; 271133Sbill (void) spl0(); 27241Sbill } 27341Sbill 2743183Swnj vatimo(dev) 2753183Swnj dev_t dev; 27641Sbill { 2773183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2783183Swnj 2793183Swnj if (sc->sc_openf) 2803183Swnj timeout(vatimo, (caddr_t)dev, hz/10); 2813183Swnj vaintr(dev); 28241Sbill } 28341Sbill 28441Sbill /*ARGSUSED*/ 28541Sbill vaintr(dev) 2863183Swnj dev_t dev; 28741Sbill { 2883183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2893183Swnj 2903183Swnj wakeup((caddr_t)sc); 29141Sbill } 29241Sbill 2933183Swnj vaclose(dev) 2943183Swnj dev_t dev; 29541Sbill { 2963183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2973183Swnj register struct vadevice *vaaddr = 2983183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 29941Sbill 3003183Swnj sc->sc_openf = 0; 3013183Swnj sc->sc_busy = 0; 3023183Swnj sc->sc_state = 0; 3033183Swnj sc->sc_ubinfo = 0; 3043183Swnj vaaddr->vacsl = 0; 30541Sbill } 306287Sbill 3073183Swnj vareset(uban) 3083183Swnj int uban; 309287Sbill { 3103183Swnj register int va11; 3113183Swnj register struct uba_device *ui; 3123183Swnj register struct va_softc *sc = va_softc; 3133183Swnj register struct vadevice *vaaddr; 314287Sbill 3153183Swnj for (va11 = 0; va11 < NVA; va11++, sc++) { 3163183Swnj if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || 3173183Swnj ui->ui_ubanum != uban || sc->sc_openf == 0) 3183183Swnj continue; 3193183Swnj printf(" va%d", va11); 3203183Swnj vaaddr = (struct vadevice *)ui->ui_addr; 3213183Swnj vaaddr->vacsl = VA_IENABLE; 3223183Swnj if (sc->sc_state & VPLOT) { 3233183Swnj vaaddr->vacsh = VAPLOT; 3243183Swnj DELAY(10000); 3253183Swnj vaaddr->vacsh = VAAUTOSTEP; 3263183Swnj } else if (sc->sc_state & VPRINTPLOT) 3273183Swnj vaaddr->vacsh = VPRINTPLOT; 3283183Swnj else 3293183Swnj vaaddr->vacsh = VAPRINTPLOT; 330287Sbill DELAY(10000); 3313183Swnj if (sc->sc_busy == 0) 3323183Swnj continue; 3333183Swnj if (sc->sc_ubinfo) { 3343183Swnj printf("<%d>", (sc->sc_ubinfo>>28)&0xf); 3353183Swnj ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 3363183Swnj } 3373183Swnj sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); 3383183Swnj sc->sc_wc = -(sc->sc_bp->b_bcount/2); 3393183Swnj vastart(sc->sc_bp->b_dev); 340287Sbill } 341287Sbill } 342*6432Ssam 343*6432Ssam vaselect() 344*6432Ssam { 345*6432Ssam return (1); 346*6432Ssam } 3471564Sbill #endif 348