|
|
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.