xref: /csrg-svn/sys/hp300/dev/ppi.c (revision 41480)
1*41480Smckusick /*
2*41480Smckusick  * Copyright (c) 1982, 1990 The Regents of the University of California.
3*41480Smckusick  * All rights reserved.
4*41480Smckusick  *
5*41480Smckusick  * %sccs.include.redist.c%
6*41480Smckusick  *
7*41480Smckusick  *	@(#)ppi.c	7.1 (Berkeley) 05/08/90
8*41480Smckusick  */
9*41480Smckusick 
10*41480Smckusick /*
11*41480Smckusick  * Printer/Plotter HPIB interface
12*41480Smckusick  */
13*41480Smckusick 
14*41480Smckusick #include "ppi.h"
15*41480Smckusick #if NPPI > 0
16*41480Smckusick 
17*41480Smckusick #include "param.h"
18*41480Smckusick #include "errno.h"
19*41480Smckusick #include "uio.h"
20*41480Smckusick #include "malloc.h"
21*41480Smckusick 
22*41480Smckusick #include "device.h"
23*41480Smckusick 
24*41480Smckusick int	ppiattach(), ppistart();
25*41480Smckusick struct	driver ppidriver = {
26*41480Smckusick 	ppiattach, "ppi", ppistart,
27*41480Smckusick };
28*41480Smckusick 
29*41480Smckusick struct	ppi_softc {
30*41480Smckusick 	int	sc_flags;
31*41480Smckusick 	struct	devqueue sc_dq;
32*41480Smckusick 	struct	hp_device *sc_hd;
33*41480Smckusick } ppi_softc[NPPI];
34*41480Smckusick 
35*41480Smckusick /* sc_flags values */
36*41480Smckusick #define	PPIF_ALIVE	0x1
37*41480Smckusick #define	PPIF_OPEN	0x2
38*41480Smckusick 
39*41480Smckusick #define UNIT(x)		minor(x)
40*41480Smckusick 
41*41480Smckusick ppiattach(hd)
42*41480Smckusick 	register struct hp_device *hd;
43*41480Smckusick {
44*41480Smckusick 	register struct ppi_softc *sc = &ppi_softc[hd->hp_unit];
45*41480Smckusick 
46*41480Smckusick 	/*
47*41480Smckusick 	 * XXX: the printer/plotter doesn't seem to really return
48*41480Smckusick 	 * an ID but this will at least prevent us from mistaking
49*41480Smckusick 	 * a cs80 disk or tape for a ppi device.
50*41480Smckusick 	 */
51*41480Smckusick 	if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200)
52*41480Smckusick 		return(0);
53*41480Smckusick 	sc->sc_flags = PPIF_ALIVE;
54*41480Smckusick 	sc->sc_dq.dq_ctlr = hd->hp_ctlr;
55*41480Smckusick 	sc->sc_dq.dq_unit = hd->hp_unit;
56*41480Smckusick 	sc->sc_dq.dq_slave = hd->hp_slave;
57*41480Smckusick 	sc->sc_dq.dq_driver = &ppidriver;
58*41480Smckusick 	sc->sc_hd = hd;
59*41480Smckusick 	return(1);
60*41480Smckusick }
61*41480Smckusick 
62*41480Smckusick ppiopen(dev, flags)
63*41480Smckusick 	dev_t dev;
64*41480Smckusick {
65*41480Smckusick 	register int unit = UNIT(dev);
66*41480Smckusick 	register struct ppi_softc *sc = &ppi_softc[unit];
67*41480Smckusick 
68*41480Smckusick 	if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0)
69*41480Smckusick 		return(ENXIO);
70*41480Smckusick 	if (sc->sc_flags & PPIF_OPEN)
71*41480Smckusick 		return(EBUSY);
72*41480Smckusick 	sc->sc_flags |= PPIF_OPEN;
73*41480Smckusick 	return(0);
74*41480Smckusick }
75*41480Smckusick 
76*41480Smckusick ppiclose(dev, flags)
77*41480Smckusick 	dev_t dev;
78*41480Smckusick {
79*41480Smckusick 	register int unit = UNIT(dev);
80*41480Smckusick 	register struct ppi_softc *sc = &ppi_softc[unit];
81*41480Smckusick 
82*41480Smckusick 	sc->sc_flags &= ~PPIF_OPEN;
83*41480Smckusick 	return(0);
84*41480Smckusick }
85*41480Smckusick 
86*41480Smckusick ppistart(unit)
87*41480Smckusick 	register int unit;
88*41480Smckusick {
89*41480Smckusick 	wakeup(&ppi_softc[unit]);
90*41480Smckusick }
91*41480Smckusick 
92*41480Smckusick ppiread(dev, uio)
93*41480Smckusick 	dev_t dev;
94*41480Smckusick 	struct uio *uio;
95*41480Smckusick {
96*41480Smckusick 
97*41480Smckusick 	return (ppirw(dev, uio, UIO_READ));
98*41480Smckusick }
99*41480Smckusick 
100*41480Smckusick ppiwrite(dev, uio)
101*41480Smckusick 	dev_t dev;
102*41480Smckusick 	struct uio *uio;
103*41480Smckusick {
104*41480Smckusick 
105*41480Smckusick 	return (ppirw(dev, uio, UIO_WRITE));
106*41480Smckusick }
107*41480Smckusick 
108*41480Smckusick ppirw(dev, uio, rw)
109*41480Smckusick 	dev_t dev;
110*41480Smckusick 	register struct uio *uio;
111*41480Smckusick 	enum uio_rw rw;
112*41480Smckusick {
113*41480Smckusick 	register struct ppi_softc *sc = &ppi_softc[UNIT(dev)];
114*41480Smckusick 	register int s, len, cnt;
115*41480Smckusick 	register char *cp;
116*41480Smckusick 	int error = 0;
117*41480Smckusick 
118*41480Smckusick 	len = MIN(CLBYTES, uio->uio_resid);
119*41480Smckusick 	cp = (char *)malloc(len, M_TEMP, M_WAITOK);
120*41480Smckusick 	while (uio->uio_resid > 0) {
121*41480Smckusick 		len = MIN(CLBYTES, uio->uio_resid);
122*41480Smckusick 		if (rw == UIO_WRITE) {
123*41480Smckusick 			error = uiomove(cp, len, uio);
124*41480Smckusick 			if (error)
125*41480Smckusick 				break;
126*41480Smckusick 		}
127*41480Smckusick 		s = splbio();
128*41480Smckusick 		if (hpibreq(&sc->sc_dq) == 0)
129*41480Smckusick 			sleep(sc, PRIBIO + 1);
130*41480Smckusick 		splx(s);
131*41480Smckusick 		if (rw == UIO_WRITE)
132*41480Smckusick 			cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
133*41480Smckusick 				-1, cp, len);
134*41480Smckusick 		else
135*41480Smckusick 			cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave,
136*41480Smckusick 				-1, cp, len);
137*41480Smckusick 		s = splbio();
138*41480Smckusick 		hpibfree(&sc->sc_dq);
139*41480Smckusick 		splx(s);
140*41480Smckusick 		if (rw == UIO_READ) {
141*41480Smckusick 			error = uiomove(cp, cnt, uio);
142*41480Smckusick 			if (error)
143*41480Smckusick 				break;
144*41480Smckusick 		}
145*41480Smckusick 		if (cnt != len) {
146*41480Smckusick 			if (rw == UIO_WRITE)
147*41480Smckusick 				uio->uio_resid += len - cnt;
148*41480Smckusick 			break;
149*41480Smckusick 		}
150*41480Smckusick 	}
151*41480Smckusick 	free(cp, M_TEMP);
152*41480Smckusick 	return (error);
153*41480Smckusick }
154*41480Smckusick #endif
155