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