1 /* $NetBSD: fhpib.c,v 1.37 2007/12/05 12:03:08 tsutsui 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.37 2007/12/05 12:03:08 tsutsui 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 bus_space_handle_t bsh; 176 177 if (bus_space_map(da->da_bst, da->da_addr, da->da_size, 0, &bsh)) { 178 printf("\n%s: can't map registers\n", self->dv_xname); 179 return; 180 } 181 sc->sc_regs = bus_space_vaddr(da->da_bst, bsh); 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, 0); 189 callout_init(&sc->sc_ppwatch_ch, 0); 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 = 202 (struct fhpib_softc *)device_parent(&hs->sc_dev); 203 struct fhpibdevice *hd = sc->sc_regs; 204 205 hd->hpib_cid = 0xFF; 206 DELAY(100); 207 hd->hpib_cmd = CT_8BIT; 208 hd->hpib_ar = AR_ARONC; 209 fhpibifc(hd); 210 hd->hpib_ie = IDS_IE; 211 hd->hpib_data = C_DCL; 212 DELAY(100000); 213 /* 214 * See if we can do word DMA. 215 * If so, we should be able to write and read back the appropos bit. 216 */ 217 hd->hpib_ie |= IDS_WDMA; 218 if (hd->hpib_ie & IDS_WDMA) { 219 hd->hpib_ie &= ~IDS_WDMA; 220 hs->sc_flags |= HPIBF_DMA16; 221 #ifdef DEBUG 222 if (fhpibdebug & FDB_DMA) 223 printf("fhpibtype: %s has word DMA\n", 224 sc->sc_dev.dv_xname); 225 #endif 226 } 227 } 228 229 static void 230 fhpibifc(struct fhpibdevice *hd) 231 { 232 233 hd->hpib_cmd |= CT_IFC; 234 hd->hpib_cmd |= CT_INITFIFO; 235 DELAY(100); 236 hd->hpib_cmd &= ~CT_IFC; 237 hd->hpib_cmd |= CT_REN; 238 hd->hpib_stat = ST_ATN; 239 } 240 241 static int 242 fhpibsend(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt) 243 { 244 struct fhpib_softc *sc = 245 (struct fhpib_softc *)device_parent(&hs->sc_dev); 246 struct fhpibdevice *hd = sc->sc_regs; 247 int cnt = origcnt; 248 int timo; 249 char *addr = ptr; 250 251 hd->hpib_stat = 0; 252 hd->hpib_imask = IM_IDLE | IM_ROOM; 253 if (fhpibwait(hd, IM_IDLE) < 0) 254 goto senderr; 255 hd->hpib_stat = ST_ATN; 256 hd->hpib_data = C_UNL; 257 hd->hpib_data = C_TAG + hs->sc_ba; 258 hd->hpib_data = C_LAG + slave; 259 if (sec < 0) { 260 if (sec == -2) /* selected device clear KLUDGE */ 261 hd->hpib_data = C_SDC; 262 } else 263 hd->hpib_data = C_SCG + sec; 264 if (fhpibwait(hd, IM_IDLE) < 0) 265 goto senderr; 266 if (cnt) { 267 hd->hpib_stat = ST_WRITE; 268 while (--cnt) { 269 hd->hpib_data = *addr++; 270 timo = hpibtimeout; 271 while ((hd->hpib_intr & IM_ROOM) == 0) { 272 if (--timo <= 0) 273 goto senderr; 274 DELAY(1); 275 } 276 } 277 hd->hpib_stat = ST_EOI; 278 hd->hpib_data = *addr; 279 FHPIBWAIT(hd, IM_ROOM); 280 hd->hpib_stat = ST_ATN; 281 /* XXX: HP-UX claims bug with CS80 transparent messages */ 282 if (sec == 0x12) 283 DELAY(150); 284 hd->hpib_data = C_UNL; 285 (void) fhpibwait(hd, IM_IDLE); 286 } 287 hd->hpib_imask = 0; 288 return origcnt; 289 290 senderr: 291 hd->hpib_imask = 0; 292 fhpibifc(hd); 293 #ifdef DEBUG 294 if (fhpibdebug & FDB_FAIL) { 295 printf("%s: fhpibsend failed: slave %d, sec %x, ", 296 sc->sc_dev.dv_xname, slave, sec); 297 printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt); 298 } 299 #endif 300 return origcnt - cnt - 1; 301 } 302 303 static int 304 fhpibrecv(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int origcnt) 305 { 306 struct fhpib_softc *sc = 307 (struct fhpib_softc *)device_parent(&hs->sc_dev); 308 struct fhpibdevice *hd = sc->sc_regs; 309 int cnt = origcnt; 310 int timo; 311 char *addr = ptr; 312 313 /* 314 * Slave < 0 implies continuation of a previous receive 315 * that probably timed out. 316 */ 317 if (slave >= 0) { 318 hd->hpib_stat = 0; 319 hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE; 320 if (fhpibwait(hd, IM_IDLE) < 0) 321 goto recverror; 322 hd->hpib_stat = ST_ATN; 323 hd->hpib_data = C_UNL; 324 hd->hpib_data = C_LAG + hs->sc_ba; 325 hd->hpib_data = C_TAG + slave; 326 if (sec != -1) 327 hd->hpib_data = C_SCG + sec; 328 if (fhpibwait(hd, IM_IDLE) < 0) 329 goto recverror; 330 hd->hpib_stat = ST_READ0; 331 hd->hpib_data = 0; 332 } 333 if (cnt) { 334 while (--cnt >= 0) { 335 timo = hpibtimeout; 336 while ((hd->hpib_intr & IM_BYTE) == 0) { 337 if (--timo == 0) 338 goto recvbyteserror; 339 DELAY(1); 340 } 341 *addr++ = hd->hpib_data; 342 } 343 FHPIBWAIT(hd, IM_ROOM); 344 hd->hpib_stat = ST_ATN; 345 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT; 346 (void) fhpibwait(hd, IM_IDLE); 347 } 348 hd->hpib_imask = 0; 349 return origcnt; 350 351 recverror: 352 fhpibifc(hd); 353 recvbyteserror: 354 hd->hpib_imask = 0; 355 #ifdef DEBUG 356 if (fhpibdebug & FDB_FAIL) { 357 printf("%s: fhpibrecv failed: slave %d, sec %x, ", 358 sc->sc_dev.dv_xname, slave, sec); 359 printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt); 360 } 361 #endif 362 return origcnt - cnt - 1; 363 } 364 365 static void 366 fhpibgo(struct hpibbus_softc *hs, int slave, int sec, void *ptr, int count, 367 int rw, int timo) 368 { 369 struct fhpib_softc *sc = 370 (struct fhpib_softc *)device_parent(&hs->sc_dev); 371 struct fhpibdevice *hd = sc->sc_regs; 372 int i; 373 char *addr = ptr; 374 int flags = 0; 375 376 hs->sc_flags |= HPIBF_IO; 377 if (timo) 378 hs->sc_flags |= HPIBF_TIMO; 379 if (rw == B_READ) 380 hs->sc_flags |= HPIBF_READ; 381 #ifdef DEBUG 382 else if (hs->sc_flags & HPIBF_READ) { 383 printf("fhpibgo: HPIBF_READ still set\n"); 384 hs->sc_flags &= ~HPIBF_READ; 385 } 386 #endif 387 hs->sc_count = count; 388 hs->sc_addr = addr; 389 #ifdef DEBUG 390 /* fhpibtransfer[unit]++; XXX */ 391 #endif 392 if ((hs->sc_flags & HPIBF_DMA16) && 393 ((int)addr & 1) == 0 && count && (count & 1) == 0 394 #ifdef DEBUG 395 && doworddma 396 #endif 397 ) { 398 #ifdef DEBUG 399 /* fhpibworddma[unit]++; XXX */ 400 #endif 401 flags |= DMAGO_WORD; 402 hd->hpib_latch = 0; 403 } 404 #ifdef DEBUG 405 if (dopriodma) 406 flags |= DMAGO_PRI; 407 #endif 408 if (hs->sc_flags & HPIBF_READ) { 409 sc->sc_cmd = CT_REN | CT_8BIT; 410 hs->sc_curcnt = count; 411 dmago(hs->sc_dq->dq_chan, addr, count, flags|DMAGO_READ); 412 if (fhpibrecv(hs, slave, sec, 0, 0) < 0) { 413 #ifdef DEBUG 414 printf("fhpibgo: recv failed, retrying...\n"); 415 #endif 416 (void) fhpibrecv(hs, slave, sec, 0, 0); 417 } 418 i = hd->hpib_cmd; 419 hd->hpib_cmd = sc->sc_cmd; 420 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) | 421 ((flags & DMAGO_WORD) ? IDS_WDMA : 0); 422 return; 423 } 424 sc->sc_cmd = CT_REN | CT_8BIT | CT_FIFOSEL; 425 if (count < hpibdmathresh) { 426 #ifdef DEBUG 427 /* fhpibnondma[unit]++; XXX */ 428 if (flags & DMAGO_WORD) 429 /* fhpibworddma[unit]--; XXX */ ; 430 #endif 431 hs->sc_curcnt = count; 432 (void) fhpibsend(hs, slave, sec, addr, count); 433 fhpibdone(hs); 434 return; 435 } 436 count -= (flags & DMAGO_WORD) ? 2 : 1; 437 hs->sc_curcnt = count; 438 dmago(hs->sc_dq->dq_chan, addr, count, flags); 439 if (fhpibsend(hs, slave, sec, 0, 0) < 0) { 440 #ifdef DEBUG 441 printf("fhpibgo: send failed, retrying...\n"); 442 #endif 443 (void) fhpibsend(hs, slave, sec, 0, 0); 444 } 445 i = hd->hpib_cmd; 446 hd->hpib_cmd = sc->sc_cmd; 447 hd->hpib_ie = IDS_DMA(hs->sc_dq->dq_chan) | IDS_WRITE | 448 ((flags & DMAGO_WORD) ? IDS_WDMA : 0); 449 } 450 451 /* 452 * A DMA read can finish but the device can still be waiting (MAG-tape 453 * with more data than we're waiting for). This timeout routine 454 * takes care of that. Somehow, the thing gets hosed. For now, since 455 * this should be a very rare occurence, we RESET it. 456 */ 457 static void 458 fhpibdmadone(void *arg) 459 { 460 struct hpibbus_softc *hs = arg; 461 struct fhpib_softc *sc = 462 (struct fhpib_softc *)device_parent(&hs->sc_dev); 463 int s = splbio(); 464 465 if (hs->sc_flags & HPIBF_IO) { 466 struct fhpibdevice *hd = sc->sc_regs; 467 struct hpibqueue *hq; 468 469 hd->hpib_imask = 0; 470 hd->hpib_cid = 0xFF; 471 DELAY(100); 472 hd->hpib_cmd = CT_8BIT; 473 hd->hpib_ar = AR_ARONC; 474 fhpibifc(hd); 475 hd->hpib_ie = IDS_IE; 476 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO); 477 dmafree(hs->sc_dq); 478 479 hq = TAILQ_FIRST(&hs->sc_queue); 480 (hq->hq_intr)(hq->hq_softc); 481 } 482 splx(s); 483 } 484 485 static void 486 fhpibdone(struct hpibbus_softc *hs) 487 { 488 struct fhpib_softc *sc = 489 (struct fhpib_softc *)device_parent(&hs->sc_dev); 490 struct fhpibdevice *hd = sc->sc_regs; 491 char *addr; 492 int cnt; 493 494 cnt = hs->sc_curcnt; 495 hs->sc_addr += cnt; 496 hs->sc_count -= cnt; 497 #ifdef DEBUG 498 if ((fhpibdebug & FDB_DMA) && 499 fhpibdebugunit == device_unit(&sc->sc_dev)) 500 printf("fhpibdone: addr %p cnt %d\n", 501 hs->sc_addr, hs->sc_count); 502 #endif 503 if (hs->sc_flags & HPIBF_READ) { 504 hd->hpib_imask = IM_IDLE | IM_BYTE; 505 if (hs->sc_flags & HPIBF_TIMO) 506 callout_reset(&sc->sc_dmadone_ch, hz >> 2, 507 fhpibdmadone, hs); 508 } else { 509 cnt = hs->sc_count; 510 if (cnt) { 511 addr = hs->sc_addr; 512 hd->hpib_imask = IM_IDLE | IM_ROOM; 513 FHPIBWAIT(hd, IM_IDLE); 514 hd->hpib_stat = ST_WRITE; 515 while (--cnt) { 516 hd->hpib_data = *addr++; 517 FHPIBWAIT(hd, IM_ROOM); 518 } 519 hd->hpib_stat = ST_EOI; 520 hd->hpib_data = *addr; 521 } 522 hd->hpib_imask = IM_IDLE; 523 } 524 hs->sc_flags |= HPIBF_DONE; 525 hd->hpib_stat = ST_IENAB; 526 hd->hpib_ie = IDS_IE; 527 } 528 529 static int 530 fhpibintr(void *arg) 531 { 532 struct fhpib_softc *sc = arg; 533 struct hpibbus_softc *hs = sc->sc_hpibbus; 534 struct fhpibdevice *hd = sc->sc_regs; 535 struct hpibqueue *hq; 536 int stat0; 537 538 stat0 = hd->hpib_ids; 539 if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) { 540 #ifdef DEBUG 541 if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) && 542 (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO) 543 printf("%s: fhpibintr: bad status %x\n", 544 sc->sc_dev.dv_xname, stat0); 545 /* fhpibbadint[0]++; XXX */ 546 #endif 547 return 0; 548 } 549 if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) { 550 #ifdef DEBUG 551 /* fhpibbadint[1]++; XXX */ 552 #endif 553 return 0; 554 } 555 #ifdef DEBUG 556 if ((fhpibdebug & FDB_DMA) && 557 fhpibdebugunit == device_unit(&sc->sc_dev)) 558 printf("fhpibintr: flags %x\n", hs->sc_flags); 559 #endif 560 hq = TAILQ_FIRST(&hs->sc_queue); 561 if (hs->sc_flags & HPIBF_IO) { 562 if (hs->sc_flags & HPIBF_TIMO) 563 callout_stop(&sc->sc_dmadone_ch); 564 stat0 = hd->hpib_cmd; 565 hd->hpib_cmd = sc->sc_cmd & ~CT_8BIT; 566 hd->hpib_stat = 0; 567 hd->hpib_cmd = CT_REN | CT_8BIT; 568 stat0 = hd->hpib_intr; 569 hd->hpib_imask = 0; 570 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO); 571 dmafree(hs->sc_dq); 572 (hq->hq_intr)(hq->hq_softc); 573 } else if (hs->sc_flags & HPIBF_PPOLL) { 574 stat0 = hd->hpib_intr; 575 #ifdef DEBUG 576 if ((fhpibdebug & FDB_FAIL) && 577 doppollint && (stat0 & IM_PPRESP) == 0) 578 printf("%s: fhpibintr: bad intr reg %x\n", 579 sc->sc_dev.dv_xname, stat0); 580 #endif 581 hd->hpib_stat = 0; 582 hd->hpib_imask = 0; 583 #ifdef DEBUG 584 stat0 = fhpibppoll(hs); 585 if ((fhpibdebug & FDB_PPOLL) && 586 fhpibdebugunit == device_unit(&sc->sc_dev)) 587 printf("fhpibintr: got PPOLL status %x\n", stat0); 588 if ((stat0 & (0x80 >> hq->hq_slave)) == 0) { 589 /* 590 * XXX give it another shot (68040) 591 */ 592 /* fhpibppollfail[unit]++; XXX */ 593 DELAY(fhpibppolldelay); 594 stat0 = fhpibppoll(hs); 595 if ((stat0 & (0x80 >> hq->hq_slave)) == 0 && 596 (fhpibdebug & FDB_PPOLL) && 597 fhpibdebugunit == device_unit(&sc->sc_dev)) 598 printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n", 599 device_unit(&sc->sc_dev), hq->hq_slave, 600 stat0); 601 } 602 #endif 603 hs->sc_flags &= ~HPIBF_PPOLL; 604 (hq->hq_intr)(hq->hq_softc); 605 } 606 return 1; 607 } 608 609 static int 610 fhpibppoll(struct hpibbus_softc *hs) 611 { 612 struct fhpib_softc *sc = 613 (struct fhpib_softc *)device_parent(&hs->sc_dev); 614 struct fhpibdevice *hd = sc->sc_regs; 615 int ppoll; 616 617 hd->hpib_stat = 0; 618 hd->hpib_psense = 0; 619 hd->hpib_pmask = 0xFF; 620 hd->hpib_imask = IM_PPRESP | IM_PABORT; 621 DELAY(25); 622 hd->hpib_intr = IM_PABORT; 623 ppoll = hd->hpib_data; 624 if (hd->hpib_intr & IM_PABORT) 625 ppoll = 0; 626 hd->hpib_imask = 0; 627 hd->hpib_pmask = 0; 628 hd->hpib_stat = ST_IENAB; 629 return ppoll; 630 } 631 632 static int 633 fhpibwait(struct fhpibdevice *hd, int x) 634 { 635 int timo = hpibtimeout; 636 637 while ((hd->hpib_intr & x) == 0 && --timo) 638 DELAY(1); 639 if (timo == 0) { 640 #ifdef DEBUG 641 if (fhpibdebug & FDB_FAIL) 642 printf("fhpibwait(%p, %x) timeout\n", hd, x); 643 #endif 644 return -1; 645 } 646 return 0; 647 } 648 649 /* 650 * XXX: this will have to change if we ever allow more than one 651 * pending operation per HP-IB. 652 */ 653 static void 654 fhpibppwatch(void *arg) 655 { 656 struct hpibbus_softc *hs = arg; 657 struct fhpib_softc *sc = 658 (struct fhpib_softc *)device_parent(&hs->sc_dev); 659 struct fhpibdevice *hd = sc->sc_regs; 660 int slave; 661 662 if ((hs->sc_flags & HPIBF_PPOLL) == 0) 663 return; 664 slave = (0x80 >> TAILQ_FIRST(&hs->sc_queue)->hq_slave); 665 #ifdef DEBUG 666 if (!doppollint) { 667 if (fhpibppoll(hs) & slave) { 668 hd->hpib_stat = ST_IENAB; 669 hd->hpib_imask = IM_IDLE | IM_ROOM; 670 } else 671 callout_reset(&sc->sc_ppwatch_ch, 1, fhpibppwatch, sc); 672 return; 673 } 674 if ((fhpibdebug & FDB_PPOLL) && 675 device_unit(&sc->sc_dev) == fhpibdebugunit) 676 printf("fhpibppwatch: sense request on %s\n", 677 sc->sc_dev.dv_xname); 678 #endif 679 hd->hpib_psense = ~slave; 680 hd->hpib_pmask = slave; 681 hd->hpib_stat = ST_IENAB; 682 hd->hpib_imask = IM_PPRESP | IM_PABORT; 683 hd->hpib_ie = IDS_IE; 684 } 685