1 /*
2 * Copyright (c) 1982, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 *
7 * @(#)ppi.c 8.2 (Berkeley) 01/09/95
8 */
9
10 /*
11 * Printer/Plotter HPIB interface
12 */
13
14 #include "ppi.h"
15 #if NPPI > 0
16
17 #include <sys/param.h>
18 #include <sys/systm.h>
19 #include <sys/errno.h>
20 #include <sys/uio.h>
21 #include <sys/malloc.h>
22
23 #include <hp/dev/device.h>
24 #include <hp300/dev/ppiioctl.h>
25
26 int ppiattach(), ppistart();
27 void ppitimo();
28 struct driver ppidriver = {
29 ppiattach, "ppi", ppistart,
30 };
31
32 struct ppi_softc {
33 int sc_flags;
34 struct devqueue sc_dq;
35 struct hp_device *sc_hd;
36 struct ppiparam sc_param;
37 #define sc_burst sc_param.burst
38 #define sc_timo sc_param.timo
39 #define sc_delay sc_param.delay
40 int sc_sec;
41 } ppi_softc[NPPI];
42
43 /* sc_flags values */
44 #define PPIF_ALIVE 0x01
45 #define PPIF_OPEN 0x02
46 #define PPIF_UIO 0x04
47 #define PPIF_TIMO 0x08
48 #define PPIF_DELAY 0x10
49
50 #define UNIT(x) minor(x)
51
52 #ifdef DEBUG
53 int ppidebug = 0x80;
54 #define PDB_FOLLOW 0x01
55 #define PDB_IO 0x02
56 #define PDB_NOCHECK 0x80
57 #endif
58
ppiattach(hd)59 ppiattach(hd)
60 register struct hp_device *hd;
61 {
62 register struct ppi_softc *sc = &ppi_softc[hd->hp_unit];
63
64 #ifdef DEBUG
65 if ((ppidebug & PDB_NOCHECK) == 0)
66 #endif
67 /*
68 * XXX: the printer/plotter doesn't seem to really return
69 * an ID but this will at least prevent us from mistaking
70 * a cs80 disk or tape for a ppi device.
71 */
72 if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200)
73 return(0);
74 sc->sc_flags = PPIF_ALIVE;
75 sc->sc_dq.dq_ctlr = hd->hp_ctlr;
76 sc->sc_dq.dq_unit = hd->hp_unit;
77 sc->sc_dq.dq_slave = hd->hp_slave;
78 sc->sc_dq.dq_driver = &ppidriver;
79 sc->sc_hd = hd;
80 return(1);
81 }
82
ppiopen(dev,flags)83 ppiopen(dev, flags)
84 dev_t dev;
85 {
86 register int unit = UNIT(dev);
87 register struct ppi_softc *sc = &ppi_softc[unit];
88
89 if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0)
90 return(ENXIO);
91 #ifdef DEBUG
92 if (ppidebug & PDB_FOLLOW)
93 printf("ppiopen(%x, %x): flags %x\n",
94 dev, flags, sc->sc_flags);
95 #endif
96 if (sc->sc_flags & PPIF_OPEN)
97 return(EBUSY);
98 sc->sc_flags |= PPIF_OPEN;
99 sc->sc_burst = PPI_BURST;
100 sc->sc_timo = ppimstohz(PPI_TIMO);
101 sc->sc_delay = ppimstohz(PPI_DELAY);
102 sc->sc_sec = -1;
103 return(0);
104 }
105
ppiclose(dev,flags)106 ppiclose(dev, flags)
107 dev_t dev;
108 {
109 register int unit = UNIT(dev);
110 register struct ppi_softc *sc = &ppi_softc[unit];
111
112 #ifdef DEBUG
113 if (ppidebug & PDB_FOLLOW)
114 printf("ppiclose(%x, %x): flags %x\n",
115 dev, flags, sc->sc_flags);
116 #endif
117 sc->sc_flags &= ~PPIF_OPEN;
118 return(0);
119 }
120
ppistart(unit)121 ppistart(unit)
122 int unit;
123 {
124 #ifdef DEBUG
125 if (ppidebug & PDB_FOLLOW)
126 printf("ppistart(%x)\n", unit);
127 #endif
128 ppi_softc[unit].sc_flags &= ~PPIF_DELAY;
129 wakeup(&ppi_softc[unit]);
130 return (0);
131 }
132
133 void
ppitimo(unit)134 ppitimo(unit)
135 int unit;
136 {
137 #ifdef DEBUG
138 if (ppidebug & PDB_FOLLOW)
139 printf("ppitimo(%x)\n", unit);
140 #endif
141 ppi_softc[unit].sc_flags &= ~(PPIF_UIO|PPIF_TIMO);
142 wakeup(&ppi_softc[unit]);
143 }
144
ppiread(dev,uio)145 ppiread(dev, uio)
146 dev_t dev;
147 struct uio *uio;
148 {
149
150 #ifdef DEBUG
151 if (ppidebug & PDB_FOLLOW)
152 printf("ppiread(%x, %x)\n", dev, uio);
153 #endif
154 return (ppirw(dev, uio));
155 }
156
ppiwrite(dev,uio)157 ppiwrite(dev, uio)
158 dev_t dev;
159 struct uio *uio;
160 {
161
162 #ifdef DEBUG
163 if (ppidebug & PDB_FOLLOW)
164 printf("ppiwrite(%x, %x)\n", dev, uio);
165 #endif
166 return (ppirw(dev, uio));
167 }
168
ppirw(dev,uio)169 ppirw(dev, uio)
170 dev_t dev;
171 register struct uio *uio;
172 {
173 int unit = UNIT(dev);
174 register struct ppi_softc *sc = &ppi_softc[unit];
175 register int s, len, cnt;
176 register char *cp;
177 int error = 0, gotdata = 0;
178 int buflen;
179 char *buf;
180
181 if (uio->uio_resid == 0)
182 return(0);
183
184 #ifdef DEBUG
185 if (ppidebug & (PDB_FOLLOW|PDB_IO))
186 printf("ppirw(%x, %x, %c): burst %d, timo %d, resid %x\n",
187 dev, uio, uio->uio_rw == UIO_READ ? 'R' : 'W',
188 sc->sc_burst, sc->sc_timo, uio->uio_resid);
189 #endif
190 buflen = min(sc->sc_burst, uio->uio_resid);
191 buf = (char *)malloc(buflen, M_DEVBUF, M_WAITOK);
192 sc->sc_flags |= PPIF_UIO;
193 if (sc->sc_timo > 0) {
194 sc->sc_flags |= PPIF_TIMO;
195 timeout(ppitimo, (void *)unit, sc->sc_timo);
196 }
197 while (uio->uio_resid > 0) {
198 len = min(buflen, uio->uio_resid);
199 cp = buf;
200 if (uio->uio_rw == UIO_WRITE) {
201 error = uiomove(cp, len, uio);
202 if (error)
203 break;
204 }
205 again:
206 s = splbio();
207 if ((sc->sc_flags & PPIF_UIO) && hpibreq(&sc->sc_dq) == 0)
208 sleep(sc, PRIBIO+1);
209 /*
210 * Check if we timed out during sleep or uiomove
211 */
212 (void) splsoftclock();
213 if ((sc->sc_flags & PPIF_UIO) == 0) {
214 #ifdef DEBUG
215 if (ppidebug & PDB_IO)
216 printf("ppirw: uiomove/sleep timo, flags %x\n",
217 sc->sc_flags);
218 #endif
219 if (sc->sc_flags & PPIF_TIMO) {
220 untimeout(ppitimo, (void *)unit);
221 sc->sc_flags &= ~PPIF_TIMO;
222 }
223 splx(s);
224 break;
225 }
226 splx(s);
227 /*
228 * Perform the operation
229 */
230 if (uio->uio_rw == UIO_WRITE)
231 cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
232 sc->sc_sec, cp, len);
233 else
234 cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
235 sc->sc_sec, cp, len);
236 s = splbio();
237 hpibfree(&sc->sc_dq);
238 #ifdef DEBUG
239 if (ppidebug & PDB_IO)
240 printf("ppirw: %s(%d, %d, %x, %x, %d) -> %d\n",
241 uio->uio_rw == UIO_READ ? "recv" : "send",
242 sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
243 sc->sc_sec, cp, len, cnt);
244 #endif
245 splx(s);
246 if (uio->uio_rw == UIO_READ) {
247 if (cnt) {
248 error = uiomove(cp, cnt, uio);
249 if (error)
250 break;
251 gotdata++;
252 }
253 /*
254 * Didn't get anything this time, but did in the past.
255 * Consider us done.
256 */
257 else if (gotdata)
258 break;
259 }
260 s = splsoftclock();
261 /*
262 * Operation timeout (or non-blocking), quit now.
263 */
264 if ((sc->sc_flags & PPIF_UIO) == 0) {
265 #ifdef DEBUG
266 if (ppidebug & PDB_IO)
267 printf("ppirw: timeout/done\n");
268 #endif
269 splx(s);
270 break;
271 }
272 /*
273 * Implement inter-read delay
274 */
275 if (sc->sc_delay > 0) {
276 sc->sc_flags |= PPIF_DELAY;
277 timeout((void (*)__P((void *)))ppistart, (void *)unit,
278 sc->sc_delay);
279 error = tsleep(sc, PCATCH|PZERO+1, "hpib", 0);
280 if (error) {
281 splx(s);
282 break;
283 }
284 }
285 splx(s);
286 /*
287 * Must not call uiomove again til we've used all data
288 * that we already grabbed.
289 */
290 if (uio->uio_rw == UIO_WRITE && cnt != len) {
291 cp += cnt;
292 len -= cnt;
293 cnt = 0;
294 goto again;
295 }
296 }
297 s = splsoftclock();
298 if (sc->sc_flags & PPIF_TIMO) {
299 untimeout(ppitimo, (void *)unit);
300 sc->sc_flags &= ~PPIF_TIMO;
301 }
302 if (sc->sc_flags & PPIF_DELAY) {
303 untimeout((void (*)__P((void *)))ppistart, (void *)unit);
304 sc->sc_flags &= ~PPIF_DELAY;
305 }
306 splx(s);
307 /*
308 * Adjust for those chars that we uiomove'ed but never wrote
309 */
310 if (uio->uio_rw == UIO_WRITE && cnt != len) {
311 uio->uio_resid += (len - cnt);
312 #ifdef DEBUG
313 if (ppidebug & PDB_IO)
314 printf("ppirw: short write, adjust by %d\n",
315 len-cnt);
316 #endif
317 }
318 free(buf, M_DEVBUF);
319 #ifdef DEBUG
320 if (ppidebug & (PDB_FOLLOW|PDB_IO))
321 printf("ppirw: return %d, resid %d\n", error, uio->uio_resid);
322 #endif
323 return (error);
324 }
325
ppiioctl(dev,cmd,data,flag)326 ppiioctl(dev, cmd, data, flag)
327 dev_t dev;
328 u_long cmd;
329 caddr_t data;
330 int flag;
331 {
332 struct ppi_softc *sc = &ppi_softc[UNIT(dev)];
333 struct ppiparam *pp, *upp;
334 int error = 0;
335
336 switch (cmd) {
337 case PPIIOCGPARAM:
338 pp = &sc->sc_param;
339 upp = (struct ppiparam *)data;
340 upp->burst = pp->burst;
341 upp->timo = ppihztoms(pp->timo);
342 upp->delay = ppihztoms(pp->delay);
343 break;
344 case PPIIOCSPARAM:
345 pp = &sc->sc_param;
346 upp = (struct ppiparam *)data;
347 if (upp->burst < PPI_BURST_MIN || upp->burst > PPI_BURST_MAX ||
348 upp->delay < PPI_DELAY_MIN || upp->delay > PPI_DELAY_MAX)
349 return(EINVAL);
350 pp->burst = upp->burst;
351 pp->timo = ppimstohz(upp->timo);
352 pp->delay = ppimstohz(upp->delay);
353 break;
354 case PPIIOCSSEC:
355 sc->sc_sec = *(int *)data;
356 break;
357 default:
358 return(EINVAL);
359 }
360 return (error);
361 }
362
ppihztoms(h)363 ppihztoms(h)
364 int h;
365 {
366 extern int hz;
367 register int m = h;
368
369 if (m > 0)
370 m = m * 1000 / hz;
371 return(m);
372 }
373
ppimstohz(m)374 ppimstohz(m)
375 int m;
376 {
377 extern int hz;
378 register int h = m;
379
380 if (h > 0) {
381 h = h * hz / 1000;
382 if (h == 0)
383 h = 1000 / hz;
384 }
385 return(h);
386 }
387 #endif
388