use up.c.SC11 #ifdef SC11
[unix-history] / usr / src / sys / vax / uba / va.c
CommitLineData
4e0c95d7 1/* va.c 4.1 %G% */
20cc8b5b 2
a5cc519e
BJ
3#include "../conf/va.h"
4#if NVA > 0
5/*
6 * Benson-Varian matrix printer/plotter
7 * dma interface driver
8 */
20cc8b5b
BJ
9#include "../h/param.h"
10#include "../h/dir.h"
11#include "../h/user.h"
12#include "../h/buf.h"
13#include "../h/systm.h"
14#include "../h/map.h"
15#include "../h/pte.h"
16#include "../h/uba.h"
17#include "../h/vcmd.h"
18
71357272 19int vabdp = 1;
20cc8b5b 20
71357272 21unsigned minvaph();
20cc8b5b
BJ
22
23#define VAPRI (PZERO-1)
24
71357272
BJ
25#define ushort unsigned short
26struct varegs {
27 ushort vaba;
28 short vawc;
20cc8b5b 29 union {
71357272 30 short Vacsw;
20cc8b5b 31 struct {
71357272
BJ
32 char Vacsl;
33 char Vacsh;
34 } vacsr;
35 } vacs;
20cc8b5b
BJ
36 short vadata;
37};
38
71357272
BJ
39#define vacsw vacs.Vacsw
40#define vacsh vacs.vacsr.Vacsh
41#define vacsl vacs.vacsr.Vacsl
42
71357272
BJ
43/* vacsw bits */
44#define ERROR 0100000 /* Some error has occurred */
a5cc519e
BJ
45#define NPRTIMO 01000 /* DMA timeout error */
46#define NOTREADY 0400 /* Something besides NPRTIMO */
47#define DONE 0200
71357272
BJ
48#define IENABLE 0100 /* Interrupt enable */
49#define SUPPLIESLOW 04
a5cc519e
BJ
50#define BOTOFFORM 02
51#define BYTEREVERSE 01 /* Reverse byte order in words */
71357272
BJ
52
53/* vacsh command bytes */
a5cc519e
BJ
54#define VAPLOT 0340
55#define VAPRINT 0100
56#define VAPRINTPLOT 0160
57#define VAAUTOSTEP 0244
58#define VANOAUTOSTEP 0045 /* unused */
71357272
BJ
59#define VAFORMFEED 0263 /* unused */
60#define VASLEW 0265 /* unused */
61#define VASTEP 0064 /* unused */
20cc8b5b
BJ
62
63struct {
71357272 64 char va_open;
20cc8b5b
BJ
65 char va_busy;
66 int va_state; /* State: bits are commands in vcmd.h. */
71357272 67 int va_wc;
20cc8b5b 68 int va_bufp;
71357272
BJ
69 struct buf *va_bp;
70} va11;
20cc8b5b
BJ
71int va_ubinfo;
72
73struct buf rvabuf; /* Used by physio for a buffer. */
74
75vaopen()
76{
77
71357272 78 if (va11.va_open) {
20cc8b5b
BJ
79 u.u_error = ENXIO;
80 return;
81 }
71357272
BJ
82 va11.va_open = 1;
83 VAADDR->vawc = 0;
84 va11.va_wc = 0;
85 va11.va_state = 0;
86 VAADDR->vacsl = IENABLE;
20cc8b5b 87 vatimo();
71357272 88 vacmd(VPRINT);
20cc8b5b
BJ
89 if (u.u_error)
90 vaclose();
91}
92
93vastrategy(bp)
94 register struct buf *bp;
95{
96 register int e;
97
81263dba 98 (void) spl4();
71357272
BJ
99 while (va11.va_busy)
100 sleep((caddr_t)&va11, VAPRI);
101 va11.va_busy = 1;
102 va11.va_bp = bp;
103 va_ubinfo = ubasetup(bp, vabdp);
104 va11.va_bufp = va_ubinfo & 0x3ffff;
20cc8b5b
BJ
105 if (e = vaerror(DONE))
106 goto brkout;
71357272 107 va11.va_wc = -(bp->b_bcount/2);
20cc8b5b 108 vastart();
71357272
BJ
109 e = vaerror(DONE); /* Wait for DMA to complete */
110 va11.va_wc = 0;
111 va11.va_bufp = 0;
112
113 /*
114 * After printing a line of characters, VPRINTPLOT mode essentially
115 * reverts to VPLOT mode, plotting things until a new mode is set.
116 * This change is indicated by sending a VAAUTOSTEP command to
117 * the va. We also change va_state to reflect this effective
118 * mode change.
20cc8b5b 119 */
71357272
BJ
120 if (va11.va_state & VPRINTPLOT) {
121 va11.va_state = (va11.va_state & ~VPRINTPLOT) | VPLOT;
122 VAADDR->vacsh = VAAUTOSTEP;
20cc8b5b
BJ
123 e |= vaerror(DONE);
124 }
81263dba 125 (void) spl0();
20cc8b5b
BJ
126brkout:
127 ubafree(va_ubinfo), va_ubinfo = 0;
71357272
BJ
128 va11.va_bp = 0;
129 va11.va_busy = 0;
20cc8b5b
BJ
130 iodone(bp);
131 if (e)
132 u.u_error = EIO;
71357272 133 wakeup((caddr_t)&va11);
20cc8b5b
BJ
134}
135
136int vablock = 16384;
137
138unsigned
139minvaph(bp)
140struct buf *bp;
141{
142 if (bp->b_bcount > vablock)
143 bp->b_bcount = vablock;
144}
145
146/*ARGSUSED*/
147vawrite(dev)
148{
149 physio(vastrategy, &rvabuf, dev, B_WRITE, minvaph);
150}
151
152/*
153 * Vaerror waits until bit or ERROR gets set, then returns non-zero if
154 * if it was ERROR that was set.
155 */
156vaerror(bit)
157{
158 register int e;
159
71357272
BJ
160 while ((e = VAADDR->vacsw & (bit|ERROR)) == 0)
161 sleep((caddr_t)&va11, VAPRI);
20cc8b5b
BJ
162 return (e & ERROR);
163}
164
20cc8b5b
BJ
165vastart()
166{
71357272
BJ
167 if (va11.va_wc) {
168 VAADDR->vaba = va11.va_bufp;
169 VAADDR->vawc = va11.va_wc;
20cc8b5b
BJ
170 return;
171 }
172}
173
174/*ARGSUSED*/
175vaioctl(dev, cmd, addr, flag)
176 register caddr_t addr;
177{
178 register int vcmd;
179
180 switch (cmd) {
181
182 case VGETSTATE:
71357272 183 (void) suword(addr, va11.va_state);
20cc8b5b
BJ
184 return;
185
186 case VSETSTATE:
187 vcmd = fuword(addr);
188 if (vcmd == -1) {
189 u.u_error = EFAULT;
190 return;
191 }
192 vacmd(vcmd);
193 return;
194
195 default:
196 u.u_error = ENOTTY; /* Not a legal ioctl cmd. */
197 return;
198 }
199}
200
71357272
BJ
201/*
202 * Send a command code to the va, and wait for it to complete.
203 * If an error occurs, u.u_error is set to EIO.
204 * In any case, update va11.va_state.
20cc8b5b 205 */
20cc8b5b
BJ
206vacmd(vcmd)
207{
81263dba 208 (void) spl4();
71357272 209 (void) vaerror(DONE); /* Wait for va to be ready */
20cc8b5b
BJ
210 switch (vcmd) {
211
212 case VPLOT:
213 /* Must turn on plot AND autostep modes. */
71357272 214 VAADDR->vacsh = VAPLOT;
20cc8b5b
BJ
215 if (vaerror(DONE))
216 u.u_error = EIO;
71357272 217 VAADDR->vacsh = VAAUTOSTEP;
20cc8b5b
BJ
218 break;
219
220 case VPRINT:
71357272 221 VAADDR->vacsh = VAPRINT;
20cc8b5b
BJ
222 break;
223
224 case VPRINTPLOT:
71357272 225 VAADDR->vacsh = VAPRINTPLOT;
20cc8b5b
BJ
226 break;
227 }
71357272
BJ
228 va11.va_state =
229 (va11.va_state & ~(VPLOT | VPRINT | VPRINTPLOT)) | vcmd;
20cc8b5b
BJ
230
231 if (vaerror(DONE)) /* Wait for command to complete. */
232 u.u_error = EIO;
81263dba 233 (void) spl0();
20cc8b5b
BJ
234}
235
236vatimo()
237{
71357272 238 if (va11.va_open)
20cc8b5b
BJ
239 timeout(vatimo, (caddr_t)0, HZ/10);
240 vaintr(0);
241}
242
243/*ARGSUSED*/
244vaintr(dev)
245{
71357272 246 wakeup((caddr_t)&va11);
20cc8b5b
BJ
247}
248
249vaclose()
250{
251
71357272
BJ
252 va11.va_open = 0;
253 va11.va_busy = 0;
254 va11.va_state = 0;
255 va11.va_wc = 0;
256 va11.va_bufp = 0;
257 VAADDR->vacsl = 0;
258}
259
260#define DELAY(N) { register int d; d = N; while (--d > 0); }
261
262vareset()
263{
264
265 if (va11.va_open == 0)
266 return;
267 printf(" va");
268 VAADDR->vacsl = IENABLE;
269 if (va11.va_state & VPLOT) {
270 VAADDR->vacsh = VAPLOT;
271 DELAY(10000);
272 VAADDR->vacsh = VAAUTOSTEP;
273 } else if (va11.va_state & VPRINTPLOT)
274 VAADDR->vacsh = VPRINTPLOT;
275 else
276 VAADDR->vacsh = VAPRINTPLOT;
277 DELAY(10000);
278 if (va11.va_busy == 0)
279 return;
280 if (va_ubinfo) {
281 printf("<%d>", (va_ubinfo>>28)&0xf);
282 ubafree(va_ubinfo), va_ubinfo = 0;
283 }
284 /* This code belongs in vastart() */
285 va_ubinfo = ubasetup(va11.va_bp, vabdp);
286 va11.va_bufp = va_ubinfo & 0x3ffff;
287 va11.va_wc = (-va11.va_bp->b_bcount/2);
288 /* End badly placed code */
289 vastart();
20cc8b5b 290}
a5cc519e 291#endif