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