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