getmdev no more dev_t
[unix-history] / usr / src / sys / vax / uba / vp.c
CommitLineData
6dcc6a91 1/* vp.c 4.24 83/03/10 */
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*/
249vpioctl(dev, cmd, addr, flag)
fc4d0a69
BJ
250 dev_t dev;
251 int cmd;
2a75a0e9 252 register caddr_t addr;
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
BJ
262 case VGETSTATE:
263 (void) suword(addr, sc->sc_state);
7da157da 264 break;
2a75a0e9 265
fc4d0a69 266 case VSETSTATE:
2a75a0e9 267 m = fuword(addr);
7da157da
BJ
268 if (m == -1)
269 return (EFAULT);
fc4d0a69
BJ
270 sc->sc_state =
271 (sc->sc_state & ~VPSC_MODE) | (m&(VPSC_MODE|VPSC_CMNDS));
2a75a0e9
BJ
272 break;
273
274 default:
7da157da 275 return (ENOTTY);
2a75a0e9 276 }
81263dba 277 (void) spl4();
fc4d0a69
BJ
278 (void) vpwait(dev);
279 if (sc->sc_state&VPSC_SPP)
280 vpaddr->plcsr |= VP_SPP;
2a75a0e9 281 else
fc4d0a69
BJ
282 vpaddr->plcsr &= ~VP_SPP;
283 sc->sc_count = 0;
284 while (sc->sc_state & VPSC_CMNDS) {
285 (void) vpwait(dev);
286 vpstart(dev);
2a75a0e9 287 }
81263dba 288 (void) spl0();
7da157da 289 return (0);
2a75a0e9
BJ
290}
291
fc4d0a69
BJ
292vptimo(dev)
293 dev_t dev;
2a75a0e9 294{
fc4d0a69 295 register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
2a75a0e9 296
fc4d0a69
BJ
297 if (sc->sc_state&VPSC_OPEN)
298 timeout(vptimo, (caddr_t)dev, hz/10);
299 vpintr(dev);
2a75a0e9
BJ
300}
301
302/*ARGSUSED*/
303vpintr(dev)
fc4d0a69 304 dev_t dev;
2a75a0e9 305{
fc4d0a69 306 register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
2a75a0e9 307
fc4d0a69 308 wakeup((caddr_t)sc);
2a75a0e9
BJ
309}
310
fc4d0a69
BJ
311vpclose(dev)
312 dev_t dev;
2a75a0e9 313{
fc4d0a69
BJ
314 register struct vp_softc *sc = &vp_softc[VPUNIT(dev)];
315 register struct vpdevice *vpaddr =
316 (struct vpdevice *)vpdinfo[VPUNIT(dev)]->ui_addr;
2a75a0e9 317
fc4d0a69
BJ
318 sc->sc_state = 0;
319 sc->sc_count = 0;
320 vpaddr->plcsr = 0;
2a75a0e9 321}
d62630e9 322
fc4d0a69
BJ
323vpreset(uban)
324 int uban;
d62630e9 325{
fc4d0a69
BJ
326 register int vp11;
327 register struct uba_device *ui;
328 register struct vp_softc *sc = vp_softc;
329 register struct vpdevice *vpaddr;
330
331 for (vp11 = 0; vp11 < NVP; vp11++, sc++) {
332 if ((ui = vpdinfo[vp11]) == 0 || ui->ui_alive == 0 ||
333 ui->ui_ubanum != uban || (sc->sc_state&VPSC_OPEN) == 0)
334 continue;
335 printf(" vp%d", vp11);
336 vpaddr = (struct vpdevice *)ui->ui_addr;
337 vpaddr->prcsr = VP_IENABLE|VP_DTCINTR;
338 if ((sc->sc_state & VPSC_BUSY) == 0)
339 continue;
7da157da 340 sc->sc_ubinfo = 0;
fc4d0a69
BJ
341 sc->sc_count = sc->sc_bp->b_bcount;
342 vpstart(sc->sc_bp->b_dev);
d62630e9 343 }
d62630e9 344}
941b74fe
SL
345
346vpselect()
347{
348 return (1);
349}
a5cc519e 350#endif