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