1*287Sbill /* va.c 3.6 06/22/80 */ 241Sbill 341Sbill #include "../h/param.h" 441Sbill #include "../h/dir.h" 541Sbill #include "../h/user.h" 641Sbill #include "../h/buf.h" 741Sbill #include "../h/systm.h" 841Sbill #include "../h/map.h" 941Sbill #include "../h/pte.h" 1041Sbill #include "../h/uba.h" 1141Sbill #include "../h/vcmd.h" 1241Sbill 1341Sbill /* 14*287Sbill * Benson-Varian matrix printer/plotter 1541Sbill * dma interface driver 1641Sbill */ 17*287Sbill int vabdp = 1; 1841Sbill 19*287Sbill unsigned minvaph(); 2041Sbill 2141Sbill #define VAPRI (PZERO-1) 2241Sbill 23*287Sbill #define ushort unsigned short 24*287Sbill struct varegs { 25*287Sbill ushort vaba; 26*287Sbill short vawc; 2741Sbill union { 28*287Sbill short Vacsw; 2941Sbill struct { 30*287Sbill char Vacsl; 31*287Sbill char Vacsh; 32*287Sbill } vacsr; 33*287Sbill } vacs; 3441Sbill short vadata; 3541Sbill }; 3641Sbill 37*287Sbill #define vacsw vacs.Vacsw 38*287Sbill #define vacsh vacs.vacsr.Vacsh 39*287Sbill #define vacsl vacs.vacsr.Vacsl 40*287Sbill 4141Sbill #define VAADDR ((struct varegs *)(UBA0_DEV + 0164000)) 4241Sbill 43*287Sbill /* vacsw bits */ 44*287Sbill #define ERROR 0100000 /* Some error has occurred */ 45*287Sbill #define NPRTIMO 01000 /* DMA timeout error */ 46*287Sbill #define NOTREADY 0400 /* Something besides NPRTIMO */ 47*287Sbill #define DONE 0200 48*287Sbill #define IENABLE 0100 /* Interrupt enable */ 49*287Sbill #define SUPPLIESLOW 04 50*287Sbill #define BOTOFFORM 02 51*287Sbill #define BYTEREVERSE 01 /* Reverse byte order in words */ 5241Sbill 53*287Sbill /* vacsh command bytes */ 5441Sbill #define VAPLOT 0340 5541Sbill #define VAPRINT 0100 5641Sbill #define VAPRINTPLOT 0160 5741Sbill #define VAAUTOSTEP 0244 58*287Sbill #define VANOAUTOSTEP 0045 /* unused */ 59*287Sbill #define VAFORMFEED 0263 /* unused */ 60*287Sbill #define VASLEW 0265 /* unused */ 61*287Sbill #define VASTEP 0064 /* unused */ 6241Sbill 6341Sbill struct { 64*287Sbill char va_open; 6541Sbill char va_busy; 6641Sbill int va_state; /* State: bits are commands in vcmd.h. */ 67*287Sbill int va_wc; 6841Sbill int va_bufp; 69*287Sbill struct buf *va_bp; 70*287Sbill } va11; 7141Sbill int va_ubinfo; 7241Sbill 7341Sbill struct buf rvabuf; /* Used by physio for a buffer. */ 7441Sbill 7541Sbill vaopen() 7641Sbill { 7741Sbill 78*287Sbill if (va11.va_open) { 7941Sbill u.u_error = ENXIO; 8041Sbill return; 8141Sbill } 82*287Sbill va11.va_open = 1; 83*287Sbill VAADDR->vawc = 0; 84*287Sbill va11.va_wc = 0; 85*287Sbill va11.va_state = 0; 86*287Sbill VAADDR->vacsl = IENABLE; 8741Sbill vatimo(); 88*287Sbill vacmd(VPRINT); 8941Sbill if (u.u_error) 9041Sbill vaclose(); 9141Sbill } 9241Sbill 9341Sbill vastrategy(bp) 9441Sbill register struct buf *bp; 9541Sbill { 9641Sbill register int e; 9741Sbill 98133Sbill (void) spl4(); 99*287Sbill while (va11.va_busy) 100*287Sbill sleep((caddr_t)&va11, VAPRI); 101*287Sbill va11.va_busy = 1; 102*287Sbill va11.va_bp = bp; 103*287Sbill va_ubinfo = ubasetup(bp, vabdp); 104*287Sbill va11.va_bufp = va_ubinfo & 0x3ffff; 10541Sbill if (e = vaerror(DONE)) 10641Sbill goto brkout; 107*287Sbill va11.va_wc = -(bp->b_bcount/2); 10841Sbill vastart(); 109*287Sbill e = vaerror(DONE); /* Wait for DMA to complete */ 110*287Sbill va11.va_wc = 0; 111*287Sbill va11.va_bufp = 0; 11241Sbill 113*287Sbill /* 114*287Sbill * After printing a line of characters, VPRINTPLOT mode essentially 115*287Sbill * reverts to VPLOT mode, plotting things until a new mode is set. 116*287Sbill * This change is indicated by sending a VAAUTOSTEP command to 117*287Sbill * the va. We also change va_state to reflect this effective 118*287Sbill * mode change. 11941Sbill */ 120*287Sbill if (va11.va_state & VPRINTPLOT) { 121*287Sbill va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT; 122*287Sbill VAADDR->vacsh = VAAUTOSTEP; 12341Sbill e |= vaerror(DONE); 12441Sbill } 125133Sbill (void) spl0(); 12641Sbill brkout: 12741Sbill ubafree(va_ubinfo), va_ubinfo = 0; 128*287Sbill va11.va_bp = 0; 129*287Sbill va11.va_busy = 0; 13041Sbill iodone(bp); 13141Sbill if (e) 13241Sbill u.u_error = EIO; 133*287Sbill wakeup((caddr_t)&va11); 13441Sbill } 13541Sbill 13641Sbill int vablock = 16384; 13741Sbill 13841Sbill unsigned 13941Sbill minvaph(bp) 14041Sbill struct buf *bp; 14141Sbill { 14241Sbill if (bp->b_bcount > vablock) 14341Sbill bp->b_bcount = vablock; 14441Sbill } 14541Sbill 14641Sbill /*ARGSUSED*/ 14741Sbill vawrite(dev) 14841Sbill { 14941Sbill physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph); 15041Sbill } 15141Sbill 15241Sbill /* 15341Sbill * Vaerror waits until bit or ERROR gets set, then returns non-zero if 15441Sbill * if it was ERROR that was set. 15541Sbill */ 15641Sbill vaerror(bit) 15741Sbill { 15841Sbill register int e; 15941Sbill 160*287Sbill while ((e = VAADDR->vacsw & (bit|ERROR)) == 0) 161*287Sbill sleep((caddr_t)&va11, VAPRI); 16241Sbill return (e & ERROR); 16341Sbill } 16441Sbill 16541Sbill vastart() 16641Sbill { 167*287Sbill if (va11.va_wc) { 168*287Sbill VAADDR->vaba = va11.va_bufp; 169*287Sbill VAADDR->vawc = va11.va_wc; 17041Sbill return; 17141Sbill } 17241Sbill } 17341Sbill 17441Sbill /*ARGSUSED*/ 17541Sbill vaioctl(dev, cmd, addr, flag) 17641Sbill register caddr_t addr; 17741Sbill { 17841Sbill register int vcmd; 17941Sbill 18041Sbill switch (cmd) { 18141Sbill 18241Sbill case VGETSTATE: 183*287Sbill (void) suword(addr, va11.va_state); 18441Sbill return; 18541Sbill 18641Sbill case VSETSTATE: 18741Sbill vcmd = fuword(addr); 18841Sbill if (vcmd == -1) { 18941Sbill u.u_error = EFAULT; 19041Sbill return; 19141Sbill } 19241Sbill vacmd(vcmd); 19341Sbill return; 19441Sbill 19541Sbill default: 19641Sbill u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 19741Sbill return; 19841Sbill } 19941Sbill } 20041Sbill 201*287Sbill /* 202*287Sbill * Send a command code to the va, and wait for it to complete. 203*287Sbill * If an error occurs, u.u_error is set to EIO. 204*287Sbill * In any case, update va11.va_state. 20541Sbill */ 20641Sbill vacmd(vcmd) 20741Sbill { 208133Sbill (void) spl4(); 209*287Sbill (void) vaerror(DONE); /* Wait for va to be ready */ 21041Sbill switch (vcmd) { 21141Sbill 21241Sbill case VPLOT: 21341Sbill /* Must turn on plot AND autostep modes. */ 214*287Sbill VAADDR->vacsh = VAPLOT; 21541Sbill if (vaerror(DONE)) 21641Sbill u.u_error = EIO; 217*287Sbill VAADDR->vacsh = VAAUTOSTEP; 21841Sbill break; 21941Sbill 22041Sbill case VPRINT: 221*287Sbill VAADDR->vacsh = VAPRINT; 22241Sbill break; 22341Sbill 22441Sbill case VPRINTPLOT: 225*287Sbill VAADDR->vacsh = VAPRINTPLOT; 22641Sbill break; 22741Sbill } 228*287Sbill va11.va_state = 229*287Sbill (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd; 23041Sbill 23141Sbill if (vaerror(DONE)) /* Wait for command to complete. */ 23241Sbill u.u_error = EIO; 233133Sbill (void) spl0(); 23441Sbill } 23541Sbill 23641Sbill vatimo() 23741Sbill { 238*287Sbill if (va11.va_open) 23941Sbill timeout(vatimo, (caddr_t)0, HZ/10); 24041Sbill vaintr(0); 24141Sbill } 24241Sbill 24341Sbill /*ARGSUSED*/ 24441Sbill vaintr(dev) 24541Sbill { 246*287Sbill wakeup((caddr_t)&va11); 24741Sbill } 24841Sbill 24941Sbill vaclose() 25041Sbill { 25141Sbill 252*287Sbill va11.va_open = 0; 253*287Sbill va11.va_busy = 0; 254*287Sbill va11.va_state = 0; 255*287Sbill va11.va_wc = 0; 256*287Sbill va11.va_bufp = 0; 257*287Sbill VAADDR->vacsl = 0; 25841Sbill } 259*287Sbill 260*287Sbill #define DELAY(N) { register int d; d = N; while (--d > 0); } 261*287Sbill 262*287Sbill vareset() 263*287Sbill { 264*287Sbill 265*287Sbill if (va11.va_open == 0) 266*287Sbill return; 267*287Sbill printf(" va"); 268*287Sbill VAADDR->vacsl = IENABLE; 269*287Sbill if (va11.va_state & VPLOT) { 270*287Sbill VAADDR->vacsh = VAPLOT; 271*287Sbill DELAY(10000); 272*287Sbill VAADDR->vacsh = VAAUTOSTEP; 273*287Sbill } else if (va11.va_state & VPRINTPLOT) 274*287Sbill VAADDR->vacsh = VPRINTPLOT; 275*287Sbill else 276*287Sbill VAADDR->vacsh = VAPRINTPLOT; 277*287Sbill DELAY(10000); 278*287Sbill if (va11.va_busy == 0) 279*287Sbill return; 280*287Sbill if (va_ubinfo) { 281*287Sbill printf("<%d>", (va_ubinfo>>28)&0xf); 282*287Sbill ubafree(va_ubinfo), va_ubinfo = 0; 283*287Sbill } 284*287Sbill /* This code belongs in vastart() */ 285*287Sbill va_ubinfo = ubasetup(va11.va_bp, vabdp); 286*287Sbill va11.va_bufp = va_ubinfo & 0x3ffff; 287*287Sbill va11.va_wc = (-va11.va_bp->b_bcount/2); 288*287Sbill /* End badly placed code */ 289*287Sbill vastart(); 290*287Sbill } 291