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