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