l_write returns a value; pass it on
[unix-history] / usr / src / sys / vax / uba / va.c
CommitLineData
f808000a 1/* va.c 4.13 82/05/19 */
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
fc4d0a69
BJ
69#define VAUNIT(dev) (minor(dev))
70
71struct buf rvabuf[NVA];
72
73int vaprobe(), vaattach();
74struct uba_device *vadinfo[NVA];
75u_short vastd[] = { 0764000, 0 };
76struct uba_driver vadriver =
77 { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo };
78
79vaprobe(reg)
80 caddr_t reg;
81{
82 register int br, cvec; /* value-result */
83 register struct vadevice *vaaddr = (struct vadevice *)reg;
84
89b8a44c
BJ
85#ifdef lint
86 br = 0; cvec = br; br = cvec;
87 vaintr(0);
88#endif
fc4d0a69
BJ
89 vaaddr->vacsl = VA_IENABLE;
90 vaaddr->vaba = 0;
91 vaaddr->vacsh = VAPLOT;
92 vaaddr->vacsl = 0;
93 vaaddr->vawc = -1;
f808000a 94 DELAY(100000);
fc4d0a69
BJ
95 vaaddr->vacsl = 0;
96}
97
98/*ARGSUSED*/
99vaattach(ui)
100 struct uba_device *ui;
101{
102
103}
104
105vaopen(dev)
106 dev_t dev;
20cc8b5b 107{
fc4d0a69
BJ
108 register struct va_softc *sc;
109 register struct vadevice *vaaddr;
110 register struct uba_device *ui;
20cc8b5b 111
fc4d0a69
BJ
112 if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
113 (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
20cc8b5b
BJ
114 u.u_error = ENXIO;
115 return;
116 }
fc4d0a69
BJ
117 vaaddr = (struct vadevice *)ui->ui_addr;
118 sc->sc_openf = 1;
119 vaaddr->vawc = 0;
120 sc->sc_wc = 0;
121 sc->sc_state = 0;
122 vaaddr->vacsl = VA_IENABLE;
123 vatimo(dev);
124 vacmd(dev, VPRINT);
20cc8b5b 125 if (u.u_error)
fc4d0a69 126 vaclose(dev);
20cc8b5b
BJ
127}
128
129vastrategy(bp)
130 register struct buf *bp;
131{
132 register int e;
fc4d0a69
BJ
133 register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)];
134 register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)];
135 register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr;
20cc8b5b 136
81263dba 137 (void) spl4();
fc4d0a69
BJ
138 while (sc->sc_busy)
139 sleep((caddr_t)sc, VAPRI);
140 sc->sc_busy = 1;
141 sc->sc_bp = bp;
142 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
143 if (e = vawait(bp->b_dev))
20cc8b5b 144 goto brkout;
fc4d0a69
BJ
145 sc->sc_wc = -(bp->b_bcount/2);
146 vastart(bp->b_dev);
147 e = vawait(bp->b_dev);
148 sc->sc_wc = 0;
149 if (sc->sc_state & VPRINTPLOT) {
150 sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
151 vaaddr->vacsh = VAAUTOSTEP;
152 e |= vawait(bp->b_dev);
20cc8b5b 153 }
81263dba 154 (void) spl0();
20cc8b5b 155brkout:
fc4d0a69
BJ
156 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
157 sc->sc_bp = 0;
158 sc->sc_busy = 0;
20cc8b5b
BJ
159 iodone(bp);
160 if (e)
161 u.u_error = EIO;
fc4d0a69 162 wakeup((caddr_t)sc);
20cc8b5b
BJ
163}
164
165int vablock = 16384;
166
167unsigned
168minvaph(bp)
fc4d0a69 169 struct buf *bp;
20cc8b5b 170{
fc4d0a69 171
20cc8b5b
BJ
172 if (bp->b_bcount > vablock)
173 bp->b_bcount = vablock;
174}
175
176/*ARGSUSED*/
177vawrite(dev)
fc4d0a69 178 dev_t dev;
20cc8b5b 179{
fc4d0a69
BJ
180
181 physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph);
20cc8b5b
BJ
182}
183
fc4d0a69
BJ
184vawait(dev)
185 dev_t dev;
20cc8b5b 186{
fc4d0a69
BJ
187 register struct vadevice *vaaddr =
188 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
20cc8b5b
BJ
189 register int e;
190
fc4d0a69
BJ
191 while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0)
192 sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI);
193 if (e & VA_NPRTIMO)
194 printf("va%d: npr timeout\n", VAUNIT(dev));
195 return (e & VA_ERROR);
20cc8b5b
BJ
196}
197
fc4d0a69
BJ
198vastart(dev)
199 dev_t;
20cc8b5b 200{
fc4d0a69
BJ
201 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
202 register struct vadevice *vaaddr =
203 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
204
205 if (sc->sc_wc == 0)
20cc8b5b 206 return;
fc4d0a69
BJ
207 vaaddr->vaba = sc->sc_ubinfo;
208 vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
209 vaaddr->vawc = sc->sc_wc;
20cc8b5b
BJ
210}
211
212/*ARGSUSED*/
213vaioctl(dev, cmd, addr, flag)
214 register caddr_t addr;
215{
216 register int vcmd;
fc4d0a69 217 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
20cc8b5b
BJ
218
219 switch (cmd) {
220
221 case VGETSTATE:
fc4d0a69 222 (void) suword(addr, sc->sc_state);
20cc8b5b
BJ
223 return;
224
225 case VSETSTATE:
226 vcmd = fuword(addr);
227 if (vcmd == -1) {
228 u.u_error = EFAULT;
229 return;
230 }
fc4d0a69 231 vacmd(dev, vcmd);
20cc8b5b
BJ
232 return;
233
234 default:
fc4d0a69 235 u.u_error = ENOTTY;
20cc8b5b
BJ
236 return;
237 }
238}
239
fc4d0a69
BJ
240vacmd(dev, vcmd)
241 dev_t dev;
242 int vcmd;
20cc8b5b 243{
fc4d0a69
BJ
244 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
245 register struct vadevice *vaaddr =
246 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
247
81263dba 248 (void) spl4();
fc4d0a69 249 (void) vawait(dev);
20cc8b5b
BJ
250 switch (vcmd) {
251
252 case VPLOT:
253 /* Must turn on plot AND autostep modes. */
fc4d0a69
BJ
254 vaaddr->vacsh = VAPLOT;
255 if (vawait(dev))
20cc8b5b 256 u.u_error = EIO;
fc4d0a69 257 vaaddr->vacsh = VAAUTOSTEP;
20cc8b5b
BJ
258 break;
259
260 case VPRINT:
fc4d0a69 261 vaaddr->vacsh = VAPRINT;
20cc8b5b
BJ
262 break;
263
264 case VPRINTPLOT:
fc4d0a69 265 vaaddr->vacsh = VAPRINTPLOT;
20cc8b5b
BJ
266 break;
267 }
fc4d0a69
BJ
268 sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
269 if (vawait(dev))
20cc8b5b 270 u.u_error = EIO;
81263dba 271 (void) spl0();
20cc8b5b
BJ
272}
273
fc4d0a69
BJ
274vatimo(dev)
275 dev_t dev;
20cc8b5b 276{
fc4d0a69
BJ
277 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
278
279 if (sc->sc_openf)
280 timeout(vatimo, (caddr_t)dev, hz/10);
281 vaintr(dev);
20cc8b5b
BJ
282}
283
284/*ARGSUSED*/
285vaintr(dev)
fc4d0a69 286 dev_t dev;
20cc8b5b 287{
fc4d0a69
BJ
288 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
289
290 wakeup((caddr_t)sc);
20cc8b5b
BJ
291}
292
fc4d0a69
BJ
293vaclose(dev)
294 dev_t dev;
20cc8b5b 295{
fc4d0a69
BJ
296 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
297 register struct vadevice *vaaddr =
298 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
299
300 sc->sc_openf = 0;
301 sc->sc_busy = 0;
302 sc->sc_state = 0;
303 sc->sc_ubinfo = 0;
304 vaaddr->vacsl = 0;
71357272
BJ
305}
306
fc4d0a69
BJ
307vareset(uban)
308 int uban;
71357272 309{
fc4d0a69
BJ
310 register int va11;
311 register struct uba_device *ui;
312 register struct va_softc *sc = va_softc;
313 register struct vadevice *vaaddr;
314
315 for (va11 = 0; va11 < NVA; va11++, sc++) {
316 if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 ||
317 ui->ui_ubanum != uban || sc->sc_openf == 0)
318 continue;
319 printf(" va%d", va11);
320 vaaddr = (struct vadevice *)ui->ui_addr;
321 vaaddr->vacsl = VA_IENABLE;
322 if (sc->sc_state & VPLOT) {
323 vaaddr->vacsh = VAPLOT;
324 DELAY(10000);
325 vaaddr->vacsh = VAAUTOSTEP;
326 } else if (sc->sc_state & VPRINTPLOT)
327 vaaddr->vacsh = VPRINTPLOT;
328 else
329 vaaddr->vacsh = VAPRINTPLOT;
71357272 330 DELAY(10000);
fc4d0a69
BJ
331 if (sc->sc_busy == 0)
332 continue;
333 if (sc->sc_ubinfo) {
334 printf("<%d>", (sc->sc_ubinfo>>28)&0xf);
335 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
336 }
337 sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP);
338 sc->sc_wc = -(sc->sc_bp->b_bcount/2);
339 vastart(sc->sc_bp->b_dev);
71357272 340 }
20cc8b5b 341}
941b74fe
SL
342
343vaselect()
344{
345 return (1);
346}
a5cc519e 347#endif