Commit | Line | Data |
---|---|---|
fc4d0a69 | 1 | /* va.c 4.9 81/03/10 */ |
20cc8b5b | 2 | |
66b4fb09 | 3 | #include "va.h" |
a5cc519e BJ |
4 | #if NVA > 0 |
5 | /* | |
fc4d0a69 | 6 | * Varian printer plotter |
a5cc519e | 7 | */ |
20cc8b5b BJ |
8 | #include "../h/param.h" |
9 | #include "../h/dir.h" | |
10 | #include "../h/user.h" | |
11 | #include "../h/buf.h" | |
12 | #include "../h/systm.h" | |
13 | #include "../h/map.h" | |
14 | #include "../h/pte.h" | |
fc4d0a69 BJ |
15 | #include "../h/ubareg.h" |
16 | #include "../h/ubavar.h" | |
20cc8b5b BJ |
17 | #include "../h/vcmd.h" |
18 | ||
71357272 | 19 | unsigned minvaph(); |
20cc8b5b BJ |
20 | |
21 | #define VAPRI (PZERO-1) | |
22 | ||
fc4d0a69 BJ |
23 | struct vadevice { |
24 | u_short vaba; /* buffer address */ | |
25 | short vawc; /* word count (2's complement) */ | |
20cc8b5b | 26 | union { |
fc4d0a69 BJ |
27 | short Vacsw; /* control status as word */ |
28 | struct { /* control status as bytes */ | |
71357272 BJ |
29 | char Vacsl; |
30 | char Vacsh; | |
31 | } vacsr; | |
32 | } vacs; | |
fc4d0a69 | 33 | short vadata; /* programmed i/o data buffer */ |
20cc8b5b BJ |
34 | }; |
35 | ||
71357272 BJ |
36 | #define vacsw vacs.Vacsw |
37 | #define vacsh vacs.vacsr.Vacsh | |
38 | #define vacsl vacs.vacsr.Vacsl | |
39 | ||
71357272 | 40 | /* vacsw bits */ |
fc4d0a69 BJ |
41 | #define VA_ERROR 0100000 /* some error has occurred */ |
42 | #define VA_NPRTIMO 0001000 /* DMA timeout error */ | |
43 | #define VA_NOTREADY 0000400 /* something besides NPRTIMO */ | |
44 | #define VA_DONE 0000200 | |
45 | #define VA_IENABLE 0000100 /* interrupt enable */ | |
46 | #define VA_SUPPLIESLOW 0000004 | |
47 | #define VA_BOTOFFORM 0000002 | |
48 | #define VA_BYTEREVERSE 0000001 /* reverse byte order in words */ | |
71357272 BJ |
49 | |
50 | /* vacsh command bytes */ | |
fc4d0a69 BJ |
51 | #define VAPLOT 0000340 |
52 | #define VAPRINT 0000100 | |
53 | #define VAPRINTPLOT 0000160 | |
54 | #define VAAUTOSTEP 0000244 | |
55 | #define VANOAUTOSTEP 0000045 | |
56 | #define VAFORMFEED 0000263 | |
57 | #define VASLEW 0000265 | |
58 | #define VASTEP 0000064 | |
59 | ||
60 | struct va_softc { | |
61 | char sc_openf; | |
62 | char sc_busy; | |
63 | int sc_state; | |
64 | int sc_wc; | |
65 | struct buf *sc_bp; | |
66 | int sc_ubinfo; | |
67 | } va_softc[NVA]; | |
68 | ||
69 | struct uba_device *vadinfo[NVA]; | |
70 | ||
71 | #define VAUNIT(dev) (minor(dev)) | |
72 | ||
73 | struct buf rvabuf[NVA]; | |
74 | ||
75 | int vaprobe(), vaattach(); | |
76 | struct uba_device *vadinfo[NVA]; | |
77 | u_short vastd[] = { 0764000, 0 }; | |
78 | struct uba_driver vadriver = | |
79 | { vaprobe, 0, vaattach, 0, vastd, "va", vadinfo }; | |
80 | ||
81 | vaprobe(reg) | |
82 | caddr_t reg; | |
83 | { | |
84 | register int br, cvec; /* value-result */ | |
85 | register struct vadevice *vaaddr = (struct vadevice *)reg; | |
86 | ||
87 | vaaddr->vacsl = VA_IENABLE; | |
88 | vaaddr->vaba = 0; | |
89 | vaaddr->vacsh = VAPLOT; | |
90 | vaaddr->vacsl = 0; | |
91 | vaaddr->vawc = -1; | |
92 | DELAY(10000); | |
93 | vaaddr->vacsl = 0; | |
94 | } | |
95 | ||
96 | /*ARGSUSED*/ | |
97 | vaattach(ui) | |
98 | struct uba_device *ui; | |
99 | { | |
100 | ||
101 | } | |
102 | ||
103 | vaopen(dev) | |
104 | dev_t dev; | |
20cc8b5b | 105 | { |
fc4d0a69 BJ |
106 | register struct va_softc *sc; |
107 | register struct vadevice *vaaddr; | |
108 | register struct uba_device *ui; | |
20cc8b5b | 109 | |
fc4d0a69 BJ |
110 | if (VAUNIT(dev) >= NVA || (sc = &va_softc[minor(dev)])->sc_openf || |
111 | (ui = vadinfo[VAUNIT(dev)]) == 0 || ui->ui_alive == 0) { | |
20cc8b5b BJ |
112 | u.u_error = ENXIO; |
113 | return; | |
114 | } | |
fc4d0a69 BJ |
115 | vaaddr = (struct vadevice *)ui->ui_addr; |
116 | sc->sc_openf = 1; | |
117 | vaaddr->vawc = 0; | |
118 | sc->sc_wc = 0; | |
119 | sc->sc_state = 0; | |
120 | vaaddr->vacsl = VA_IENABLE; | |
121 | vatimo(dev); | |
122 | vacmd(dev, VPRINT); | |
20cc8b5b | 123 | if (u.u_error) |
fc4d0a69 | 124 | vaclose(dev); |
20cc8b5b BJ |
125 | } |
126 | ||
127 | vastrategy(bp) | |
128 | register struct buf *bp; | |
129 | { | |
130 | register int e; | |
fc4d0a69 BJ |
131 | register struct va_softc *sc = &va_softc[VAUNIT(bp->b_dev)]; |
132 | register struct uba_device *ui = vadinfo[VAUNIT(bp->b_dev)]; | |
133 | register struct vadevice *vaaddr = (struct vadevice *)ui->ui_addr; | |
20cc8b5b | 134 | |
81263dba | 135 | (void) spl4(); |
fc4d0a69 BJ |
136 | while (sc->sc_busy) |
137 | sleep((caddr_t)sc, VAPRI); | |
138 | sc->sc_busy = 1; | |
139 | sc->sc_bp = bp; | |
140 | sc->sc_ubinfo = ubasetup(ui->ui_ubanum, bp, UBA_NEEDBDP); | |
141 | if (e = vawait(bp->b_dev)) | |
20cc8b5b | 142 | goto brkout; |
fc4d0a69 BJ |
143 | sc->sc_wc = -(bp->b_bcount/2); |
144 | vastart(bp->b_dev); | |
145 | e = vawait(bp->b_dev); | |
146 | sc->sc_wc = 0; | |
147 | if (sc->sc_state & VPRINTPLOT) { | |
148 | sc->sc_state = (sc->sc_state & ~VPRINTPLOT) | VPLOT; | |
149 | vaaddr->vacsh = VAAUTOSTEP; | |
150 | e |= vawait(bp->b_dev); | |
20cc8b5b | 151 | } |
81263dba | 152 | (void) spl0(); |
20cc8b5b | 153 | brkout: |
fc4d0a69 BJ |
154 | ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); |
155 | sc->sc_bp = 0; | |
156 | sc->sc_busy = 0; | |
20cc8b5b BJ |
157 | iodone(bp); |
158 | if (e) | |
159 | u.u_error = EIO; | |
fc4d0a69 | 160 | wakeup((caddr_t)sc); |
20cc8b5b BJ |
161 | } |
162 | ||
163 | int vablock = 16384; | |
164 | ||
165 | unsigned | |
166 | minvaph(bp) | |
fc4d0a69 | 167 | struct buf *bp; |
20cc8b5b | 168 | { |
fc4d0a69 | 169 | |
20cc8b5b BJ |
170 | if (bp->b_bcount > vablock) |
171 | bp->b_bcount = vablock; | |
172 | } | |
173 | ||
174 | /*ARGSUSED*/ | |
175 | vawrite(dev) | |
fc4d0a69 | 176 | dev_t dev; |
20cc8b5b | 177 | { |
fc4d0a69 BJ |
178 | |
179 | physio(vastrategy, &rvabuf[VAUNIT(dev)], dev, B_WRITE, minvaph); | |
20cc8b5b BJ |
180 | } |
181 | ||
fc4d0a69 BJ |
182 | vawait(dev) |
183 | dev_t dev; | |
20cc8b5b | 184 | { |
fc4d0a69 BJ |
185 | register struct vadevice *vaaddr = |
186 | (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; | |
20cc8b5b BJ |
187 | register int e; |
188 | ||
fc4d0a69 BJ |
189 | while (((e = vaaddr->vacsw) & (VA_DONE|VA_ERROR)) == 0) |
190 | sleep((caddr_t)&va_softc[VAUNIT(dev)], VAPRI); | |
191 | if (e & VA_NPRTIMO) | |
192 | printf("va%d: npr timeout\n", VAUNIT(dev)); | |
193 | return (e & VA_ERROR); | |
20cc8b5b BJ |
194 | } |
195 | ||
fc4d0a69 BJ |
196 | vastart(dev) |
197 | dev_t; | |
20cc8b5b | 198 | { |
fc4d0a69 BJ |
199 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
200 | register struct vadevice *vaaddr = | |
201 | (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; | |
202 | ||
203 | if (sc->sc_wc == 0) | |
20cc8b5b | 204 | return; |
fc4d0a69 BJ |
205 | vaaddr->vaba = sc->sc_ubinfo; |
206 | vaaddr->vacsl = (sc->sc_ubinfo >> 12) & 0x30; | |
207 | vaaddr->vawc = sc->sc_wc; | |
20cc8b5b BJ |
208 | } |
209 | ||
210 | /*ARGSUSED*/ | |
211 | vaioctl(dev, cmd, addr, flag) | |
212 | register caddr_t addr; | |
213 | { | |
214 | register int vcmd; | |
fc4d0a69 | 215 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
20cc8b5b BJ |
216 | |
217 | switch (cmd) { | |
218 | ||
219 | case VGETSTATE: | |
fc4d0a69 | 220 | (void) suword(addr, sc->sc_state); |
20cc8b5b BJ |
221 | return; |
222 | ||
223 | case VSETSTATE: | |
224 | vcmd = fuword(addr); | |
225 | if (vcmd == -1) { | |
226 | u.u_error = EFAULT; | |
227 | return; | |
228 | } | |
fc4d0a69 | 229 | vacmd(dev, vcmd); |
20cc8b5b BJ |
230 | return; |
231 | ||
232 | default: | |
fc4d0a69 | 233 | u.u_error = ENOTTY; |
20cc8b5b BJ |
234 | return; |
235 | } | |
236 | } | |
237 | ||
fc4d0a69 BJ |
238 | vacmd(dev, vcmd) |
239 | dev_t dev; | |
240 | int vcmd; | |
20cc8b5b | 241 | { |
fc4d0a69 BJ |
242 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
243 | register struct vadevice *vaaddr = | |
244 | (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; | |
245 | ||
81263dba | 246 | (void) spl4(); |
fc4d0a69 | 247 | (void) vawait(dev); |
20cc8b5b BJ |
248 | switch (vcmd) { |
249 | ||
250 | case VPLOT: | |
251 | /* Must turn on plot AND autostep modes. */ | |
fc4d0a69 BJ |
252 | vaaddr->vacsh = VAPLOT; |
253 | if (vawait(dev)) | |
20cc8b5b | 254 | u.u_error = EIO; |
fc4d0a69 | 255 | vaaddr->vacsh = VAAUTOSTEP; |
20cc8b5b BJ |
256 | break; |
257 | ||
258 | case VPRINT: | |
fc4d0a69 | 259 | vaaddr->vacsh = VAPRINT; |
20cc8b5b BJ |
260 | break; |
261 | ||
262 | case VPRINTPLOT: | |
fc4d0a69 | 263 | vaaddr->vacsh = VAPRINTPLOT; |
20cc8b5b BJ |
264 | break; |
265 | } | |
fc4d0a69 BJ |
266 | sc->sc_state = (sc->sc_state & ~(VPLOT|VPRINT|VPRINTPLOT)) | vcmd; |
267 | if (vawait(dev)) | |
20cc8b5b | 268 | u.u_error = EIO; |
81263dba | 269 | (void) spl0(); |
20cc8b5b BJ |
270 | } |
271 | ||
fc4d0a69 BJ |
272 | vatimo(dev) |
273 | dev_t dev; | |
20cc8b5b | 274 | { |
fc4d0a69 BJ |
275 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
276 | ||
277 | if (sc->sc_openf) | |
278 | timeout(vatimo, (caddr_t)dev, hz/10); | |
279 | vaintr(dev); | |
20cc8b5b BJ |
280 | } |
281 | ||
282 | /*ARGSUSED*/ | |
283 | vaintr(dev) | |
fc4d0a69 | 284 | dev_t dev; |
20cc8b5b | 285 | { |
fc4d0a69 BJ |
286 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
287 | ||
288 | wakeup((caddr_t)sc); | |
20cc8b5b BJ |
289 | } |
290 | ||
fc4d0a69 BJ |
291 | vaclose(dev) |
292 | dev_t dev; | |
20cc8b5b | 293 | { |
fc4d0a69 BJ |
294 | register struct va_softc *sc = &va_softc[VAUNIT(dev)]; |
295 | register struct vadevice *vaaddr = | |
296 | (struct vadevice *)vadinfo[VAUNIT(dev)]->ui_addr; | |
297 | ||
298 | sc->sc_openf = 0; | |
299 | sc->sc_busy = 0; | |
300 | sc->sc_state = 0; | |
301 | sc->sc_ubinfo = 0; | |
302 | vaaddr->vacsl = 0; | |
71357272 BJ |
303 | } |
304 | ||
fc4d0a69 BJ |
305 | vareset(uban) |
306 | int uban; | |
71357272 | 307 | { |
fc4d0a69 BJ |
308 | register int va11; |
309 | register struct uba_device *ui; | |
310 | register struct va_softc *sc = va_softc; | |
311 | register struct vadevice *vaaddr; | |
312 | ||
313 | for (va11 = 0; va11 < NVA; va11++, sc++) { | |
314 | if ((ui = vadinfo[va11]) == 0 || ui->ui_alive == 0 || | |
315 | ui->ui_ubanum != uban || sc->sc_openf == 0) | |
316 | continue; | |
317 | printf(" va%d", va11); | |
318 | vaaddr = (struct vadevice *)ui->ui_addr; | |
319 | vaaddr->vacsl = VA_IENABLE; | |
320 | if (sc->sc_state & VPLOT) { | |
321 | vaaddr->vacsh = VAPLOT; | |
322 | DELAY(10000); | |
323 | vaaddr->vacsh = VAAUTOSTEP; | |
324 | } else if (sc->sc_state & VPRINTPLOT) | |
325 | vaaddr->vacsh = VPRINTPLOT; | |
326 | else | |
327 | vaaddr->vacsh = VAPRINTPLOT; | |
71357272 | 328 | DELAY(10000); |
fc4d0a69 BJ |
329 | if (sc->sc_busy == 0) |
330 | continue; | |
331 | if (sc->sc_ubinfo) { | |
332 | printf("<%d>", (sc->sc_ubinfo>>28)&0xf); | |
333 | ubarelse(ui->ui_ubanum, &sc->sc_ubinfo); | |
334 | } | |
335 | sc->sc_ubinfo = ubasetup(ui->ui_ubanum, sc->sc_bp, UBA_NEEDBDP); | |
336 | sc->sc_wc = -(sc->sc_bp->b_bcount/2); | |
337 | vastart(sc->sc_bp->b_dev); | |
71357272 | 338 | } |
20cc8b5b | 339 | } |
a5cc519e | 340 | #endif |