xref: /netbsd-src/sys/arch/hp300/dev/hpib.c (revision 81b108b45f75f89f1e3ffad9fb6f074e771c0935)
1 /*	$NetBSD: hpib.c,v 1.9 1996/05/17 15:09:39 thorpej Exp $	*/
2 
3 /*
4  * Copyright (c) 1982, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)hpib.c	8.2 (Berkeley) 1/12/94
36  */
37 
38 /*
39  * HPIB driver
40  */
41 #include "hpib.h"
42 #if NHPIB > 0
43 
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/buf.h>
47 
48 #include <hp300/dev/device.h>
49 #include <hp300/dev/hpibvar.h>
50 #include <hp300/dev/dmavar.h>
51 
52 #include <machine/cpu.h>
53 #include <hp300/hp300/isr.h>
54 
55 int	hpibmatch __P((struct hp_ctlr *));
56 void	hpibattach __P((struct hp_ctlr *));
57 void	hpibstart __P((int));
58 void	hpibgo __P((int, int, int, void *, int, int, int));
59 void	hpibdone __P((int));
60 int	hpibintr __P((void *));
61 
62 struct	driver hpibdriver = {
63 	hpibmatch,
64 	hpibattach,
65 	"hpib",
66 	(int(*)())hpibstart,			/* XXX */
67 	(int(*)())hpibgo,			/* XXX */
68 	hpibintr,
69 	(int(*)())hpibdone,			/* XXX */
70 };
71 
72 struct	hpib_softc hpib_softc[NHPIB];
73 
74 extern	int nhpibtype __P((struct hp_ctlr *));	/* XXX */
75 extern	int fhpibtype __P((struct hp_ctlr *));	/* XXX */
76 extern	void nhpibattach __P((struct hp_ctlr *));	/* XXX */
77 extern	void fhpibattach __P((struct hp_ctlr *));	/* XXX */
78 
79 int	hpibtimeout = 100000;	/* # of status tests before we give up */
80 int	hpibidtimeout = 10000;	/* # of status tests for hpibid() calls */
81 int	hpibdmathresh = 3;	/* byte count beyond which to attempt dma */
82 
83 int
84 hpibmatch(hc)
85 	register struct hp_ctlr *hc;
86 {
87 	struct hp_hw *hw = hc->hp_args;
88 	extern caddr_t internalhpib;
89 
90 	/* Special case for internal HP-IB. */
91 	if ((hw->hw_sc == 7) && internalhpib)
92 		goto hwid_ok;
93 
94 	switch (hw->hw_id) {
95 	case 8:			/* 98625B */
96 	case 128:		/* 98624A */
97  hwid_ok:
98 		if (nhpibtype(hc) || fhpibtype(hc))
99 			return (1);
100 	}
101 
102 	return (0);
103 }
104 
105 void
106 hpibattach(hc)
107 	struct hp_ctlr *hc;
108 {
109 	struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
110 
111 	/*
112 	 * Call the appropriate "attach" routine for this controller.
113 	 * The type is set in the "type" routine.
114 	 *
115 	 * XXX This is, by the way, exactly backwards.
116 	 */
117 	switch (hs->sc_type) {
118 	case HPIBA:
119 	case HPIBB:
120 		nhpibattach(hc);
121 		break;
122 
123 	case HPIBC:
124 		fhpibattach(hc);
125 		break;
126 
127 	default:
128 		panic("hpibattach: unknown type 0x%x", hs->sc_type);
129 		/* NOTREACHED */
130 	}
131 
132 	hs->sc_hc = hc;
133 	hs->sc_dq.dq_unit = hc->hp_unit;
134 	hs->sc_dq.dq_driver = &hpibdriver;
135 	hs->sc_sq.dq_forw = hs->sc_sq.dq_back = &hs->sc_sq;
136 
137 	/* Establish the interrupt handler. */
138 	isrlink(hpibintr, hs, hc->hp_ipl, ISRPRI_BIO);
139 
140 	/* Reset the controller, display what we've seen, and we're done. */
141 	hpibreset(hc->hp_unit);
142 	printf(": %s\n", hs->sc_descrip);
143 }
144 
145 void
146 hpibreset(unit)
147 	register int unit;
148 {
149 
150 	(hpib_softc[unit].sc_controller->hpib_reset)(unit);
151 }
152 
153 int
154 hpibreq(dq)
155 	register struct devqueue *dq;
156 {
157 	register struct devqueue *hq;
158 
159 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
160 	insque(dq, hq->dq_back);
161 	if (dq->dq_back == hq)
162 		return(1);
163 	return(0);
164 }
165 
166 void
167 hpibfree(dq)
168 	register struct devqueue *dq;
169 {
170 	register struct devqueue *hq;
171 
172 	hq = &hpib_softc[dq->dq_ctlr].sc_sq;
173 	remque(dq);
174 	if ((dq = hq->dq_forw) != hq)
175 		(dq->dq_driver->d_start)(dq->dq_unit);
176 }
177 
178 int
179 hpibid(unit, slave)
180 	int unit, slave;
181 {
182 	short id;
183 	int ohpibtimeout;
184 
185 	/*
186 	 * XXX shorten timeout value so autoconfig doesn't
187 	 * take forever on slow CPUs.
188 	 */
189 	ohpibtimeout = hpibtimeout;
190 	hpibtimeout = hpibidtimeout * (cpuspeed / 8);
191 	if (hpibrecv(unit, 31, slave, &id, 2) != 2)
192 		id = 0;
193 	hpibtimeout = ohpibtimeout;
194 	return(id);
195 }
196 
197 int
198 hpibsend(unit, slave, sec, addr, cnt)
199 	int unit, slave, sec, cnt;
200 	void *addr;
201 {
202 
203 	return ((hpib_softc[unit].sc_controller->hpib_send)(unit, slave,
204 	    sec, addr, cnt));
205 }
206 
207 int
208 hpibrecv(unit, slave, sec, addr, cnt)
209 	int unit, slave, sec, cnt;
210 	void *addr;
211 {
212 
213 	return ((hpib_softc[unit].sc_controller->hpib_recv)(unit, slave,
214 	    sec, addr, cnt));
215 }
216 
217 int
218 hpibpptest(unit, slave)
219 	register int unit;
220 	int slave;
221 {
222 
223 	return ((hpib_softc[unit].sc_controller->hpib_ppoll)(unit) &
224 	    (0x80 >> slave));
225 }
226 
227 void
228 hpibppclear(unit)
229 	int unit;
230 {
231 	hpib_softc[unit].sc_flags &= ~HPIBF_PPOLL;
232 }
233 
234 hpibawait(unit)
235 	int unit;
236 {
237 	register struct hpib_softc *hs = &hpib_softc[unit];
238 
239 	hs->sc_flags |= HPIBF_PPOLL;
240 	(hs->sc_controller->hpib_ppwatch)((void *)unit);
241 }
242 
243 int
244 hpibswait(unit, slave)
245 	register int unit;
246 	int slave;
247 {
248 	register int timo = hpibtimeout;
249 	register int mask, (*ppoll) __P((int));
250 
251 	ppoll = hpib_softc[unit].sc_controller->hpib_ppoll;
252 	mask = 0x80 >> slave;
253 	while (((ppoll)(unit) & mask) == 0)
254 		if (--timo == 0) {
255 			printf("%s: swait timeout\n",
256 			    hpib_softc[unit].sc_hc->hp_xname);
257 			return(-1);
258 		}
259 	return(0);
260 }
261 
262 int
263 hpibustart(unit)
264 	int unit;
265 {
266 	register struct hpib_softc *hs = &hpib_softc[unit];
267 
268 	if (hs->sc_type == HPIBA)
269 		hs->sc_dq.dq_ctlr = DMA0;
270 	else
271 		hs->sc_dq.dq_ctlr = DMA0 | DMA1;
272 	if (dmareq(&hs->sc_dq))
273 		return(1);
274 	return(0);
275 }
276 
277 void
278 hpibstart(unit)
279 	int unit;
280 {
281 	register struct devqueue *dq;
282 
283 	dq = hpib_softc[unit].sc_sq.dq_forw;
284 	(dq->dq_driver->d_go)(dq->dq_unit);
285 }
286 
287 void
288 hpibgo(unit, slave, sec, addr, count, rw, timo)
289 	int unit, slave, sec, count, rw, timo;
290 	void *addr;
291 {
292 
293 	(hpib_softc[unit].sc_controller->hpib_go)(unit, slave, sec,
294 	    addr, count, rw, timo);
295 }
296 
297 void
298 hpibdone(unit)
299 	register int unit;
300 {
301 
302 	(hpib_softc[unit].sc_controller->hpib_done)(unit);
303 }
304 
305 int
306 hpibintr(arg)
307 	void *arg;
308 {
309 	struct hpib_softc *hs = arg;
310 
311 	return ((hs->sc_controller->hpib_intr)(arg));
312 }
313 #endif /* NHPIB > 0 */
314