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