1*9362Smckusick /* va.c 4.13.1.2 82/11/27 */ 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" 18*9362Smckusick #include "../h/uio.h" 1941Sbill 20287Sbill unsigned minvaph(); 2141Sbill 2241Sbill #define VAPRI (PZERO-1) 2341Sbill 243183Swnj struct vadevice { 253183Swnj u_short vaba; /* buffer address */ 263183Swnj short vawc; /* word count (2's complement) */ 2741Sbill union { 283183Swnj short Vacsw; /* control status as word */ 293183Swnj struct { /* control status as bytes */ 30287Sbill char Vacsl; 31287Sbill char Vacsh; 32287Sbill } vacsr; 33287Sbill } vacs; 343183Swnj short vadata; /* programmed i/o data buffer */ 3541Sbill }; 3641Sbill 37287Sbill #define vacsw vacs.Vacsw 38287Sbill #define vacsh vacs.vacsr.Vacsh 39287Sbill #define vacsl vacs.vacsr.Vacsl 40287Sbill 41287Sbill /* vacsw bits */ 423183Swnj #define VA_ERROR 0100000 /* some error has occurred */ 433183Swnj #define VA_NPRTIMO 0001000 /* DMA timeout error */ 443183Swnj #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ 453183Swnj #define VA_DONE 0000200 463183Swnj #define VA_IENABLE 0000100 /* interrupt enable */ 47*9362Smckusick #define VA_DMAGO 0000010 /* DMA go bit */ 483183Swnj #define VA_SUPPLIESLOW 0000004 493183Swnj #define VA_BOTOFFORM 0000002 503183Swnj #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ 5141Sbill 52287Sbill /* vacsh command bytes */ 533183Swnj #define VAPLOT 0000340 543183Swnj #define VAPRINT 0000100 553183Swnj #define VAPRINTPLOT 0000160 563183Swnj #define VAAUTOSTEP 0000244 573183Swnj #define VANOAUTOSTEP 0000045 583183Swnj #define VAFORMFEED 0000263 593183Swnj #define VASLEW 0000265 603183Swnj #define VASTEP 0000064 6141Sbill 623183Swnj struct va_softc { 639361Smckusick char sc_openf; 649361Smckusick char sc_busy; 659361Smckusick int sc_state; 669361Smckusick int sc_wc; 679361Smckusick struct buf *sc_bp; 689361Smckusick int sc_ubinfo; 693183Swnj } va_softc[NVA]; 7041Sbill 713183Swnj #define VAUNIT(dev) (minor(dev)) 723183Swnj 733183Swnj struct buf rvabuf[NVA]; 743183Swnj 759361Smckusick int vaprobe(), vaattach(); 763183Swnj struct uba_device *vadinfo[NVA]; 773183Swnj u_short vastd[] = { 0764000, 0 }; 783183Swnj struct uba_driver vadriver = 799361Smckusick { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; 803183Swnj 813183Swnj vaprobe(reg) 823183Swnj caddr_t reg; 8341Sbill { 843183Swnj register int br, cvec; /* value-result */ 853183Swnj register struct vadevice *vaaddr = (struct vadevice *)reg; 8641Sbill 879267Smckusick #ifdef lint 889267Smckusick br = 0; cvec = br; br = cvec; 899267Smckusick vaintr(0); 909267Smckusick #endif 913183Swnj vaaddr->vacsl = VA_IENABLE; 923183Swnj vaaddr->vaba = 0; 933183Swnj vaaddr->vacsh = VAPLOT; 94*9362Smckusick #ifndef VARIANGOBIT 959361Smckusick vaaddr->vacsl = 0; 96*9362Smckusick #endif 973183Swnj vaaddr->vawc = -1; 989361Smckusick DELAY(100000); 993183Swnj vaaddr->vacsl = 0; 100*9362Smckusick return (sizeof (struct vadevice)); 1013183Swnj } 1023183Swnj 1033183Swnj /*ARGSUSED*/ 1043183Swnj vaattach(ui) 1053183Swnj struct uba_device *ui; 1063183Swnj { 1073183Swnj 1083183Swnj } 1093183Swnj 1103183Swnj vaopen(dev) 1113183Swnj dev_t dev; 1123183Swnj { 1133183Swnj register struct va_softc *sc; 1143183Swnj register struct vadevice *vaaddr; 1153183Swnj register struct uba_device *ui; 1163183Swnj 1179361Smckusick if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || 1189361Smckusick (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { 11941Sbill u.u_error = ENXIO; 12041Sbill return; 12141Sbill } 1223183Swnj vaaddr = (struct vadevice *)ui->ui_addr; 1233183Swnj sc->sc_openf = 1; 1243183Swnj vaaddr->vawc = 0; 1259361Smckusick sc->sc_wc = 0; 1263183Swnj sc->sc_state = 0; 1273183Swnj vaaddr->vacsl = VA_IENABLE; 1283183Swnj vatimo(dev); 1293183Swnj vacmd(dev, VPRINT); 13041Sbill if (u.u_error) 1313183Swnj vaclose(dev); 13241Sbill } 13341Sbill 13441Sbill vastrategy(bp) 13541Sbill register struct buf *bp; 13641Sbill { 1379361Smckusick register int e; 1389361Smckusick register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; 1399361Smckusick register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; 1409361Smckusick register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; 14141Sbill 1429361Smckusick (void) spl4(); 1439361Smckusick while (sc->sc_busy) 1449361Smckusick sleep((caddr_t)sc, VAPRI); 1459361Smckusick sc->sc_busy = 1; 1469361Smckusick sc->sc_bp = bp; 1479361Smckusick sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); 1489361Smckusick if (e = vawait(bp->b_dev)) 1499361Smckusick goto brkout; 1509361Smckusick sc->sc_wc = -(bp->b_bcount/2); 1519361Smckusick vastart(bp->b_dev); 1529361Smckusick e = vawait(bp->b_dev); 1539361Smckusick sc->sc_wc = 0; 1549361Smckusick if (sc->sc_state & VPRINTPLOT) { 1559361Smckusick sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; 1569361Smckusick vaaddr->vacsh = VAAUTOSTEP; 1579361Smckusick e |= vawait(bp->b_dev); 15841Sbill } 1599361Smckusick (void) spl0(); 1609361Smckusick brkout: 1619361Smckusick ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 1629361Smckusick sc->sc_bp = 0; 1639361Smckusick sc->sc_busy = 0; 1649361Smckusick iodone(bp); 1659361Smckusick if (e) 1669361Smckusick u.u_error = EIO; 1679361Smckusick wakeup((caddr_t)sc); 16841Sbill } 16941Sbill 17041Sbill int vablock = 16384; 17141Sbill 17241Sbill unsigned 17341Sbill minvaph(bp) 1743183Swnj struct buf *bp; 17541Sbill { 1763183Swnj 17741Sbill if (bp->b_bcount > vablock) 17841Sbill bp->b_bcount = vablock; 17941Sbill } 18041Sbill 18141Sbill /*ARGSUSED*/ 182*9362Smckusick vawrite(dev, uio) 1833183Swnj dev_t dev; 184*9362Smckusick struct uio *uio; 18541Sbill { 1869267Smckusick 187*9362Smckusick if (VAUNIT(dev) > NVA) 188*9362Smckusick u.u_error = ENXIO; 189*9362Smckusick else 190*9362Smckusick physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, 191*9362Smckusick minvaph, uio); 19241Sbill } 19341Sbill 1949361Smckusick vawait(dev) 1959361Smckusick dev_t dev; 19641Sbill { 1979361Smckusick register struct vadevice *vaaddr = 1989361Smckusick (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 1999361Smckusick register int e; 20041Sbill 2019361Smckusick while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) 2029361Smckusick sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); 2039361Smckusick if (e & VA_NPRTIMO) 2049361Smckusick printf("va%d: npr timeout\n", VAUNIT(dev)); 2059361Smckusick return (e & VA_ERROR); 20641Sbill } 20741Sbill 2089361Smckusick vastart(dev) 2099361Smckusick dev_t; 21041Sbill { 2119361Smckusick register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2129361Smckusick register struct vadevice *vaaddr = 2139361Smckusick (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 2143183Swnj 2159361Smckusick if (sc->sc_wc == 0) 2169361Smckusick return; 2179361Smckusick vaaddr->vaba = sc->sc_ubinfo; 218*9362Smckusick #ifndef VARIANGOBIT 2199361Smckusick vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; 220*9362Smckusick #else 221*9362Smckusick vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30 | VA_IENABLE | VA_DMAGO; 222*9362Smckusick #endif 2239361Smckusick vaaddr->vawc = sc->sc_wc; 22441Sbill } 22541Sbill 22641Sbill /*ARGSUSED*/ 227*9362Smckusick vaioctl(dev, cmd, data, flag) 228*9362Smckusick register caddr_t data; 22941Sbill { 23041Sbill register int vcmd; 2313183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 23241Sbill 23341Sbill switch (cmd) { 23441Sbill 23541Sbill case VGETSTATE: 236*9362Smckusick *(int *)data = sc->sc_state; 23741Sbill return; 23841Sbill 23941Sbill case VSETSTATE: 240*9362Smckusick vacmd(dev, *(int *)data); 24141Sbill return; 24241Sbill 24341Sbill default: 2443183Swnj u.u_error = ENOTTY; 24541Sbill return; 24641Sbill } 24741Sbill } 24841Sbill 2493183Swnj vacmd(dev, vcmd) 2503183Swnj dev_t dev; 2513183Swnj int vcmd; 25241Sbill { 2533183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2549361Smckusick register struct vadevice *vaaddr = 2559361Smckusick (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 2563183Swnj 2579361Smckusick (void) spl4(); 2589361Smckusick (void) vawait(dev); 25941Sbill switch (vcmd) { 26041Sbill 26141Sbill case VPLOT: 26241Sbill /* Must turn on plot AND autostep modes. */ 2639361Smckusick vaaddr->vacsh = VAPLOT; 2649361Smckusick if (vawait(dev)) 26541Sbill u.u_error = EIO; 2669361Smckusick vaaddr->vacsh = VAAUTOSTEP; 26741Sbill break; 26841Sbill 26941Sbill case VPRINT: 2709361Smckusick vaaddr->vacsh = VAPRINT; 27141Sbill break; 27241Sbill 27341Sbill case VPRINTPLOT: 2749361Smckusick vaaddr->vacsh = VAPRINTPLOT; 27541Sbill break; 27641Sbill } 2773183Swnj sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; 2789361Smckusick if (vawait(dev)) 27941Sbill u.u_error = EIO; 2809361Smckusick (void) spl0(); 28141Sbill } 28241Sbill 2833183Swnj vatimo(dev) 2843183Swnj dev_t dev; 28541Sbill { 2863183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2873183Swnj 2883183Swnj if (sc->sc_openf) 2899361Smckusick timeout(vatimo, (caddr_t)dev, hz/10); 2909267Smckusick vaintr(dev); 29141Sbill } 29241Sbill 29341Sbill /*ARGSUSED*/ 29441Sbill vaintr(dev) 2953183Swnj dev_t dev; 29641Sbill { 2979361Smckusick register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 2983183Swnj 2999361Smckusick wakeup((caddr_t)sc); 30041Sbill } 30141Sbill 3023183Swnj vaclose(dev) 3033183Swnj dev_t dev; 30441Sbill { 3053183Swnj register struct va_softc *sc = &va_softc[VAUNIT(dev)]; 3063183Swnj register struct vadevice *vaaddr = 3073183Swnj (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; 30841Sbill 3093183Swnj sc->sc_openf = 0; 3109361Smckusick sc->sc_busy = 0; 3113183Swnj sc->sc_state = 0; 3129361Smckusick sc->sc_ubinfo = 0; 3133183Swnj vaaddr->vacsl = 0; 31441Sbill } 315287Sbill 3163183Swnj vareset(uban) 3173183Swnj int uban; 318287Sbill { 3193183Swnj register int va11; 3209361Smckusick register struct uba_device *ui; 3219361Smckusick register struct va_softc *sc = va_softc; 3223183Swnj register struct vadevice *vaaddr; 323287Sbill 3243183Swnj for (va11 = 0; va11 < NVA; va11++, sc++) { 3259361Smckusick if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || 3269361Smckusick ui->ui_ubanum != uban || sc->sc_openf == 0) 3273183Swnj continue; 3283183Swnj printf(" va%d", va11); 3299361Smckusick vaaddr = (struct vadevice *)ui->ui_addr; 3303183Swnj vaaddr->vacsl = VA_IENABLE; 3313183Swnj if (sc->sc_state & VPLOT) { 3323183Swnj vaaddr->vacsh = VAPLOT; 3333183Swnj DELAY(10000); 3343183Swnj vaaddr->vacsh = VAAUTOSTEP; 3353183Swnj } else if (sc->sc_state & VPRINTPLOT) 3363183Swnj vaaddr->vacsh = VPRINTPLOT; 3373183Swnj else 3383183Swnj vaaddr->vacsh = VAPRINTPLOT; 339287Sbill DELAY(10000); 3409361Smckusick if (sc->sc_busy == 0) 3419361Smckusick continue; 3429361Smckusick if (sc->sc_ubinfo) { 3439361Smckusick printf("<%d>", (sc->sc_ubinfo>>28)&0xf); 3449361Smckusick ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); 3453183Swnj } 3469361Smckusick sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); 3479361Smckusick sc->sc_wc = -(sc->sc_bp->b_bcount/2); 3489361Smckusick vastart(sc->sc_bp->b_dev); 349287Sbill } 350287Sbill } 3516432Ssam 3526432Ssam vaselect() 3536432Ssam { 3546432Ssam return (1); 3556432Ssam } 3561564Sbill #endif 357