Home | History | Annotate | Line # | Download | only in dev
fhpib.c revision 1.18
      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