|
|
1.1 ! root 1: /* va.c 4.1 11/9/80 */ ! 2: ! 3: #include "../conf/va.h" ! 4: #if NVA > 0 ! 5: /* ! 6: * Benson-Varian matrix printer/plotter ! 7: * dma interface driver ! 8: */ ! 9: #include "../h/param.h" ! 10: #include "../h/dir.h" ! 11: #include "../h/user.h" ! 12: #include "../h/buf.h" ! 13: #include "../h/systm.h" ! 14: #include "../h/map.h" ! 15: #include "../h/pte.h" ! 16: #include "../h/uba.h" ! 17: #include "../h/vcmd.h" ! 18: ! 19: int vabdp = 1; ! 20: ! 21: unsigned minvaph(); ! 22: ! 23: #define VAPRI (PZERO-1) ! 24: ! 25: #define ushort unsigned short ! 26: struct varegs { ! 27: ushort vaba; ! 28: short vawc; ! 29: union { ! 30: short Vacsw; ! 31: struct { ! 32: char Vacsl; ! 33: char Vacsh; ! 34: } vacsr; ! 35: } vacs; ! 36: short vadata; ! 37: }; ! 38: ! 39: #define vacsw vacs.Vacsw ! 40: #define vacsh vacs.vacsr.Vacsh ! 41: #define vacsl vacs.vacsr.Vacsl ! 42: ! 43: /* vacsw bits */ ! 44: #define ERROR 0100000 /* Some error has occurred */ ! 45: #define NPRTIMO 01000 /* DMA timeout error */ ! 46: #define NOTREADY 0400 /* Something besides NPRTIMO */ ! 47: #define DONE 0200 ! 48: #define IENABLE 0100 /* Interrupt enable */ ! 49: #define SUPPLIESLOW 04 ! 50: #define BOTOFFORM 02 ! 51: #define BYTEREVERSE 01 /* Reverse byte order in words */ ! 52: ! 53: /* vacsh command bytes */ ! 54: #define VAPLOT 0340 ! 55: #define VAPRINT 0100 ! 56: #define VAPRINTPLOT 0160 ! 57: #define VAAUTOSTEP 0244 ! 58: #define VANOAUTOSTEP 0045 /* unused */ ! 59: #define VAFORMFEED 0263 /* unused */ ! 60: #define VASLEW 0265 /* unused */ ! 61: #define VASTEP 0064 /* unused */ ! 62: ! 63: struct { ! 64: char va_open; ! 65: char va_busy; ! 66: int va_state; /* State: bits are commands in vcmd.h. */ ! 67: int va_wc; ! 68: int va_bufp; ! 69: struct buf *va_bp; ! 70: } va11; ! 71: int va_ubinfo; ! 72: ! 73: struct buf rvabuf; /* Used by physio for a buffer. */ ! 74: ! 75: vaopen() ! 76: { ! 77: ! 78: if (va11.va_open) { ! 79: u.u_error = ENXIO; ! 80: return; ! 81: } ! 82: va11.va_open = 1; ! 83: VAADDR->vawc = 0; ! 84: va11.va_wc = 0; ! 85: va11.va_state = 0; ! 86: VAADDR->vacsl = IENABLE; ! 87: vatimo(); ! 88: vacmd(VPRINT); ! 89: if (u.u_error) ! 90: vaclose(); ! 91: } ! 92: ! 93: vastrategy(bp) ! 94: register struct buf *bp; ! 95: { ! 96: register int e; ! 97: ! 98: (void) spl4(); ! 99: while (va11.va_busy) ! 100: sleep((caddr_t)&va11, VAPRI); ! 101: va11.va_busy = 1; ! 102: va11.va_bp = bp; ! 103: va_ubinfo = ubasetup(bp, vabdp); ! 104: va11.va_bufp = va_ubinfo & 0x3ffff; ! 105: if (e = vaerror(DONE)) ! 106: goto brkout; ! 107: va11.va_wc = -(bp->b_bcount/2); ! 108: vastart(); ! 109: e = vaerror(DONE); /* Wait for DMA to complete */ ! 110: va11.va_wc = 0; ! 111: va11.va_bufp = 0; ! 112: ! 113: /* ! 114: * After printing a line of characters, VPRINTPLOT mode essentially ! 115: * reverts to VPLOT mode, plotting things until a new mode is set. ! 116: * This change is indicated by sending a VAAUTOSTEP command to ! 117: * the va. We also change va_state to reflect this effective ! 118: * mode change. ! 119: */ ! 120: if (va11.va_state & VPRINTPLOT) { ! 121: va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT; ! 122: VAADDR->vacsh = VAAUTOSTEP; ! 123: e |= vaerror(DONE); ! 124: } ! 125: (void) spl0(); ! 126: brkout: ! 127: ubafree(va_ubinfo), va_ubinfo = 0; ! 128: va11.va_bp = 0; ! 129: va11.va_busy = 0; ! 130: iodone(bp); ! 131: if (e) ! 132: u.u_error = EIO; ! 133: wakeup((caddr_t)&va11); ! 134: } ! 135: ! 136: int vablock = 16384; ! 137: ! 138: unsigned ! 139: minvaph(bp) ! 140: struct buf *bp; ! 141: { ! 142: if (bp->b_bcount > vablock) ! 143: bp->b_bcount = vablock; ! 144: } ! 145: ! 146: /*ARGSUSED*/ ! 147: vawrite(dev) ! 148: { ! 149: physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph); ! 150: } ! 151: ! 152: /* ! 153: * Vaerror waits until bit or ERROR gets set, then returns non-zero if ! 154: * if it was ERROR that was set. ! 155: */ ! 156: vaerror(bit) ! 157: { ! 158: register int e; ! 159: ! 160: while ((e = VAADDR->vacsw & (bit|ERROR)) == 0) ! 161: sleep((caddr_t)&va11, VAPRI); ! 162: return (e & ERROR); ! 163: } ! 164: ! 165: vastart() ! 166: { ! 167: if (va11.va_wc) { ! 168: VAADDR->vaba = va11.va_bufp; ! 169: VAADDR->vawc = va11.va_wc; ! 170: return; ! 171: } ! 172: } ! 173: ! 174: /*ARGSUSED*/ ! 175: vaioctl(dev, cmd, addr, flag) ! 176: register caddr_t addr; ! 177: { ! 178: register int vcmd; ! 179: ! 180: switch (cmd) { ! 181: ! 182: case VGETSTATE: ! 183: (void) suword(addr, va11.va_state); ! 184: return; ! 185: ! 186: case VSETSTATE: ! 187: vcmd = fuword(addr); ! 188: if (vcmd == -1) { ! 189: u.u_error = EFAULT; ! 190: return; ! 191: } ! 192: vacmd(vcmd); ! 193: return; ! 194: ! 195: default: ! 196: u.u_error = ENOTTY; /* Not a legal ioctl cmd. */ ! 197: return; ! 198: } ! 199: } ! 200: ! 201: /* ! 202: * Send a command code to the va, and wait for it to complete. ! 203: * If an error occurs, u.u_error is set to EIO. ! 204: * In any case, update va11.va_state. ! 205: */ ! 206: vacmd(vcmd) ! 207: { ! 208: (void) spl4(); ! 209: (void) vaerror(DONE); /* Wait for va to be ready */ ! 210: switch (vcmd) { ! 211: ! 212: case VPLOT: ! 213: /* Must turn on plot AND autostep modes. */ ! 214: VAADDR->vacsh = VAPLOT; ! 215: if (vaerror(DONE)) ! 216: u.u_error = EIO; ! 217: VAADDR->vacsh = VAAUTOSTEP; ! 218: break; ! 219: ! 220: case VPRINT: ! 221: VAADDR->vacsh = VAPRINT; ! 222: break; ! 223: ! 224: case VPRINTPLOT: ! 225: VAADDR->vacsh = VAPRINTPLOT; ! 226: break; ! 227: } ! 228: va11.va_state = ! 229: (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd; ! 230: ! 231: if (vaerror(DONE)) /* Wait for command to complete. */ ! 232: u.u_error = EIO; ! 233: (void) spl0(); ! 234: } ! 235: ! 236: vatimo() ! 237: { ! 238: if (va11.va_open) ! 239: timeout(vatimo, (caddr_t)0, HZ/10); ! 240: vaintr(0); ! 241: } ! 242: ! 243: /*ARGSUSED*/ ! 244: vaintr(dev) ! 245: { ! 246: wakeup((caddr_t)&va11); ! 247: } ! 248: ! 249: vaclose() ! 250: { ! 251: ! 252: va11.va_open = 0; ! 253: va11.va_busy = 0; ! 254: va11.va_state = 0; ! 255: va11.va_wc = 0; ! 256: va11.va_bufp = 0; ! 257: VAADDR->vacsl = 0; ! 258: } ! 259: ! 260: #define DELAY(N) { register int d; d = N; while (--d > 0); } ! 261: ! 262: vareset() ! 263: { ! 264: ! 265: if (va11.va_open == 0) ! 266: return; ! 267: printf(" va"); ! 268: VAADDR->vacsl = IENABLE; ! 269: if (va11.va_state & VPLOT) { ! 270: VAADDR->vacsh = VAPLOT; ! 271: DELAY(10000); ! 272: VAADDR->vacsh = VAAUTOSTEP; ! 273: } else if (va11.va_state & VPRINTPLOT) ! 274: VAADDR->vacsh = VPRINTPLOT; ! 275: else ! 276: VAADDR->vacsh = VAPRINTPLOT; ! 277: DELAY(10000); ! 278: if (va11.va_busy == 0) ! 279: return; ! 280: if (va_ubinfo) { ! 281: printf("<%d>", (va_ubinfo>>28)&0xf); ! 282: ubafree(va_ubinfo), va_ubinfo = 0; ! 283: } ! 284: /* This code belongs in vastart() */ ! 285: va_ubinfo = ubasetup(va11.va_bp, vabdp); ! 286: va11.va_bufp = va_ubinfo & 0x3ffff; ! 287: va11.va_wc = (-va11.va_bp->b_bcount/2); ! 288: /* End badly placed code */ ! 289: vastart(); ! 290: } ! 291: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.