xref: /csrg-svn/sys/vax/uba/vp.c (revision 2054)
1 /*	vp.c	4.5	12/30/80	*/
2 
3 #include "vp.h"
4 #if NVP > 0
5 /*
6  * Versatec matrix printer/plotter
7  * dma interface driver
8  */
9 #include "../h/param.h"
10 #include "../h/dir.h"
11 #include "../h/user.h"
12 #include "../h/buf.h"
13 #include "../h/systm.h"
14 #include "../h/map.h"
15 #include "../h/pte.h"
16 #include "../h/uba.h"
17 
18 int	vpbdp = 1;
19 
20 unsigned minvpph();
21 
22 #define	VPPRI	(PZERO-1)
23 
24 struct	vpregs {
25 	short	plbcr;
26 	short	pbxaddr;
27 	short	prbcr;
28 	unsigned short pbaddr;
29 	short	plcsr;
30 	short	plbuf;
31 	short	prcsr;
32 	unsigned short prbuf;
33 };
34 
35 #define	ERROR	0100000
36 #define	DTCINTR	040000
37 #define	DMAACT	020000
38 #define	READY	0200
39 #define	IENABLE	0100
40 #define	TERMCOM	040
41 #define	FFCOM	020
42 #define	EOTCOM	010
43 #define	CLRCOM	04
44 #define	RESET	02
45 #define	SPP	01
46 
47 struct {
48 	int	vp_state;
49 	int	vp_count;
50 	int	vp_bufp;
51 	struct	buf *vp_bp;
52 } vp11;
53 int	vp_ubinfo;
54 
55 struct	buf rvpbuf;
56 
57 #define	VISOPEN	01
58 #define	CMNDS	076
59 #define	MODE	0700
60 #define	PRINT	0100
61 #define	PLOT	0200
62 #define	PPLOT	0400
63 #define	VBUSY	01000
64 
65 vpopen()
66 {
67 
68 	if (vp11.vp_state & VISOPEN) {
69 		u.u_error = ENXIO;
70 		return;
71 	}
72 	vp11.vp_state = VISOPEN | PRINT | CLRCOM | RESET;
73 	vp11.vp_count = 0;
74 	VPADDR->prcsr = IENABLE | DTCINTR;
75 	vptimo();
76 	while (vp11.vp_state & CMNDS) {
77 		(void) spl4();
78 		if (vperror(READY)) {
79 			vpclose();
80 			u.u_error = EIO;
81 			return;
82 		}
83 		vpstart();
84 		(void) spl0();
85 	}
86 }
87 
88 vpstrategy(bp)
89 	register struct buf *bp;
90 {
91 	register int e;
92 
93 	(void) spl4();
94 	while (vp11.vp_state & VBUSY)
95 		sleep((caddr_t)&vp11, VPPRI);
96 	vp11.vp_state |= VBUSY;
97 	vp11.vp_bp = bp;
98 	vp_ubinfo = ubasetup(bp, vpbdp);
99 	vp11.vp_bufp = vp_ubinfo & 0x3ffff;
100 	if (e = vperror(READY))
101 		goto brkout;
102 	vp11.vp_count = bp->b_bcount;
103 	vpstart();
104 	while ((vp11.vp_state&PLOT ? VPADDR->plcsr : VPADDR->prcsr) & DMAACT)
105 		sleep((caddr_t)&vp11, VPPRI);
106 	vp11.vp_count = 0;
107 	vp11.vp_bufp = 0;
108 	if ((vp11.vp_state&MODE) == PPLOT)
109 		vp11.vp_state = (vp11.vp_state &~ MODE) | PLOT;
110 	(void) spl0();
111 brkout:
112 	ubarelse(&vp_ubinfo);
113 	vp11.vp_state &= ~VBUSY;
114 	vp11.vp_bp = 0;
115 	iodone(bp);
116 	if (e)
117 		u.u_error = EIO;
118 	wakeup((caddr_t)&vp11);
119 }
120 
121 int	vpblock = 16384;
122 
123 unsigned
124 minvpph(bp)
125 struct buf *bp;
126 {
127 
128 	if (bp->b_bcount > vpblock)
129 		bp->b_bcount = vpblock;
130 }
131 
132 /*ARGSUSED*/
133 vpwrite(dev)
134 {
135 
136 	physio(vpstrategy, &rvpbuf, dev, B_WRITE, minvpph);
137 }
138 
139 vperror(bit)
140 {
141 	register int state, e;
142 
143 	state = vp11.vp_state & PLOT;
144 	while ((e = (state ? VPADDR->plcsr : VPADDR->prcsr) & (bit|ERROR)) == 0)
145 		sleep((caddr_t)&vp11, VPPRI);
146 	return (e & ERROR);
147 }
148 
149 vpstart()
150 {
151 	register short bit;
152 
153 	if (vp11.vp_count) {
154 		VPADDR->pbaddr = vp11.vp_bufp;
155 		VPADDR->pbxaddr = (vp11.vp_bufp>>12)&0x30;
156 		if (vp11.vp_state & (PRINT|PPLOT))
157 			VPADDR->prbcr = vp11.vp_count;
158 		else
159 			VPADDR->plbcr = vp11.vp_count;
160 		return;
161 	}
162 	for (bit = 1; bit != 0; bit <<= 1)
163 		if (vp11.vp_state&bit&CMNDS) {
164 			VPADDR->plcsr |= bit;
165 			vp11.vp_state &= ~bit;
166 			return;
167 		}
168 }
169 
170 /*ARGSUSED*/
171 vpioctl(dev, cmd, addr, flag)
172 	register caddr_t addr;
173 {
174 	register int m;
175 
176 	switch (cmd) {
177 
178 	case ('v'<<8)+0:
179 		(void) suword(addr, vp11.vp_state);
180 		return;
181 
182 	case ('v'<<8)+1:
183 		m = fuword(addr);
184 		if (m == -1) {
185 			u.u_error = EFAULT;
186 			return;
187 		}
188 		vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS));
189 		break;
190 
191 	default:
192 		u.u_error = ENOTTY;
193 		return;
194 	}
195 	(void) spl4();
196 	(void) vperror(READY);
197 	if (vp11.vp_state&PPLOT)
198 		VPADDR->plcsr |= SPP;
199 	else
200 		VPADDR->plcsr &= ~SPP;
201 	vp11.vp_count = 0;
202 	while (CMNDS & vp11.vp_state) {
203 		(void) vperror(READY);
204 		vpstart();
205 	}
206 	(void) spl0();
207 }
208 
209 vptimo()
210 {
211 
212 	if (vp11.vp_state&VISOPEN)
213 		timeout(vptimo, (caddr_t)0, HZ/10);
214 	vpintr(0);
215 }
216 
217 /*ARGSUSED*/
218 vpintr(dev)
219 {
220 
221 	wakeup((caddr_t)&vp11);
222 }
223 
224 vpclose()
225 {
226 
227 	vp11.vp_state = 0;
228 	vp11.vp_count = 0;
229 	vp11.vp_bufp = 0;
230 	VPADDR->plcsr = 0;
231 }
232 
233 vpreset()
234 {
235 
236 	if ((vp11.vp_state & VISOPEN) == 0)
237 		return;
238 	printf(" vp");
239 	VPADDR->prcsr = IENABLE | DTCINTR;
240 	if ((vp11.vp_state & VBUSY) == 0)
241 		return;
242 	if (vp_ubinfo) {
243 		printf("<%d>", (vp_ubinfo>>28)&0xf);
244 		ubarelse(&vp_ubinfo);
245 	}
246 	vp11.vp_bufp = vp_ubinfo & 0x3ffff;
247 	vp11.vp_count = vp11.vp_bp->b_bcount;
248 	vpstart();
249 }
250 #endif
251