|
|
1.1 ! root 1: /* vp.c 6.3 83/09/25 */ ! 2: ! 3: #include "vp.h" ! 4: #if NVP > 0 ! 5: /* ! 6: * Versatec matrix printer/plotter ! 7: * dma interface driver ! 8: * ! 9: * SETUP NOTES: ! 10: * Set up both print and plot interrupts to go through the same vector ! 11: * (or kludge probe to reset second vector to first; ! 12: * default 174/200 is already handled). ! 13: * Give the address of the plcsr register in the config specification ! 14: */ ! 15: #include "../machine/pte.h" ! 16: ! 17: #include "../h/param.h" ! 18: #include "../h/dir.h" ! 19: #include "../h/user.h" ! 20: #include "../h/buf.h" ! 21: #include "../h/systm.h" ! 22: #include "../h/map.h" ! 23: #include "../h/ioctl.h" ! 24: #include "../h/vcmd.h" ! 25: #include "../h/uio.h" ! 26: #include "../h/kernel.h" ! 27: ! 28: #include "../vaxuba/ubavar.h" ! 29: #include "../vaxuba/ubareg.h" ! 30: ! 31: unsigned minvpph(); ! 32: ! 33: #define VPPRI (PZERO-1) ! 34: ! 35: struct vpdevice { ! 36: short plbcr; ! 37: short pbxaddr; ! 38: short prbcr; ! 39: u_short pbaddr; ! 40: short plcsr; ! 41: short plbuf; ! 42: short prcsr; ! 43: u_short prbuf; ! 44: }; ! 45: ! 46: #define VP_ERROR 0100000 ! 47: #define VP_DTCINTR 0040000 ! 48: #define VP_DMAACT 0020000 ! 49: #define VP_READY 0000200 ! 50: #define VP_IENABLE 0000100 ! 51: #define VP_TERMCOM 0000040 ! 52: #define VP_FFCOM 0000020 ! 53: #define VP_EOTCOM 0000010 ! 54: #define VP_CLRCOM 0000004 ! 55: #define VP_RESET 0000002 ! 56: #define VP_SPP 0000001 ! 57: ! 58: struct vp_softc { ! 59: int sc_state; ! 60: int sc_count; ! 61: int sc_bufp; ! 62: struct buf *sc_bp; ! 63: int sc_ubinfo; ! 64: } vp_softc[NVP]; ! 65: ! 66: /* sc_state bits */ ! 67: #define VPSC_BUSY 0001000 ! 68: #define VPSC_MODE 0000700 ! 69: #define VPSC_SPP 0000400 ! 70: #define VPSC_PLOT 0000200 ! 71: #define VPSC_PRINT 0000100 ! 72: #define VPSC_CMNDS 0000076 ! 73: #define VPSC_OPEN 0000001 ! 74: ! 75: struct uba_device *vpdinfo[NVP]; ! 76: ! 77: #define VPUNIT(dev) (minor(dev)) ! 78: ! 79: struct buf rvpbuf[NVP]; ! 80: ! 81: int vpprobe(), vpattach(); ! 82: struct uba_device *vpdinfo[NVP]; ! 83: u_short vpstd[] = { 0777500, 0 }; ! 84: struct uba_driver vpdriver = ! 85: { vpprobe, 0, vpattach, 0, vpstd, "vp", vpdinfo }; ! 86: ! 87: vpprobe(reg) ! 88: caddr_t reg; ! 89: { ! 90: register int br, cvec; /* value-result */ ! 91: register struct vpdevice *vpaddr = (struct vpdevice *)(reg-010); ! 92: ! 93: #ifdef lint ! 94: br = 0; cvec = br; br = cvec; ! 95: vpintr(0); ! 96: #endif ! 97: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR; ! 98: vpaddr->pbaddr = 0; ! 99: vpaddr->pbxaddr = 0; ! 100: vpaddr->prbcr = 1; ! 101: DELAY(10000); ! 102: vpaddr->prcsr = 0; ! 103: /* GET INTERRUPT AT SECOND VECTOR BUT WANT FIRST */ ! 104: if (cvec == 0200) { ! 105: printf("vp reset vec from 200 to 174\n"); ! 106: cvec = 0174; ! 107: } ! 108: return (sizeof (struct vpdevice)); ! 109: } ! 110: ! 111: /*ARGSUSED*/ ! 112: vpattach(ui) ! 113: struct uba_device *ui; ! 114: { ! 115: ! 116: ui->ui_addr -= 010; ! 117: ui->ui_physaddr -= 010; ! 118: } ! 119: ! 120: vpopen(dev) ! 121: dev_t dev; ! 122: { ! 123: register struct vp_softc *sc; ! 124: register struct vpdevice *vpaddr; ! 125: register struct uba_device *ui; ! 126: ! 127: if (VPUNIT(dev) >= NVP || ! 128: ((sc = &vp_softc[minor(dev)])->sc_state&VPSC_OPEN) || ! 129: (ui = vpdinfo[VPUNIT(dev)]) == 0 || ui->ui_alive == 0) ! 130: return (ENXIO); ! 131: vpaddr = (struct vpdevice *)ui->ui_addr; ! 132: sc->sc_state = VPSC_OPEN|VPSC_PRINT | VP_CLRCOM|VP_RESET; ! 133: sc->sc_count = 0; ! 134: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR; ! 135: vptimo(dev); ! 136: while (sc->sc_state & VPSC_CMNDS) { ! 137: (void) spl4(); ! 138: if (vpwait(dev)) { ! 139: vpclose(dev); ! 140: return (EIO); ! 141: } ! 142: vpstart(dev); ! 143: (void) spl0(); ! 144: } ! 145: return (0); ! 146: } ! 147: ! 148: vpstrategy(bp) ! 149: register struct buf *bp; ! 150: { ! 151: register int e; ! 152: register struct vp_softc *sc = &vp_softc[VPUNIT(bp->b_dev)]; ! 153: register struct uba_device *ui = vpdinfo[VPUNIT(bp->b_dev)]; ! 154: register struct vpdevice *vpaddr = (struct vpdevice *)ui->ui_addr; ! 155: ! 156: (void) spl4(); ! 157: while (sc->sc_state & VPSC_BUSY) ! 158: sleep((caddr_t)sc, VPPRI); ! 159: sc->sc_state |= VPSC_BUSY; ! 160: sc->sc_bp = bp; ! 161: sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); ! 162: if (e = vpwait(bp->b_dev)) ! 163: goto brkout; ! 164: sc->sc_count = bp->b_bcount; ! 165: vpstart(bp->b_dev); ! 166: while (((sc->sc_state&VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr) & VP_DMAACT) ! 167: sleep((caddr_t)sc, VPPRI); ! 168: sc->sc_count = 0; ! 169: if ((sc->sc_state&VPSC_MODE) == VPSC_SPP) ! 170: sc->sc_state = (sc->sc_state &~ VPSC_MODE) | VPSC_PLOT; ! 171: (void) spl0(); ! 172: brkout: ! 173: ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); ! 174: sc->sc_state &= ~VPSC_BUSY; ! 175: sc->sc_bp = 0; ! 176: if (e) ! 177: bp->b_flags |= B_ERROR; ! 178: iodone(bp); ! 179: wakeup((caddr_t)sc); ! 180: } ! 181: ! 182: int vpblock = 16384; ! 183: ! 184: unsigned ! 185: minvpph(bp) ! 186: struct buf *bp; ! 187: { ! 188: ! 189: if (bp->b_bcount > vpblock) ! 190: bp->b_bcount = vpblock; ! 191: } ! 192: ! 193: /*ARGSUSED*/ ! 194: vpwrite(dev, uio) ! 195: dev_t dev; ! 196: struct uio *uio; ! 197: { ! 198: ! 199: if (VPUNIT(dev) >= NVP) ! 200: return (ENXIO); ! 201: return (physio(vpstrategy, &rvpbuf[VPUNIT(dev)], dev, B_WRITE, ! 202: minvpph, uio)); ! 203: } ! 204: ! 205: vpwait(dev) ! 206: dev_t dev; ! 207: { ! 208: register struct vpdevice *vpaddr = ! 209: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr; ! 210: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 211: register int e; ! 212: ! 213: for (;;) { ! 214: e = (sc->sc_state & VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr; ! 215: if (e & (VP_READY|VP_ERROR)) ! 216: break; ! 217: sleep((caddr_t)sc, VPPRI); ! 218: } ! 219: /* I WISH I COULD TELL WHETHER AN ERROR INDICATED AN NPR TIMEOUT */ ! 220: return (e & VP_ERROR); ! 221: } ! 222: ! 223: vpstart(dev) ! 224: dev_t; ! 225: { ! 226: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 227: register struct vpdevice *vpaddr = ! 228: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr; ! 229: short bit; ! 230: ! 231: if (sc->sc_count) { ! 232: vpaddr->pbaddr = sc->sc_ubinfo; ! 233: vpaddr->pbxaddr = (sc->sc_ubinfo>>12)&0x30; ! 234: if (sc->sc_state & (VPSC_PRINT|VPSC_SPP)) ! 235: vpaddr->prbcr = sc->sc_count; ! 236: else ! 237: vpaddr->plbcr = sc->sc_count; ! 238: return; ! 239: } ! 240: for (bit = 1; bit != 0; bit <<= 1) ! 241: if (sc->sc_state&bit&VPSC_CMNDS) { ! 242: vpaddr->plcsr |= bit; ! 243: sc->sc_state &= ~bit; ! 244: return; ! 245: } ! 246: } ! 247: ! 248: /*ARGSUSED*/ ! 249: vpioctl(dev, cmd, data, flag) ! 250: dev_t dev; ! 251: int cmd; ! 252: register caddr_t data; ! 253: int flag; ! 254: { ! 255: register int m; ! 256: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 257: register struct vpdevice *vpaddr = ! 258: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr; ! 259: ! 260: switch (cmd) { ! 261: ! 262: case VGETSTATE: ! 263: *(int *)data = sc->sc_state; ! 264: break; ! 265: ! 266: case VSETSTATE: ! 267: sc->sc_state = ! 268: (sc->sc_state & ~VPSC_MODE) | ! 269: ((*(int *)data) & (VPSC_MODE|VPSC_CMNDS)); ! 270: break; ! 271: ! 272: default: ! 273: return (ENOTTY); ! 274: } ! 275: (void) spl4(); ! 276: (void) vpwait(dev); ! 277: if (sc->sc_state&VPSC_SPP) ! 278: vpaddr->plcsr |= VP_SPP; ! 279: else ! 280: vpaddr->plcsr &= ~VP_SPP; ! 281: sc->sc_count = 0; ! 282: while (sc->sc_state & VPSC_CMNDS) { ! 283: (void) vpwait(dev); ! 284: vpstart(dev); ! 285: } ! 286: (void) spl0(); ! 287: return (0); ! 288: } ! 289: ! 290: vptimo(dev) ! 291: dev_t dev; ! 292: { ! 293: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 294: ! 295: if (sc->sc_state&VPSC_OPEN) ! 296: timeout(vptimo, (caddr_t)dev, hz/10); ! 297: vpintr(dev); ! 298: } ! 299: ! 300: /*ARGSUSED*/ ! 301: vpintr(dev) ! 302: dev_t dev; ! 303: { ! 304: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 305: ! 306: wakeup((caddr_t)sc); ! 307: } ! 308: ! 309: vpclose(dev) ! 310: dev_t dev; ! 311: { ! 312: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)]; ! 313: register struct vpdevice *vpaddr = ! 314: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr; ! 315: ! 316: sc->sc_state = 0; ! 317: sc->sc_count = 0; ! 318: vpaddr->plcsr = 0; ! 319: } ! 320: ! 321: vpreset(uban) ! 322: int uban; ! 323: { ! 324: register int vp11; ! 325: register struct uba_device *ui; ! 326: register struct vp_softc *sc = vp_softc; ! 327: register struct vpdevice *vpaddr; ! 328: ! 329: for (vp11 = 0; vp11 < NVP; vp11++, sc++) { ! 330: if ((ui = vpdinfo[vp11]) == 0 || ui->ui_alive == 0 || ! 331: ui->ui_ubanum != uban || (sc->sc_state&VPSC_OPEN) == 0) ! 332: continue; ! 333: printf(" vp%d", vp11); ! 334: vpaddr = (struct vpdevice *)ui->ui_addr; ! 335: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR; ! 336: if ((sc->sc_state & VPSC_BUSY) == 0) ! 337: continue; ! 338: sc->sc_ubinfo = 0; ! 339: sc->sc_count = sc->sc_bp->b_bcount; ! 340: vpstart(sc->sc_bp->b_dev); ! 341: } ! 342: } ! 343: ! 344: vpselect() ! 345: { ! 346: return (1); ! 347: } ! 348: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.