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