1*1938Swnj /* va.c 4.3 12/19/80 */ 241Sbill 3*1938Swnj #include "va.h" 41564Sbill #if NVA > 0 51564Sbill /* 61564Sbill * Benson-Varian matrix printer/plotter 71564Sbill * dma interface driver 81564Sbill */ 941Sbill #include "../h/param.h" 1041Sbill #include "../h/dir.h" 1141Sbill #include "../h/user.h" 1241Sbill #include "../h/buf.h" 1341Sbill #include "../h/systm.h" 1441Sbill #include "../h/map.h" 1541Sbill #include "../h/pte.h" 1641Sbill #include "../h/uba.h" 1741Sbill #include "../h/vcmd.h" 1841Sbill 19287Sbill int vabdp = 1; 2041Sbill 21287Sbill unsigned minvaph(); 2241Sbill 2341Sbill #define VAPRI (PZERO-1) 2441Sbill 25287Sbill #define ushort unsigned short 26287Sbill struct varegs { 27287Sbill ushort vaba; 28287Sbill short vawc; 2941Sbill union { 30287Sbill short Vacsw; 3141Sbill struct { 32287Sbill char Vacsl; 33287Sbill char Vacsh; 34287Sbill } vacsr; 35287Sbill } vacs; 3641Sbill short vadata; 3741Sbill }; 3841Sbill 39287Sbill #define vacsw vacs.Vacsw 40287Sbill #define vacsh vacs.vacsr.Vacsh 41287Sbill #define vacsl vacs.vacsr.Vacsl 42287Sbill 43287Sbill /* vacsw bits */ 44287Sbill #define ERROR 0100000 /* Some error has occurred */ 451564Sbill #define NPRTIMO 01000 /* DMA timeout error */ 461564Sbill #define NOTREADY 0400 /* Something besides NPRTIMO */ 471564Sbill #define DONE 0200 48287Sbill #define IENABLE 0100 /* Interrupt enable */ 49287Sbill #define SUPPLIESLOW 04 501564Sbill #define BOTOFFORM 02 511564Sbill #define BYTEREVERSE 01 /* Reverse byte order in words */ 5241Sbill 53287Sbill /* vacsh command bytes */ 541564Sbill #define VAPLOT 0340 551564Sbill #define VAPRINT 0100 561564Sbill #define VAPRINTPLOT 0160 571564Sbill #define VAAUTOSTEP 0244 581564Sbill #define VANOAUTOSTEP 0045 /* unused */ 59287Sbill #define VAFORMFEED 0263 /* unused */ 60287Sbill #define VASLEW 0265 /* unused */ 61287Sbill #define VASTEP 0064 /* unused */ 6241Sbill 6341Sbill struct { 64287Sbill char va_open; 6541Sbill char va_busy; 6641Sbill int va_state; /* State: bits are commands in vcmd.h. */ 67287Sbill int va_wc; 6841Sbill int va_bufp; 69287Sbill struct buf *va_bp; 70287Sbill } va11; 7141Sbill int va_ubinfo; 7241Sbill 7341Sbill struct buf rvabuf; /* Used by physio for a buffer. */ 7441Sbill 7541Sbill vaopen() 7641Sbill { 7741Sbill 78287Sbill if (va11.va_open) { 7941Sbill u.u_error = ENXIO; 8041Sbill return; 8141Sbill } 82287Sbill va11.va_open = 1; 83287Sbill VAADDR->vawc = 0; 84287Sbill va11.va_wc = 0; 85287Sbill va11.va_state = 0; 86287Sbill VAADDR->vacsl = IENABLE; 8741Sbill vatimo(); 88287Sbill 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(); 99287Sbill while (va11.va_busy) 100287Sbill sleep((caddr_t)&va11, VAPRI); 101287Sbill va11.va_busy = 1; 102287Sbill va11.va_bp = bp; 103287Sbill va_ubinfo = ubasetup(bp, vabdp); 104287Sbill va11.va_bufp = va_ubinfo & 0x3ffff; 10541Sbill if (e = vaerror(DONE)) 10641Sbill goto brkout; 107287Sbill va11.va_wc = -(bp->b_bcount/2); 10841Sbill vastart(); 109287Sbill e = vaerror(DONE); /* Wait for DMA to complete */ 110287Sbill va11.va_wc = 0; 111287Sbill va11.va_bufp = 0; 11241Sbill 113287Sbill /* 114287Sbill * After printing a line of characters, VPRINTPLOT mode essentially 115287Sbill * reverts to VPLOT mode, plotting things until a new mode is set. 116287Sbill * This change is indicated by sending a VAAUTOSTEP command to 117287Sbill * the va. We also change va_state to reflect this effective 118287Sbill * mode change. 11941Sbill */ 120287Sbill if (va11.va_state & VPRINTPLOT) { 121287Sbill va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT; 122287Sbill VAADDR->vacsh = VAAUTOSTEP; 12341Sbill e |= vaerror(DONE); 12441Sbill } 125133Sbill (void) spl0(); 12641Sbill brkout: 12741Sbill ubafree(va_ubinfo), va_ubinfo = 0; 128287Sbill va11.va_bp = 0; 129287Sbill va11.va_busy = 0; 13041Sbill iodone(bp); 13141Sbill if (e) 13241Sbill u.u_error = EIO; 133287Sbill 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 160287Sbill while ((e = VAADDR->vacsw & (bit|ERROR)) == 0) 161287Sbill sleep((caddr_t)&va11, VAPRI); 16241Sbill return (e & ERROR); 16341Sbill } 16441Sbill 16541Sbill vastart() 16641Sbill { 167287Sbill if (va11.va_wc) { 168287Sbill VAADDR->vaba = va11.va_bufp; 1691903Swnj VAADDR->vacsl = (va11.va_bufp >> 12) & 0x30; 170287Sbill VAADDR->vawc = va11.va_wc; 17141Sbill return; 17241Sbill } 17341Sbill } 17441Sbill 17541Sbill /*ARGSUSED*/ 17641Sbill vaioctl(dev, cmd, addr, flag) 17741Sbill register caddr_t addr; 17841Sbill { 17941Sbill register int vcmd; 18041Sbill 18141Sbill switch (cmd) { 18241Sbill 18341Sbill case VGETSTATE: 184287Sbill (void) suword(addr, va11.va_state); 18541Sbill return; 18641Sbill 18741Sbill case VSETSTATE: 18841Sbill vcmd = fuword(addr); 18941Sbill if (vcmd == -1) { 19041Sbill u.u_error = EFAULT; 19141Sbill return; 19241Sbill } 19341Sbill vacmd(vcmd); 19441Sbill return; 19541Sbill 19641Sbill default: 19741Sbill u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ 19841Sbill return; 19941Sbill } 20041Sbill } 20141Sbill 202287Sbill /* 203287Sbill * Send a command code to the va, and wait for it to complete. 204287Sbill * If an error occurs, u.u_error is set to EIO. 205287Sbill * In any case, update va11.va_state. 20641Sbill */ 20741Sbill vacmd(vcmd) 20841Sbill { 209133Sbill (void) spl4(); 210287Sbill (void) vaerror(DONE); /* Wait for va to be ready */ 21141Sbill switch (vcmd) { 21241Sbill 21341Sbill case VPLOT: 21441Sbill /* Must turn on plot AND autostep modes. */ 215287Sbill VAADDR->vacsh = VAPLOT; 21641Sbill if (vaerror(DONE)) 21741Sbill u.u_error = EIO; 218287Sbill VAADDR->vacsh = VAAUTOSTEP; 21941Sbill break; 22041Sbill 22141Sbill case VPRINT: 222287Sbill VAADDR->vacsh = VAPRINT; 22341Sbill break; 22441Sbill 22541Sbill case VPRINTPLOT: 226287Sbill VAADDR->vacsh = VAPRINTPLOT; 22741Sbill break; 22841Sbill } 229287Sbill va11.va_state = 230287Sbill (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd; 23141Sbill 23241Sbill if (vaerror(DONE)) /* Wait for command to complete. */ 23341Sbill u.u_error = EIO; 234133Sbill (void) spl0(); 23541Sbill } 23641Sbill 23741Sbill vatimo() 23841Sbill { 239287Sbill if (va11.va_open) 24041Sbill timeout(vatimo, (caddr_t)0, HZ/10); 24141Sbill vaintr(0); 24241Sbill } 24341Sbill 24441Sbill /*ARGSUSED*/ 24541Sbill vaintr(dev) 24641Sbill { 247287Sbill wakeup((caddr_t)&va11); 24841Sbill } 24941Sbill 25041Sbill vaclose() 25141Sbill { 25241Sbill 253287Sbill va11.va_open = 0; 254287Sbill va11.va_busy = 0; 255287Sbill va11.va_state = 0; 256287Sbill va11.va_wc = 0; 257287Sbill va11.va_bufp = 0; 258287Sbill VAADDR->vacsl = 0; 25941Sbill } 260287Sbill 261287Sbill #define DELAY(N) { register int d; d = N; while (--d > 0); } 262287Sbill 263287Sbill vareset() 264287Sbill { 265287Sbill 266287Sbill if (va11.va_open == 0) 267287Sbill return; 268287Sbill printf(" va"); 269287Sbill VAADDR->vacsl = IENABLE; 270287Sbill if (va11.va_state & VPLOT) { 271287Sbill VAADDR->vacsh = VAPLOT; 272287Sbill DELAY(10000); 273287Sbill VAADDR->vacsh = VAAUTOSTEP; 274287Sbill } else if (va11.va_state & VPRINTPLOT) 275287Sbill VAADDR->vacsh = VPRINTPLOT; 276287Sbill else 277287Sbill VAADDR->vacsh = VAPRINTPLOT; 278287Sbill DELAY(10000); 279287Sbill if (va11.va_busy == 0) 280287Sbill return; 281287Sbill if (va_ubinfo) { 282287Sbill printf("<%d>", (va_ubinfo>>28)&0xf); 283287Sbill ubafree(va_ubinfo), va_ubinfo = 0; 284287Sbill } 285287Sbill /* This code belongs in vastart() */ 286287Sbill va_ubinfo = ubasetup(va11.va_bp, vabdp); 287287Sbill va11.va_bufp = va_ubinfo & 0x3ffff; 288287Sbill va11.va_wc = (-va11.va_bp->b_bcount/2); 289287Sbill /* End badly placed code */ 290287Sbill vastart(); 291287Sbill } 2921564Sbill #endif 293