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