|
|
1.1 ! root 1: /* va.c 4.10 81/07/08 */ ! 2: ! 3: #include "va.h" ! 4: #if NVA > 0 ! 5: /* ! 6: * Varian printer plotter ! 7: */ ! 8: #include "../h/param.h" ! 9: #include "../h/dir.h" ! 10: #include "../h/user.h" ! 11: #include "../h/buf.h" ! 12: #include "../h/systm.h" ! 13: #include "../h/map.h" ! 14: #include "../h/pte.h" ! 15: #include "../h/ubareg.h" ! 16: #include "../h/ubavar.h" ! 17: #include "../h/vcmd.h" ! 18: ! 19: unsigned minvaph(); ! 20: ! 21: #define VAPRI (PZERO-1) ! 22: ! 23: struct vadevice { ! 24: u_short vaba; /* buffer address */ ! 25: short vawc; /* word count (2's complement) */ ! 26: union { ! 27: short Vacsw; /* control status as word */ ! 28: struct { /* control status as bytes */ ! 29: char Vacsl; ! 30: char Vacsh; ! 31: } vacsr; ! 32: } vacs; ! 33: short vadata; /* programmed i/o data buffer */ ! 34: }; ! 35: ! 36: #define vacsw vacs.Vacsw ! 37: #define vacsh vacs.vacsr.Vacsh ! 38: #define vacsl vacs.vacsr.Vacsl ! 39: ! 40: /* vacsw bits */ ! 41: #define VA_ERROR 0100000 /* some error has occurred */ ! 42: #define VA_NPRTIMO 0001000 /* DMA timeout error */ ! 43: #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ ! 44: #define VA_DONE 0000200 ! 45: #define VA_IENABLE 0000100 /* interrupt enable */ ! 46: #define VA_SUPPLIESLOW 0000004 ! 47: #define VA_BOTOFFORM 0000002 ! 48: #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ ! 49: ! 50: /* vacsh command bytes */ ! 51: #define VAPLOT 0000340 ! 52: #define VAPRINT 0000100 ! 53: #define VAPRINTPLOT 0000160 ! 54: #define VAAUTOSTEP 0000244 ! 55: #define VANOAUTOSTEP 0000045 ! 56: #define VAFORMFEED 0000263 ! 57: #define VASLEW 0000265 ! 58: #define VASTEP 0000064 ! 59: ! 60: struct va_softc { ! 61: char sc_openf; ! 62: char sc_busy; ! 63: int sc_state; ! 64: int sc_wc; ! 65: struct buf *sc_bp; ! 66: int sc_ubinfo; ! 67: } va_softc[NVA]; ! 68: ! 69: #define VAUNIT(dev) (minor(dev)) ! 70: ! 71: struct buf rvabuf[NVA]; ! 72: ! 73: int vaprobe(), vaattach(); ! 74: struct uba_device *vadinfo[NVA]; ! 75: u_short vastd[] = { 0764000, 0 }; ! 76: struct uba_driver vadriver = ! 77: { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; ! 78: ! 79: vaprobe(reg) ! 80: caddr_t reg; ! 81: { ! 82: register int br, cvec; /* value-result */ ! 83: register struct vadevice *vaaddr = (struct vadevice *)reg; ! 84: ! 85: vaaddr->vacsl = VA_IENABLE; ! 86: vaaddr->vaba = 0; ! 87: vaaddr->vacsh = VAPLOT; ! 88: vaaddr->vacsl = 0; ! 89: vaaddr->vawc = -1; ! 90: DELAY(10000); ! 91: vaaddr->vacsl = 0; ! 92: } ! 93: ! 94: /*ARGSUSED*/ ! 95: vaattach(ui) ! 96: struct uba_device *ui; ! 97: { ! 98: ! 99: } ! 100: ! 101: vaopen(dev) ! 102: dev_t dev; ! 103: { ! 104: register struct va_softc *sc; ! 105: register struct vadevice *vaaddr; ! 106: register struct uba_device *ui; ! 107: ! 108: if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || ! 109: (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { ! 110: u.u_error = ENXIO; ! 111: return; ! 112: } ! 113: vaaddr = (struct vadevice *)ui->ui_addr; ! 114: sc->sc_openf = 1; ! 115: vaaddr->vawc = 0; ! 116: sc->sc_wc = 0; ! 117: sc->sc_state = 0; ! 118: vaaddr->vacsl = VA_IENABLE; ! 119: vatimo(dev); ! 120: vacmd(dev, VPRINT); ! 121: if (u.u_error) ! 122: vaclose(dev); ! 123: } ! 124: ! 125: vastrategy(bp) ! 126: register struct buf *bp; ! 127: { ! 128: register int e; ! 129: register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; ! 130: register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; ! 131: register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; ! 132: ! 133: (void) spl4(); ! 134: while (sc->sc_busy) ! 135: sleep((caddr_t)sc, VAPRI); ! 136: sc->sc_busy = 1; ! 137: sc->sc_bp = bp; ! 138: sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); ! 139: if (e = vawait(bp->b_dev)) ! 140: goto brkout; ! 141: sc->sc_wc = -(bp->b_bcount/2); ! 142: vastart(bp->b_dev); ! 143: e = vawait(bp->b_dev); ! 144: sc->sc_wc = 0; ! 145: if (sc->sc_state & VPRINTPLOT) { ! 146: sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; ! 147: vaaddr->vacsh = VAAUTOSTEP; ! 148: e |= vawait(bp->b_dev); ! 149: } ! 150: (void) spl0(); ! 151: brkout: ! 152: ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); ! 153: sc->sc_bp = 0; ! 154: sc->sc_busy = 0; ! 155: iodone(bp); ! 156: if (e) ! 157: u.u_error = EIO; ! 158: wakeup((caddr_t)sc); ! 159: } ! 160: ! 161: int vablock = 16384; ! 162: ! 163: unsigned ! 164: minvaph(bp) ! 165: struct buf *bp; ! 166: { ! 167: ! 168: if (bp->b_bcount > vablock) ! 169: bp->b_bcount = vablock; ! 170: } ! 171: ! 172: /*ARGSUSED*/ ! 173: vawrite(dev) ! 174: dev_t dev; ! 175: { ! 176: ! 177: physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph); ! 178: } ! 179: ! 180: vawait(dev) ! 181: dev_t dev; ! 182: { ! 183: register struct vadevice *vaaddr = ! 184: (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; ! 185: register int e; ! 186: ! 187: while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) ! 188: sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); ! 189: if (e & VA_NPRTIMO) ! 190: printf("va%d: npr timeout\n", VAUNIT(dev)); ! 191: return (e & VA_ERROR); ! 192: } ! 193: ! 194: vastart(dev) ! 195: dev_t; ! 196: { ! 197: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 198: register struct vadevice *vaaddr = ! 199: (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; ! 200: ! 201: if (sc->sc_wc == 0) ! 202: return; ! 203: vaaddr->vaba = sc->sc_ubinfo; ! 204: vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; ! 205: vaaddr->vawc = sc->sc_wc; ! 206: } ! 207: ! 208: /*ARGSUSED*/ ! 209: vaioctl(dev, cmd, addr, flag) ! 210: register caddr_t addr; ! 211: { ! 212: register int vcmd; ! 213: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 214: ! 215: switch (cmd) { ! 216: ! 217: case VGETSTATE: ! 218: (void) suword(addr, sc->sc_state); ! 219: return; ! 220: ! 221: case VSETSTATE: ! 222: vcmd = fuword(addr); ! 223: if (vcmd == -1) { ! 224: u.u_error = EFAULT; ! 225: return; ! 226: } ! 227: vacmd(dev, vcmd); ! 228: return; ! 229: ! 230: default: ! 231: u.u_error = ENOTTY; ! 232: return; ! 233: } ! 234: } ! 235: ! 236: vacmd(dev, vcmd) ! 237: dev_t dev; ! 238: int vcmd; ! 239: { ! 240: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 241: register struct vadevice *vaaddr = ! 242: (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; ! 243: ! 244: (void) spl4(); ! 245: (void) vawait(dev); ! 246: switch (vcmd) { ! 247: ! 248: case VPLOT: ! 249: /* Must turn on plot AND autostep modes. */ ! 250: vaaddr->vacsh = VAPLOT; ! 251: if (vawait(dev)) ! 252: u.u_error = EIO; ! 253: vaaddr->vacsh = VAAUTOSTEP; ! 254: break; ! 255: ! 256: case VPRINT: ! 257: vaaddr->vacsh = VAPRINT; ! 258: break; ! 259: ! 260: case VPRINTPLOT: ! 261: vaaddr->vacsh = VAPRINTPLOT; ! 262: break; ! 263: } ! 264: sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; ! 265: if (vawait(dev)) ! 266: u.u_error = EIO; ! 267: (void) spl0(); ! 268: } ! 269: ! 270: vatimo(dev) ! 271: dev_t dev; ! 272: { ! 273: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 274: ! 275: if (sc->sc_openf) ! 276: timeout(vatimo, (caddr_t)dev, hz/10); ! 277: vaintr(dev); ! 278: } ! 279: ! 280: /*ARGSUSED*/ ! 281: vaintr(dev) ! 282: dev_t dev; ! 283: { ! 284: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 285: ! 286: wakeup((caddr_t)sc); ! 287: } ! 288: ! 289: vaclose(dev) ! 290: dev_t dev; ! 291: { ! 292: register struct va_softc *sc = &va_softc[VAUNIT(dev)]; ! 293: register struct vadevice *vaaddr = ! 294: (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; ! 295: ! 296: sc->sc_openf = 0; ! 297: sc->sc_busy = 0; ! 298: sc->sc_state = 0; ! 299: sc->sc_ubinfo = 0; ! 300: vaaddr->vacsl = 0; ! 301: } ! 302: ! 303: vareset(uban) ! 304: int uban; ! 305: { ! 306: register int va11; ! 307: register struct uba_device *ui; ! 308: register struct va_softc *sc = va_softc; ! 309: register struct vadevice *vaaddr; ! 310: ! 311: for (va11 = 0; va11 < NVA; va11++, sc++) { ! 312: if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || ! 313: ui->ui_ubanum != uban || sc->sc_openf == 0) ! 314: continue; ! 315: printf(" va%d", va11); ! 316: vaaddr = (struct vadevice *)ui->ui_addr; ! 317: vaaddr->vacsl = VA_IENABLE; ! 318: if (sc->sc_state & VPLOT) { ! 319: vaaddr->vacsh = VAPLOT; ! 320: DELAY(10000); ! 321: vaaddr->vacsh = VAAUTOSTEP; ! 322: } else if (sc->sc_state & VPRINTPLOT) ! 323: vaaddr->vacsh = VPRINTPLOT; ! 324: else ! 325: vaaddr->vacsh = VAPRINTPLOT; ! 326: DELAY(10000); ! 327: if (sc->sc_busy == 0) ! 328: continue; ! 329: if (sc->sc_ubinfo) { ! 330: printf("<%d>", (sc->sc_ubinfo>>28)&0xf); ! 331: ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); ! 332: } ! 333: sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); ! 334: sc->sc_wc = -(sc->sc_bp->b_bcount/2); ! 335: vastart(sc->sc_bp->b_dev); ! 336: } ! 337: } ! 338: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.