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

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

unix.superglobalmegacorp.com

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