fhpib.c revision 1.7 1 1.7 thorpej /* $NetBSD: fhpib.c,v 1.7 1995/11/19 17:57:15 thorpej Exp $ */
2 1.5 cgd
3 1.1 cgd /*
4 1.4 mycroft * Copyright (c) 1982, 1990, 1993
5 1.4 mycroft * The Regents of the University of California. All rights reserved.
6 1.1 cgd *
7 1.1 cgd * Redistribution and use in source and binary forms, with or without
8 1.1 cgd * modification, are permitted provided that the following conditions
9 1.1 cgd * are met:
10 1.1 cgd * 1. Redistributions of source code must retain the above copyright
11 1.1 cgd * notice, this list of conditions and the following disclaimer.
12 1.1 cgd * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 cgd * notice, this list of conditions and the following disclaimer in the
14 1.1 cgd * documentation and/or other materials provided with the distribution.
15 1.1 cgd * 3. All advertising materials mentioning features or use of this software
16 1.1 cgd * must display the following acknowledgement:
17 1.1 cgd * This product includes software developed by the University of
18 1.1 cgd * California, Berkeley and its contributors.
19 1.1 cgd * 4. Neither the name of the University nor the names of its contributors
20 1.1 cgd * may be used to endorse or promote products derived from this software
21 1.1 cgd * without specific prior written permission.
22 1.1 cgd *
23 1.1 cgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 1.1 cgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 1.1 cgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 1.1 cgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 1.1 cgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 1.1 cgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 1.1 cgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 1.1 cgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 1.1 cgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 1.1 cgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 1.1 cgd * SUCH DAMAGE.
34 1.1 cgd *
35 1.5 cgd * @(#)fhpib.c 8.2 (Berkeley) 1/12/94
36 1.1 cgd */
37 1.1 cgd
38 1.1 cgd /*
39 1.1 cgd * 98625A/B HPIB driver
40 1.1 cgd */
41 1.1 cgd #include "hpib.h"
42 1.1 cgd #if NHPIB > 0
43 1.1 cgd
44 1.4 mycroft #include <sys/param.h>
45 1.4 mycroft #include <sys/systm.h>
46 1.6 mycroft #include <sys/kernel.h>
47 1.4 mycroft #include <sys/buf.h>
48 1.4 mycroft
49 1.4 mycroft #include <hp300/dev/device.h>
50 1.4 mycroft #include <hp300/dev/fhpibreg.h>
51 1.4 mycroft #include <hp300/dev/hpibvar.h>
52 1.4 mycroft #include <hp300/dev/dmavar.h>
53 1.1 cgd
54 1.1 cgd /*
55 1.1 cgd * Inline version of fhpibwait to be used in places where
56 1.1 cgd * we don't worry about getting hung.
57 1.1 cgd */
58 1.1 cgd #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
59 1.1 cgd
60 1.1 cgd #ifdef DEBUG
61 1.1 cgd int fhpibdebugunit = -1;
62 1.1 cgd int fhpibdebug = 0;
63 1.1 cgd #define FDB_FAIL 0x01
64 1.1 cgd #define FDB_DMA 0x02
65 1.1 cgd #define FDB_WAIT 0x04
66 1.1 cgd #define FDB_PPOLL 0x08
67 1.1 cgd
68 1.1 cgd int dopriodma = 0; /* use high priority DMA */
69 1.1 cgd int doworddma = 1; /* non-zero if we should attempt word dma */
70 1.1 cgd int doppollint = 1; /* use ppoll interrupts instead of watchdog */
71 1.4 mycroft int fhpibppolldelay = 50;
72 1.1 cgd
73 1.1 cgd long fhpibbadint[2] = { 0 };
74 1.1 cgd long fhpibtransfer[NHPIB] = { 0 };
75 1.1 cgd long fhpibnondma[NHPIB] = { 0 };
76 1.1 cgd long fhpibworddma[NHPIB] = { 0 };
77 1.4 mycroft long fhpibppollfail[NHPIB] = { 0 };
78 1.1 cgd #endif
79 1.1 cgd
80 1.1 cgd int fhpibcmd[NHPIB];
81 1.1 cgd
82 1.7 thorpej void fhpibreset __P((int));
83 1.7 thorpej int fhpibsend __P((int, int, int, void *, int));
84 1.7 thorpej int fhpibrecv __P((int, int, int, void *, int));
85 1.7 thorpej int fhpibppoll __P((int));
86 1.7 thorpej void fhpibppwatch __P((void *));
87 1.7 thorpej void fhpibgo __P((int, int, int, void *, int, int, int));
88 1.7 thorpej void fhpibdone __P((int));
89 1.7 thorpej int fhpibintr __P((int));
90 1.7 thorpej
91 1.7 thorpej /*
92 1.7 thorpej * Our controller ops structure.
93 1.7 thorpej */
94 1.7 thorpej struct hpib_controller fhpib_controller = {
95 1.7 thorpej fhpibreset,
96 1.7 thorpej fhpibsend,
97 1.7 thorpej fhpibrecv,
98 1.7 thorpej fhpibppoll,
99 1.7 thorpej fhpibppwatch,
100 1.7 thorpej fhpibgo,
101 1.7 thorpej fhpibdone,
102 1.7 thorpej fhpibintr
103 1.7 thorpej };
104 1.7 thorpej
105 1.7 thorpej int
106 1.1 cgd fhpibtype(hc)
107 1.1 cgd register struct hp_ctlr *hc;
108 1.1 cgd {
109 1.1 cgd register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
110 1.1 cgd register struct fhpibdevice *hd = (struct fhpibdevice *)hc->hp_addr;
111 1.1 cgd
112 1.1 cgd if (hd->hpib_cid != HPIBC)
113 1.1 cgd return(0);
114 1.7 thorpej
115 1.1 cgd hs->sc_type = HPIBC;
116 1.1 cgd hs->sc_ba = HPIBC_BA;
117 1.1 cgd hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
118 1.7 thorpej
119 1.7 thorpej hs->sc_controller = &fhpib_controller;
120 1.7 thorpej hs->sc_descrip = "98625A or 98625B fast HP-IB";
121 1.1 cgd return(1);
122 1.1 cgd }
123 1.1 cgd
124 1.7 thorpej void
125 1.1 cgd fhpibreset(unit)
126 1.4 mycroft int unit;
127 1.1 cgd {
128 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
129 1.1 cgd register struct fhpibdevice *hd;
130 1.1 cgd
131 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
132 1.1 cgd hd->hpib_cid = 0xFF;
133 1.1 cgd DELAY(100);
134 1.1 cgd hd->hpib_cmd = CT_8BIT;
135 1.1 cgd hd->hpib_ar = AR_ARONC;
136 1.1 cgd fhpibifc(hd);
137 1.1 cgd hd->hpib_ie = IDS_IE;
138 1.1 cgd hd->hpib_data = C_DCL;
139 1.1 cgd DELAY(100000);
140 1.1 cgd /*
141 1.1 cgd * See if we can do word dma.
142 1.1 cgd * If so, we should be able to write and read back the appropos bit.
143 1.1 cgd */
144 1.1 cgd hd->hpib_ie |= IDS_WDMA;
145 1.1 cgd if (hd->hpib_ie & IDS_WDMA) {
146 1.1 cgd hd->hpib_ie &= ~IDS_WDMA;
147 1.1 cgd hs->sc_flags |= HPIBF_DMA16;
148 1.1 cgd #ifdef DEBUG
149 1.1 cgd if (fhpibdebug & FDB_DMA)
150 1.1 cgd printf("fhpibtype: unit %d has word dma\n", unit);
151 1.1 cgd
152 1.1 cgd #endif
153 1.1 cgd }
154 1.1 cgd }
155 1.1 cgd
156 1.1 cgd fhpibifc(hd)
157 1.1 cgd register struct fhpibdevice *hd;
158 1.1 cgd {
159 1.1 cgd hd->hpib_cmd |= CT_IFC;
160 1.1 cgd hd->hpib_cmd |= CT_INITFIFO;
161 1.1 cgd DELAY(100);
162 1.1 cgd hd->hpib_cmd &= ~CT_IFC;
163 1.1 cgd hd->hpib_cmd |= CT_REN;
164 1.1 cgd hd->hpib_stat = ST_ATN;
165 1.1 cgd }
166 1.1 cgd
167 1.7 thorpej int
168 1.7 thorpej fhpibsend(unit, slave, sec, ptr, origcnt)
169 1.4 mycroft int unit, slave, sec, origcnt;
170 1.7 thorpej void *ptr;
171 1.1 cgd {
172 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
173 1.1 cgd register struct fhpibdevice *hd;
174 1.1 cgd register int cnt = origcnt;
175 1.1 cgd register int timo;
176 1.7 thorpej char *addr = ptr;
177 1.1 cgd
178 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
179 1.1 cgd hd->hpib_stat = 0;
180 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
181 1.1 cgd if (fhpibwait(hd, IM_IDLE) < 0)
182 1.1 cgd goto senderr;
183 1.1 cgd hd->hpib_stat = ST_ATN;
184 1.1 cgd hd->hpib_data = C_UNL;
185 1.1 cgd hd->hpib_data = C_TAG + hs->sc_ba;
186 1.1 cgd hd->hpib_data = C_LAG + slave;
187 1.6 mycroft if (sec < 0) {
188 1.6 mycroft if (sec == -2) /* selected device clear KLUDGE */
189 1.6 mycroft hd->hpib_data = C_SDC;
190 1.6 mycroft } else
191 1.1 cgd hd->hpib_data = C_SCG + sec;
192 1.1 cgd if (fhpibwait(hd, IM_IDLE) < 0)
193 1.1 cgd goto senderr;
194 1.1 cgd if (cnt) {
195 1.1 cgd hd->hpib_stat = ST_WRITE;
196 1.1 cgd while (--cnt) {
197 1.1 cgd hd->hpib_data = *addr++;
198 1.1 cgd timo = hpibtimeout;
199 1.1 cgd while ((hd->hpib_intr & IM_ROOM) == 0) {
200 1.1 cgd if (--timo <= 0)
201 1.1 cgd goto senderr;
202 1.1 cgd DELAY(1);
203 1.1 cgd }
204 1.1 cgd }
205 1.1 cgd hd->hpib_stat = ST_EOI;
206 1.1 cgd hd->hpib_data = *addr;
207 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
208 1.1 cgd hd->hpib_stat = ST_ATN;
209 1.1 cgd /* XXX: HP-UX claims bug with CS80 transparent messages */
210 1.1 cgd if (sec == 0x12)
211 1.1 cgd DELAY(150);
212 1.1 cgd hd->hpib_data = C_UNL;
213 1.1 cgd (void) fhpibwait(hd, IM_IDLE);
214 1.1 cgd }
215 1.1 cgd hd->hpib_imask = 0;
216 1.1 cgd return (origcnt);
217 1.6 mycroft
218 1.1 cgd senderr:
219 1.1 cgd hd->hpib_imask = 0;
220 1.1 cgd fhpibifc(hd);
221 1.1 cgd #ifdef DEBUG
222 1.1 cgd if (fhpibdebug & FDB_FAIL) {
223 1.1 cgd printf("hpib%d: fhpibsend failed: slave %d, sec %x, ",
224 1.1 cgd unit, slave, sec);
225 1.1 cgd printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
226 1.1 cgd }
227 1.1 cgd #endif
228 1.6 mycroft return (origcnt - cnt - 1);
229 1.1 cgd }
230 1.1 cgd
231 1.7 thorpej int
232 1.7 thorpej fhpibrecv(unit, slave, sec, ptr, origcnt)
233 1.4 mycroft int unit, slave, sec, origcnt;
234 1.7 thorpej void *ptr;
235 1.1 cgd {
236 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
237 1.1 cgd register struct fhpibdevice *hd;
238 1.1 cgd register int cnt = origcnt;
239 1.1 cgd register int timo;
240 1.7 thorpej char *addr = ptr;
241 1.1 cgd
242 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
243 1.6 mycroft /*
244 1.6 mycroft * Slave < 0 implies continuation of a previous receive
245 1.6 mycroft * that probably timed out.
246 1.6 mycroft */
247 1.6 mycroft if (slave >= 0) {
248 1.6 mycroft hd->hpib_stat = 0;
249 1.6 mycroft hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
250 1.6 mycroft if (fhpibwait(hd, IM_IDLE) < 0)
251 1.6 mycroft goto recverror;
252 1.6 mycroft hd->hpib_stat = ST_ATN;
253 1.6 mycroft hd->hpib_data = C_UNL;
254 1.6 mycroft hd->hpib_data = C_LAG + hs->sc_ba;
255 1.6 mycroft hd->hpib_data = C_TAG + slave;
256 1.6 mycroft if (sec != -1)
257 1.6 mycroft hd->hpib_data = C_SCG + sec;
258 1.6 mycroft if (fhpibwait(hd, IM_IDLE) < 0)
259 1.6 mycroft goto recverror;
260 1.6 mycroft hd->hpib_stat = ST_READ0;
261 1.6 mycroft hd->hpib_data = 0;
262 1.6 mycroft }
263 1.1 cgd if (cnt) {
264 1.1 cgd while (--cnt >= 0) {
265 1.1 cgd timo = hpibtimeout;
266 1.1 cgd while ((hd->hpib_intr & IM_BYTE) == 0) {
267 1.1 cgd if (--timo == 0)
268 1.1 cgd goto recvbyteserror;
269 1.1 cgd DELAY(1);
270 1.1 cgd }
271 1.1 cgd *addr++ = hd->hpib_data;
272 1.1 cgd }
273 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
274 1.1 cgd hd->hpib_stat = ST_ATN;
275 1.1 cgd hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
276 1.1 cgd (void) fhpibwait(hd, IM_IDLE);
277 1.1 cgd }
278 1.1 cgd hd->hpib_imask = 0;
279 1.1 cgd return (origcnt);
280 1.1 cgd
281 1.1 cgd recverror:
282 1.1 cgd fhpibifc(hd);
283 1.1 cgd recvbyteserror:
284 1.1 cgd hd->hpib_imask = 0;
285 1.1 cgd #ifdef DEBUG
286 1.1 cgd if (fhpibdebug & FDB_FAIL) {
287 1.1 cgd printf("hpib%d: fhpibrecv failed: slave %d, sec %x, ",
288 1.1 cgd unit, slave, sec);
289 1.1 cgd printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
290 1.1 cgd }
291 1.1 cgd #endif
292 1.6 mycroft return (origcnt - cnt - 1);
293 1.1 cgd }
294 1.1 cgd
295 1.7 thorpej void
296 1.7 thorpej fhpibgo(unit, slave, sec, ptr, count, rw, timo)
297 1.7 thorpej int unit, slave, sec, count, rw, timo;
298 1.7 thorpej void *ptr;
299 1.1 cgd {
300 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
301 1.1 cgd register struct fhpibdevice *hd;
302 1.1 cgd register int i;
303 1.7 thorpej char *addr = ptr;
304 1.1 cgd int flags = 0;
305 1.1 cgd
306 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
307 1.1 cgd hs->sc_flags |= HPIBF_IO;
308 1.6 mycroft if (timo)
309 1.6 mycroft hs->sc_flags |= HPIBF_TIMO;
310 1.1 cgd if (rw == B_READ)
311 1.1 cgd hs->sc_flags |= HPIBF_READ;
312 1.1 cgd #ifdef DEBUG
313 1.1 cgd else if (hs->sc_flags & HPIBF_READ) {
314 1.1 cgd printf("fhpibgo: HPIBF_READ still set\n");
315 1.1 cgd hs->sc_flags &= ~HPIBF_READ;
316 1.1 cgd }
317 1.1 cgd #endif
318 1.1 cgd hs->sc_count = count;
319 1.1 cgd hs->sc_addr = addr;
320 1.1 cgd #ifdef DEBUG
321 1.1 cgd fhpibtransfer[unit]++;
322 1.1 cgd #endif
323 1.1 cgd if ((hs->sc_flags & HPIBF_DMA16) &&
324 1.1 cgd ((int)addr & 1) == 0 && count && (count & 1) == 0
325 1.1 cgd #ifdef DEBUG
326 1.1 cgd && doworddma
327 1.1 cgd #endif
328 1.1 cgd ) {
329 1.1 cgd #ifdef DEBUG
330 1.1 cgd fhpibworddma[unit]++;
331 1.1 cgd #endif
332 1.1 cgd flags |= DMAGO_WORD;
333 1.1 cgd hd->hpib_latch = 0;
334 1.1 cgd }
335 1.1 cgd #ifdef DEBUG
336 1.1 cgd if (dopriodma)
337 1.1 cgd flags |= DMAGO_PRI;
338 1.1 cgd #endif
339 1.1 cgd if (hs->sc_flags & HPIBF_READ) {
340 1.1 cgd fhpibcmd[unit] = CT_REN | CT_8BIT;
341 1.1 cgd hs->sc_curcnt = count;
342 1.1 cgd dmago(hs->sc_dq.dq_ctlr, addr, count, flags|DMAGO_READ);
343 1.1 cgd if (fhpibrecv(unit, slave, sec, 0, 0) < 0) {
344 1.1 cgd #ifdef DEBUG
345 1.1 cgd printf("fhpibgo: recv failed, retrying...\n");
346 1.1 cgd #endif
347 1.1 cgd (void) fhpibrecv(unit, slave, sec, 0, 0);
348 1.1 cgd }
349 1.1 cgd i = hd->hpib_cmd;
350 1.1 cgd hd->hpib_cmd = fhpibcmd[unit];
351 1.1 cgd hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) |
352 1.1 cgd ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
353 1.1 cgd return;
354 1.1 cgd }
355 1.1 cgd fhpibcmd[unit] = CT_REN | CT_8BIT | CT_FIFOSEL;
356 1.1 cgd if (count < hpibdmathresh) {
357 1.1 cgd #ifdef DEBUG
358 1.1 cgd fhpibnondma[unit]++;
359 1.1 cgd if (flags & DMAGO_WORD)
360 1.1 cgd fhpibworddma[unit]--;
361 1.1 cgd #endif
362 1.1 cgd hs->sc_curcnt = count;
363 1.1 cgd (void) fhpibsend(unit, slave, sec, addr, count);
364 1.1 cgd fhpibdone(unit);
365 1.1 cgd return;
366 1.1 cgd }
367 1.1 cgd count -= (flags & DMAGO_WORD) ? 2 : 1;
368 1.1 cgd hs->sc_curcnt = count;
369 1.1 cgd dmago(hs->sc_dq.dq_ctlr, addr, count, flags);
370 1.1 cgd if (fhpibsend(unit, slave, sec, 0, 0) < 0) {
371 1.1 cgd #ifdef DEBUG
372 1.1 cgd printf("fhpibgo: send failed, retrying...\n");
373 1.1 cgd #endif
374 1.1 cgd (void) fhpibsend(unit, slave, sec, 0, 0);
375 1.1 cgd }
376 1.1 cgd i = hd->hpib_cmd;
377 1.1 cgd hd->hpib_cmd = fhpibcmd[unit];
378 1.1 cgd hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) | IDS_WRITE |
379 1.1 cgd ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
380 1.1 cgd }
381 1.1 cgd
382 1.6 mycroft /*
383 1.6 mycroft * A DMA read can finish but the device can still be waiting (MAG-tape
384 1.6 mycroft * with more data than we're waiting for). This timeout routine
385 1.6 mycroft * takes care of that. Somehow, the thing gets hosed. For now, since
386 1.6 mycroft * this should be a very rare occurence, we RESET it.
387 1.6 mycroft */
388 1.6 mycroft void
389 1.6 mycroft fhpibdmadone(arg)
390 1.6 mycroft void *arg;
391 1.6 mycroft {
392 1.6 mycroft register int unit;
393 1.6 mycroft register struct hpib_softc *hs;
394 1.6 mycroft int s = splbio();
395 1.6 mycroft
396 1.6 mycroft unit = (int)arg;
397 1.6 mycroft hs = &hpib_softc[unit];
398 1.6 mycroft if (hs->sc_flags & HPIBF_IO) {
399 1.6 mycroft register struct fhpibdevice *hd;
400 1.6 mycroft register struct devqueue *dq;
401 1.6 mycroft
402 1.6 mycroft hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
403 1.6 mycroft hd->hpib_imask = 0;
404 1.6 mycroft hd->hpib_cid = 0xFF;
405 1.6 mycroft DELAY(100);
406 1.6 mycroft hd->hpib_cmd = CT_8BIT;
407 1.6 mycroft hd->hpib_ar = AR_ARONC;
408 1.6 mycroft fhpibifc(hd);
409 1.6 mycroft hd->hpib_ie = IDS_IE;
410 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
411 1.6 mycroft dmafree(&hs->sc_dq);
412 1.6 mycroft dq = hs->sc_sq.dq_forw;
413 1.6 mycroft (dq->dq_driver->d_intr)(dq->dq_unit);
414 1.6 mycroft }
415 1.6 mycroft (void) splx(s);
416 1.6 mycroft }
417 1.6 mycroft
418 1.7 thorpej void
419 1.1 cgd fhpibdone(unit)
420 1.4 mycroft int unit;
421 1.1 cgd {
422 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
423 1.1 cgd register struct fhpibdevice *hd;
424 1.1 cgd register char *addr;
425 1.1 cgd register int cnt;
426 1.1 cgd
427 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
428 1.1 cgd cnt = hs->sc_curcnt;
429 1.1 cgd hs->sc_addr += cnt;
430 1.1 cgd hs->sc_count -= cnt;
431 1.1 cgd #ifdef DEBUG
432 1.1 cgd if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
433 1.1 cgd printf("fhpibdone: addr %x cnt %d\n",
434 1.1 cgd hs->sc_addr, hs->sc_count);
435 1.1 cgd #endif
436 1.6 mycroft if (hs->sc_flags & HPIBF_READ) {
437 1.1 cgd hd->hpib_imask = IM_IDLE | IM_BYTE;
438 1.6 mycroft if (hs->sc_flags & HPIBF_TIMO)
439 1.6 mycroft timeout(fhpibdmadone, (void *)unit, hz >> 2);
440 1.6 mycroft } else {
441 1.1 cgd cnt = hs->sc_count;
442 1.1 cgd if (cnt) {
443 1.1 cgd addr = hs->sc_addr;
444 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
445 1.1 cgd FHPIBWAIT(hd, IM_IDLE);
446 1.1 cgd hd->hpib_stat = ST_WRITE;
447 1.1 cgd while (--cnt) {
448 1.1 cgd hd->hpib_data = *addr++;
449 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
450 1.1 cgd }
451 1.1 cgd hd->hpib_stat = ST_EOI;
452 1.1 cgd hd->hpib_data = *addr;
453 1.1 cgd }
454 1.1 cgd hd->hpib_imask = IM_IDLE;
455 1.1 cgd }
456 1.1 cgd hs->sc_flags |= HPIBF_DONE;
457 1.1 cgd hd->hpib_stat = ST_IENAB;
458 1.1 cgd hd->hpib_ie = IDS_IE;
459 1.1 cgd }
460 1.1 cgd
461 1.7 thorpej int
462 1.1 cgd fhpibintr(unit)
463 1.1 cgd register int unit;
464 1.1 cgd {
465 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
466 1.1 cgd register struct fhpibdevice *hd;
467 1.1 cgd register struct devqueue *dq;
468 1.1 cgd register int stat0;
469 1.1 cgd
470 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
471 1.1 cgd stat0 = hd->hpib_ids;
472 1.1 cgd if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
473 1.1 cgd #ifdef DEBUG
474 1.1 cgd if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
475 1.1 cgd (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
476 1.1 cgd printf("hpib%d: fhpibintr: bad status %x\n",
477 1.1 cgd unit, stat0);
478 1.1 cgd fhpibbadint[0]++;
479 1.1 cgd #endif
480 1.1 cgd return(0);
481 1.1 cgd }
482 1.1 cgd if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
483 1.1 cgd #ifdef DEBUG
484 1.1 cgd fhpibbadint[1]++;
485 1.1 cgd #endif
486 1.1 cgd return(0);
487 1.1 cgd }
488 1.1 cgd #ifdef DEBUG
489 1.1 cgd if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
490 1.1 cgd printf("fhpibintr: flags %x\n", hs->sc_flags);
491 1.1 cgd #endif
492 1.1 cgd dq = hs->sc_sq.dq_forw;
493 1.1 cgd if (hs->sc_flags & HPIBF_IO) {
494 1.6 mycroft if (hs->sc_flags & HPIBF_TIMO)
495 1.6 mycroft untimeout(fhpibdmadone, (void *)unit);
496 1.1 cgd stat0 = hd->hpib_cmd;
497 1.1 cgd hd->hpib_cmd = fhpibcmd[unit] & ~CT_8BIT;
498 1.1 cgd hd->hpib_stat = 0;
499 1.1 cgd hd->hpib_cmd = CT_REN | CT_8BIT;
500 1.1 cgd stat0 = hd->hpib_intr;
501 1.1 cgd hd->hpib_imask = 0;
502 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
503 1.1 cgd dmafree(&hs->sc_dq);
504 1.1 cgd (dq->dq_driver->d_intr)(dq->dq_unit);
505 1.1 cgd } else if (hs->sc_flags & HPIBF_PPOLL) {
506 1.1 cgd stat0 = hd->hpib_intr;
507 1.1 cgd #ifdef DEBUG
508 1.1 cgd if ((fhpibdebug & FDB_FAIL) &&
509 1.1 cgd doppollint && (stat0 & IM_PPRESP) == 0)
510 1.1 cgd printf("hpib%d: fhpibintr: bad intr reg %x\n",
511 1.1 cgd unit, stat0);
512 1.1 cgd #endif
513 1.1 cgd hd->hpib_stat = 0;
514 1.1 cgd hd->hpib_imask = 0;
515 1.1 cgd #ifdef DEBUG
516 1.1 cgd stat0 = fhpibppoll(unit);
517 1.1 cgd if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
518 1.1 cgd printf("fhpibintr: got PPOLL status %x\n", stat0);
519 1.1 cgd if ((stat0 & (0x80 >> dq->dq_slave)) == 0) {
520 1.4 mycroft /*
521 1.4 mycroft * XXX give it another shot (68040)
522 1.4 mycroft */
523 1.4 mycroft fhpibppollfail[unit]++;
524 1.4 mycroft DELAY(fhpibppolldelay);
525 1.4 mycroft stat0 = fhpibppoll(unit);
526 1.4 mycroft if ((stat0 & (0x80 >> dq->dq_slave)) == 0 &&
527 1.4 mycroft (fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
528 1.4 mycroft printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
529 1.4 mycroft unit, dq->dq_slave, stat0);
530 1.1 cgd }
531 1.1 cgd #endif
532 1.1 cgd hs->sc_flags &= ~HPIBF_PPOLL;
533 1.1 cgd (dq->dq_driver->d_intr)(dq->dq_unit);
534 1.1 cgd }
535 1.1 cgd return(1);
536 1.1 cgd }
537 1.1 cgd
538 1.7 thorpej int
539 1.1 cgd fhpibppoll(unit)
540 1.4 mycroft int unit;
541 1.1 cgd {
542 1.1 cgd register struct fhpibdevice *hd;
543 1.1 cgd register int ppoll;
544 1.1 cgd
545 1.1 cgd hd = (struct fhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
546 1.1 cgd hd->hpib_stat = 0;
547 1.1 cgd hd->hpib_psense = 0;
548 1.1 cgd hd->hpib_pmask = 0xFF;
549 1.1 cgd hd->hpib_imask = IM_PPRESP | IM_PABORT;
550 1.1 cgd DELAY(25);
551 1.1 cgd hd->hpib_intr = IM_PABORT;
552 1.1 cgd ppoll = hd->hpib_data;
553 1.1 cgd if (hd->hpib_intr & IM_PABORT)
554 1.1 cgd ppoll = 0;
555 1.1 cgd hd->hpib_imask = 0;
556 1.1 cgd hd->hpib_pmask = 0;
557 1.1 cgd hd->hpib_stat = ST_IENAB;
558 1.1 cgd return(ppoll);
559 1.1 cgd }
560 1.1 cgd
561 1.7 thorpej int
562 1.1 cgd fhpibwait(hd, x)
563 1.1 cgd register struct fhpibdevice *hd;
564 1.4 mycroft int x;
565 1.1 cgd {
566 1.1 cgd register int timo = hpibtimeout;
567 1.1 cgd
568 1.1 cgd while ((hd->hpib_intr & x) == 0 && --timo)
569 1.1 cgd DELAY(1);
570 1.1 cgd if (timo == 0) {
571 1.1 cgd #ifdef DEBUG
572 1.1 cgd if (fhpibdebug & FDB_FAIL)
573 1.1 cgd printf("fhpibwait(%x, %x) timeout\n", hd, x);
574 1.1 cgd #endif
575 1.1 cgd return(-1);
576 1.1 cgd }
577 1.1 cgd return(0);
578 1.1 cgd }
579 1.1 cgd
580 1.1 cgd /*
581 1.4 mycroft * XXX: this will have to change if we ever allow more than one
582 1.1 cgd * pending operation per HP-IB.
583 1.1 cgd */
584 1.4 mycroft void
585 1.3 mycroft fhpibppwatch(arg)
586 1.3 mycroft void *arg;
587 1.1 cgd {
588 1.4 mycroft register int unit;
589 1.4 mycroft register struct hpib_softc *hs;
590 1.1 cgd register struct fhpibdevice *hd;
591 1.1 cgd register int slave;
592 1.1 cgd
593 1.4 mycroft unit = (int)arg;
594 1.4 mycroft hs = &hpib_softc[unit];
595 1.1 cgd if ((hs->sc_flags & HPIBF_PPOLL) == 0)
596 1.1 cgd return;
597 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
598 1.1 cgd slave = (0x80 >> hs->sc_sq.dq_forw->dq_slave);
599 1.1 cgd #ifdef DEBUG
600 1.1 cgd if (!doppollint) {
601 1.1 cgd if (fhpibppoll(unit) & slave) {
602 1.1 cgd hd->hpib_stat = ST_IENAB;
603 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
604 1.1 cgd } else
605 1.3 mycroft timeout(fhpibppwatch, (void *)unit, 1);
606 1.1 cgd return;
607 1.1 cgd }
608 1.1 cgd if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
609 1.1 cgd printf("fhpibppwatch: sense request on %d\n", unit);
610 1.1 cgd #endif
611 1.1 cgd hd->hpib_psense = ~slave;
612 1.1 cgd hd->hpib_pmask = slave;
613 1.1 cgd hd->hpib_stat = ST_IENAB;
614 1.1 cgd hd->hpib_imask = IM_PPRESP | IM_PABORT;
615 1.1 cgd hd->hpib_ie = IDS_IE;
616 1.1 cgd }
617 1.7 thorpej #endif /* NHPIB > 0 */
618