fhpib.c revision 1.13 1 1.13 christos /* $NetBSD: fhpib.c,v 1.13 1996/10/13 03:14:10 christos 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.11 thorpej #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.9 thorpej int fhpibintr __P((void *));
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.8 thorpej return (0);
114 1.7 thorpej
115 1.1 cgd hs->sc_type = HPIBC;
116 1.1 cgd hc->hp_ipl = HPIB_IPL(hd->hpib_ids);
117 1.7 thorpej
118 1.8 thorpej return (1);
119 1.8 thorpej }
120 1.8 thorpej
121 1.8 thorpej void
122 1.8 thorpej fhpibattach(hc)
123 1.8 thorpej struct hp_ctlr *hc;
124 1.8 thorpej {
125 1.8 thorpej register struct hpib_softc *hs = &hpib_softc[hc->hp_unit];
126 1.8 thorpej
127 1.8 thorpej if (hs->sc_type != HPIBC)
128 1.8 thorpej panic("fhpibattach: unknown type 0x%x", hs->sc_type);
129 1.8 thorpej /* NOTREACHED */
130 1.8 thorpej
131 1.8 thorpej hs->sc_ba = HPIBC_BA;
132 1.8 thorpej hs->sc_descrip = "98625A or 98625B fast HP-IB";
133 1.7 thorpej hs->sc_controller = &fhpib_controller;
134 1.1 cgd }
135 1.1 cgd
136 1.7 thorpej void
137 1.1 cgd fhpibreset(unit)
138 1.4 mycroft int unit;
139 1.1 cgd {
140 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
141 1.1 cgd register struct fhpibdevice *hd;
142 1.1 cgd
143 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
144 1.1 cgd hd->hpib_cid = 0xFF;
145 1.1 cgd DELAY(100);
146 1.1 cgd hd->hpib_cmd = CT_8BIT;
147 1.1 cgd hd->hpib_ar = AR_ARONC;
148 1.1 cgd fhpibifc(hd);
149 1.1 cgd hd->hpib_ie = IDS_IE;
150 1.1 cgd hd->hpib_data = C_DCL;
151 1.1 cgd DELAY(100000);
152 1.1 cgd /*
153 1.1 cgd * See if we can do word dma.
154 1.1 cgd * If so, we should be able to write and read back the appropos bit.
155 1.1 cgd */
156 1.1 cgd hd->hpib_ie |= IDS_WDMA;
157 1.1 cgd if (hd->hpib_ie & IDS_WDMA) {
158 1.1 cgd hd->hpib_ie &= ~IDS_WDMA;
159 1.1 cgd hs->sc_flags |= HPIBF_DMA16;
160 1.1 cgd #ifdef DEBUG
161 1.1 cgd if (fhpibdebug & FDB_DMA)
162 1.13 christos printf("fhpibtype: unit %d has word dma\n", unit);
163 1.1 cgd
164 1.1 cgd #endif
165 1.1 cgd }
166 1.1 cgd }
167 1.1 cgd
168 1.1 cgd fhpibifc(hd)
169 1.1 cgd register struct fhpibdevice *hd;
170 1.1 cgd {
171 1.1 cgd hd->hpib_cmd |= CT_IFC;
172 1.1 cgd hd->hpib_cmd |= CT_INITFIFO;
173 1.1 cgd DELAY(100);
174 1.1 cgd hd->hpib_cmd &= ~CT_IFC;
175 1.1 cgd hd->hpib_cmd |= CT_REN;
176 1.1 cgd hd->hpib_stat = ST_ATN;
177 1.1 cgd }
178 1.1 cgd
179 1.7 thorpej int
180 1.7 thorpej fhpibsend(unit, slave, sec, ptr, origcnt)
181 1.4 mycroft int unit, slave, sec, origcnt;
182 1.7 thorpej void *ptr;
183 1.1 cgd {
184 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
185 1.1 cgd register struct fhpibdevice *hd;
186 1.1 cgd register int cnt = origcnt;
187 1.1 cgd register int timo;
188 1.7 thorpej char *addr = ptr;
189 1.1 cgd
190 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
191 1.1 cgd hd->hpib_stat = 0;
192 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
193 1.1 cgd if (fhpibwait(hd, IM_IDLE) < 0)
194 1.1 cgd goto senderr;
195 1.1 cgd hd->hpib_stat = ST_ATN;
196 1.1 cgd hd->hpib_data = C_UNL;
197 1.1 cgd hd->hpib_data = C_TAG + hs->sc_ba;
198 1.1 cgd hd->hpib_data = C_LAG + slave;
199 1.6 mycroft if (sec < 0) {
200 1.6 mycroft if (sec == -2) /* selected device clear KLUDGE */
201 1.6 mycroft hd->hpib_data = C_SDC;
202 1.6 mycroft } else
203 1.1 cgd hd->hpib_data = C_SCG + sec;
204 1.1 cgd if (fhpibwait(hd, IM_IDLE) < 0)
205 1.1 cgd goto senderr;
206 1.1 cgd if (cnt) {
207 1.1 cgd hd->hpib_stat = ST_WRITE;
208 1.1 cgd while (--cnt) {
209 1.1 cgd hd->hpib_data = *addr++;
210 1.1 cgd timo = hpibtimeout;
211 1.1 cgd while ((hd->hpib_intr & IM_ROOM) == 0) {
212 1.1 cgd if (--timo <= 0)
213 1.1 cgd goto senderr;
214 1.11 thorpej DELAY(1);
215 1.1 cgd }
216 1.1 cgd }
217 1.1 cgd hd->hpib_stat = ST_EOI;
218 1.1 cgd hd->hpib_data = *addr;
219 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
220 1.1 cgd hd->hpib_stat = ST_ATN;
221 1.1 cgd /* XXX: HP-UX claims bug with CS80 transparent messages */
222 1.1 cgd if (sec == 0x12)
223 1.1 cgd DELAY(150);
224 1.1 cgd hd->hpib_data = C_UNL;
225 1.1 cgd (void) fhpibwait(hd, IM_IDLE);
226 1.1 cgd }
227 1.1 cgd hd->hpib_imask = 0;
228 1.1 cgd return (origcnt);
229 1.6 mycroft
230 1.1 cgd senderr:
231 1.1 cgd hd->hpib_imask = 0;
232 1.1 cgd fhpibifc(hd);
233 1.1 cgd #ifdef DEBUG
234 1.1 cgd if (fhpibdebug & FDB_FAIL) {
235 1.13 christos printf("%s: fhpibsend failed: slave %d, sec %x, ",
236 1.8 thorpej hs->sc_hc->hp_xname, slave, sec);
237 1.13 christos printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
238 1.1 cgd }
239 1.1 cgd #endif
240 1.6 mycroft return (origcnt - cnt - 1);
241 1.1 cgd }
242 1.1 cgd
243 1.7 thorpej int
244 1.7 thorpej fhpibrecv(unit, slave, sec, ptr, origcnt)
245 1.4 mycroft int unit, slave, sec, origcnt;
246 1.7 thorpej void *ptr;
247 1.1 cgd {
248 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
249 1.1 cgd register struct fhpibdevice *hd;
250 1.1 cgd register int cnt = origcnt;
251 1.1 cgd register int timo;
252 1.7 thorpej char *addr = ptr;
253 1.1 cgd
254 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
255 1.6 mycroft /*
256 1.6 mycroft * Slave < 0 implies continuation of a previous receive
257 1.6 mycroft * that probably timed out.
258 1.6 mycroft */
259 1.6 mycroft if (slave >= 0) {
260 1.6 mycroft hd->hpib_stat = 0;
261 1.6 mycroft hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
262 1.6 mycroft if (fhpibwait(hd, IM_IDLE) < 0)
263 1.6 mycroft goto recverror;
264 1.6 mycroft hd->hpib_stat = ST_ATN;
265 1.6 mycroft hd->hpib_data = C_UNL;
266 1.6 mycroft hd->hpib_data = C_LAG + hs->sc_ba;
267 1.6 mycroft hd->hpib_data = C_TAG + slave;
268 1.6 mycroft if (sec != -1)
269 1.6 mycroft hd->hpib_data = C_SCG + sec;
270 1.6 mycroft if (fhpibwait(hd, IM_IDLE) < 0)
271 1.6 mycroft goto recverror;
272 1.6 mycroft hd->hpib_stat = ST_READ0;
273 1.6 mycroft hd->hpib_data = 0;
274 1.6 mycroft }
275 1.1 cgd if (cnt) {
276 1.1 cgd while (--cnt >= 0) {
277 1.1 cgd timo = hpibtimeout;
278 1.1 cgd while ((hd->hpib_intr & IM_BYTE) == 0) {
279 1.1 cgd if (--timo == 0)
280 1.1 cgd goto recvbyteserror;
281 1.11 thorpej DELAY(1);
282 1.1 cgd }
283 1.1 cgd *addr++ = hd->hpib_data;
284 1.1 cgd }
285 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
286 1.1 cgd hd->hpib_stat = ST_ATN;
287 1.1 cgd hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
288 1.1 cgd (void) fhpibwait(hd, IM_IDLE);
289 1.1 cgd }
290 1.1 cgd hd->hpib_imask = 0;
291 1.1 cgd return (origcnt);
292 1.1 cgd
293 1.1 cgd recverror:
294 1.1 cgd fhpibifc(hd);
295 1.1 cgd recvbyteserror:
296 1.1 cgd hd->hpib_imask = 0;
297 1.1 cgd #ifdef DEBUG
298 1.1 cgd if (fhpibdebug & FDB_FAIL) {
299 1.13 christos printf("%s: fhpibrecv failed: slave %d, sec %x, ",
300 1.8 thorpej hs->sc_hc->hp_xname, slave, sec);
301 1.13 christos printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
302 1.1 cgd }
303 1.1 cgd #endif
304 1.6 mycroft return (origcnt - cnt - 1);
305 1.1 cgd }
306 1.1 cgd
307 1.7 thorpej void
308 1.7 thorpej fhpibgo(unit, slave, sec, ptr, count, rw, timo)
309 1.7 thorpej int unit, slave, sec, count, rw, timo;
310 1.7 thorpej void *ptr;
311 1.1 cgd {
312 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
313 1.1 cgd register struct fhpibdevice *hd;
314 1.1 cgd register int i;
315 1.7 thorpej char *addr = ptr;
316 1.1 cgd int flags = 0;
317 1.1 cgd
318 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
319 1.1 cgd hs->sc_flags |= HPIBF_IO;
320 1.6 mycroft if (timo)
321 1.6 mycroft hs->sc_flags |= HPIBF_TIMO;
322 1.1 cgd if (rw == B_READ)
323 1.1 cgd hs->sc_flags |= HPIBF_READ;
324 1.1 cgd #ifdef DEBUG
325 1.1 cgd else if (hs->sc_flags & HPIBF_READ) {
326 1.13 christos printf("fhpibgo: HPIBF_READ still set\n");
327 1.1 cgd hs->sc_flags &= ~HPIBF_READ;
328 1.1 cgd }
329 1.1 cgd #endif
330 1.1 cgd hs->sc_count = count;
331 1.1 cgd hs->sc_addr = addr;
332 1.1 cgd #ifdef DEBUG
333 1.1 cgd fhpibtransfer[unit]++;
334 1.1 cgd #endif
335 1.1 cgd if ((hs->sc_flags & HPIBF_DMA16) &&
336 1.1 cgd ((int)addr & 1) == 0 && count && (count & 1) == 0
337 1.1 cgd #ifdef DEBUG
338 1.1 cgd && doworddma
339 1.1 cgd #endif
340 1.1 cgd ) {
341 1.1 cgd #ifdef DEBUG
342 1.1 cgd fhpibworddma[unit]++;
343 1.1 cgd #endif
344 1.1 cgd flags |= DMAGO_WORD;
345 1.1 cgd hd->hpib_latch = 0;
346 1.1 cgd }
347 1.1 cgd #ifdef DEBUG
348 1.1 cgd if (dopriodma)
349 1.1 cgd flags |= DMAGO_PRI;
350 1.1 cgd #endif
351 1.1 cgd if (hs->sc_flags & HPIBF_READ) {
352 1.1 cgd fhpibcmd[unit] = CT_REN | CT_8BIT;
353 1.1 cgd hs->sc_curcnt = count;
354 1.1 cgd dmago(hs->sc_dq.dq_ctlr, addr, count, flags|DMAGO_READ);
355 1.1 cgd if (fhpibrecv(unit, slave, sec, 0, 0) < 0) {
356 1.1 cgd #ifdef DEBUG
357 1.13 christos printf("fhpibgo: recv failed, retrying...\n");
358 1.1 cgd #endif
359 1.1 cgd (void) fhpibrecv(unit, slave, sec, 0, 0);
360 1.1 cgd }
361 1.1 cgd i = hd->hpib_cmd;
362 1.1 cgd hd->hpib_cmd = fhpibcmd[unit];
363 1.1 cgd hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) |
364 1.1 cgd ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
365 1.1 cgd return;
366 1.1 cgd }
367 1.1 cgd fhpibcmd[unit] = CT_REN | CT_8BIT | CT_FIFOSEL;
368 1.1 cgd if (count < hpibdmathresh) {
369 1.1 cgd #ifdef DEBUG
370 1.1 cgd fhpibnondma[unit]++;
371 1.1 cgd if (flags & DMAGO_WORD)
372 1.1 cgd fhpibworddma[unit]--;
373 1.1 cgd #endif
374 1.1 cgd hs->sc_curcnt = count;
375 1.1 cgd (void) fhpibsend(unit, slave, sec, addr, count);
376 1.1 cgd fhpibdone(unit);
377 1.1 cgd return;
378 1.1 cgd }
379 1.1 cgd count -= (flags & DMAGO_WORD) ? 2 : 1;
380 1.1 cgd hs->sc_curcnt = count;
381 1.1 cgd dmago(hs->sc_dq.dq_ctlr, addr, count, flags);
382 1.1 cgd if (fhpibsend(unit, slave, sec, 0, 0) < 0) {
383 1.1 cgd #ifdef DEBUG
384 1.13 christos printf("fhpibgo: send failed, retrying...\n");
385 1.1 cgd #endif
386 1.1 cgd (void) fhpibsend(unit, slave, sec, 0, 0);
387 1.1 cgd }
388 1.1 cgd i = hd->hpib_cmd;
389 1.1 cgd hd->hpib_cmd = fhpibcmd[unit];
390 1.1 cgd hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) | IDS_WRITE |
391 1.1 cgd ((flags & DMAGO_WORD) ? IDS_WDMA : 0);
392 1.1 cgd }
393 1.1 cgd
394 1.6 mycroft /*
395 1.6 mycroft * A DMA read can finish but the device can still be waiting (MAG-tape
396 1.6 mycroft * with more data than we're waiting for). This timeout routine
397 1.6 mycroft * takes care of that. Somehow, the thing gets hosed. For now, since
398 1.6 mycroft * this should be a very rare occurence, we RESET it.
399 1.6 mycroft */
400 1.6 mycroft void
401 1.6 mycroft fhpibdmadone(arg)
402 1.6 mycroft void *arg;
403 1.6 mycroft {
404 1.6 mycroft register int unit;
405 1.6 mycroft register struct hpib_softc *hs;
406 1.6 mycroft int s = splbio();
407 1.6 mycroft
408 1.6 mycroft unit = (int)arg;
409 1.6 mycroft hs = &hpib_softc[unit];
410 1.6 mycroft if (hs->sc_flags & HPIBF_IO) {
411 1.6 mycroft register struct fhpibdevice *hd;
412 1.6 mycroft register struct devqueue *dq;
413 1.6 mycroft
414 1.6 mycroft hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
415 1.6 mycroft hd->hpib_imask = 0;
416 1.6 mycroft hd->hpib_cid = 0xFF;
417 1.6 mycroft DELAY(100);
418 1.6 mycroft hd->hpib_cmd = CT_8BIT;
419 1.6 mycroft hd->hpib_ar = AR_ARONC;
420 1.6 mycroft fhpibifc(hd);
421 1.6 mycroft hd->hpib_ie = IDS_IE;
422 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
423 1.6 mycroft dmafree(&hs->sc_dq);
424 1.6 mycroft dq = hs->sc_sq.dq_forw;
425 1.9 thorpej (dq->dq_driver->d_intr)(dq->dq_softc);
426 1.6 mycroft }
427 1.6 mycroft (void) splx(s);
428 1.6 mycroft }
429 1.6 mycroft
430 1.7 thorpej void
431 1.1 cgd fhpibdone(unit)
432 1.4 mycroft int unit;
433 1.1 cgd {
434 1.1 cgd register struct hpib_softc *hs = &hpib_softc[unit];
435 1.1 cgd register struct fhpibdevice *hd;
436 1.1 cgd register char *addr;
437 1.1 cgd register int cnt;
438 1.1 cgd
439 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
440 1.1 cgd cnt = hs->sc_curcnt;
441 1.1 cgd hs->sc_addr += cnt;
442 1.1 cgd hs->sc_count -= cnt;
443 1.1 cgd #ifdef DEBUG
444 1.1 cgd if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
445 1.13 christos printf("fhpibdone: addr %x cnt %d\n",
446 1.1 cgd hs->sc_addr, hs->sc_count);
447 1.1 cgd #endif
448 1.6 mycroft if (hs->sc_flags & HPIBF_READ) {
449 1.1 cgd hd->hpib_imask = IM_IDLE | IM_BYTE;
450 1.6 mycroft if (hs->sc_flags & HPIBF_TIMO)
451 1.6 mycroft timeout(fhpibdmadone, (void *)unit, hz >> 2);
452 1.6 mycroft } else {
453 1.1 cgd cnt = hs->sc_count;
454 1.1 cgd if (cnt) {
455 1.1 cgd addr = hs->sc_addr;
456 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
457 1.1 cgd FHPIBWAIT(hd, IM_IDLE);
458 1.1 cgd hd->hpib_stat = ST_WRITE;
459 1.1 cgd while (--cnt) {
460 1.1 cgd hd->hpib_data = *addr++;
461 1.1 cgd FHPIBWAIT(hd, IM_ROOM);
462 1.1 cgd }
463 1.1 cgd hd->hpib_stat = ST_EOI;
464 1.1 cgd hd->hpib_data = *addr;
465 1.1 cgd }
466 1.1 cgd hd->hpib_imask = IM_IDLE;
467 1.1 cgd }
468 1.1 cgd hs->sc_flags |= HPIBF_DONE;
469 1.1 cgd hd->hpib_stat = ST_IENAB;
470 1.1 cgd hd->hpib_ie = IDS_IE;
471 1.1 cgd }
472 1.1 cgd
473 1.7 thorpej int
474 1.9 thorpej fhpibintr(arg)
475 1.9 thorpej void *arg;
476 1.1 cgd {
477 1.9 thorpej register struct hpib_softc *hs = arg;
478 1.1 cgd register struct fhpibdevice *hd;
479 1.1 cgd register struct devqueue *dq;
480 1.9 thorpej register int stat0, unit = hs->sc_hc->hp_unit;
481 1.1 cgd
482 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
483 1.1 cgd stat0 = hd->hpib_ids;
484 1.1 cgd if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
485 1.1 cgd #ifdef DEBUG
486 1.1 cgd if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
487 1.1 cgd (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
488 1.13 christos printf("%s: fhpibintr: bad status %x\n",
489 1.8 thorpej hs->sc_hc->hp_xname, stat0);
490 1.1 cgd fhpibbadint[0]++;
491 1.1 cgd #endif
492 1.1 cgd return(0);
493 1.1 cgd }
494 1.1 cgd if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
495 1.1 cgd #ifdef DEBUG
496 1.1 cgd fhpibbadint[1]++;
497 1.1 cgd #endif
498 1.1 cgd return(0);
499 1.1 cgd }
500 1.1 cgd #ifdef DEBUG
501 1.1 cgd if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit)
502 1.13 christos printf("fhpibintr: flags %x\n", hs->sc_flags);
503 1.1 cgd #endif
504 1.1 cgd dq = hs->sc_sq.dq_forw;
505 1.1 cgd if (hs->sc_flags & HPIBF_IO) {
506 1.6 mycroft if (hs->sc_flags & HPIBF_TIMO)
507 1.6 mycroft untimeout(fhpibdmadone, (void *)unit);
508 1.1 cgd stat0 = hd->hpib_cmd;
509 1.1 cgd hd->hpib_cmd = fhpibcmd[unit] & ~CT_8BIT;
510 1.1 cgd hd->hpib_stat = 0;
511 1.1 cgd hd->hpib_cmd = CT_REN | CT_8BIT;
512 1.1 cgd stat0 = hd->hpib_intr;
513 1.1 cgd hd->hpib_imask = 0;
514 1.6 mycroft hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
515 1.1 cgd dmafree(&hs->sc_dq);
516 1.9 thorpej (dq->dq_driver->d_intr)(dq->dq_softc);
517 1.1 cgd } else if (hs->sc_flags & HPIBF_PPOLL) {
518 1.1 cgd stat0 = hd->hpib_intr;
519 1.1 cgd #ifdef DEBUG
520 1.1 cgd if ((fhpibdebug & FDB_FAIL) &&
521 1.1 cgd doppollint && (stat0 & IM_PPRESP) == 0)
522 1.13 christos printf("%s: fhpibintr: bad intr reg %x\n",
523 1.8 thorpej hs->sc_hc->hp_xname, stat0);
524 1.1 cgd #endif
525 1.1 cgd hd->hpib_stat = 0;
526 1.1 cgd hd->hpib_imask = 0;
527 1.1 cgd #ifdef DEBUG
528 1.1 cgd stat0 = fhpibppoll(unit);
529 1.1 cgd if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
530 1.13 christos printf("fhpibintr: got PPOLL status %x\n", stat0);
531 1.1 cgd if ((stat0 & (0x80 >> dq->dq_slave)) == 0) {
532 1.4 mycroft /*
533 1.4 mycroft * XXX give it another shot (68040)
534 1.4 mycroft */
535 1.4 mycroft fhpibppollfail[unit]++;
536 1.4 mycroft DELAY(fhpibppolldelay);
537 1.4 mycroft stat0 = fhpibppoll(unit);
538 1.4 mycroft if ((stat0 & (0x80 >> dq->dq_slave)) == 0 &&
539 1.4 mycroft (fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
540 1.13 christos printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
541 1.4 mycroft unit, dq->dq_slave, stat0);
542 1.1 cgd }
543 1.1 cgd #endif
544 1.1 cgd hs->sc_flags &= ~HPIBF_PPOLL;
545 1.9 thorpej (dq->dq_driver->d_intr)(dq->dq_softc);
546 1.1 cgd }
547 1.1 cgd return(1);
548 1.1 cgd }
549 1.1 cgd
550 1.7 thorpej int
551 1.1 cgd fhpibppoll(unit)
552 1.4 mycroft int unit;
553 1.1 cgd {
554 1.1 cgd register struct fhpibdevice *hd;
555 1.1 cgd register int ppoll;
556 1.1 cgd
557 1.1 cgd hd = (struct fhpibdevice *)hpib_softc[unit].sc_hc->hp_addr;
558 1.1 cgd hd->hpib_stat = 0;
559 1.1 cgd hd->hpib_psense = 0;
560 1.1 cgd hd->hpib_pmask = 0xFF;
561 1.1 cgd hd->hpib_imask = IM_PPRESP | IM_PABORT;
562 1.1 cgd DELAY(25);
563 1.1 cgd hd->hpib_intr = IM_PABORT;
564 1.1 cgd ppoll = hd->hpib_data;
565 1.1 cgd if (hd->hpib_intr & IM_PABORT)
566 1.1 cgd ppoll = 0;
567 1.1 cgd hd->hpib_imask = 0;
568 1.1 cgd hd->hpib_pmask = 0;
569 1.1 cgd hd->hpib_stat = ST_IENAB;
570 1.1 cgd return(ppoll);
571 1.1 cgd }
572 1.1 cgd
573 1.7 thorpej int
574 1.1 cgd fhpibwait(hd, x)
575 1.1 cgd register struct fhpibdevice *hd;
576 1.4 mycroft int x;
577 1.1 cgd {
578 1.1 cgd register int timo = hpibtimeout;
579 1.1 cgd
580 1.1 cgd while ((hd->hpib_intr & x) == 0 && --timo)
581 1.11 thorpej DELAY(1);
582 1.1 cgd if (timo == 0) {
583 1.1 cgd #ifdef DEBUG
584 1.1 cgd if (fhpibdebug & FDB_FAIL)
585 1.13 christos printf("fhpibwait(%x, %x) timeout\n", hd, x);
586 1.1 cgd #endif
587 1.1 cgd return(-1);
588 1.1 cgd }
589 1.1 cgd return(0);
590 1.1 cgd }
591 1.1 cgd
592 1.1 cgd /*
593 1.4 mycroft * XXX: this will have to change if we ever allow more than one
594 1.1 cgd * pending operation per HP-IB.
595 1.1 cgd */
596 1.4 mycroft void
597 1.3 mycroft fhpibppwatch(arg)
598 1.3 mycroft void *arg;
599 1.1 cgd {
600 1.4 mycroft register int unit;
601 1.4 mycroft register struct hpib_softc *hs;
602 1.1 cgd register struct fhpibdevice *hd;
603 1.1 cgd register int slave;
604 1.1 cgd
605 1.4 mycroft unit = (int)arg;
606 1.4 mycroft hs = &hpib_softc[unit];
607 1.1 cgd if ((hs->sc_flags & HPIBF_PPOLL) == 0)
608 1.1 cgd return;
609 1.1 cgd hd = (struct fhpibdevice *)hs->sc_hc->hp_addr;
610 1.1 cgd slave = (0x80 >> hs->sc_sq.dq_forw->dq_slave);
611 1.1 cgd #ifdef DEBUG
612 1.1 cgd if (!doppollint) {
613 1.1 cgd if (fhpibppoll(unit) & slave) {
614 1.1 cgd hd->hpib_stat = ST_IENAB;
615 1.1 cgd hd->hpib_imask = IM_IDLE | IM_ROOM;
616 1.1 cgd } else
617 1.3 mycroft timeout(fhpibppwatch, (void *)unit, 1);
618 1.1 cgd return;
619 1.1 cgd }
620 1.1 cgd if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit)
621 1.13 christos printf("fhpibppwatch: sense request on %d\n", unit);
622 1.1 cgd #endif
623 1.1 cgd hd->hpib_psense = ~slave;
624 1.1 cgd hd->hpib_pmask = slave;
625 1.1 cgd hd->hpib_stat = ST_IENAB;
626 1.1 cgd hd->hpib_imask = IM_PPRESP | IM_PABORT;
627 1.1 cgd hd->hpib_ie = IDS_IE;
628 1.1 cgd }
629 1.7 thorpej #endif /* NHPIB > 0 */
630