Annotation of 43BSDReno/sys/tahoevba/ik.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1986 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution is only permitted until one year after the first shipment
                      6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
                      7:  * binary forms are permitted provided that: (1) source distributions retain
                      8:  * this entire copyright notice and comment, and (2) distributions including
                      9:  * binaries display the following acknowledgement:  This product includes
                     10:  * software developed by the University of California, Berkeley and its
                     11:  * contributors'' in the documentation or other materials provided with the
                     12:  * distribution and in all advertising materials mentioning features or use
                     13:  * of this software.  Neither the name of the University nor the names of
                     14:  * its contributors may be used to endorse or promote products derived from
                     15:  * this software without specific prior written permission.
                     16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     19:  *
                     20:  *     @(#)ik.c        7.6 (Berkeley) 6/28/90
                     21:  */
                     22: 
                     23: #include "ik.h"
                     24: #if NIK > 0
                     25: /*
                     26:  * PS300/IKON DR-11W Device Driver.
                     27:  */
                     28: #include "param.h"
                     29: #include "buf.h"
                     30: #include "cmap.h"
                     31: #include "conf.h"
                     32: #include "dkstat.h"
                     33: #include "map.h"
                     34: #include "systm.h"
                     35: #include "user.h"
                     36: #include "vmmac.h"
                     37: #include "proc.h"
                     38: #include "kernel.h"
                     39: #include "syslog.h"
                     40: 
                     41: #include "../tahoe/mtpr.h"
                     42: #include "../tahoe/pte.h"
                     43: 
                     44: #include "../tahoevba/vbavar.h"
                     45: #include "../tahoevba/ikreg.h"
                     46: #include "../tahoevba/psreg.h"
                     47: #include "../tahoevba/psproto.h"
                     48: 
                     49: int    ikprobe(), ikattach(), iktimer();
                     50: struct vba_device *ikinfo[NIK];
                     51: long   ikstd[] = { 0 };
                     52: struct vba_driver ikdriver = { ikprobe, 0, ikattach, 0, ikstd, "ik", ikinfo };
                     53: 
                     54: #define splik()                spl4()
                     55: /*
                     56:  * Devices are organized in pairs with the odd valued
                     57:  * device being used for ``diagnostic'' purposes.  That
                     58:  * is diagnostic devices don't get auto-attach'd and
                     59:  * detach'd on open-close.
                     60:  */
                     61: #define IKUNIT(dev)    (minor(dev) >> 1)
                     62: #define IKDIAG(dev)    (minor(dev) & 01)       /* is a diagnostic unit */
                     63: 
                     64: struct ik_softc {
                     65:        uid_t   is_uid;         /* uid of open processes */
                     66:        u_short is_timeout;     /* current timeout (seconds) */
                     67:        u_short is_error;       /* internal error codes */
                     68:        u_short is_flags;
                     69: #define IKF_ATTACHED   0x1     /* unit is attached (not used yet) */
                     70:        union {
                     71:                u_short w[2];
                     72:                u_long  l;
                     73:        } is_nameaddr;          /* address of last symbol lookup */
                     74:        caddr_t is_buf[PS_MAXDMA];/* i/o buffer XXX */
                     75: } ik_softc[NIK];
                     76: 
                     77: struct buf iktab[NIK];         /* unit command queue headers */
                     78: struct buf rikbuf[NIK];        /* buffers for read/write operations */
                     79: struct buf cikbuf[NIK];        /* buffers for control operations */
                     80: 
                     81: /* buf overlay definitions */
                     82: #define b_command      b_resid
                     83: 
                     84: int    ikdiotimo = PS_DIOTIMO; /* dio polling timeout */
                     85: int    iktimeout = PS_TIMEOUT; /* attention/dma timeout (in hz) */
                     86: 
                     87: ikprobe(reg, vi)
                     88:        caddr_t reg;
                     89:        struct vba_device *vi;
                     90: {
                     91:        register int br, cvec;          /* r12, r11 */
                     92:        register struct ikdevice *ik;
                     93: 
                     94: #ifdef lint
                     95:        br = 0; cvec = br; br = cvec;
                     96:        ikintr(0);
                     97: #endif
                     98:        if (badaddr(reg, 2))
                     99:                return (0);
                    100:        ik = (struct ikdevice *)reg;
                    101:        ik->ik_vec = --vi->ui_hd->vh_lastiv;
                    102:        /*
                    103:         * Use extended non-privileged address modifier
                    104:         * to avoid address overlap with 24-bit devices.
                    105:         */
                    106:        ik->ik_mod = 0xf1;                      /* address modifier */
                    107:        /*
                    108:         * Try and reset the PS300.  Since this
                    109:         * won't work if it's powered off, we
                    110:         * can't use sucess/failure to decide
                    111:         * if the device is present.
                    112:         */
                    113:        br = 0;
                    114:        (void) psreset(ik, IKCSR_IENA);
                    115:        if (br == 0)                            /* XXX */
                    116:                br = 0x18, cvec = ik->ik_vec;   /* XXX */
                    117:        return (sizeof (struct ikdevice));
                    118: }
                    119: 
                    120: /*
                    121:  * Perform a ``hard'' reset.
                    122:  */
                    123: psreset(ik, iena)
                    124:        register struct ikdevice *ik;
                    125: {
                    126: 
                    127:        ik->ik_csr = IKCSR_MCLR|iena;
                    128:        DELAY(10000);
                    129:        ik->ik_csr = IKCSR_FNC3|iena;
                    130:        if (!iena)
                    131:                return (dioread(ik) == PS_RESET);
                    132:        return (1);
                    133: }
                    134: 
                    135: ikattach(vi)
                    136:        struct vba_device *vi;
                    137: {
                    138: 
                    139:        ik_softc[vi->ui_unit].is_uid = -1;
                    140: }
                    141: 
                    142: /*
                    143:  * Open a PS300 and attach.  We allow multiple
                    144:  * processes with the same uid to share a unit.
                    145:  */
                    146: /*ARGSUSED*/
                    147: ikopen(dev, flag)
                    148:        dev_t dev;
                    149:        int flag;
                    150: {
                    151:        register int unit = IKUNIT(dev);
                    152:        register struct ik_softc *sc;
                    153:        struct vba_device *vi;
                    154:        struct ikdevice *ik;
                    155:        int reset;
                    156: 
                    157:        if (unit >= NIK || (vi = ikinfo[unit]) == 0 || vi->ui_alive == 0)
                    158:                return (ENXIO);
                    159:        sc = &ik_softc[unit];
                    160:        if (sc->is_uid != (uid_t)-1 && sc->is_uid != u.u_uid)
                    161:                return (EBUSY);
                    162:        if (sc->is_uid == (uid_t)-1) {
                    163:                sc->is_timeout = 0;
                    164:                timeout(iktimer, (caddr_t)unit, hz);
                    165:                /*
                    166:                 * Perform PS300 attach for first process.
                    167:                 */
                    168:                if (!IKDIAG(dev)) {
                    169:                        reset = 0;
                    170:                again:
                    171:                        if (ikcommand(dev, PS_ATTACH, 1)) {
                    172:                                /*
                    173:                                 * If attach fails, perform a hard
                    174:                                 * reset once, then retry the command.
                    175:                                 */
                    176:                                ik = (struct ikdevice *)ikinfo[unit]->ui_addr;
                    177:                                if (!reset++ && psreset(ik, 0))
                    178:                                        goto again;
                    179:                                untimeout(iktimer, (caddr_t)unit);
                    180:                                return (EIO);
                    181:                        }
                    182:                }
                    183:                sc->is_uid = u.u_uid;
                    184:        }
                    185:        return (0);
                    186: }
                    187: 
                    188: /*ARGSUSED*/
                    189: ikclose(dev, flag)
                    190:        dev_t dev;
                    191:        int flag;
                    192: {
                    193:        int unit = IKUNIT(dev);
                    194:        register struct ik_softc *sc = &ik_softc[unit];
                    195: 
                    196:        if (!IKDIAG(dev))
                    197:                (void) ikcommand(dev, PS_DETACH, 1);    /* auto detach */
                    198:        sc->is_uid = -1;
                    199:        untimeout(iktimer, (caddr_t)unit);
                    200:        return (0);
                    201: }
                    202: 
                    203: ikread(dev, uio)
                    204:        dev_t dev;
                    205:        struct uio *uio;
                    206: {
                    207: 
                    208:        return (ikrw(dev, uio, B_READ));
                    209: }
                    210: 
                    211: ikwrite(dev, uio)
                    212:        dev_t dev;
                    213:        struct uio *uio;
                    214: {
                    215: 
                    216:        return (ikrw(dev, uio, B_WRITE));
                    217: }
                    218: 
                    219: /*
                    220:  * Take read/write request and perform physical i/o
                    221:  * transaction with PS300.  This involves constructing
                    222:  * a physical i/o request vector based on the uio
                    223:  * vector, performing the dma, and, finally, moving
                    224:  * the data to it's final destination (because of CCI
                    225:  * VERSAbus bogosities).
                    226:  */
                    227: ikrw(dev, uio, rw)
                    228:        dev_t dev;
                    229:        register struct uio *uio;
                    230:        int rw;
                    231: {
                    232:        int error, unit = IKUNIT(dev), s, wrcmd;
                    233:        register struct buf *bp;
                    234:        register struct iovec *iov;
                    235:        register struct psalist *ap;
                    236:        struct ik_softc *sc = &ik_softc[unit];
                    237: 
                    238:        if (unit >= NIK)
                    239:                return (ENXIO);
                    240:        bp = &rikbuf[unit];
                    241:        error = 0, iov = uio->uio_iov, wrcmd = PS_WRPHY;
                    242:        for (; !error && uio->uio_iovcnt; iov++, uio->uio_iovcnt--) { 
                    243:                /*
                    244:                 * Hack way to set PS300 address w/o doing an lseek
                    245:                 * and specify write physical w/ refresh synchronization.
                    246:                 */
                    247:                if (iov->iov_len == 0) {
                    248:                        if ((int)iov->iov_base&PSIO_SYNC)
                    249:                                wrcmd = PS_WRPHY_SYNC;
                    250:                        uio->uio_offset = (int)iov->iov_base & ~PSIO_SYNC;
                    251:                        continue;
                    252:                }
                    253:                if (iov->iov_len > PS_MAXDMA) {
                    254:                        sc->is_error = PSERROR_INVALBC, error = EINVAL;
                    255:                        continue;
                    256:                }
                    257:                if ((int)uio->uio_offset&01) {
                    258:                        sc->is_error = PSERROR_BADADDR, error = EINVAL;
                    259:                        continue;
                    260:                }
                    261:                s = splbio();
                    262:                while (bp->b_flags&B_BUSY) {
                    263:                        bp->b_flags |= B_WANTED;
                    264:                        sleep((caddr_t)bp, PRIBIO+1);
                    265:                }
                    266:                splx(s);
                    267:                bp->b_flags = B_BUSY | rw;
                    268:                /*
                    269:                 * Construct address descriptor in buffer.
                    270:                 */
                    271:                ap = (struct psalist *)sc->is_buf;
                    272:                ap->nblocks = 1;
                    273:                /* work-around dr300 word swapping */
                    274:                ap->addr[0] = uio->uio_offset & 0xffff;
                    275:                ap->addr[1] = uio->uio_offset >> 16;
                    276:                ap->wc = (iov->iov_len + 1) >> 1;
                    277:                if (rw == B_WRITE) {
                    278:                        error = copyin(iov->iov_base, (caddr_t)&ap[1],
                    279:                            (unsigned)iov->iov_len);
                    280:                        if (!error)
                    281:                                error = ikcommand(dev, wrcmd,
                    282:                                    iov->iov_len + sizeof (*ap));
                    283:                } else {
                    284:                        caddr_t cp;
                    285:                        int len;
                    286: 
                    287:                        error = ikcommand(dev, PS_RDPHY, sizeof (*ap));
                    288:                        cp = (caddr_t)&ap[1], len = iov->iov_len;
                    289:                        for (; len > 0; len -= NBPG, cp += NBPG)
                    290:                                mtpr(P1DC, cp);
                    291:                        if (!error)
                    292:                                error = copyout((caddr_t)&ap[1], iov->iov_base,
                    293:                                    (unsigned)iov->iov_len);
                    294:                }
                    295:                (void) splbio();
                    296:                if (bp->b_flags&B_WANTED)
                    297:                        wakeup((caddr_t)bp);
                    298:                splx(s);
                    299:                uio->uio_resid -= iov->iov_len;
                    300:                uio->uio_offset += iov->iov_len;
                    301:                bp->b_flags &= ~(B_BUSY|B_WANTED);
                    302:        }
                    303:        return (error);
                    304: }
                    305: 
                    306: /*
                    307:  * Perform a PS300 command.
                    308:  */
                    309: ikcommand(dev, com, count)
                    310:        dev_t dev;
                    311:        int com, count;
                    312: {
                    313:        register struct buf *bp;
                    314:        register int s;
                    315:        int error;
                    316: 
                    317:        bp = &cikbuf[IKUNIT(dev)];
                    318:        s = splik();
                    319:        while (bp->b_flags&B_BUSY) {
                    320:                if (bp->b_flags&B_DONE)
                    321:                        break;
                    322:                bp->b_flags |= B_WANTED;
                    323:                sleep((caddr_t)bp, PRIBIO);
                    324:        }
                    325:        bp->b_flags = B_BUSY|B_READ;
                    326:        splx(s);
                    327:        bp->b_dev = dev;
                    328:        bp->b_command = com;
                    329:        bp->b_bcount = count;
                    330:        ikstrategy(bp);
                    331:        error = biowait(bp);
                    332:        if (bp->b_flags&B_WANTED)
                    333:                wakeup((caddr_t)bp);
                    334:        bp->b_flags &= B_ERROR;
                    335:        return (error);
                    336: }
                    337: 
                    338: /*
                    339:  * Physio strategy routine
                    340:  */
                    341: ikstrategy(bp)
                    342:        register struct buf *bp;
                    343: {
                    344:        register struct buf *dp;
                    345: 
                    346:        /*
                    347:         * Put request at end of controller queue.
                    348:         */
                    349:        dp = &iktab[IKUNIT(bp->b_dev)];
                    350:        bp->av_forw = NULL;
                    351:        (void) splik();
                    352:        if (dp->b_actf != NULL) {
                    353:                dp->b_actl->av_forw = bp;
                    354:                dp->b_actl = bp;
                    355:        } else
                    356:                dp->b_actf = dp->b_actl = bp;
                    357:        if (!dp->b_active)
                    358:                ikstart(dp);
                    359:        (void) spl0();
                    360: }
                    361: 
                    362: /*
                    363:  * Start the next command on the controller's queue.
                    364:  */
                    365: ikstart(dp)
                    366:        register struct buf *dp;
                    367: {
                    368:        register struct buf *bp;
                    369:        register struct ikdevice *ik;
                    370:        register struct ik_softc *sc;
                    371:        u_short bc, csr;
                    372:        u_int addr;
                    373:        int unit;
                    374: 
                    375: loop:
                    376:        /*
                    377:         * Pull a request off the controller queue
                    378:         */
                    379:        if ((bp = dp->b_actf) == NULL) {
                    380:                dp->b_active = 0;
                    381:                return;
                    382:        }
                    383:        /*
                    384:         * Mark controller busy and process this request.
                    385:         */
                    386:        dp->b_active = 1;
                    387:        unit = IKUNIT(bp->b_dev);
                    388:        sc = &ik_softc[unit];
                    389:        ik = (struct ikdevice *)ikinfo[unit]->ui_addr;
                    390:        switch ((int)bp->b_command) {
                    391: 
                    392:        case PS_ATTACH:         /* logical unit attach */
                    393:        case PS_DETACH:         /* logical unit detach */
                    394:        case PS_LOOKUP:         /* name lookup */
                    395:        case PS_RDPHY:          /* physical i/o read */
                    396:        case PS_WRPHY:          /* physical i/o write */
                    397:        case PS_WRPHY_SYNC:     /* physical i/o write w/ sync */
                    398:                /*
                    399:                 * Handshake command and, optionally,
                    400:                 * byte count and byte swap flag.
                    401:                 */
                    402:                if (sc->is_error = diowrite(ik, (u_short)bp->b_command))
                    403:                        goto bad;
                    404:                if (bp->b_command < PS_DETACH) {
                    405:                        if (sc->is_error = diowrite(ik, (u_short)bp->b_bcount))
                    406:                                goto bad;
                    407:                        if (sc->is_error = diowrite(ik, (u_short)0 /* !swab */))
                    408:                                goto bad;
                    409:                }
                    410:                /*
                    411:                 * Set timeout and wait for an attention interrupt.
                    412:                 */
                    413:                sc->is_timeout = iktimeout;
                    414:                return;
                    415: 
                    416:        case PS_DMAOUT:         /* dma data host->PS300 */
                    417:                bc = bp->b_bcount;
                    418:                csr = IKCSR_CYCLE;
                    419:                break;
                    420: 
                    421:        case PS_DMAIN:          /* dma data PS300->host */
                    422:                bc = bp->b_bcount;
                    423:                csr = IKCSR_CYCLE|IKCSR_FNC1;
                    424:                break;
                    425: 
                    426:        default:
                    427:                log(LOG_ERR, "ik%d: bad cmd %x\n", unit, bp->b_command);
                    428:                sc->is_error = PSERROR_BADCMD;
                    429:                goto bad;
                    430:        }
                    431:        /* initiate dma transfer */
                    432:        addr = vtoph((struct proc *)0, (unsigned)sc->is_buf);
                    433:        ik->ik_bahi = addr >> 17;
                    434:        ik->ik_balo = (addr >> 1) & 0xffff;
                    435:        ik->ik_wc = ((bc + 1) >> 1) - 1;        /* round & convert */
                    436:        ik->ik_pulse = IKPULSE_RATTF|IKPULSE_RDMAF;
                    437:        sc->is_timeout = iktimeout;
                    438:        ik->ik_csr = IKCSR_IENA|IKCSR_GO|csr;
                    439:        return;
                    440: bad:
                    441:        bp->b_flags |= B_ERROR;
                    442:        dp->b_actf = bp->av_forw;               /* remove from queue */
                    443:        biodone(bp);
                    444:        goto loop;
                    445: }
                    446: 
                    447: #define FETCHWORD(i) { \
                    448:        v = dioread(ik); \
                    449:        if (v == -1) { \
                    450:                sc->is_error = PSERROR_NAMETIMO; \
                    451:                goto bad; \
                    452:        } \
                    453:        sc->is_nameaddr.w[i] = v; \
                    454: }
                    455: 
                    456: /*
                    457:  * Process a device interrupt.
                    458:  */
                    459: ikintr(ikon)
                    460:        int ikon;
                    461: {
                    462:        register struct ikdevice *ik;
                    463:        register struct buf *bp, *dp;
                    464:        struct ik_softc *sc;
                    465:        register u_short data;
                    466:        int v;
                    467: 
                    468:        /* should go by controller, but for now... */
                    469:        if (ikinfo[ikon] == 0)
                    470:                return;
                    471:        ik = (struct ikdevice *)ikinfo[ikon]->ui_addr;
                    472:        /*
                    473:         * Discard all non-attention interrupts.  The
                    474:         * interrupts we're throwing away should all be
                    475:         * associated with DMA completion.
                    476:         */
                    477:        data = ik->ik_data;
                    478:        if ((ik->ik_csr&(IKCSR_ATTF|IKCSR_STATC)) != IKCSR_ATTF) {
                    479:                ik->ik_pulse = IKPULSE_RATTF|IKPULSE_RDMAF|IKPULSE_SIENA;
                    480:                return;
                    481:        }
                    482:        /*
                    483:         * Fetch attention code immediately.
                    484:         */
                    485:        ik->ik_csr = IKCSR_RATTF|IKCSR_RDMAF|IKCSR_FNC1;
                    486:        ik->ik_pulse = IKPULSE_FNC2;
                    487:        /*
                    488:         * Get device and block structures, and a pointer
                    489:         * to the vba_device for the device.  We receive an
                    490:         * unsolicited interrupt whenever the PS300 is power
                    491:         * cycled (so ignore it in that case).
                    492:         */
                    493:        dp = &iktab[ikon];
                    494:        if ((bp = dp->b_actf) == NULL) {
                    495:                if (PS_CODE(data) != PS_RESET)          /* power failure */
                    496:                        log(LOG_WARNING, "ik%d: spurious interrupt, code %x\n",
                    497:                            ikon, data);
                    498:                goto enable;
                    499:        }
                    500:        sc = &ik_softc[IKUNIT(bp->b_dev)];
                    501:        sc->is_timeout = 0;                     /* disable timer */
                    502:        switch (PS_CODE(data)) {
                    503: 
                    504:        case PS_LOOKUP:                         /* name lookup */
                    505:                if (data == PS_LOOKUP) {        /* dma name */
                    506:                        bp->b_command = PS_DMAOUT;
                    507:                        goto opcont;
                    508:                }
                    509:                if (data == PS_DMAOK(PS_LOOKUP)) {
                    510:                        /* reenable interrupt and wait for address */
                    511:                        sc->is_timeout = iktimeout;
                    512:                        goto enable;
                    513:                }
                    514:                /*
                    515:                 * Address should be present, extract it one
                    516:                 * word at a time from the PS300 (yech).
                    517:                 */
                    518:                if (data != PS_ADROK(PS_LOOKUP))
                    519:                        goto bad;
                    520:                FETCHWORD(0);
                    521:                FETCHWORD(1);
                    522:                goto opdone;
                    523: 
                    524:        case PS_WRPHY_SYNC:                     /* physical i/o write w/ sync */
                    525:                if (data == PS_WRPHY_SYNC) {    /* start dma transfer */
                    526:                        bp->b_command = PS_DMAOUT;
                    527:                        goto opcont;
                    528:                }
                    529:                if (data != PS_DMAOK(PS_WRPHY_SYNC))
                    530:                        goto bad;
                    531:                goto opdone;
                    532: 
                    533:        case PS_WRPHY:                          /* physical i/o write */
                    534:                if (data == PS_WRPHY) { /* start dma transfer */
                    535:                        bp->b_command = PS_DMAOUT;
                    536:                        goto opcont;
                    537:                }
                    538:                if (data != PS_DMAOK(PS_WRPHY))
                    539:                        goto bad;
                    540:                goto opdone;
                    541: 
                    542:        case PS_ATTACH:                         /* attach unit */
                    543:        case PS_DETACH:                         /* detach unit */
                    544:        case PS_ABORT:                          /* abort code from ps300 */
                    545:                if (data != bp->b_command)
                    546:                        goto bad;
                    547:                goto opdone;
                    548: 
                    549:        case PS_RDPHY:                          /* physical i/o read */
                    550:                if (data == PS_RDPHY) {         /* dma address list */
                    551:                        bp->b_command = PS_DMAOUT;
                    552:                        goto opcont;
                    553:                }
                    554:                if (data == PS_ADROK(PS_RDPHY)) {
                    555:                        /* collect read byte count and start dma */
                    556:                        bp->b_bcount = dioread(ik);
                    557:                        if (bp->b_bcount == -1)
                    558:                                goto bad;
                    559:                        bp->b_command = PS_DMAIN;
                    560:                        goto opcont;
                    561:                }
                    562:                if (data == PS_DMAOK(PS_RDPHY))
                    563:                        goto opdone;
                    564:                goto bad;
                    565:        }
                    566: bad:
                    567:        sc->is_error = data;
                    568:        bp->b_flags |= B_ERROR;
                    569: opdone:
                    570:        dp->b_actf = bp->av_forw;               /* remove from queue */
                    571:        biodone(bp);
                    572: opcont:
                    573:        ikstart(dp);
                    574: enable:
                    575:        ik->ik_pulse = IKPULSE_SIENA;           /* explicitly reenable */
                    576: }
                    577: 
                    578: /*
                    579:  * Watchdog timer.
                    580:  */
                    581: iktimer(unit)
                    582:        int unit;
                    583: {
                    584:        register struct ik_softc *sc = &ik_softc[unit];
                    585: 
                    586:        if (sc->is_timeout && --sc->is_timeout == 0) {
                    587:                register struct buf *dp, *bp;
                    588:                int s;
                    589: 
                    590:                log(LOG_ERR, "ik%d: timeout\n", unit);
                    591:                s = splik();
                    592:                /* should abort current command */
                    593:                dp = &iktab[unit];
                    594:                if (bp = dp->b_actf) {
                    595:                        sc->is_error = PSERROR_CMDTIMO;
                    596:                        bp->b_flags |= B_ERROR;
                    597:                        dp->b_actf = bp->av_forw;       /* remove from queue */
                    598:                        biodone(bp);
                    599:                        ikstart(dp);
                    600:                }
                    601:                splx(s);
                    602:        }
                    603:        timeout(iktimer, (caddr_t)unit, hz);
                    604: }
                    605: 
                    606: /*
                    607:  * Handshake read from DR300.
                    608:  */
                    609: dioread(ik)
                    610:        register struct ikdevice *ik;
                    611: {
                    612:        register int t;
                    613:        u_short data;
                    614: 
                    615:        for (t = ikdiotimo; t > 0; t--)
                    616:                if ((ik->ik_csr&(IKCSR_ATTF|IKCSR_STATC)) == IKCSR_ATTF) {
                    617:                        data = ik->ik_data;
                    618:                        ik->ik_csr = IKCSR_RATTF|IKCSR_RDMAF|IKCSR_FNC1;
                    619:                        ik->ik_pulse = IKPULSE_FNC2;
                    620:                        return (data);
                    621:                }
                    622:        return (-1);
                    623: }
                    624: 
                    625: /*
                    626:  * Handshake write to DR300. 
                    627:  *
                    628:  * Interrupts are enabled before completing the work
                    629:  * so the caller should either be at splik or be
                    630:  * prepared to take the interrupt immediately.
                    631:  */
                    632: diowrite(ik, v)
                    633:        register struct ikdevice *ik;
                    634:        u_short v;
                    635: {
                    636:        register int t;
                    637:        register u_short csr;
                    638: 
                    639: top:
                    640:        /*
                    641:         * Deposit data and generate dr300 attention
                    642:         */
                    643:        ik->ik_data = v;
                    644:        ik->ik_csr = IKCSR_RDMAF|IKCSR_RATTF;
                    645:        ik->ik_pulse = IKPULSE_FNC2;
                    646:        for (t = ikdiotimo; t > 0; t--) {
                    647:                csr = ik->ik_csr;
                    648: #define IKCSR_DONE     (IKCSR_STATA|IKCSR_STATC)
                    649:                if ((csr&IKCSR_DONE) == IKCSR_DONE) {
                    650:                        /* 
                    651:                         * Done, complete handshake by notifying dr300.
                    652:                         */
                    653:                        ik->ik_csr = IKCSR_IENA;        /* ~IKCSR_FNC1 */
                    654:                        ik->ik_pulse = IKPULSE_FNC2;
                    655:                        return (0);
                    656:                }
                    657:                /* beware of potential deadlock with dioread */
                    658:                if ((csr&(IKCSR_ATTF|IKCSR_STATC)) == IKCSR_ATTF)
                    659:                        goto top;
                    660:        }
                    661:        ik->ik_csr = IKCSR_IENA;
                    662:        return (PSERROR_DIOTIMO);
                    663: }
                    664: 
                    665: /*ARGSUSED*/
                    666: ikioctl(dev, cmd, data, flag)
                    667:        dev_t dev;
                    668:        int cmd;
                    669:        caddr_t data;
                    670:        int flag;
                    671: {
                    672:        int error = 0, unit = IKUNIT(dev), s;
                    673:        register struct ik_softc *sc = &ik_softc[unit];
                    674: 
                    675:        switch (cmd) {
                    676: 
                    677:        case PSIOGETERROR:              /* get error code for last operation */
                    678:                *(int *)data = sc->is_error;
                    679:                break;
                    680: 
                    681:        case PSIOLOOKUP: {              /* PS300 name lookup */
                    682:                register struct pslookup *lp = (struct pslookup *)data;
                    683:                register struct buf *bp;
                    684: 
                    685:                if (lp->pl_len > PS_MAXNAMELEN)
                    686:                        return (EINVAL);
                    687:                bp = &rikbuf[unit];
                    688:                s = splbio();
                    689:                while (bp->b_flags&B_BUSY) {
                    690:                        bp->b_flags |= B_WANTED;
                    691:                        sleep((caddr_t)bp, PRIBIO+1);
                    692:                }
                    693:                splx(s);
                    694:                bp->b_flags = B_BUSY | B_WRITE;
                    695:                error = copyin(lp->pl_name, (caddr_t)sc->is_buf,
                    696:                    (unsigned)lp->pl_len);
                    697:                if (error == 0) {
                    698:                        if (lp->pl_len&1)
                    699:                                sc->is_buf[lp->pl_len] = '\0';
                    700:                        error = ikcommand(dev, PS_LOOKUP, lp->pl_len);
                    701:                }
                    702:                s = splbio();
                    703:                if (bp->b_flags&B_WANTED)
                    704:                        wakeup((caddr_t)bp);
                    705:                splx(s);
                    706:                bp->b_flags &= ~(B_BUSY|B_WANTED);
                    707:                lp->pl_addr = sc->is_nameaddr.l;
                    708:                break;
                    709:        }
                    710:        default:
                    711:                return (ENOTTY);
                    712:        }
                    713:        return (error);
                    714: }
                    715: #endif

unix.superglobalmegacorp.com

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