[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     ! 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