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