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