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