xref: /netbsd-src/sys/arch/hp300/dev/fhpib.c (revision fdecd6a253f999ae92b139670d9e15cc9df4497c)
1 /*	$NetBSD: fhpib.c,v 1.18 1997/05/05 21:04:16 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 #include <machine/intr.h>
51 
52 #include <hp300/dev/dioreg.h>
53 #include <hp300/dev/diovar.h>
54 #include <hp300/dev/diodevs.h>
55 
56 #include <hp300/dev/dmavar.h>
57 
58 #include <hp300/dev/fhpibreg.h>
59 #include <hp300/dev/hpibvar.h>
60 
61 /*
62  * Inline version of fhpibwait to be used in places where
63  * we don't worry about getting hung.
64  */
65 #define	FHPIBWAIT(hd, m)	while (((hd)->hpib_intr & (m)) == 0) DELAY(1)
66 
67 #ifdef DEBUG
68 int	fhpibdebugunit = -1;
69 int	fhpibdebug = 0;
70 #define FDB_FAIL	0x01
71 #define FDB_DMA		0x02
72 #define FDB_WAIT	0x04
73 #define FDB_PPOLL	0x08
74 
75 int	dopriodma = 0;	/* use high priority DMA */
76 int	doworddma = 1;	/* non-zero if we should attempt word dma */
77 int	doppollint = 1;	/* use ppoll interrupts instead of watchdog */
78 int	fhpibppolldelay = 50;
79 #endif
80 
81 void	fhpibifc __P((struct fhpibdevice *));
82 void	fhpibdmadone __P((void *));
83 int	fhpibwait __P((struct fhpibdevice *, int));
84 
85 void	fhpibreset __P((struct hpibbus_softc *));
86 int	fhpibsend __P((struct hpibbus_softc *, int, int, void *, int));
87 int	fhpibrecv __P((struct hpibbus_softc *, int, int, void *, int));
88 int	fhpibppoll __P((struct hpibbus_softc *));
89 void	fhpibppwatch __P((void *));
90 void	fhpibgo __P((struct hpibbus_softc *, int, int, void *, int, int, int));
91 void	fhpibdone __P((struct hpibbus_softc *));
92 int	fhpibintr __P((void *));
93 
94 /*
95  * Our controller ops structure.
96  */
97 struct	hpib_controller fhpib_controller = {
98 	fhpibreset,
99 	fhpibsend,
100 	fhpibrecv,
101 	fhpibppoll,
102 	fhpibppwatch,
103 	fhpibgo,
104 	fhpibdone,
105 	fhpibintr
106 };
107 
108 struct fhpib_softc {
109 	struct device sc_dev;		/* generic device glue */
110 	struct fhpibdevice *sc_regs;	/* device registers */
111 	int	sc_cmd;
112 	struct hpibbus_softc *sc_hpibbus; /* XXX */
113 };
114 
115 int	fhpibmatch __P((struct device *, struct cfdata *, void *));
116 void	fhpibattach __P((struct device *, struct device *, void *));
117 
118 struct cfattach fhpib_ca = {
119 	sizeof(struct fhpib_softc), fhpibmatch, fhpibattach
120 };
121 
122 struct cfdriver fhpib_cd = {
123 	NULL, "fhpib", DV_DULL
124 };
125 
126 int
127 fhpibmatch(parent, match, aux)
128 	struct device *parent;
129 	struct cfdata *match;
130 	void *aux;
131 {
132 	struct dio_attach_args *da = aux;
133 
134 	if (da->da_id == DIO_DEVICE_ID_FHPIB)
135 		return (1);
136 
137 	return (0);
138 }
139 
140 void
141 fhpibattach(parent, self, aux)
142 	struct device *parent, *self;
143 	void *aux;
144 {
145 	struct fhpib_softc *sc = (struct fhpib_softc *)self;
146 	struct dio_attach_args *da = aux;
147 	struct hpibdev_attach_args ha;
148 	int ipl;
149 
150 	sc->sc_regs = (struct fhpibdevice *)iomap(dio_scodetopa(da->da_scode),
151 	    da->da_size);
152 	if (sc->sc_regs == NULL) {
153 		printf("\n%s: can't map registers\n", self->dv_xname);
154 		return;
155 	}
156 
157 	ipl = DIO_IPL(sc->sc_regs);
158 	printf(" ipl %d: %s\n", ipl, DIO_DEVICE_DESC_FHPIB);
159 
160 	/* Establish the interrupt handler. */
161 	(void) dio_intr_establish(fhpibintr, sc, ipl, IPL_BIO);
162 
163 	ha.ha_ops = &fhpib_controller;
164 	ha.ha_type = HPIBC;			/* XXX */
165 	ha.ha_ba = HPIBC_BA;
166 	ha.ha_softcpp = &sc->sc_hpibbus;	/* XXX */
167 	(void)config_found(self, &ha, hpibdevprint);
168 }
169 
170 void
171 fhpibreset(hs)
172 	struct hpibbus_softc *hs;
173 {
174 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
175 	struct fhpibdevice *hd = sc->sc_regs;
176 
177 	hd->hpib_cid = 0xFF;
178 	DELAY(100);
179 	hd->hpib_cmd = CT_8BIT;
180 	hd->hpib_ar = AR_ARONC;
181 	fhpibifc(hd);
182 	hd->hpib_ie = IDS_IE;
183 	hd->hpib_data = C_DCL;
184 	DELAY(100000);
185 	/*
186 	 * See if we can do word dma.
187 	 * If so, we should be able to write and read back the appropos bit.
188 	 */
189 	hd->hpib_ie |= IDS_WDMA;
190 	if (hd->hpib_ie & IDS_WDMA) {
191 		hd->hpib_ie &= ~IDS_WDMA;
192 		hs->sc_flags |= HPIBF_DMA16;
193 #ifdef DEBUG
194 		if (fhpibdebug & FDB_DMA)
195 			printf("fhpibtype: %s has word dma\n",
196 			    sc->sc_dev.dv_xname);
197 
198 #endif
199 	}
200 }
201 
202 void
203 fhpibifc(hd)
204 	struct fhpibdevice *hd;
205 {
206 	hd->hpib_cmd |= CT_IFC;
207 	hd->hpib_cmd |= CT_INITFIFO;
208 	DELAY(100);
209 	hd->hpib_cmd &= ~CT_IFC;
210 	hd->hpib_cmd |= CT_REN;
211 	hd->hpib_stat = ST_ATN;
212 }
213 
214 int
215 fhpibsend(hs, slave, sec, ptr, origcnt)
216 	struct hpibbus_softc *hs;
217 	int slave, sec, origcnt;
218 	void *ptr;
219 {
220 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
221 	struct fhpibdevice *hd = sc->sc_regs;
222 	int cnt = origcnt;
223 	int timo;
224 	char *addr = ptr;
225 
226 	hd->hpib_stat = 0;
227 	hd->hpib_imask = IM_IDLE | IM_ROOM;
228 	if (fhpibwait(hd, IM_IDLE) < 0)
229 		goto senderr;
230 	hd->hpib_stat = ST_ATN;
231 	hd->hpib_data = C_UNL;
232 	hd->hpib_data = C_TAG + hs->sc_ba;
233 	hd->hpib_data = C_LAG + slave;
234 	if (sec < 0) {
235 		if (sec == -2)		/* selected device clear KLUDGE */
236 			hd->hpib_data = C_SDC;
237 	} else
238 		hd->hpib_data = C_SCG + sec;
239 	if (fhpibwait(hd, IM_IDLE) < 0)
240 		goto senderr;
241 	if (cnt) {
242 		hd->hpib_stat = ST_WRITE;
243 		while (--cnt) {
244 			hd->hpib_data = *addr++;
245 			timo = hpibtimeout;
246 			while ((hd->hpib_intr & IM_ROOM) == 0) {
247 				if (--timo <= 0)
248 					goto senderr;
249 				DELAY(1);
250 			}
251 		}
252 		hd->hpib_stat = ST_EOI;
253 		hd->hpib_data = *addr;
254 		FHPIBWAIT(hd, IM_ROOM);
255 		hd->hpib_stat = ST_ATN;
256 		/* XXX: HP-UX claims bug with CS80 transparent messages */
257 		if (sec == 0x12)
258 			DELAY(150);
259 		hd->hpib_data = C_UNL;
260 		(void) fhpibwait(hd, IM_IDLE);
261 	}
262 	hd->hpib_imask = 0;
263 	return (origcnt);
264 
265 senderr:
266 	hd->hpib_imask = 0;
267 	fhpibifc(hd);
268 #ifdef DEBUG
269 	if (fhpibdebug & FDB_FAIL) {
270 		printf("%s: fhpibsend failed: slave %d, sec %x, ",
271 		    sc->sc_dev.dv_xname, slave, sec);
272 		printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt);
273 	}
274 #endif
275 	return (origcnt - cnt - 1);
276 }
277 
278 int
279 fhpibrecv(hs, slave, sec, ptr, origcnt)
280 	struct hpibbus_softc *hs;
281 	int slave, sec, origcnt;
282 	void *ptr;
283 {
284 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
285 	struct fhpibdevice *hd = sc->sc_regs;
286 	int cnt = origcnt;
287 	int timo;
288 	char *addr = ptr;
289 
290 	/*
291 	 * Slave < 0 implies continuation of a previous receive
292 	 * that probably timed out.
293 	 */
294 	if (slave >= 0) {
295 		hd->hpib_stat = 0;
296 		hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE;
297 		if (fhpibwait(hd, IM_IDLE) < 0)
298 			goto recverror;
299 		hd->hpib_stat = ST_ATN;
300 		hd->hpib_data = C_UNL;
301 		hd->hpib_data = C_LAG + hs->sc_ba;
302 		hd->hpib_data = C_TAG + slave;
303 		if (sec != -1)
304 			hd->hpib_data = C_SCG + sec;
305 		if (fhpibwait(hd, IM_IDLE) < 0)
306 			goto recverror;
307 		hd->hpib_stat = ST_READ0;
308 		hd->hpib_data = 0;
309 	}
310 	if (cnt) {
311 		while (--cnt >= 0) {
312 			timo = hpibtimeout;
313 			while ((hd->hpib_intr & IM_BYTE) == 0) {
314 				if (--timo == 0)
315 					goto recvbyteserror;
316 				DELAY(1);
317 			}
318 			*addr++ = hd->hpib_data;
319 		}
320 		FHPIBWAIT(hd, IM_ROOM);
321 		hd->hpib_stat = ST_ATN;
322 		hd->hpib_data = (slave == 31) ? C_UNA : C_UNT;
323 		(void) fhpibwait(hd, IM_IDLE);
324 	}
325 	hd->hpib_imask = 0;
326 	return (origcnt);
327 
328 recverror:
329 	fhpibifc(hd);
330 recvbyteserror:
331 	hd->hpib_imask = 0;
332 #ifdef DEBUG
333 	if (fhpibdebug & FDB_FAIL) {
334 		printf("%s: fhpibrecv failed: slave %d, sec %x, ",
335 		    sc->sc_dev.dv_xname, slave, sec);
336 		printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt);
337 	}
338 #endif
339 	return (origcnt - cnt - 1);
340 }
341 
342 void
343 fhpibgo(hs, slave, sec, ptr, count, rw, timo)
344 	struct hpibbus_softc *hs;
345 	int slave, sec, count, rw, timo;
346 	void *ptr;
347 {
348 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
349 	struct fhpibdevice *hd = sc->sc_regs;
350 	int i;
351 	char *addr = ptr;
352 	int flags = 0;
353 
354 	hs->sc_flags |= HPIBF_IO;
355 	if (timo)
356 		hs->sc_flags |= HPIBF_TIMO;
357 	if (rw == B_READ)
358 		hs->sc_flags |= HPIBF_READ;
359 #ifdef DEBUG
360 	else if (hs->sc_flags & HPIBF_READ) {
361 		printf("fhpibgo: HPIBF_READ still set\n");
362 		hs->sc_flags &= ~HPIBF_READ;
363 	}
364 #endif
365 	hs->sc_count = count;
366 	hs->sc_addr = addr;
367 #ifdef DEBUG
368 	/* fhpibtransfer[unit]++;			XXX */
369 #endif
370 	if ((hs->sc_flags & HPIBF_DMA16) &&
371 	    ((int)addr & 1) == 0 && count && (count & 1) == 0
372 #ifdef DEBUG
373 	    && doworddma
374 #endif
375 	    ) {
376 #ifdef DEBUG
377 		/* fhpibworddma[unit]++;		XXX */
378 #endif
379 		flags |= DMAGO_WORD;
380 		hd->hpib_latch = 0;
381 	}
382 #ifdef DEBUG
383 	if (dopriodma)
384 		flags |= DMAGO_PRI;
385 #endif
386 	if (hs->sc_flags & HPIBF_READ) {
387 		sc->sc_cmd = CT_REN | CT_8BIT;
388 		hs->sc_curcnt = count;
389 		dmago(hs->sc_dq->dq_chan, addr, count, flags|DMAGO_READ);
390 		if (fhpibrecv(hs, slave, sec, 0, 0) < 0) {
391 #ifdef DEBUG
392 			printf("fhpibgo: recv failed, retrying...\n");
393 #endif
394 			(void) fhpibrecv(hs, slave, sec, 0, 0);
395 		}
396 		i = hd->hpib_cmd;
397 		hd->hpib_cmd = sc->sc_cmd;
398 		hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) |
399 			((flags & DMAGO_WORD) ? IDS_WDMA : 0);
400 		return;
401 	}
402 	sc->sc_cmd = CT_REN | CT_8BIT | CT_FIFOSEL;
403 	if (count < hpibdmathresh) {
404 #ifdef DEBUG
405 		/* fhpibnondma[unit]++;			XXX */
406 		if (flags & DMAGO_WORD)
407 			/* fhpibworddma[unit]--;	XXX */ ;
408 #endif
409 		hs->sc_curcnt = count;
410 		(void) fhpibsend(hs, slave, sec, addr, count);
411 		fhpibdone(hs);
412 		return;
413 	}
414 	count -= (flags & DMAGO_WORD) ? 2 : 1;
415 	hs->sc_curcnt = count;
416 	dmago(hs->sc_dq->dq_chan, addr, count, flags);
417 	if (fhpibsend(hs, slave, sec, 0, 0) < 0) {
418 #ifdef DEBUG
419 		printf("fhpibgo: send failed, retrying...\n");
420 #endif
421 		(void) fhpibsend(hs, slave, sec, 0, 0);
422 	}
423 	i = hd->hpib_cmd;
424 	hd->hpib_cmd = sc->sc_cmd;
425 	hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) | IDS_WRITE |
426 		((flags & DMAGO_WORD) ? IDS_WDMA : 0);
427 }
428 
429 /*
430  * A DMA read can finish but the device can still be waiting (MAG-tape
431  * with more data than we're waiting for).  This timeout routine
432  * takes care of that.  Somehow, the thing gets hosed.  For now, since
433  * this should be a very rare occurence, we RESET it.
434  */
435 void
436 fhpibdmadone(arg)
437 	void *arg;
438 {
439 	struct hpibbus_softc *hs = arg;
440 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
441 	int s = splbio();
442 
443 	if (hs->sc_flags & HPIBF_IO) {
444 		struct fhpibdevice *hd = sc->sc_regs;
445 		struct hpibqueue *hq;
446 
447 		hd->hpib_imask = 0;
448 		hd->hpib_cid = 0xFF;
449 		DELAY(100);
450 		hd->hpib_cmd = CT_8BIT;
451 		hd->hpib_ar = AR_ARONC;
452 		fhpibifc(hd);
453 		hd->hpib_ie = IDS_IE;
454 		hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
455 		dmafree(hs->sc_dq);
456 
457 		hq = hs->sc_queue.tqh_first;
458 		(hq->hq_intr)(hq->hq_softc);
459 	}
460 	splx(s);
461 }
462 
463 void
464 fhpibdone(hs)
465 	struct hpibbus_softc *hs;
466 {
467 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
468 	struct fhpibdevice *hd = sc->sc_regs;
469 	char *addr;
470 	int cnt;
471 
472 	cnt = hs->sc_curcnt;
473 	hs->sc_addr += cnt;
474 	hs->sc_count -= cnt;
475 #ifdef DEBUG
476 	if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == sc->sc_dev.dv_unit)
477 		printf("fhpibdone: addr %p cnt %d\n",
478 		       hs->sc_addr, hs->sc_count);
479 #endif
480 	if (hs->sc_flags & HPIBF_READ) {
481 		hd->hpib_imask = IM_IDLE | IM_BYTE;
482 		if (hs->sc_flags & HPIBF_TIMO)
483 			timeout(fhpibdmadone, hs, hz >> 2);
484 	} else {
485 		cnt = hs->sc_count;
486 		if (cnt) {
487 			addr = hs->sc_addr;
488 			hd->hpib_imask = IM_IDLE | IM_ROOM;
489 			FHPIBWAIT(hd, IM_IDLE);
490 			hd->hpib_stat = ST_WRITE;
491 			while (--cnt) {
492 				hd->hpib_data = *addr++;
493 				FHPIBWAIT(hd, IM_ROOM);
494 			}
495 			hd->hpib_stat = ST_EOI;
496 			hd->hpib_data = *addr;
497 		}
498 		hd->hpib_imask = IM_IDLE;
499 	}
500 	hs->sc_flags |= HPIBF_DONE;
501 	hd->hpib_stat = ST_IENAB;
502 	hd->hpib_ie = IDS_IE;
503 }
504 
505 int
506 fhpibintr(arg)
507 	void *arg;
508 {
509 	struct fhpib_softc *sc = arg;
510 	struct hpibbus_softc *hs = sc->sc_hpibbus;
511 	struct fhpibdevice *hd = sc->sc_regs;
512 	struct hpibqueue *hq;
513 	int stat0;
514 
515 	stat0 = hd->hpib_ids;
516 	if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) {
517 #ifdef DEBUG
518 		if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) &&
519 		    (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO)
520 			printf("%s: fhpibintr: bad status %x\n",
521 			sc->sc_dev.dv_xname, stat0);
522 		/* fhpibbadint[0]++;			XXX */
523 #endif
524 		return(0);
525 	}
526 	if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) {
527 #ifdef DEBUG
528 		/* fhpibbadint[1]++;			XXX */
529 #endif
530 		return(0);
531 	}
532 #ifdef DEBUG
533 	if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == sc->sc_dev.dv_unit)
534 		printf("fhpibintr: flags %x\n", hs->sc_flags);
535 #endif
536 	hq = hs->sc_queue.tqh_first;
537 	if (hs->sc_flags & HPIBF_IO) {
538 		if (hs->sc_flags & HPIBF_TIMO)
539 			untimeout(fhpibdmadone, hs);
540 		stat0 = hd->hpib_cmd;
541 		hd->hpib_cmd = sc->sc_cmd & ~CT_8BIT;
542 		hd->hpib_stat = 0;
543 		hd->hpib_cmd = CT_REN | CT_8BIT;
544 		stat0 = hd->hpib_intr;
545 		hd->hpib_imask = 0;
546 		hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO);
547 		dmafree(hs->sc_dq);
548 		(hq->hq_intr)(hq->hq_softc);
549 	} else if (hs->sc_flags & HPIBF_PPOLL) {
550 		stat0 = hd->hpib_intr;
551 #ifdef DEBUG
552 		if ((fhpibdebug & FDB_FAIL) &&
553 		    doppollint && (stat0 & IM_PPRESP) == 0)
554 			printf("%s: fhpibintr: bad intr reg %x\n",
555 			    sc->sc_dev.dv_xname, stat0);
556 #endif
557 		hd->hpib_stat = 0;
558 		hd->hpib_imask = 0;
559 #ifdef DEBUG
560 		stat0 = fhpibppoll(hs);
561 		if ((fhpibdebug & FDB_PPOLL) &&
562 		    fhpibdebugunit == sc->sc_dev.dv_unit)
563 			printf("fhpibintr: got PPOLL status %x\n", stat0);
564 		if ((stat0 & (0x80 >> hq->hq_slave)) == 0) {
565 			/*
566 			 * XXX give it another shot (68040)
567 			 */
568 			/* fhpibppollfail[unit]++;	XXX */
569 			DELAY(fhpibppolldelay);
570 			stat0 = fhpibppoll(hs);
571 			if ((stat0 & (0x80 >> hq->hq_slave)) == 0 &&
572 			    (fhpibdebug & FDB_PPOLL) &&
573 			    fhpibdebugunit == sc->sc_dev.dv_unit)
574 				printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n",
575 				       sc->sc_dev.dv_unit, hq->hq_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 	struct fhpibdevice *hd = sc->sc_regs;
590 	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 	struct fhpibdevice *hd;
610 	int x;
611 {
612 	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(%p, %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 	struct hpibbus_softc *hs = arg;
635 	struct fhpib_softc *sc = (struct fhpib_softc *)hs->sc_dev.dv_parent;
636 	struct fhpibdevice *hd = sc->sc_regs;
637 	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