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