xref: /original-bsd/sys/vax/uba/vp.c (revision d25e1985)
1 /*	vp.c	3.4	06/22/80	*/
2 
3 #include "../h/param.h"
4 #include "../h/dir.h"
5 #include "../h/user.h"
6 #include "../h/buf.h"
7 #include "../h/systm.h"
8 #include "../h/map.h"
9 #include "../h/pte.h"
10 #include "../h/uba.h"
11 
12 /*
13  * Versatec matrix printer/plotter
14  * dma interface driver
15  */
16 int	vpbdp = 1;
17 
18 unsigned minvpph();
19 
20 #define	VPPRI	(PZERO-1)
21 
22 struct	vpregs {
23 	short	plbcr;
24 	short	fill;
25 	short	prbcr;
26 	unsigned short pbaddr;
27 	short	plcsr;
28 	short	plbuf;
29 	short	prcsr;
30 	unsigned short prbuf;
31 };
32 
33 #define	VPADDR	((struct vpregs *)(UBA0_DEV + 0177500))
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 	ubafree(vp_ubinfo), vp_ubinfo = 0;
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 		if (vp11.vp_state & (PRINT|PPLOT))
156 			VPADDR->prbcr = vp11.vp_count;
157 		else
158 			VPADDR->plbcr = vp11.vp_count;
159 		return;
160 	}
161 	for (bit = 1; bit != 0; bit <<= 1)
162 		if (vp11.vp_state&bit&CMNDS) {
163 			VPADDR->plcsr |= bit;
164 			vp11.vp_state &= ~bit;
165 			return;
166 		}
167 }
168 
169 /*ARGSUSED*/
170 vpioctl(dev, cmd, addr, flag)
171 	register caddr_t addr;
172 {
173 	register int m;
174 
175 	switch (cmd) {
176 
177 	case ('v'<<8)+0:
178 		(void) suword(addr, vp11.vp_state);
179 		return;
180 
181 	case ('v'<<8)+1:
182 		m = fuword(addr);
183 		if (m == -1) {
184 			u.u_error = EFAULT;
185 			return;
186 		}
187 		vp11.vp_state = (vp11.vp_state & ~MODE) | (m&(MODE|CMNDS));
188 		break;
189 
190 	default:
191 		u.u_error = ENOTTY;
192 		return;
193 	}
194 	(void) spl4();
195 	(void) vperror(READY);
196 	if (vp11.vp_state&PPLOT)
197 		VPADDR->plcsr |= SPP;
198 	else
199 		VPADDR->plcsr &= ~SPP;
200 	vp11.vp_count = 0;
201 	while (CMNDS & vp11.vp_state) {
202 		(void) vperror(READY);
203 		vpstart();
204 	}
205 	(void) spl0();
206 }
207 
208 vptimo()
209 {
210 
211 	if (vp11.vp_state&VISOPEN)
212 		timeout(vptimo, (caddr_t)0, HZ/10);
213 	vpintr(0);
214 }
215 
216 /*ARGSUSED*/
217 vpintr(dev)
218 {
219 
220 	wakeup((caddr_t)&vp11);
221 }
222 
223 vpclose()
224 {
225 
226 	vp11.vp_state = 0;
227 	vp11.vp_count = 0;
228 	vp11.vp_bufp = 0;
229 	VPADDR->plcsr = 0;
230 }
231 
232 vpreset()
233 {
234 
235 	if ((vp11.vp_state & VISOPEN) == 0)
236 		return;
237 	printf(" vp");
238 	VPADDR->prcsr = IENABLE | DTCINTR;
239 	if ((vp11.vp_state & VBUSY) == 0)
240 		return;
241 	if (vp_ubinfo) {
242 		printf("<%d>", (vp_ubinfo>>28)&0xf);
243 		ubafree(vp_ubinfo), vp_ubinfo = 0;
244 	}
245 	vp11.vp_bufp = vp_ubinfo & 0x3ffff;
246 	vp11.vp_count = vp11.vp_bp->b_bcount;
247 	vpstart();
248 }
249