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