1 /* $NetBSD: fhpib.c,v 1.6 1995/01/07 10:30:10 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1990, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)fhpib.c 8.2 (Berkeley) 1/12/94 36 */ 37 38 /* 39 * 98625A/B HPIB driver 40 */ 41 #include "hpib.h" 42 #if NHPIB > 0 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/kernel.h> 47 #include <sys/buf.h> 48 49 #include <hp300/dev/device.h> 50 #include <hp300/dev/fhpibreg.h> 51 #include <hp300/dev/hpibvar.h> 52 #include <hp300/dev/dmavar.h> 53 54 /* 55 * Inline version of fhpibwait to be used in places where 56 * we don't worry about getting hung. 57 */ 58 #define FHPIBWAIT(hd, m) while (((hd)->hpib_intr & (m)) == 0) DELAY(1) 59 60 #ifdef DEBUG 61 int fhpibdebugunit = -1; 62 int fhpibdebug = 0; 63 #define FDB_FAIL 0x01 64 #define FDB_DMA 0x02 65 #define FDB_WAIT 0x04 66 #define FDB_PPOLL 0x08 67 68 int dopriodma = 0; /* use high priority DMA */ 69 int doworddma = 1; /* non-zero if we should attempt word dma */ 70 int doppollint = 1; /* use ppoll interrupts instead of watchdog */ 71 int fhpibppolldelay = 50; 72 73 long fhpibbadint[2] = { 0 }; 74 long fhpibtransfer[NHPIB] = { 0 }; 75 long fhpibnondma[NHPIB] = { 0 }; 76 long fhpibworddma[NHPIB] = { 0 }; 77 long fhpibppollfail[NHPIB] = { 0 }; 78 #endif 79 80 int fhpibcmd[NHPIB]; 81 82 fhpibtype(hc) 83 register struct hp_ctlr *hc; 84 { 85 register struct hpib_softc *hs = &hpib_softc[hc->hp_unit]; 86 register struct fhpibdevice *hd = (struct fhpibdevice *)hc->hp_addr; 87 88 if (hd->hpib_cid != HPIBC) 89 return(0); 90 hs->sc_type = HPIBC; 91 hs->sc_ba = HPIBC_BA; 92 hc->hp_ipl = HPIB_IPL(hd->hpib_ids); 93 return(1); 94 } 95 96 fhpibreset(unit) 97 int unit; 98 { 99 register struct hpib_softc *hs = &hpib_softc[unit]; 100 register struct fhpibdevice *hd; 101 102 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 103 hd->hpib_cid = 0xFF; 104 DELAY(100); 105 hd->hpib_cmd = CT_8BIT; 106 hd->hpib_ar = AR_ARONC; 107 fhpibifc(hd); 108 hd->hpib_ie = IDS_IE; 109 hd->hpib_data = C_DCL; 110 DELAY(100000); 111 /* 112 * See if we can do word dma. 113 * If so, we should be able to write and read back the appropos bit. 114 */ 115 hd->hpib_ie |= IDS_WDMA; 116 if (hd->hpib_ie & IDS_WDMA) { 117 hd->hpib_ie &= ~IDS_WDMA; 118 hs->sc_flags |= HPIBF_DMA16; 119 #ifdef DEBUG 120 if (fhpibdebug & FDB_DMA) 121 printf("fhpibtype: unit %d has word dma\n", unit); 122 123 #endif 124 } 125 } 126 127 fhpibifc(hd) 128 register struct fhpibdevice *hd; 129 { 130 hd->hpib_cmd |= CT_IFC; 131 hd->hpib_cmd |= CT_INITFIFO; 132 DELAY(100); 133 hd->hpib_cmd &= ~CT_IFC; 134 hd->hpib_cmd |= CT_REN; 135 hd->hpib_stat = ST_ATN; 136 } 137 138 fhpibsend(unit, slave, sec, addr, origcnt) 139 int unit, slave, sec, origcnt; 140 register char *addr; 141 { 142 register struct hpib_softc *hs = &hpib_softc[unit]; 143 register struct fhpibdevice *hd; 144 register int cnt = origcnt; 145 register int timo; 146 147 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 148 hd->hpib_stat = 0; 149 hd->hpib_imask = IM_IDLE | IM_ROOM; 150 if (fhpibwait(hd, IM_IDLE) < 0) 151 goto senderr; 152 hd->hpib_stat = ST_ATN; 153 hd->hpib_data = C_UNL; 154 hd->hpib_data = C_TAG + hs->sc_ba; 155 hd->hpib_data = C_LAG + slave; 156 if (sec < 0) { 157 if (sec == -2) /* selected device clear KLUDGE */ 158 hd->hpib_data = C_SDC; 159 } else 160 hd->hpib_data = C_SCG + sec; 161 if (fhpibwait(hd, IM_IDLE) < 0) 162 goto senderr; 163 if (cnt) { 164 hd->hpib_stat = ST_WRITE; 165 while (--cnt) { 166 hd->hpib_data = *addr++; 167 timo = hpibtimeout; 168 while ((hd->hpib_intr & IM_ROOM) == 0) { 169 if (--timo <= 0) 170 goto senderr; 171 DELAY(1); 172 } 173 } 174 hd->hpib_stat = ST_EOI; 175 hd->hpib_data = *addr; 176 FHPIBWAIT(hd, IM_ROOM); 177 hd->hpib_stat = ST_ATN; 178 /* XXX: HP-UX claims bug with CS80 transparent messages */ 179 if (sec == 0x12) 180 DELAY(150); 181 hd->hpib_data = C_UNL; 182 (void) fhpibwait(hd, IM_IDLE); 183 } 184 hd->hpib_imask = 0; 185 return (origcnt); 186 187 senderr: 188 hd->hpib_imask = 0; 189 fhpibifc(hd); 190 #ifdef DEBUG 191 if (fhpibdebug & FDB_FAIL) { 192 printf("hpib%d: fhpibsend failed: slave %d, sec %x, ", 193 unit, slave, sec); 194 printf("sent %d of %d bytes\n", origcnt-cnt-1, origcnt); 195 } 196 #endif 197 return (origcnt - cnt - 1); 198 } 199 200 fhpibrecv(unit, slave, sec, addr, origcnt) 201 int unit, slave, sec, origcnt; 202 register char *addr; 203 { 204 register struct hpib_softc *hs = &hpib_softc[unit]; 205 register struct fhpibdevice *hd; 206 register int cnt = origcnt; 207 register int timo; 208 209 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 210 /* 211 * Slave < 0 implies continuation of a previous receive 212 * that probably timed out. 213 */ 214 if (slave >= 0) { 215 hd->hpib_stat = 0; 216 hd->hpib_imask = IM_IDLE | IM_ROOM | IM_BYTE; 217 if (fhpibwait(hd, IM_IDLE) < 0) 218 goto recverror; 219 hd->hpib_stat = ST_ATN; 220 hd->hpib_data = C_UNL; 221 hd->hpib_data = C_LAG + hs->sc_ba; 222 hd->hpib_data = C_TAG + slave; 223 if (sec != -1) 224 hd->hpib_data = C_SCG + sec; 225 if (fhpibwait(hd, IM_IDLE) < 0) 226 goto recverror; 227 hd->hpib_stat = ST_READ0; 228 hd->hpib_data = 0; 229 } 230 if (cnt) { 231 while (--cnt >= 0) { 232 timo = hpibtimeout; 233 while ((hd->hpib_intr & IM_BYTE) == 0) { 234 if (--timo == 0) 235 goto recvbyteserror; 236 DELAY(1); 237 } 238 *addr++ = hd->hpib_data; 239 } 240 FHPIBWAIT(hd, IM_ROOM); 241 hd->hpib_stat = ST_ATN; 242 hd->hpib_data = (slave == 31) ? C_UNA : C_UNT; 243 (void) fhpibwait(hd, IM_IDLE); 244 } 245 hd->hpib_imask = 0; 246 return (origcnt); 247 248 recverror: 249 fhpibifc(hd); 250 recvbyteserror: 251 hd->hpib_imask = 0; 252 #ifdef DEBUG 253 if (fhpibdebug & FDB_FAIL) { 254 printf("hpib%d: fhpibrecv failed: slave %d, sec %x, ", 255 unit, slave, sec); 256 printf("got %d of %d bytes\n", origcnt-cnt-1, origcnt); 257 } 258 #endif 259 return (origcnt - cnt - 1); 260 } 261 262 fhpibgo(unit, slave, sec, addr, count, rw, timo) 263 register int unit; 264 int slave, sec, count, rw; 265 char *addr; 266 { 267 register struct hpib_softc *hs = &hpib_softc[unit]; 268 register struct fhpibdevice *hd; 269 register int i; 270 int flags = 0; 271 272 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 273 hs->sc_flags |= HPIBF_IO; 274 if (timo) 275 hs->sc_flags |= HPIBF_TIMO; 276 if (rw == B_READ) 277 hs->sc_flags |= HPIBF_READ; 278 #ifdef DEBUG 279 else if (hs->sc_flags & HPIBF_READ) { 280 printf("fhpibgo: HPIBF_READ still set\n"); 281 hs->sc_flags &= ~HPIBF_READ; 282 } 283 #endif 284 hs->sc_count = count; 285 hs->sc_addr = addr; 286 #ifdef DEBUG 287 fhpibtransfer[unit]++; 288 #endif 289 if ((hs->sc_flags & HPIBF_DMA16) && 290 ((int)addr & 1) == 0 && count && (count & 1) == 0 291 #ifdef DEBUG 292 && doworddma 293 #endif 294 ) { 295 #ifdef DEBUG 296 fhpibworddma[unit]++; 297 #endif 298 flags |= DMAGO_WORD; 299 hd->hpib_latch = 0; 300 } 301 #ifdef DEBUG 302 if (dopriodma) 303 flags |= DMAGO_PRI; 304 #endif 305 if (hs->sc_flags & HPIBF_READ) { 306 fhpibcmd[unit] = CT_REN | CT_8BIT; 307 hs->sc_curcnt = count; 308 dmago(hs->sc_dq.dq_ctlr, addr, count, flags|DMAGO_READ); 309 if (fhpibrecv(unit, slave, sec, 0, 0) < 0) { 310 #ifdef DEBUG 311 printf("fhpibgo: recv failed, retrying...\n"); 312 #endif 313 (void) fhpibrecv(unit, slave, sec, 0, 0); 314 } 315 i = hd->hpib_cmd; 316 hd->hpib_cmd = fhpibcmd[unit]; 317 hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) | 318 ((flags & DMAGO_WORD) ? IDS_WDMA : 0); 319 return; 320 } 321 fhpibcmd[unit] = CT_REN | CT_8BIT | CT_FIFOSEL; 322 if (count < hpibdmathresh) { 323 #ifdef DEBUG 324 fhpibnondma[unit]++; 325 if (flags & DMAGO_WORD) 326 fhpibworddma[unit]--; 327 #endif 328 hs->sc_curcnt = count; 329 (void) fhpibsend(unit, slave, sec, addr, count); 330 fhpibdone(unit); 331 return; 332 } 333 count -= (flags & DMAGO_WORD) ? 2 : 1; 334 hs->sc_curcnt = count; 335 dmago(hs->sc_dq.dq_ctlr, addr, count, flags); 336 if (fhpibsend(unit, slave, sec, 0, 0) < 0) { 337 #ifdef DEBUG 338 printf("fhpibgo: send failed, retrying...\n"); 339 #endif 340 (void) fhpibsend(unit, slave, sec, 0, 0); 341 } 342 i = hd->hpib_cmd; 343 hd->hpib_cmd = fhpibcmd[unit]; 344 hd->hpib_ie = IDS_DMA(hs->sc_dq.dq_ctlr) | IDS_WRITE | 345 ((flags & DMAGO_WORD) ? IDS_WDMA : 0); 346 } 347 348 /* 349 * A DMA read can finish but the device can still be waiting (MAG-tape 350 * with more data than we're waiting for). This timeout routine 351 * takes care of that. Somehow, the thing gets hosed. For now, since 352 * this should be a very rare occurence, we RESET it. 353 */ 354 void 355 fhpibdmadone(arg) 356 void *arg; 357 { 358 register int unit; 359 register struct hpib_softc *hs; 360 int s = splbio(); 361 362 unit = (int)arg; 363 hs = &hpib_softc[unit]; 364 if (hs->sc_flags & HPIBF_IO) { 365 register struct fhpibdevice *hd; 366 register struct devqueue *dq; 367 368 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 369 hd->hpib_imask = 0; 370 hd->hpib_cid = 0xFF; 371 DELAY(100); 372 hd->hpib_cmd = CT_8BIT; 373 hd->hpib_ar = AR_ARONC; 374 fhpibifc(hd); 375 hd->hpib_ie = IDS_IE; 376 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO); 377 dmafree(&hs->sc_dq); 378 dq = hs->sc_sq.dq_forw; 379 (dq->dq_driver->d_intr)(dq->dq_unit); 380 } 381 (void) splx(s); 382 } 383 384 fhpibdone(unit) 385 int unit; 386 { 387 register struct hpib_softc *hs = &hpib_softc[unit]; 388 register struct fhpibdevice *hd; 389 register char *addr; 390 register int cnt; 391 392 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 393 cnt = hs->sc_curcnt; 394 hs->sc_addr += cnt; 395 hs->sc_count -= cnt; 396 #ifdef DEBUG 397 if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit) 398 printf("fhpibdone: addr %x cnt %d\n", 399 hs->sc_addr, hs->sc_count); 400 #endif 401 if (hs->sc_flags & HPIBF_READ) { 402 hd->hpib_imask = IM_IDLE | IM_BYTE; 403 if (hs->sc_flags & HPIBF_TIMO) 404 timeout(fhpibdmadone, (void *)unit, hz >> 2); 405 } else { 406 cnt = hs->sc_count; 407 if (cnt) { 408 addr = hs->sc_addr; 409 hd->hpib_imask = IM_IDLE | IM_ROOM; 410 FHPIBWAIT(hd, IM_IDLE); 411 hd->hpib_stat = ST_WRITE; 412 while (--cnt) { 413 hd->hpib_data = *addr++; 414 FHPIBWAIT(hd, IM_ROOM); 415 } 416 hd->hpib_stat = ST_EOI; 417 hd->hpib_data = *addr; 418 } 419 hd->hpib_imask = IM_IDLE; 420 } 421 hs->sc_flags |= HPIBF_DONE; 422 hd->hpib_stat = ST_IENAB; 423 hd->hpib_ie = IDS_IE; 424 } 425 426 fhpibintr(unit) 427 register int unit; 428 { 429 register struct hpib_softc *hs = &hpib_softc[unit]; 430 register struct fhpibdevice *hd; 431 register struct devqueue *dq; 432 register int stat0; 433 434 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 435 stat0 = hd->hpib_ids; 436 if ((stat0 & (IDS_IE|IDS_IR)) != (IDS_IE|IDS_IR)) { 437 #ifdef DEBUG 438 if ((fhpibdebug & FDB_FAIL) && (stat0 & IDS_IR) && 439 (hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) != HPIBF_IO) 440 printf("hpib%d: fhpibintr: bad status %x\n", 441 unit, stat0); 442 fhpibbadint[0]++; 443 #endif 444 return(0); 445 } 446 if ((hs->sc_flags & (HPIBF_IO|HPIBF_DONE)) == HPIBF_IO) { 447 #ifdef DEBUG 448 fhpibbadint[1]++; 449 #endif 450 return(0); 451 } 452 #ifdef DEBUG 453 if ((fhpibdebug & FDB_DMA) && fhpibdebugunit == unit) 454 printf("fhpibintr: flags %x\n", hs->sc_flags); 455 #endif 456 dq = hs->sc_sq.dq_forw; 457 if (hs->sc_flags & HPIBF_IO) { 458 if (hs->sc_flags & HPIBF_TIMO) 459 untimeout(fhpibdmadone, (void *)unit); 460 stat0 = hd->hpib_cmd; 461 hd->hpib_cmd = fhpibcmd[unit] & ~CT_8BIT; 462 hd->hpib_stat = 0; 463 hd->hpib_cmd = CT_REN | CT_8BIT; 464 stat0 = hd->hpib_intr; 465 hd->hpib_imask = 0; 466 hs->sc_flags &= ~(HPIBF_DONE|HPIBF_IO|HPIBF_READ|HPIBF_TIMO); 467 dmafree(&hs->sc_dq); 468 (dq->dq_driver->d_intr)(dq->dq_unit); 469 } else if (hs->sc_flags & HPIBF_PPOLL) { 470 stat0 = hd->hpib_intr; 471 #ifdef DEBUG 472 if ((fhpibdebug & FDB_FAIL) && 473 doppollint && (stat0 & IM_PPRESP) == 0) 474 printf("hpib%d: fhpibintr: bad intr reg %x\n", 475 unit, stat0); 476 #endif 477 hd->hpib_stat = 0; 478 hd->hpib_imask = 0; 479 #ifdef DEBUG 480 stat0 = fhpibppoll(unit); 481 if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit) 482 printf("fhpibintr: got PPOLL status %x\n", stat0); 483 if ((stat0 & (0x80 >> dq->dq_slave)) == 0) { 484 /* 485 * XXX give it another shot (68040) 486 */ 487 fhpibppollfail[unit]++; 488 DELAY(fhpibppolldelay); 489 stat0 = fhpibppoll(unit); 490 if ((stat0 & (0x80 >> dq->dq_slave)) == 0 && 491 (fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit) 492 printf("fhpibintr: PPOLL: unit %d slave %d stat %x\n", 493 unit, dq->dq_slave, stat0); 494 } 495 #endif 496 hs->sc_flags &= ~HPIBF_PPOLL; 497 (dq->dq_driver->d_intr)(dq->dq_unit); 498 } 499 return(1); 500 } 501 502 fhpibppoll(unit) 503 int unit; 504 { 505 register struct fhpibdevice *hd; 506 register int ppoll; 507 508 hd = (struct fhpibdevice *)hpib_softc[unit].sc_hc->hp_addr; 509 hd->hpib_stat = 0; 510 hd->hpib_psense = 0; 511 hd->hpib_pmask = 0xFF; 512 hd->hpib_imask = IM_PPRESP | IM_PABORT; 513 DELAY(25); 514 hd->hpib_intr = IM_PABORT; 515 ppoll = hd->hpib_data; 516 if (hd->hpib_intr & IM_PABORT) 517 ppoll = 0; 518 hd->hpib_imask = 0; 519 hd->hpib_pmask = 0; 520 hd->hpib_stat = ST_IENAB; 521 return(ppoll); 522 } 523 524 fhpibwait(hd, x) 525 register struct fhpibdevice *hd; 526 int x; 527 { 528 register int timo = hpibtimeout; 529 530 while ((hd->hpib_intr & x) == 0 && --timo) 531 DELAY(1); 532 if (timo == 0) { 533 #ifdef DEBUG 534 if (fhpibdebug & FDB_FAIL) 535 printf("fhpibwait(%x, %x) timeout\n", hd, x); 536 #endif 537 return(-1); 538 } 539 return(0); 540 } 541 542 /* 543 * XXX: this will have to change if we ever allow more than one 544 * pending operation per HP-IB. 545 */ 546 void 547 fhpibppwatch(arg) 548 void *arg; 549 { 550 register int unit; 551 register struct hpib_softc *hs; 552 register struct fhpibdevice *hd; 553 register int slave; 554 555 unit = (int)arg; 556 hs = &hpib_softc[unit]; 557 if ((hs->sc_flags & HPIBF_PPOLL) == 0) 558 return; 559 hd = (struct fhpibdevice *)hs->sc_hc->hp_addr; 560 slave = (0x80 >> hs->sc_sq.dq_forw->dq_slave); 561 #ifdef DEBUG 562 if (!doppollint) { 563 if (fhpibppoll(unit) & slave) { 564 hd->hpib_stat = ST_IENAB; 565 hd->hpib_imask = IM_IDLE | IM_ROOM; 566 } else 567 timeout(fhpibppwatch, (void *)unit, 1); 568 return; 569 } 570 if ((fhpibdebug & FDB_PPOLL) && unit == fhpibdebugunit) 571 printf("fhpibppwatch: sense request on %d\n", unit); 572 #endif 573 hd->hpib_psense = ~slave; 574 hd->hpib_pmask = slave; 575 hd->hpib_stat = ST_IENAB; 576 hd->hpib_imask = IM_PPRESP | IM_PABORT; 577 hd->hpib_ie = IDS_IE; 578 } 579 #endif 580