Annotation of Net2/arch/hp300/dev/fhpib.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.