hpib.c revision 1.8 1 /* $NetBSD: hpib.c,v 1.8 1996/02/14 02:44:28 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;
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