[BACK]Return to fhpib.c CVS log [TXT][DIR] Up to [local] / sys / arch / hp300 / dev

Annotation of sys/arch/hp300/dev/fhpib.c, Revision 1.1.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