|
|
1.1 ! root 1: /* ! 2: * Versatec model 122 matrix printer/plotter ! 3: * dma interface driver ! 4: * ! 5: */ ! 6: #include "sys/param.h" ! 7: #include "sys/conf.h" ! 8: #include "sys/user.h" ! 9: #include "sys/buf.h" ! 10: #include "sys/ubaddr.h" ! 11: ! 12: #include "sys/vplot.h" ! 13: #include "sys/vplotcmd.h" ! 14: ! 15: struct device { ! 16: short csr; ! 17: short buf; ! 18: }; ! 19: ! 20: #define ERROR 0100000 ! 21: #define SPP 0020000 ! 22: #define BTCNT 0010000 ! 23: #define ADDR 0004000 ! 24: #define PP 0002000 ! 25: #define SWPBT 0001000 ! 26: #define READY 0000200 ! 27: #define IENABLE 0000100 ! 28: #define XMEM 0000060 ! 29: #define xmem(a) (((a) >> 12) & XMEM) ! 30: #define REMOTE 0000016 ! 31: #define GO 0000001 ! 32: ! 33: #define MASK (SPP|PP|SWPBT|REMOTE) ! 34: ! 35: #define RESET (06 << 1) ! 36: ! 37: /* ! 38: * config glue ! 39: */ ! 40: int vplotopen(), vplotclose(), vplotwrite(), vplotioctl(); ! 41: ! 42: extern struct vplot vplot[]; ! 43: extern struct ubaddr vplotaddr[]; ! 44: extern int vplotcnt; ! 45: struct cdevsw vplotcdev = ! 46: cdinit(vplotopen, vplotclose, nodev, vplotwrite, vplotioctl); ! 47: ! 48: #define VPLOTPRI (PZERO-1) ! 49: ! 50: vplotopen(d, f) ! 51: { ! 52: register int dev; ! 53: register struct vplot *vp; ! 54: ! 55: if((dev = minor(d)) >= vplotcnt) { ! 56: u.u_error = ENODEV; ! 57: return; ! 58: } ! 59: if((vp = &vplot[dev])->open) { ! 60: u.u_error = EBUSY; ! 61: return; ! 62: } ! 63: if((vp->addr = (struct device *)ubaddr(&vplotaddr[dev])) == 0 ! 64: || ubbadaddr(vplotaddr[dev].ubno, (caddr_t)vp->addr, sizeof(u_short))) { ! 65: printf("vplot%d absent\n", dev); ! 66: u.u_error = ENODEV; ! 67: return; ! 68: } ! 69: vp->open = 1; ! 70: vp->addr->csr = RESET; ! 71: if(vplotwait(vp)) { ! 72: u.u_error = ENXIO; ! 73: vplotclose(d); ! 74: return; ! 75: } ! 76: vp->addr->csr |= IENABLE; ! 77: vplottimo(vp); ! 78: if(u.u_error) ! 79: vplotclose(d); ! 80: } ! 81: ! 82: vplotclose(d) ! 83: { ! 84: register struct vplot *vp = &vplot[minor(d)]; ! 85: ! 86: vp->open = 0; ! 87: vp->addr->csr = 0; ! 88: } ! 89: ! 90: vplotstrategy(bp) ! 91: register struct buf *bp; ! 92: { ! 93: register struct vplot *vp = &vplot[minor(bp->b_dev)]; ! 94: register ubm_t ubm; ! 95: register uaddr_t uaddr; ! 96: register int cc, e, s; ! 97: ! 98: s = spl4(); ! 99: (void) vplotwait(vp); ! 100: ubm = ubmbuf(vplotaddr[minor(bp->b_dev)].ubno, bp, UBDP|USLP); ! 101: uaddr = ubadbuf(vplotaddr[minor(bp->b_dev)].ubno, bp, ubm); ! 102: if(e = vplotwait(vp)) ! 103: goto out; ! 104: if((cc = -(bp->b_bcount)) != 0) { ! 105: vp->addr->csr |= IENABLE | ADDR; ! 106: vp->addr->csr &= ~BTCNT; ! 107: vp->addr->buf = uaddr; ! 108: vp->addr->csr |= BTCNT; ! 109: vp->addr->buf = cc; ! 110: vp->addr->csr |= xmem(uaddr) | GO; ! 111: } ! 112: e = vplotwait(vp); ! 113: out: ! 114: (void) splx(s); ! 115: ubmfree(vplotaddr[minor(bp->b_dev)].ubno, ubm); ! 116: if(e) ! 117: bp->b_flags |= B_ERROR; ! 118: iodone(bp); ! 119: } ! 120: ! 121: int vplotblock = 16384; ! 122: ! 123: unsigned ! 124: minvplotph(bp) ! 125: struct buf *bp; ! 126: { ! 127: if(bp->b_bcount > vplotblock) ! 128: bp->b_bcount = vplotblock; ! 129: } ! 130: ! 131: /*ARGSUSED*/ ! 132: vplotwrite(d) ! 133: { ! 134: if(u.u_count == 0) ! 135: return; ! 136: physio(vplotstrategy, &vplot[minor(d)].buf, d, B_WRITE, minvplotph); ! 137: } ! 138: ! 139: vplotwait(vp) ! 140: register struct vplot *vp; ! 141: { ! 142: register int e; ! 143: ! 144: for(;;) { ! 145: if(vp->addr->csr & (ERROR|READY)) ! 146: break; ! 147: if(tsleep((caddr_t)vp, VPLOTPRI, HZ) != TS_OK) ! 148: break; ! 149: } ! 150: if((vp->addr->csr & ERROR) == 0) ! 151: return 0; ! 152: /* Check for NXM - ERROR remains 1 if NOT NXM) */ ! 153: vp->addr->csr &= ~ERROR; ! 154: if((e = (vp->addr->csr & ERROR)) == 0) ! 155: printf("vplot%d: NXM\n", vp - vplot); ! 156: return e; ! 157: } ! 158: ! 159: /*ARGSUSED*/ ! 160: vplotioctl(dev, cmd, addr, flag) ! 161: caddr_t addr; ! 162: { ! 163: register struct vplot *vp = &vplot[minor(dev)]; ! 164: u_short csr; ! 165: int m; ! 166: ! 167: switch(cmd) { ! 168: ! 169: case VGETSTATE: ! 170: m = vp->addr->csr; ! 171: if(copyout((caddr_t)&m, addr, sizeof(m))) ! 172: u.u_error = EFAULT; ! 173: break; ! 174: ! 175: case VSETSTATE: ! 176: if(copyin(addr, (caddr_t)&m, sizeof(m))) { ! 177: u.u_error = EFAULT; ! 178: return; ! 179: } ! 180: (void) spl4(); ! 181: csr = (vp->addr->csr & ~MASK) | (m & MASK); ! 182: vp->addr->csr = csr; ! 183: if(vplotwait(vp)) ! 184: u.u_error = EIO; ! 185: (void) spl0(); ! 186: break; ! 187: ! 188: default: ! 189: u.u_error = ENOTTY; ! 190: break; ! 191: } ! 192: } ! 193: ! 194: vplottimo(vp) ! 195: register struct vplot *vp; ! 196: { ! 197: if(vp->open) ! 198: timeout(vplottimo, (caddr_t)vp, HZ/10); ! 199: vplot0int(vp - vplot); ! 200: } ! 201: ! 202: vplot0int(d) ! 203: { ! 204: wakeup((caddr_t)&vplot[d]); ! 205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.