|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)va.c 7.3 (Berkeley) 2/17/90
7: */
8:
9: #include "va.h"
10: #if NVA > 0
11: /*
12: * Varian printer plotter
13: */
14: #include "machine/pte.h"
15:
16: #include "param.h"
17: #include "user.h"
18: #include "buf.h"
19: #include "systm.h"
20: #include "map.h"
21: #include "ioctl.h"
22: #include "vcmd.h"
23: #include "uio.h"
24: #include "kernel.h"
25:
26: #include "ubareg.h"
27: #include "ubavar.h"
28:
29: int vadebug = 0;
30: #define dprintf if(vadebug)printf
31:
32: unsigned minvaph();
33:
34: #define VAPRI (PZERO-1)
35:
36: struct vadevice {
37: u_short vaba; /* buffer address */
38: short vawc; /* word count (2's complement) */
39: union {
40: short Vacsw; /* control status as word */
41: struct { /* control status as bytes */
42: char Vacsl;
43: char Vacsh;
44: } vacsr;
45: } vacs;
46: short vadata; /* programmed i/o data buffer */
47: };
48:
49: #define vacsw vacs.Vacsw
50: #define vacsh vacs.vacsr.Vacsh
51: #define vacsl vacs.vacsr.Vacsl
52:
53: /* vacsw bits */
54: #define VA_ERROR 0100000 /* some error has occurred */
55: #define VA_NPRTIMO 0001000 /* DMA timeout error */
56: #define VA_NOTREADY 0000400 /* something besides NPRTIMO */
57: #define VA_DONE 0000200
58: #define VA_IENABLE 0000100 /* interrupt enable */
59: #define VA_DMAGO 0000010 /* DMA go bit */
60: #define VA_DMAGO 0000010 /* DMA go bit */
61: #define VA_SUPPLIESLOW 0000004
62: #define VA_BOTOFFORM 0000002
63: #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */
64:
65: /* vacsh command bytes */
66: #define VAPLOT 0000340
67: #define VAPRINT 0000100
68: #define VAPRINTPLOT 0000160
69: #define VAAUTOSTEP 0000244
70: #define VANOAUTOSTEP 0000045
71: #define VAFORMFEED 0000263
72: #define VASLEW 0000265
73: #define VASTEP 0000064
74:
75: struct va_softc {
76: u_char sc_openf; /* exclusive open flag */
77: u_char sc_iostate; /* kind of I/O going on */
78: #define VAS_IDLE 0 /* no I/O, free */
79: #define VAS_PIO 1 /* programmed I/O */
80: #define VAS_DMA 2 /* DMA, block pio */
81: #define VAS_WANT 4 /* wakeup when iostate changes */
82: short sc_tocnt; /* time out counter */
83: short sc_info; /* csw passed from vaintr */
84: int sc_state; /* print/plot state of device */
85: } va_softc[NVA];
86:
87: #define VAUNIT(dev) (minor(dev))
88:
89: struct buf rvabuf[NVA];
90:
91: int vaprobe(), vaslave(), vaattach(), vadgo();
92: struct uba_device *vadinfo[NVA];
93: struct uba_ctlr *vaminfo[NVA];
94: struct buf vabhdr[NVA];
95: u_short vastd[] = { 0764000, 0 };
96: struct uba_driver vadriver =
97: { vaprobe, vaslave, vaattach, vadgo, vastd, "vz", vadinfo, "va", vaminfo };
98:
99: vaprobe(reg)
100: caddr_t reg;
101: {
102: register int br, cvec; /* value-result */
103: register struct vadevice *vaaddr = (struct vadevice *)reg;
104:
105: #ifdef lint
106: br = 0; cvec = br; br = cvec;
107: vaintr(0);
108: #endif
109: #ifndef UCBVAX
110: vaaddr->vacsl = VA_IENABLE;
111: vaaddr->vaba = 0;
112: vaaddr->vacsh = VAPLOT;
113: vaaddr->vacsl = VA_IENABLE|VA_DMAGO;
114: vaaddr->vawc = -1;
115: DELAY(10000);
116: vaaddr->vacsl = 0;
117: vaaddr->vawc = 0;
118: #else
119: br=0x14;
120: cvec=0170;
121: #endif
122: return (sizeof (struct vadevice));
123: }
124:
125: /*ARGSUSED*/
126: vaslave(ui, reg)
127: struct uba_device *ui;
128: caddr_t reg;
129: {
130:
131: ui->ui_dk = 0;
132: return (ui->ui_unit <= 0);
133: }
134:
135: /*ARGSUSED*/
136: vaattach(ui)
137: struct uba_device *ui;
138: {
139:
140: ui->ui_mi->um_tab.b_actf = &vabhdr[ui->ui_unit];
141: }
142:
143: vaopen(dev)
144: dev_t dev;
145: {
146: register struct va_softc *sc;
147: register struct vadevice *vaaddr;
148: register struct uba_device *ui;
149: int error;
150: int unit = VAUNIT(dev);
151:
152: if (unit >= NVA || (sc = &va_softc[unit])->sc_openf ||
153: (ui = vadinfo[unit]) == 0 || ui->ui_alive == 0)
154: return (ENXIO);
155: vaaddr = (struct vadevice *)ui->ui_addr;
156: sc->sc_openf = 1;
157: vaaddr->vawc = 0;
158: sc->sc_state = 0;
159: sc->sc_tocnt = 0;
160: sc->sc_iostate = VAS_IDLE;
161: vaaddr->vacsl = VA_IENABLE;
162: vatimo(dev);
163: error = vacmd(dev, VPRINT);
164: if (error)
165: vaclose(dev);
166: return (error);
167: }
168:
169: vastrategy(bp)
170: register struct buf *bp;
171: {
172: register struct uba_device *ui;
173: register struct uba_ctlr *um;
174: int s;
175:
176: dprintf("vastrategy(%x)\n", bp);
177: ui = vadinfo[VAUNIT(bp->b_dev)];
178: if (ui == 0 || ui->ui_alive == 0) {
179: bp->b_flags |= B_ERROR;
180: iodone(bp);
181: return;
182: }
183: s = spl4();
184: um = ui->ui_mi;
185: bp->b_actf = NULL;
186: if (um->um_tab.b_actf->b_actf == NULL)
187: um->um_tab.b_actf->b_actf = bp;
188: else {
189: printf("bp = 0x%x, um->um_tab.b_actf->b_actf = 0x%x\n",
190: bp, um->um_tab.b_actf->b_actf);
191: panic("vastrategy");
192: um->um_tab.b_actf->b_actl->b_forw = bp;
193: }
194: um->um_tab.b_actf->b_actl = bp;
195: bp = um->um_tab.b_actf;
196: dprintf("vastrategy: bp=%x actf=%x active=%d\n",
197: bp, bp->b_actf, bp->b_active);
198: if (bp->b_actf && bp->b_active == 0)
199: (void) vastart(um);
200: splx(s);
201: }
202:
203: int vablock = 16384;
204:
205: unsigned
206: minvaph(bp)
207: struct buf *bp;
208: {
209:
210: if (bp->b_bcount > vablock)
211: bp->b_bcount = vablock;
212: }
213:
214: /*ARGSUSED*/
215: vawrite(dev, uio)
216: dev_t dev;
217: struct uio *uio;
218: {
219:
220: if (VAUNIT(dev) > NVA)
221: return (ENXIO);
222: return (physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE,
223: minvaph, uio));
224: }
225:
226: vastart(um)
227: register struct uba_ctlr *um;
228: {
229: struct buf *bp;
230: struct vadevice *vaaddr;
231: register struct va_softc *sc;
232: int unit;
233:
234: dprintf("vastart(%x), bp=%x\n", um, um->um_tab.b_actf->b_actf);
235: if ((bp = um->um_tab.b_actf->b_actf) == NULL)
236: return;
237: unit = VAUNIT(bp->b_dev);
238: sc = &va_softc[unit];
239: sc->sc_tocnt = 0;
240: while (sc->sc_iostate&VAS_PIO) {
241: sc->sc_iostate |= VAS_WANT;
242: sleep((caddr_t)&sc->sc_iostate, VAPRI);
243: }
244: sc->sc_iostate |= VAS_DMA;
245: vaaddr = (struct vadevice *)um->um_addr;
246: vaaddr->vacsl = 0;
247: vaaddr->vawc = -(bp->b_bcount / 2);
248: um->um_cmd = VA_DMAGO | VA_IENABLE;
249: (void) ubago(vadinfo[unit]);
250: }
251:
252: vadgo(um)
253: register struct uba_ctlr *um;
254: {
255: register struct vadevice *vaaddr = (struct vadevice *)um->um_addr;
256: register struct buf *bp;
257:
258: bp = um->um_tab.b_actf;
259: va_softc[VAUNIT(bp->b_actf->b_dev)].sc_tocnt = 0;
260: bp->b_active++;
261: vaaddr->vaba = um->um_ubinfo;
262: vaaddr->vacsl = ((um->um_ubinfo >> 12) & 0x30) | um->um_cmd;
263: }
264:
265: /*ARGSUSED*/
266: vaioctl(dev, cmd, data, flag)
267: register caddr_t data;
268: {
269: register struct va_softc *sc = &va_softc[VAUNIT(dev)];
270:
271: switch (cmd) {
272:
273: case VGETSTATE:
274: *(int *)data = sc->sc_state;
275: break;
276:
277: case VSETSTATE:
278: return (vacmd(dev, *(int *)data));
279:
280: default:
281: return (ENOTTY);
282: }
283: return (0);
284: }
285:
286: vacmd(dev, vcmd)
287: dev_t dev;
288: int vcmd;
289: {
290: register struct va_softc *sc = &va_softc[VAUNIT(dev)];
291: int error = 0;
292: int s, cmd;
293:
294: s = spl4();
295: while (sc->sc_iostate&VAS_DMA) {
296: sc->sc_iostate |= VAS_WANT;
297: sleep((caddr_t)&sc->sc_iostate, VAPRI);
298: }
299: sc->sc_iostate |= VAS_PIO;
300: sc->sc_tocnt = 0;
301: cmd = 0;
302: switch (vcmd) {
303:
304: case VPLOT:
305: /* Must turn on plot AND autostep modes. */
306: if (vadopio(dev, VAPLOT))
307: error = EIO;
308: cmd = VAAUTOSTEP;
309: break;
310:
311: case VPRINT:
312: cmd = VAPRINT;
313: break;
314:
315: case VPRINTPLOT:
316: cmd = VAPRINTPLOT;
317: break;
318: }
319: sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd;
320: if (cmd && vadopio(dev, cmd))
321: error = EIO;
322: sc->sc_iostate &= ~VAS_PIO;
323: if (sc->sc_iostate&VAS_WANT) {
324: sc->sc_iostate &= ~VAS_WANT;
325: wakeup((caddr_t)&sc->sc_iostate);
326: }
327: splx(s);
328: return (error);
329: }
330:
331: vadopio(dev, cmd)
332: dev_t dev;
333: int cmd;
334: {
335: register struct vadevice *vaaddr =
336: (struct vadevice *)vaminfo[VAUNIT(dev)]->um_addr;
337: register struct va_softc *sc = &va_softc[VAUNIT(dev)];
338:
339: sc->sc_info = 0;
340: vaaddr->vacsh = cmd;
341: while ((sc->sc_info&(VA_DONE|VA_ERROR)) == 0)
342: sleep((caddr_t)&sc->sc_info, VAPRI);
343: return (sc->sc_info&VA_ERROR);
344: }
345:
346: vatimo(dev)
347: dev_t dev;
348: {
349: register struct va_softc *sc = &va_softc[VAUNIT(dev)];
350:
351: if (sc->sc_openf)
352: timeout(vatimo, (caddr_t)dev, hz/2);
353: if (++sc->sc_tocnt < 2)
354: return;
355: sc->sc_tocnt = 0;
356: dprintf("vatimo: calling vaintr\n");
357: vaintr(dev);
358: }
359:
360: /*ARGSUSED*/
361: vaintr(dev)
362: dev_t dev;
363: {
364: register struct uba_ctlr *um;
365: struct vadevice *vaaddr;
366: struct buf *bp;
367: register int unit = VAUNIT(dev), e;
368: register struct va_softc *sc = &va_softc[unit];
369:
370: um = vaminfo[unit];
371: vaaddr = (struct vadevice *)um->um_addr;
372: e = vaaddr->vacsw;
373: dprintf("vaintr: um=0x%x, e=0x%x, b_active %d\n",
374: um, e, um->um_tab.b_actf->b_active);
375: if ((e&(VA_DONE|VA_ERROR)) == 0)
376: return;
377: vaaddr->vacsl = 0;
378: if ((e&VA_ERROR) && (e&VA_NPRTIMO))
379: printf("va%d: npr timeout\n", unit);
380: if (sc->sc_iostate&VAS_PIO) {
381: sc->sc_info = e;
382: wakeup((caddr_t)&sc->sc_info);
383: return;
384: }
385: if (um->um_tab.b_actf->b_active) {
386: bp = um->um_tab.b_actf->b_actf;
387: if (e&VA_ERROR)
388: bp->b_flags |= B_ERROR;
389: if (sc->sc_state&VPRINTPLOT) {
390: sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT;
391: vaaddr->vacsh = VAAUTOSTEP;
392: return;
393: }
394: ubadone(um);
395: um->um_tab.b_actf->b_active = 0;
396: um->um_tab.b_actf->b_actf = bp->b_forw;
397: bp->b_active = 0;
398: bp->b_errcnt = 0;
399: bp->b_resid = 0;
400: iodone(bp);
401: }
402: if (um->um_tab.b_actf->b_actf == 0) {
403: sc->sc_iostate &= ~VAS_DMA;
404: if (sc->sc_iostate&VAS_WANT) {
405: sc->sc_iostate &= ~VAS_WANT;
406: wakeup((caddr_t)&sc->sc_iostate);
407: }
408: return;
409: }
410: if (um->um_tab.b_actf->b_active == 0)
411: vastart(um);
412: }
413:
414: vaclose(dev)
415: dev_t dev;
416: {
417: register struct va_softc *sc = &va_softc[VAUNIT(dev)];
418: register struct vadevice *vaaddr =
419: (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr;
420:
421: sc->sc_openf = 0;
422: sc->sc_state = 0;
423: if (sc->sc_iostate != VAS_IDLE)
424: wakeup((caddr_t)&sc->sc_iostate);
425: sc->sc_iostate = VAS_IDLE;
426: vaaddr->vacsl = 0;
427: vaaddr->vawc = 0;
428: }
429:
430: vareset(uban)
431: int uban;
432: {
433: register int va11;
434: register struct uba_ctlr *um;
435: register struct vadevice *vaaddr;
436: register struct va_softc *sc;
437:
438: for (va11 = 0; va11 < NVA; va11++, sc++) {
439: if ((um = vaminfo[va11]) == 0 || um->um_ubanum != uban ||
440: um->um_alive == 0)
441: continue;
442: sc = &va_softc[um->um_ctlr];
443: if (sc->sc_openf == 0)
444: continue;
445: printf(" va%d", va11);
446: vaaddr = (struct vadevice *)um->um_addr;
447: vaaddr->vacsl = VA_IENABLE;
448: if (sc->sc_state & VPLOT) {
449: vaaddr->vacsh = VAPLOT;
450: DELAY(10000);
451: vaaddr->vacsh = VAAUTOSTEP;
452: } else if (sc->sc_state & VPRINTPLOT)
453: vaaddr->vacsh = VPRINTPLOT;
454: else
455: vaaddr->vacsh = VAPRINTPLOT;
456: DELAY(10000);
457: sc->sc_iostate = VAS_IDLE;
458: um->um_tab.b_actf->b_active = 0;
459: um->um_tab.b_actf->b_actf = um->um_tab.b_actf->b_actl = 0;
460: if (um->um_ubinfo) {
461: printf("<%d>", (um->um_ubinfo >> 28) & 0xf);
462: um->um_ubinfo = 0;
463: }
464: (void) vastart(um);
465: }
466: }
467:
468: vaselect()
469: {
470:
471: return (1);
472: }
473: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.