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: * @(#)vp.c 7.1 (Berkeley) 6/5/86
7: */
8:
9: #include "vp.h"
10: #if NVP > 0
11: /*
12: * Versatec matrix printer/plotter
13: * dma interface driver
14: *
15: * SETUP NOTES:
16: * Set up both print and plot interrupts to go through the same vector
17: * (or kludge probe to reset second vector to first;
18: * default 174/200 is already handled).
19: * Give the address of the plcsr register in the config specification
20: */
21: #include "../machine/pte.h"
22:
23: #include "param.h"
24: #include "dir.h"
25: #include "user.h"
26: #include "buf.h"
27: #include "systm.h"
28: #include "map.h"
29: #include "ioctl.h"
30: #include "vcmd.h"
31: #include "uio.h"
32: #include "kernel.h"
33:
34: #include "ubavar.h"
35: #include "ubareg.h"
36:
37: unsigned minvpph();
38:
39: #define VPPRI (PZERO-1)
40:
41: struct vpdevice {
42: short plbcr;
43: short pbxaddr;
44: short prbcr;
45: u_short pbaddr;
46: short plcsr;
47: short plbuf;
48: short prcsr;
49: u_short prbuf;
50: };
51:
52: #define VP_ERROR 0100000
53: #define VP_DTCINTR 0040000
54: #define VP_DMAACT 0020000
55: #define VP_READY 0000200
56: #define VP_IENABLE 0000100
57: #define VP_TERMCOM 0000040
58: #define VP_FFCOM 0000020
59: #define VP_EOTCOM 0000010
60: #define VP_CLRCOM 0000004
61: #define VP_RESET 0000002
62: #define VP_SPP 0000001
63:
64: struct vp_softc {
65: int sc_state;
66: int sc_count;
67: int sc_bufp;
68: struct buf *sc_bp;
69: int sc_ubinfo;
70: } vp_softc[NVP];
71:
72: /* sc_state bits */
73: #define VPSC_BUSY 0001000
74: #define VPSC_MODE 0000700
75: #define VPSC_SPP 0000400
76: #define VPSC_PLOT 0000200
77: #define VPSC_PRINT 0000100
78: #define VPSC_CMNDS 0000076
79: #define VPSC_OPEN 0000001
80:
81: struct uba_device *vpdinfo[NVP];
82:
83: #define VPUNIT(dev) (minor(dev))
84:
85: struct buf rvpbuf[NVP];
86:
87: int vpprobe(), vpattach();
88: struct uba_device *vpdinfo[NVP];
89: u_short vpstd[] = { 0777500, 0 };
90: struct uba_driver vpdriver =
91: { vpprobe, 0, vpattach, 0, vpstd, "vp", vpdinfo };
92:
93: vpprobe(reg)
94: caddr_t reg;
95: {
96: register int br, cvec; /* value-result */
97: register struct vpdevice *vpaddr = (struct vpdevice *)(reg-010);
98:
99: #ifdef lint
100: br = 0; cvec = br; br = cvec;
101: vpintr(0);
102: #endif
103: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
104: vpaddr->pbaddr = 0;
105: vpaddr->pbxaddr = 0;
106: vpaddr->prbcr = 1;
107: DELAY(10000);
108: vpaddr->prcsr = 0;
109: /* GET INTERRUPT AT SECOND VECTOR BUT WANT FIRST */
110: if (cvec == 0200) {
111: printf("vp reset vec from 200 to 174\n");
112: cvec = 0174;
113: }
114: return (sizeof (struct vpdevice));
115: }
116:
117: /*ARGSUSED*/
118: vpattach(ui)
119: struct uba_device *ui;
120: {
121:
122: ui->ui_addr -= 010;
123: ui->ui_physaddr -= 010;
124: }
125:
126: vpopen(dev)
127: dev_t dev;
128: {
129: register struct vp_softc *sc;
130: register struct vpdevice *vpaddr;
131: register struct uba_device *ui;
132:
133: if (VPUNIT(dev) >= NVP ||
134: ((sc = &vp_softc[minor(dev)])->sc_state&VPSC_OPEN) ||
135: (ui = vpdinfo[VPUNIT(dev)]) == 0 || ui->ui_alive == 0)
136: return (ENXIO);
137: vpaddr = (struct vpdevice *)ui->ui_addr;
138: sc->sc_state = VPSC_OPEN|VPSC_PRINT | VP_CLRCOM|VP_RESET;
139: sc->sc_count = 0;
140: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
141: vptimo(dev);
142: while (sc->sc_state & VPSC_CMNDS) {
143: (void) spl4();
144: if (vpwait(dev)) {
145: vpclose(dev);
146: return (EIO);
147: }
148: vpstart(dev);
149: (void) spl0();
150: }
151: return (0);
152: }
153:
154: vpstrategy(bp)
155: register struct buf *bp;
156: {
157: register int e;
158: register struct vp_softc *sc = &vp_softc[VPUNIT(bp->b_dev)];
159: register struct uba_device *ui = vpdinfo[VPUNIT(bp->b_dev)];
160: register struct vpdevice *vpaddr = (struct vpdevice *)ui->ui_addr;
161:
162: (void) spl4();
163: while (sc->sc_state & VPSC_BUSY)
164: sleep((caddr_t)sc, VPPRI);
165: sc->sc_state |= VPSC_BUSY;
166: sc->sc_bp = bp;
167: sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP);
168: if (e = vpwait(bp->b_dev))
169: goto brkout;
170: sc->sc_count = bp->b_bcount;
171: vpstart(bp->b_dev);
172: while (((sc->sc_state&VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr) & VP_DMAACT)
173: sleep((caddr_t)sc, VPPRI);
174: sc->sc_count = 0;
175: if ((sc->sc_state&VPSC_MODE) == VPSC_SPP)
176: sc->sc_state = (sc->sc_state &~ VPSC_MODE) | VPSC_PLOT;
177: (void) spl0();
178: brkout:
179: ubarelse(ui->ui_ubanum, &sc->sc_ubinfo);
180: sc->sc_state &= ~VPSC_BUSY;
181: sc->sc_bp = 0;
182: if (e)
183: bp->b_flags |= B_ERROR;
184: iodone(bp);
185: wakeup((caddr_t)sc);
186: }
187:
188: int vpblock = 16384;
189:
190: unsigned
191: minvpph(bp)
192: struct buf *bp;
193: {
194:
195: if (bp->b_bcount > vpblock)
196: bp->b_bcount = vpblock;
197: }
198:
199: /*ARGSUSED*/
200: vpwrite(dev, uio)
201: dev_t dev;
202: struct uio *uio;
203: {
204:
205: if (VPUNIT(dev) >= NVP)
206: return (ENXIO);
207: return (physio(vpstrategy, &rvpbuf[VPUNIT(dev)], dev, B_WRITE,
208: minvpph, uio));
209: }
210:
211: vpwait(dev)
212: dev_t dev;
213: {
214: register struct vpdevice *vpaddr =
215: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
216: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
217: register int e;
218:
219: for (;;) {
220: e = (sc->sc_state & VPSC_PLOT) ? vpaddr->plcsr : vpaddr->prcsr;
221: if (e & (VP_READY|VP_ERROR))
222: break;
223: sleep((caddr_t)sc, VPPRI);
224: }
225: /* I WISH I COULD TELL WHETHER AN ERROR INDICATED AN NPR TIMEOUT */
226: return (e & VP_ERROR);
227: }
228:
229: vpstart(dev)
230: dev_t;
231: {
232: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
233: register struct vpdevice *vpaddr =
234: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
235: short bit;
236:
237: if (sc->sc_count) {
238: vpaddr->pbaddr = sc->sc_ubinfo;
239: vpaddr->pbxaddr = (sc->sc_ubinfo>>12)&0x30;
240: if (sc->sc_state & (VPSC_PRINT|VPSC_SPP))
241: vpaddr->prbcr = sc->sc_count;
242: else
243: vpaddr->plbcr = sc->sc_count;
244: return;
245: }
246: for (bit = 1; bit != 0; bit <<= 1)
247: if (sc->sc_state&bit&VPSC_CMNDS) {
248: vpaddr->plcsr |= bit;
249: sc->sc_state &= ~bit;
250: return;
251: }
252: }
253:
254: /*ARGSUSED*/
255: vpioctl(dev, cmd, data, flag)
256: dev_t dev;
257: int cmd;
258: register caddr_t data;
259: int flag;
260: {
261: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
262: register struct vpdevice *vpaddr =
263: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
264:
265: switch (cmd) {
266:
267: case VGETSTATE:
268: *(int *)data = sc->sc_state;
269: return (0);
270:
271: case VSETSTATE:
272: sc->sc_state =
273: (sc->sc_state & ~VPSC_MODE) |
274: ((*(int *)data) & (VPSC_MODE|VPSC_CMNDS));
275: break;
276:
277: default:
278: return (ENOTTY);
279: }
280: (void) spl4();
281: (void) vpwait(dev);
282: if (sc->sc_state&VPSC_SPP)
283: vpaddr->plcsr |= VP_SPP;
284: else
285: vpaddr->plcsr &= ~VP_SPP;
286: sc->sc_count = 0;
287: while (sc->sc_state & VPSC_CMNDS) {
288: (void) vpwait(dev);
289: vpstart(dev);
290: }
291: (void) spl0();
292: return (0);
293: }
294:
295: vptimo(dev)
296: dev_t dev;
297: {
298: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
299:
300: if (sc->sc_state&VPSC_OPEN)
301: timeout(vptimo, (caddr_t)dev, hz/10);
302: vpintr(dev);
303: }
304:
305: /*ARGSUSED*/
306: vpintr(dev)
307: dev_t dev;
308: {
309: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
310:
311: wakeup((caddr_t)sc);
312: }
313:
314: vpclose(dev)
315: dev_t dev;
316: {
317: register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
318: register struct vpdevice *vpaddr =
319: (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
320:
321: sc->sc_state = 0;
322: sc->sc_count = 0;
323: vpaddr->plcsr = 0;
324: }
325:
326: vpreset(uban)
327: int uban;
328: {
329: register int vp11;
330: register struct uba_device *ui;
331: register struct vp_softc *sc = vp_softc;
332: register struct vpdevice *vpaddr;
333:
334: for (vp11 = 0; vp11 < NVP; vp11++, sc++) {
335: if ((ui = vpdinfo[vp11]) == 0 || ui->ui_alive == 0 ||
336: ui->ui_ubanum != uban || (sc->sc_state&VPSC_OPEN) == 0)
337: continue;
338: printf(" vp%d", vp11);
339: vpaddr = (struct vpdevice *)ui->ui_addr;
340: vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
341: if ((sc->sc_state & VPSC_BUSY) == 0)
342: continue;
343: sc->sc_ubinfo = 0;
344: sc->sc_count = sc->sc_bp->b_bcount;
345: vpstart(sc->sc_bp->b_dev);
346: }
347: }
348:
349: vpselect()
350: {
351: return (1);
352: }
353: #endif
Defined functions
Defined variables
vpstd
defined in line
89; used 1 times
Defined struct's
vpdevice
defined in line
41; used 34 times
- in line 97(4),
114(2),
130(2),
137(2),
160(4),
214-215(4),
233-234(4),
262-263(4),
318-319(4),
332(2),
339(2)
Defined macros
VPPRI
defined in line
39; used 3 times
VPUNIT
defined in line
83; used 16 times