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