date and time created 82/06/14 18:09:52 by peter
[unix-history] / usr / src / sys / vax / uba / va.c
... / ...
CommitLineData
1/* va.c 4.13 82/05/19 */
2
3#include "va.h"
4#if NVA > 0
5/*
6 * Varian printer plotter
7 */
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"
15#include "../h/ubareg.h"
16#include "../h/ubavar.h"
17#include "../h/vcmd.h"
18
19unsigned minvaph();
20
21#define VAPRI (PZERO-1)
22
23struct vadevice {
24 u_short vaba; /* buffer address */
25 short vawc; /* word count (2's complement) */
26 union {
27 short Vacsw; /* control status as word */
28 struct { /* control status as bytes */
29 char Vacsl;
30 char Vacsh;
31 } vacsr;
32 } vacs;
33 short vadata; /* programmed i/o data buffer */
34};
35
36#define vacsw vacs.Vacsw
37#define vacsh vacs.vacsr.Vacsh
38#define vacsl vacs.vacsr.Vacsl
39
40/* vacsw bits */
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 */
49
50/* vacsh command bytes */
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
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
85#ifdef lint
86 br = 0; cvec = br; br = cvec;
87 vaintr(0);
88#endif
89 vaaddr->vacsl = VA_IENABLE;
90 vaaddr->vaba = 0;
91 vaaddr->vacsh = VAPLOT;
92 vaaddr->vacsl = 0;
93 vaaddr->vawc = -1;
94 DELAY(100000);
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;
107{
108 register struct va_softc *sc;
109 register struct vadevice *vaaddr;
110 register struct uba_device *ui;
111
112 if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf ||
113 (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) {
114 u.u_error = ENXIO;
115 return;
116 }
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);
125 if (u.u_error)
126 vaclose(dev);
127}
128
129vastrategy(bp)
130 register struct buf *bp;
131{
132 register int e;
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;
136
137 (void) spl4();
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))
144 goto brkout;
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);
153 }
154 (void) spl0();
155brkout:
156 ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
157 sc->sc_bp = 0;
158 sc->sc_busy = 0;
159 iodone(bp);
160 if (e)
161 u.u_error = EIO;
162 wakeup((caddr_t)sc);
163}
164
165int vablock = 16384;
166
167unsigned
168minvaph(bp)
169 struct buf *bp;
170{
171
172 if (bp->b_bcount > vablock)
173 bp->b_bcount = vablock;
174}
175
176/*ARGSUSED*/
177vawrite(dev)
178 dev_t dev;
179{
180
181 physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph);
182}
183
184vawait(dev)
185 dev_t dev;
186{
187 register struct vadevice *vaaddr =
188 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
189 register int e;
190
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);
196}
197
198vastart(dev)
199 dev_t;
200{
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)
206 return;
207 vaaddr->vaba = sc->sc_ubinfo;
208 vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30;
209 vaaddr->vawc = sc->sc_wc;
210}
211
212/*ARGSUSED*/
213vaioctl(dev, cmd, addr, flag)
214 register caddr_t addr;
215{
216 register int vcmd;
217 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
218
219 switch (cmd) {
220
221 case VGETSTATE:
222 (void) suword(addr, sc->sc_state);
223 return;
224
225 case VSETSTATE:
226 vcmd = fuword(addr);
227 if (vcmd == -1) {
228 u.u_error = EFAULT;
229 return;
230 }
231 vacmd(dev, vcmd);
232 return;
233
234 default:
235 u.u_error = ENOTTY;
236 return;
237 }
238}
239
240vacmd(dev, vcmd)
241 dev_t dev;
242 int vcmd;
243{
244 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
245 register struct vadevice *vaaddr =
246 (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
247
248 (void) spl4();
249 (void) vawait(dev);
250 switch (vcmd) {
251
252 case VPLOT:
253 /* Must turn on plot AND autostep modes. */
254 vaaddr->vacsh = VAPLOT;
255 if (vawait(dev))
256 u.u_error = EIO;
257 vaaddr->vacsh = VAAUTOSTEP;
258 break;
259
260 case VPRINT:
261 vaaddr->vacsh = VAPRINT;
262 break;
263
264 case VPRINTPLOT:
265 vaaddr->vacsh = VAPRINTPLOT;
266 break;
267 }
268 sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
269 if (vawait(dev))
270 u.u_error = EIO;
271 (void) spl0();
272}
273
274vatimo(dev)
275 dev_t dev;
276{
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);
282}
283
284/*ARGSUSED*/
285vaintr(dev)
286 dev_t dev;
287{
288 register struct va_softc *sc = &va_softc[VAUNIT(dev)];
289
290 wakeup((caddr_t)sc);
291}
292
293vaclose(dev)
294 dev_t dev;
295{
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;
305}
306
307vareset(uban)
308 int uban;
309{
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;
330 DELAY(10000);
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);
340 }
341}
342
343vaselect()
344{
345 return (1);
346}
347#endif