fixes from ernie
[unix-history] / usr / src / sys / vax / uba / va.c
CommitLineData
fc4d0a69 1/* va.c 4.9 81/03/10 */
20cc8b5b 2
66b4fb09 3#include "va.h"
a5cc519e
BJ
4#if NVA > 0
5/*
fc4d0a69 6 * Varian printer plotter
a5cc519e 7 */
20cc8b5b
BJ
8#include "../h/param.h"
9#include "../h/dir.h"
10#include "../h/user.h"
11#include "../h/buf.h"
12#include "../h/systm.h"
13#include "../h/map.h"
14#include "../h/pte.h"
fc4d0a69
BJ
15#include "../h/ubareg.h"
16#include "../h/ubavar.h"
20cc8b5b
BJ
17#include "../h/vcmd.h"
18
71357272 19unsigned minvaph();
20cc8b5b
BJ
20
21#define VAPRI (PZERO-1)
22
fc4d0a69
BJ
23struct vadevice {
24 u_short vaba; /* buffer address */
25 short vawc; /* word count (2's complement) */
20cc8b5b 26 union {
fc4d0a69
BJ
27 short Vacsw; /* control status as word */
28 struct { /* control status as bytes */
71357272
BJ
29 char Vacsl;
30 char Vacsh;
31 } vacsr;
32 } vacs;
fc4d0a69 33 short vadata; /* programmed i/o data buffer */
20cc8b5b
BJ
34};
35
71357272
BJ
36#define vacsw vacs.Vacsw
37#define vacsh vacs.vacsr.Vacsh
38#define vacsl vacs.vacsr.Vacsl
39
71357272 40/* vacsw bits */
fc4d0a69
BJ
41#define VA_ERROR 0100000 /* some error has occurred */
42#define VA_NPRTIMO 0001000 /* DMA timeout error */
43#define VA_NOTREADY 0000400 /* something besides NPRTIMO */
44#define VA_DONE 0000200
45#define VA_IENABLE 0000100 /* interrupt enable */
46#define VA_SUPPLIESLOW 0000004
47#define VA_BOTOFFORM 0000002
48#define VA_BYTEREVERSE 0000001 /* reverse byte order in words */
71357272
BJ
49
50/* vacsh command bytes */
fc4d0a69
BJ
51#define VAPLOT 0000340
52#define VAPRINT 0000100
53#define VAPRINTPLOT 0000160
54#define VAAUTOSTEP 0000244
55#define VANOAUTOSTEP 0000045
56#define VAFORMFEED 0000263
57#define VASLEW 0000265
58#define VASTEP 0000064
59
60struct va_softc {
61 char sc_openf;
62 char sc_busy;
63 int sc_state;
64 int sc_wc;
65 struct buf *sc_bp;
66 int sc_ubinfo;
67} va_softc[NVA];
68
69struct uba_device *vadinfo[NVA];
70
71#define VAUNIT(dev) (minor(dev))
72
73struct buf rvabuf[NVA];
74
75int vaprobe(), vaattach();
76struct uba_device *vadinfo[NVA];
77u_short vastd[] = { 0764000, 0 };
78struct uba_driver vadriver =
79 { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo };
80
81vaprobe(reg)
82 caddr_t reg;
83{
84 register int br, cvec; /* value-result */
85 register struct vadevice *vaaddr = (struct vadevice *)reg;
86
87 vaaddr->vacsl = VA_IENABLE;
88 vaaddr->vaba = 0;
89 vaaddr->vacsh = VAPLOT;
90 vaaddr->vacsl = 0;
91 vaaddr->vawc = -1;
92 DELAY(10000);
93 vaaddr->vacsl = 0;
94}
95
96/*ARGSUSED*/
97vaattach(ui)
98 struct uba_device *ui;
99{
100
101}
102
103vaopen(dev)
104 dev_t dev;
20cc8b5b 105{
fc4d0a69
BJ
106 register struct va_softc *sc;
107 register struct vadevice *vaaddr;
108 register struct uba_device *ui;
20cc8b5b 109
fc4d0a69
BJ
110 if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
111 (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
20cc8b5b
BJ
112 u.u_error = ENXIO;
113 return;
114 }
fc4d0a69
BJ
115 vaaddr = (struct vadevice *)ui->ui_addr;
116 sc->sc_openf = 1;
117 vaaddr->vawc = 0;
118 sc->sc_wc = 0;
119 sc->sc_state = 0;
120 vaaddr->vacsl = VA_IENABLE;
121 vatimo(dev);
122 vacmd(dev, VPRINT);
20cc8b5b 123 if (u.u_error)
fc4d0a69 124 vaclose(dev);
20cc8b5b
BJ
125}
126
127vastrategy(bp)
128 register struct buf *bp;
129{
130 register int e;
fc4d0a69
BJ
131 register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)];
132 register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)];
133 register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr;
20cc8b5b 134
81263dba 135 (void) spl4();
fc4d0a69
BJ
136 while (sc->sc_busy)
137 sleep((caddr_t)sc, VAPRI);
138 sc->sc_busy = 1;
139 sc->sc_bp = bp;
140 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
141 if (e = vawait(bp->b_dev))
20cc8b5b 142 goto brkout;
fc4d0a69
BJ
143 sc->sc_wc = -(bp->b_bcount/2);
144 vastart(bp->b_dev);
145 e = vawait(bp->b_dev);
146 sc->sc_wc = 0;
147 if (sc->sc_state & VPRINTPLOT) {
148 sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
149 vaaddr->vacsh = VAAUTOSTEP;
150 e |= vawait(bp->b_dev);
20cc8b5b 151 }
81263dba 152 (void) spl0();
20cc8b5b 153brkout:
fc4d0a69
BJ
154 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
155 sc->sc_bp = 0;
156 sc->sc_busy = 0;
20cc8b5b
BJ
157 iodone(bp);
158 if (e)
159 u.u_error = EIO;
fc4d0a69 160 wakeup((caddr_t)sc);
20cc8b5b
BJ
161}
162
163int vablock = 16384;
164
165unsigned
166minvaph(bp)
fc4d0a69 167 struct buf *bp;
20cc8b5b 168{
fc4d0a69 169
20cc8b5b
BJ
170 if (bp->b_bcount > vablock)
171 bp->b_bcount = vablock;
172}
173
174/*ARGSUSED*/
175vawrite(dev)
fc4d0a69 176 dev_t dev;
20cc8b5b 177{
fc4d0a69
BJ
178
179 physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph);
20cc8b5b
BJ
180}
181
fc4d0a69
BJ
182vawait(dev)
183 dev_t dev;
20cc8b5b 184{
fc4d0a69
BJ
185 register struct vadevice *vaaddr =
186 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
20cc8b5b
BJ
187 register int e;
188
fc4d0a69
BJ
189 while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0)
190 sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI);
191 if (e & VA_NPRTIMO)
192 printf("va%d: npr timeout\n", VAUNIT(dev));
193 return (e & VA_ERROR);
20cc8b5b
BJ
194}
195
fc4d0a69
BJ
196vastart(dev)
197 dev_t;
20cc8b5b 198{
fc4d0a69
BJ
199 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
200 register struct vadevice *vaaddr =
201 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
202
203 if (sc->sc_wc == 0)
20cc8b5b 204 return;
fc4d0a69
BJ
205 vaaddr->vaba = sc->sc_ubinfo;
206 vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
207 vaaddr->vawc = sc->sc_wc;
20cc8b5b
BJ
208}
209
210/*ARGSUSED*/
211vaioctl(dev, cmd, addr, flag)
212 register caddr_t addr;
213{
214 register int vcmd;
fc4d0a69 215 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
20cc8b5b
BJ
216
217 switch (cmd) {
218
219 case VGETSTATE:
fc4d0a69 220 (void) suword(addr, sc->sc_state);
20cc8b5b
BJ
221 return;
222
223 case VSETSTATE:
224 vcmd = fuword(addr);
225 if (vcmd == -1) {
226 u.u_error = EFAULT;
227 return;
228 }
fc4d0a69 229 vacmd(dev, vcmd);
20cc8b5b
BJ
230 return;
231
232 default:
fc4d0a69 233 u.u_error = ENOTTY;
20cc8b5b
BJ
234 return;
235 }
236}
237
fc4d0a69
BJ
238vacmd(dev, vcmd)
239 dev_t dev;
240 int vcmd;
20cc8b5b 241{
fc4d0a69
BJ
242 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
243 register struct vadevice *vaaddr =
244 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
245
81263dba 246 (void) spl4();
fc4d0a69 247 (void) vawait(dev);
20cc8b5b
BJ
248 switch (vcmd) {
249
250 case VPLOT:
251 /* Must turn on plot AND autostep modes. */
fc4d0a69
BJ
252 vaaddr->vacsh = VAPLOT;
253 if (vawait(dev))
20cc8b5b 254 u.u_error = EIO;
fc4d0a69 255 vaaddr->vacsh = VAAUTOSTEP;
20cc8b5b
BJ
256 break;
257
258 case VPRINT:
fc4d0a69 259 vaaddr->vacsh = VAPRINT;
20cc8b5b
BJ
260 break;
261
262 case VPRINTPLOT:
fc4d0a69 263 vaaddr->vacsh = VAPRINTPLOT;
20cc8b5b
BJ
264 break;
265 }
fc4d0a69
BJ
266 sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
267 if (vawait(dev))
20cc8b5b 268 u.u_error = EIO;
81263dba 269 (void) spl0();
20cc8b5b
BJ
270}
271
fc4d0a69
BJ
272vatimo(dev)
273 dev_t dev;
20cc8b5b 274{
fc4d0a69
BJ
275 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
276
277 if (sc->sc_openf)
278 timeout(vatimo, (caddr_t)dev, hz/10);
279 vaintr(dev);
20cc8b5b
BJ
280}
281
282/*ARGSUSED*/
283vaintr(dev)
fc4d0a69 284 dev_t dev;
20cc8b5b 285{
fc4d0a69
BJ
286 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
287
288 wakeup((caddr_t)sc);
20cc8b5b
BJ
289}
290
fc4d0a69
BJ
291vaclose(dev)
292 dev_t dev;
20cc8b5b 293{
fc4d0a69
BJ
294 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
295 register struct vadevice *vaaddr =
296 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
297
298 sc->sc_openf = 0;
299 sc->sc_busy = 0;
300 sc->sc_state = 0;
301 sc->sc_ubinfo = 0;
302 vaaddr->vacsl = 0;
71357272
BJ
303}
304
fc4d0a69
BJ
305vareset(uban)
306 int uban;
71357272 307{
fc4d0a69
BJ
308 register int va11;
309 register struct uba_device *ui;
310 register struct va_softc *sc = va_softc;
311 register struct vadevice *vaaddr;
312
313 for (va11 = 0; va11 < NVA; va11++, sc++) {
314 if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 ||
315 ui->ui_ubanum != uban || sc->sc_openf == 0)
316 continue;
317 printf(" va%d", va11);
318 vaaddr = (struct vadevice *)ui->ui_addr;
319 vaaddr->vacsl = VA_IENABLE;
320 if (sc->sc_state & VPLOT) {
321 vaaddr->vacsh = VAPLOT;
322 DELAY(10000);
323 vaaddr->vacsh = VAAUTOSTEP;
324 } else if (sc->sc_state & VPRINTPLOT)
325 vaaddr->vacsh = VPRINTPLOT;
326 else
327 vaaddr->vacsh = VAPRINTPLOT;
71357272 328 DELAY(10000);
fc4d0a69
BJ
329 if (sc->sc_busy == 0)
330 continue;
331 if (sc->sc_ubinfo) {
332 printf("<%d>", (sc->sc_ubinfo>>28)&0xf);
333 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
334 }
335 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP);
336 sc->sc_wc = -(sc->sc_bp->b_bcount/2);
337 vastart(sc->sc_bp->b_dev);
71357272 338 }
20cc8b5b 339}
a5cc519e 340#endif