Annotation of 43BSDReno/sys/vaxuba/vs.c, revision 1.1

1.1     ! root        1: /* @(#)vs.c    7.7 (MIT) 6/21/90 */
        !             2:  /****************************************************************************
        !             3:  *                                                                         *
        !             4:  *  Copyright (c) 1983, 1984 by                                                    *
        !             5:  *  DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts.                 *
        !             6:  *  All rights reserved.                                                   *
        !             7:  *                                                                         *
        !             8:  *  This software is furnished on an as-is basis and may be used and copied *
        !             9:  *  only with inclusion of the above copyright notice. This software or any *
        !            10:  *  other copies thereof may be provided or otherwise made available to     *
        !            11:  *  others only for non-commercial purposes.  No title to or ownership of   *
        !            12:  *  the software is hereby transferred.                                            *
        !            13:  *                                                                         *
        !            14:  *  The information in this software is  subject to change without notice   *
        !            15:  *  and  should  not  be  construed as  a commitment by DIGITAL EQUIPMENT   *
        !            16:  *  CORPORATION.                                                           *
        !            17:  *                                                                         *
        !            18:  *  DIGITAL assumes no responsibility for the use  or  reliability of its   *
        !            19:  *  software on equipment which is not supplied by DIGITAL.                *
        !            20:  *                                                                         *
        !            21:  *                                                                         *
        !            22:  ****************************************************************************/
        !            23: 
        !            24: #include "vs.h"
        !            25: #if NVS > 0
        !            26: 
        !            27: #include "machine/pte.h"
        !            28: 
        !            29: #include "param.h"
        !            30: #include "user.h"
        !            31: #include "buf.h"
        !            32: #include "systm.h"
        !            33: #include "map.h"
        !            34: #include "kernel.h"
        !            35: #include "ioctl.h"
        !            36: 
        !            37: #include "vsio.h" 
        !            38: 
        !            39: #include "proc.h"
        !            40: #include "uio.h"
        !            41: #include "vmmac.h"
        !            42: #include "file.h"
        !            43: 
        !            44: #include "ubareg.h"
        !            45: #include "ubavar.h"
        !            46: #include "vsreg.h"
        !            47: 
        !            48: #include "../vax/mtpr.h"
        !            49: 
        !            50: #define        VSWAITPRI       (PZERO+1)
        !            51: #define        VSMAXEVQ        64      /* must be power of 2 */
        !            52: #define EVROUND(x)     ((x) & (VSMAXEVQ - 1))
        !            53: 
        !            54: 
        !            55: #define VSBUFFSIZE     3072
        !            56: struct vsBuffArea {
        !            57:        vsIoAddr vsioa;
        !            58:        char    obuff[VSBUFFSIZE];
        !            59:        vsEvent ibuff[VSMAXEVQ];
        !            60: };
        !            61: struct vsBuffArea vsBuff[NVS];
        !            62: 
        !            63: 
        !            64: int vsprobe(), vsattach();
        !            65: struct uba_device *vsdinfo[NVS];
        !            66: u_short vsstd[] = { 0 };
        !            67: struct uba_driver vsdriver =
        !            68:        { vsprobe, 0, vsattach, 0, vsstd, "vs", vsdinfo, 0, 0 };
        !            69: 
        !            70: #define        VSUNIT(dev)     (minor(dev))
        !            71: 
        !            72: struct vs_softc {
        !            73:        unsigned inited : 1;            /* has this ever been inited? */
        !            74:        unsigned open : 1;              /* only one open, please */
        !            75:        unsigned linkAvail : 1;         /* link is up */
        !            76:        short   pgrp;                   /* process group for SIGHUP */
        !            77:        int     romVersion;             /* rom version */
        !            78:        struct vs_fparm offset;         /* address base */
        !            79:        struct vs_csr   csr;            /* saved csr0 */
        !            80:        struct vs_intr  irr;            /* saved interrupt reason */
        !            81:        struct vs_kbd   krr;            /* saved keyboard */
        !            82:        struct vs_fparm pr;             /* saved parameter regs */
        !            83:        struct proc *rsel;              /* process waiting for select */
        !            84:        struct vs_fparm vs_nextgo;      /* next packet to go */
        !            85:        short vs_status;                /* status from previous packet */
        !            86:        vsStats stats;                  /* statistics */
        !            87:        int vsBuff_ubinfo;              /* ubinfo for vsBuff */
        !            88: }vs_softc[NVS];
        !            89: 
        !            90: #define        TRUE    1
        !            91: #define        FALSE   0
        !            92: 
        !            93: #define        printI  if (vsIntrPrintfs)printf
        !            94: #define        printD  if (vsDebugPrintfs)printf
        !            95: #define        printM  if (vsMlpPrintfs) vsMlpPrintfs--,printf
        !            96: int    vsIntrPrintfs = 0;
        !            97: int    vsDebugPrintfs = 0;
        !            98: int    vsMlpPrintfs = 0;
        !            99: 
        !           100: /* 
        !           101:  * Tell the system that it's out there, and set up the device's interrupt
        !           102:  * vector. Since we are supporting vs100s and vs125s,
        !           103:  * this is a bit kludgey. The vs100 works much
        !           104:  * as one expects, but the vs125 tries to set all the fiber link
        !           105:  * related bits when you hit VS_IE, ignoring the way the 100 works.
        !           106:  * Also, the vs100 will let you set the interrupt vector, but
        !           107:  * the vs125 ignores this and uses its hard-wired value.
        !           108:  * And there's no sure fire to tell which variant it is.
        !           109:  * Ugh. Ugh. Ugh.
        !           110:  */
        !           111: 
        !           112: vsprobe(reg)
        !           113: caddr_t reg;
        !           114: {
        !           115:        register int br, cvec;          /* value-result */
        !           116:        register struct vsdevice *vsaddr = (struct vsdevice *)reg;
        !           117: 
        !           118: #ifdef lint
        !           119:        br = 0; cvec = br; br = cvec;
        !           120:        vsintr(0);
        !           121: #endif
        !           122:        br = 0x15;
        !           123:        cvec = (uba_hd[numuba].uh_lastiv -= 4*8);
        !           124:        /* 
        !           125:         * uh_lastiv is the last free interrupt vector in the
        !           126:         * unibus addapter header (uba_hd).
        !           127:         */
        !           128: 
        !           129:        vsaddr->vs_csr0 = cvec >> 2;    /* Save the vector for use on next device */
        !           130:        vsaddr->vs_irr = 0;             /* Csr will only be read if irr == 0 */
        !           131:        vsaddr->vs_irr = 0;             /* Clear interrupt reason register */
        !           132:        vsaddr->vs_pr1  = 0;            /* Clear function parameter */
        !           133:        vsaddr->vs_pr2  = 0;            /* Clear function parameter */
        !           134:        vsaddr->vs_ivr = cvec;          /* set up vector (no-op for vs125) */
        !           135: 
        !           136:        DELAY(100000);
        !           137:        if (vsaddr->vs_csr0 & VS_LNK_AVL)
        !           138:                return(0);      /* light won't go off! */
        !           139:        vsaddr->vs_csr0 &= ~VS_LNK_TRNS;
        !           140:        vsaddr->vs_csr0 |= VS_IE;       /* enable interrupts */
        !           141:        DELAY(200000);
        !           142: 
        !           143:        return sizeof(struct vsdevice);
        !           144: }
        !           145: 
        !           146: vsattach(uip)
        !           147: struct uba_device *uip;
        !           148: {
        !           149:        register struct vs_softc *vsp;
        !           150:        register struct vsdevice *vsaddr;
        !           151: 
        !           152:        vsp = &vs_softc[VSUNIT(uip->ui_unit)];
        !           153:        vsp->inited  = FALSE;
        !           154:        vsp->open = FALSE;
        !           155:        vsBuff[VSUNIT(uip->ui_unit)].vsioa.mbox.bottom = 0;
        !           156:        vsp->linkAvail = FALSE;
        !           157:        vsp->romVersion = 0;
        !           158:        vsp->vs_nextgo.fparm_all = NULL;
        !           159:        
        !           160:        vsaddr = (struct vsdevice *) uip->ui_addr;
        !           161:        vsaddr->vs_csr0 |= (VS_IE | VS_XMIT_ON);
        !           162: }
        !           163: 
        !           164: vsopen(dev, flag)
        !           165: dev_t dev;
        !           166: int flag;
        !           167: {
        !           168:        register struct vs_softc *vsp;
        !           169:        register struct uba_device *uip;
        !           170:        register struct vsdevice *vsaddr;
        !           171:        int s;
        !           172:        int ret;
        !           173:        struct buf vsbuf;
        !           174:        struct vsBuffArea *vsb;
        !           175:        caddr_t vsBuffpage;
        !           176:        int vsBuffnpages;
        !           177: 
        !           178:        if (VSUNIT(dev) >= NVS || (vsp = &vs_softc[VSUNIT(dev)])->open ||
        !           179:            (uip = vsdinfo[VSUNIT(dev)]) == 0 || uip->ui_alive == 0)
        !           180:                return (ENXIO);
        !           181: 
        !           182:        vsaddr = (struct vsdevice *) uip->ui_addr;
        !           183:        vsb = &vsBuff[VSUNIT(dev)];
        !           184:        printM("vsopen csr0=%x, csr1=%x, csr2=%x, csr3=%x, csr4=%x, csr5=%x, csr6=%x, csr7=%x\n",
        !           185:                vsaddr->vs_csr0, vsaddr->vs_csr1, vsaddr->vs_csr2, vsaddr->vs_csr3,
        !           186:                vsaddr->vs_csr4, vsaddr->vs_csr5, vsaddr->vs_csr6, vsaddr->vs_csr7);
        !           187: 
        !           188:        /* 
        !           189:         * Finally! We can now set up the device.
        !           190:         */
        !           191: 
        !           192:        if (!vsp->inited && !(flag & FNDELAY)) {
        !           193:                ret = vsInitDev(dev, TRUE);
        !           194:                if (ret)
        !           195:                        return (ret);
        !           196:                if (ret = vsError(vsp))
        !           197:                        return(ret);
        !           198:        }
        !           199: 
        !           200:        vsp->open = TRUE;               /* we're open */
        !           201:        vsp->pgrp = u.u_procp->p_pgrp;
        !           202: 
        !           203:        /* reset statistics */
        !           204:        bzero((caddr_t) &vsp->stats, sizeof(vsStats));
        !           205: 
        !           206:        /* initialize user I/O addresses */
        !           207:        vsb->vsioa.ioreg = (short *)vsaddr;
        !           208:        vsb->vsioa.status = 0;
        !           209:        vsb->vsioa.obuff = vsb->obuff;
        !           210:        vsb->vsioa.obufflen = VSBUFFSIZE;
        !           211:        vsb->vsioa.ibuff = vsb->ibuff;
        !           212:        vsb->vsioa.ihead = 0;
        !           213:        vsb->vsioa.itail = 0;
        !           214:        vsb->vsioa.iqsize = VSMAXEVQ;
        !           215:        /* map io regs into user address space (assume they don't cross a page) */
        !           216:        maptouser(vsaddr);
        !           217:        /* map vsBuff into user address space */
        !           218:        vsBuffpage = (caddr_t)((int)vsb & ~PGOFSET);
        !           219:        vsBuffnpages = (((int)vsb & PGOFSET) +
        !           220:                         (NBPG-1) + sizeof(struct vsBuffArea)) >> PGSHIFT;
        !           221:        while (vsBuffnpages>0) {
        !           222:            maptouser(vsBuffpage);
        !           223:            vsBuffpage += NBPG;
        !           224:            vsBuffnpages--;
        !           225:        }
        !           226:        /* lock in the buffer */
        !           227:        vsbuf.b_error = 0;
        !           228:        vsbuf.b_proc = u.u_procp;
        !           229:        vsbuf.b_un.b_addr = vsb->obuff;
        !           230:        vsbuf.b_flags = B_BUSY;
        !           231:        vsbuf.b_bcount = VSBUFFSIZE;
        !           232:        vsp->vsBuff_ubinfo = ubasetup(uip->ui_ubanum, &vsbuf, UBA_CANTWAIT);
        !           233: 
        !           234:        vsb->vsioa.reloc = (int) (vsp->offset.fparm_all
        !           235:                        + UBAI_ADDR(vsp->vsBuff_ubinfo));
        !           236:        return(0);
        !           237: }
        !           238: 
        !           239: vsclose(dev)
        !           240: dev_t dev;
        !           241: {
        !           242:        register struct uba_device *uip = vsdinfo[VSUNIT(dev)];
        !           243:        register struct vs_softc *vsp = &vs_softc[VSUNIT(dev)];
        !           244:        int s, i;
        !           245:        struct vsdevice *vsaddr;
        !           246:        struct vsBuffArea *vsb;
        !           247:        caddr_t vsBuffpage;
        !           248:        int vsBuffnpages;
        !           249:        
        !           250:        vsaddr = (struct vsdevice *) uip->ui_addr;
        !           251:        printM("vsclose csr0=%x, csr1=%x, csr2=%x, csr3=%x, csr4=%x, csr5=%x, csr6=%x, csr7=%x\n",
        !           252:                vsaddr->vs_csr0, vsaddr->vs_csr1, vsaddr->vs_csr2, vsaddr->vs_csr3,
        !           253:                vsaddr->vs_csr4, vsaddr->vs_csr5, vsaddr->vs_csr6, vsaddr->vs_csr7);
        !           254:                vsb = &vsBuff[VSUNIT(dev)];
        !           255:        if (vsDebugPrintfs) {
        !           256:                printf("vs%d: %d errors, %d unsolicited interrupts",
        !           257:                        VSUNIT(dev), vsp->stats.errors, vsp->stats.unsolIntr);
        !           258:                printf(", %d link errors", vsp->stats.linkErrors);
        !           259:                printf(", %d overruns", vsp->stats.overruns);
        !           260:                printf(", csr0 %x, csr1 %x", vsaddr->vs_csr0, vsaddr->vs_csr1);
        !           261:                printf("\n");
        !           262:        }
        !           263: 
        !           264:        vsp->open = FALSE;
        !           265:        vsp->inited = FALSE;            /* init on every open */
        !           266:        vsp->vs_nextgo.fparm_all = NULL;
        !           267:        vsb->vsioa.mbox.bottom = 0;
        !           268:        /* release the buffer */
        !           269:        if (vsp->vsBuff_ubinfo!=0) {
        !           270:                ubarelse(uip->ui_ubanum, &vsp->vsBuff_ubinfo);
        !           271:        }
        !           272: 
        !           273: #ifdef notdef
        !           274:        /* unmap io regs into user address space (assume they don't cross a page) */
        !           275:        unmaptouser(vsaddr);
        !           276:        /* unmap vsBuff into user address space */
        !           277:        vsBuffpage = (caddr_t)((int)vsb & ~PGOFSET);
        !           278:        vsBuffnpages = (((int)vsb&PGOFSET) +
        !           279:                         (NBPG-1)+ sizeof(struct vsBuffArea)) >> PGSHIFT;
        !           280:        while (vsBuffnpages>0) {
        !           281:            unmaptouser(vsBuffpage);
        !           282:            vsBuffpage += NBPG;
        !           283:            vsBuffnpages--;
        !           284:        }
        !           285: #endif
        !           286:        return (0);
        !           287: }
        !           288: 
        !           289: vsread(dev,uio)
        !           290: dev_t   dev;
        !           291: struct uio      *uio;
        !           292: {
        !           293:         return(-1);
        !           294: }
        !           295: 
        !           296: vswrite(dev, uio)
        !           297: dev_t   dev;
        !           298: struct uio      *uio;
        !           299: {
        !           300:         return(-1);
        !           301: }
        !           302: 
        !           303: /*ARGSUSED*/
        !           304: vsioctl(dev, cmd, addr, flag)
        !           305: dev_t dev;
        !           306: register caddr_t addr;
        !           307: {
        !           308:        register struct uba_device *uip = vsdinfo[VSUNIT(dev)];
        !           309:        register struct vs_softc *vsp = &vs_softc[VSUNIT(dev)];
        !           310:        register struct vsdevice *vsaddr = (struct vsdevice *) uip->ui_addr;
        !           311:        register struct vsBuffArea *vsb = &vsBuff[VSUNIT(dev)];
        !           312:        struct vs_fparm vsAddr;
        !           313:        int s, error = 0;
        !           314:        int func;
        !           315:        int ret;
        !           316: 
        !           317:        switch(cmd) {                   /* things that don't need the device */
        !           318:        case VSIOWAITGO:
        !           319:                /* wait for user I/O operation to complete, then go */
        !           320:                s = spl5();
        !           321:                if ((ret = vsb->vsioa.status) == 0) {
        !           322:                        vsp->vs_nextgo.fparm_all = ((struct vs_fparm *) addr)->fparm_all;
        !           323:                        do {
        !           324:                                error = tsleep((caddr_t)vsp, VSWAITPRI | PCATCH,
        !           325:                                    devwait, 0);
        !           326:                        } while (vsp->vs_nextgo.fparm_all && error == 0);
        !           327:                        ret = vsp->vs_status;
        !           328:                } else {
        !           329:                        vsaddr->vs_pr1 = ((struct vs_fparm *)addr)->fparm_low;
        !           330:                        vsaddr->vs_pr2 = ((struct vs_fparm *)addr)->fparm_high;
        !           331:                        vsb->vsioa.status = 0;
        !           332:                        vsaddr->vs_csr0 &= ~VS_FCN;     /* clear bits */
        !           333:                        vsaddr->vs_csr0 |= (VS_IE | (VS_SEND << VS_FCSHIFT) | VS_GO);
        !           334:                }
        !           335:                splx(s);
        !           336:                if (error)
        !           337:                        return (error);
        !           338:                if (ret & VS_ERROR)
        !           339:                        return ((ret & VS_REASON) + 128);
        !           340:                return(0);
        !           341: 
        !           342:        case VSIOUSERWAIT:
        !           343:                /* wait for user I/O operation to complete */
        !           344:                s = spl5();
        !           345:                while (vsb->vsioa.status == 0) {
        !           346:                        error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH,
        !           347:                            devio, 0);
        !           348:                }
        !           349:                splx(s);
        !           350:                return (error);
        !           351: 
        !           352:        case VSIOGETVER:                /* get ROM version */
        !           353:                if (!vsp->inited)
        !           354:                        return(ENODEV);
        !           355:                *(int *) addr = vsp->romVersion;
        !           356:                return(0);
        !           357: 
        !           358:        case VSIOGETSTATS:              /* get statistics block */
        !           359:                *(vsStats *)addr = vsp->stats;
        !           360:                return(0);
        !           361: 
        !           362:        case VSIOGETIOA:                /* get io addresses */
        !           363:                if (vsp->vsBuff_ubinfo==0) {
        !           364:                    return(EIO);
        !           365:                }
        !           366:                *((vsIoAddrAddr *)addr) = &vsb->vsioa;
        !           367:                return(0);
        !           368: 
        !           369:        default:                        /* a command that could block */
        !           370:                if (ret = vsError(vsp))
        !           371:                        return(ret);
        !           372:                break;
        !           373:        }
        !           374: 
        !           375:        switch(cmd) {                   /* Commands that cause an interrupt */
        !           376:        case VSIOINIT:                  /* initialize device */
        !           377:                vsInitDev(dev, FALSE);
        !           378:                return(vsError(vsp));
        !           379: 
        !           380:        case VSIOSTART:                 /* start microcode */
        !           381:                vsAddr.fparm_all = *(caddr_t *)addr;
        !           382:                s = spl5();
        !           383:                vsaddr->vs_pr1 = vsAddr.fparm_low;
        !           384:                vsaddr->vs_pr2 = vsAddr.fparm_high;
        !           385:                vsaddr->vs_irr = 0;
        !           386:                vsaddr->vs_csr0 &= ~VS_FCN;     /* clear bits */
        !           387:                vsaddr->vs_csr0 |= (VS_IE | (VS_START << VS_FCSHIFT) | VS_GO);
        !           388:                /* synchronous */
        !           389:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           390:                splx(s);
        !           391:                if (error)
        !           392:                        return (error);
        !           393:                return(vsError(vsp));
        !           394: 
        !           395:        case VSIOABORT:                 /* abort a command chain */
        !           396:                s = spl5();
        !           397:                vsaddr->vs_irr = 0;
        !           398:                vsaddr->vs_csr0 &= ~VS_FCN;
        !           399:                vsaddr->vs_csr0 |= (VS_IE | (VS_ABORT << VS_FCSHIFT) | VS_GO);
        !           400:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           401:                splx(s);
        !           402:                if (error)
        !           403:                        return (error);
        !           404:                return(vsError(vsp));
        !           405: 
        !           406:        case VSIOPWRUP:                 /* power-up reset */
        !           407:                s = spl5();
        !           408:                vsaddr->vs_irr = 0;
        !           409:                vsaddr->vs_csr0 &= ~VS_FCN;
        !           410:                vsaddr->vs_csr0 |= (VS_IE | (VS_PWRUP << VS_FCSHIFT) | VS_GO);
        !           411:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           412:                splx(s);
        !           413:                if (error)
        !           414:                        return (error);
        !           415:                return(vsError(vsp));
        !           416: 
        !           417:        case VSIOBBACTL:                /* enable/disable BBA */
        !           418:                s = spl5();
        !           419:                vsaddr->vs_irr = 0;
        !           420:                vsaddr->vs_csr0 &= ~VS_FCN;
        !           421:                func = *(int *)addr == VSIO_ON ? VS_ENABBA : VS_DISBBA;
        !           422:                vsaddr->vs_csr0 |= (VS_IE | (func << VS_FCSHIFT) | VS_GO);
        !           423:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           424:                splx(s);
        !           425:                if (error)
        !           426:                        return (error);
        !           427:                return(vsError(vsp));
        !           428: 
        !           429:        case VSIOFIBCTL:                /* turn the fiber lamp on/off */
        !           430:                s = spl5();
        !           431:                if (*(int *)addr == VSIO_OFF)
        !           432:                        vsaddr->vs_csr0 &= ~VS_XMIT_ON;
        !           433:                else
        !           434:                        vsaddr->vs_csr0 |= (VS_IE | VS_XMIT_ON);
        !           435:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           436:                splx(s);
        !           437:                if (error)
        !           438:                        return (error);
        !           439:                return(vsError(vsp));
        !           440: 
        !           441:        case VSIOFIBRETRY:              /* set fiber retries */
        !           442:                s = spl5();
        !           443:                vsaddr->vs_irr = 0;
        !           444:                vsaddr->vs_csr0 &= ~VS_FCN;
        !           445:                func = *(int *)addr == VS_FIB_FINITE ? VS_FINITE : VS_INFINITE;
        !           446:                vsaddr->vs_csr0 |= (VS_IE | (func << VS_FCSHIFT) | VS_GO);
        !           447:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH, devwait, 0);
        !           448:                splx(s);
        !           449:                if (error)
        !           450:                        return (error);
        !           451:                return(vsError(vsp));
        !           452: 
        !           453:        case VSIOSYNC:                  /* get synchronized with device */
        !           454:                break;
        !           455: 
        !           456:        default:
        !           457:                return(ENOTTY);
        !           458:        }
        !           459: 
        !           460:        return(0);
        !           461: }
        !           462: 
        !           463: vsintr(dev)
        !           464: dev_t dev;
        !           465: {
        !           466:        register struct vsdevice *vsaddr;
        !           467:        register struct vs_softc *vsp;
        !           468:        register vsEvent *vep;
        !           469:        struct uba_device *uip;
        !           470:        register struct vsBuffArea *vsb;
        !           471:        int i;
        !           472:        vsCursor cur;
        !           473: 
        !           474:        if (VSUNIT(dev) >= NVS || (uip = vsdinfo[VSUNIT(dev)]) == 0
        !           475:            || uip->ui_alive == 0) {
        !           476:                printI("vs%d stray interrupt\n", VSUNIT(dev));
        !           477:                return;
        !           478:        }
        !           479: 
        !           480:        vsaddr = (struct vsdevice *) uip->ui_addr;
        !           481:        vsp = &vs_softc[VSUNIT(dev)];
        !           482:        vsb = &vsBuff[VSUNIT(dev)];
        !           483: #ifdef notdef
        !           484:        printM("vsintr csr0=%x, csr1=%x, csr2=%x, csr3=%x, csr4=%x, csr5=%x, csr6=%x, csr7=%x\n",
        !           485:                vsaddr->vs_csr0, vsaddr->vs_csr1, vsaddr->vs_csr2, vsaddr->vs_csr3,
        !           486:                vsaddr->vs_csr4, vsaddr->vs_csr5, vsaddr->vs_csr6, vsaddr->vs_csr7);
        !           487: 
        !           488:        printI("vs%dintr ", VSUNIT(dev));
        !           489: #endif
        !           490: 
        !           491:        /* 
        !           492:         * get the information out of the soft registers
        !           493:         */
        !           494: 
        !           495:        vsp->irr.intr_reg = vsaddr->vs_irr;
        !           496:        vsp->krr.kbd_reg = vsaddr->vs_krr;
        !           497:        vsp->pr.fparm_low = vsaddr->vs_pr1;
        !           498:        vsp->pr.fparm_high = vsaddr->vs_pr2;
        !           499:        cur.x = vsaddr->vs_cxr;
        !           500:        cur.y = vsaddr->vs_cyr;
        !           501:        vsp->csr.csr_reg = vsaddr->vs_csr0;
        !           502: 
        !           503:        if (vsp->irr.intr_reason)
        !           504:                vsaddr->vs_irr = 0;     /* clear int reason, if any */
        !           505: 
        !           506:        vsaddr->vs_csr0 &= ~VS_OWN;     /* clear owner bit */
        !           507: 
        !           508:        if (vsp->csr.csr_linkTran) {
        !           509:                vsaddr->vs_csr0 &= ~VS_LNK_TRNS;        /* clear the bit */
        !           510:                printI("link transition: ");
        !           511:                if (vsp->csr.csr_linkErr)
        !           512:                        vsp->stats.linkErrors++;
        !           513: 
        !           514:                if (vsp->csr.csr_linkAvail == vsp->linkAvail) { /* flash */
        !           515:                        vsp->stats.flashes++;
        !           516:                        printI("flash\n");
        !           517:                } else if (!vsp->csr.csr_linkAvail && vsp->linkAvail) { /* on -> off */
        !           518:                        vsp->stats.douses++;
        !           519:                        printI("douse\n");
        !           520:                        vsp->inited = FALSE;
        !           521:                        if (vsp->open && vsp->pgrp)
        !           522:                                gsignal(vsp->pgrp, SIGHUP);
        !           523:                        wakeup((caddr_t) vsp);
        !           524:                } else {                                                /* off -> on */
        !           525:                        vsp->stats.ignites++;
        !           526:                        printI("ignite\n");
        !           527:                        wakeup((caddr_t) vsp);
        !           528:                }
        !           529: 
        !           530:                i = 200;
        !           531:                while ((vsaddr->vs_csr0 & VS_LNK_TRNS) && i)
        !           532:                        i--;
        !           533:                if (i == 0) {           /* bit stuck */
        !           534:                        printI("vs%d: Link Transition bit stuck\n", VSUNIT(dev));
        !           535:                        vsp->inited = FALSE;
        !           536:                        if (vsp->open && vsp->pgrp)
        !           537:                                gsignal(vsp->pgrp, SIGHUP);
        !           538:                        vsaddr->vs_csr0 &= ~VS_XMIT_ON;
        !           539:                        vsp->csr.csr_linkAvail = FALSE;
        !           540:                }
        !           541: 
        !           542:                vsp->linkAvail = vsp->csr.csr_linkAvail;
        !           543: 
        !           544:                return;
        !           545:        }
        !           546: 
        !           547:        if (vsp->irr.intr_error) {
        !           548:                printI("error 0x%x\n", vsp->irr.intr_reg&0xffff);
        !           549:                vsp->stats.errors++;
        !           550:                /* set status and wake up user if necessary */
        !           551:                if (vsp->vs_nextgo.fparm_all) {
        !           552:                        vsp->vs_status = vsp->irr.intr_reg;
        !           553:                        vsaddr->vs_pr1 = vsp->vs_nextgo.fparm_low;
        !           554:                        vsaddr->vs_pr2 = vsp->vs_nextgo.fparm_high;
        !           555:                        vsp->vs_nextgo.fparm_all = NULL;
        !           556:                        vsaddr->vs_csr0 &= ~VS_FCN;     /* clear bits */
        !           557:                        vsaddr->vs_csr0 |= (VS_IE | (VS_SEND << VS_FCSHIFT) | VS_GO);
        !           558:                } else
        !           559:                        vsb->vsioa.status = vsp->irr.intr_reg;
        !           560:                wakeup((caddr_t) vsp);
        !           561:                return;
        !           562:        }
        !           563: 
        !           564: #ifdef notdef
        !           565:        printI("reason is %b\n", vsp->irr.intr_reason, VSIRR_BITS);
        !           566: #endif
        !           567:        switch(vsp->irr.intr_reason) {
        !           568:        case VS_INT_CD:                 /* command done */
        !           569:                /* set status and start a new command if necessary */
        !           570:                if (vsp->vs_nextgo.fparm_all) {
        !           571:                        vsp->vs_status = vsp->irr.intr_reg;
        !           572:                        vsaddr->vs_pr1 = vsp->vs_nextgo.fparm_low;
        !           573:                        vsaddr->vs_pr2 = vsp->vs_nextgo.fparm_high;
        !           574:                        vsp->vs_nextgo.fparm_all = NULL;
        !           575:                        vsaddr->vs_csr0 &= ~VS_FCN;     /* clear bits */
        !           576:                        vsaddr->vs_csr0 |= (VS_IE | (VS_SEND << VS_FCSHIFT) | VS_GO);
        !           577:                } else
        !           578:                        vsb->vsioa.status = vsp->irr.intr_reg;
        !           579:                break;
        !           580: 
        !           581:        case VS_INT_MM:                 /* mouse moved */
        !           582: 
        !           583:                vsb->vsioa.mouse = cur;
        !           584: 
        !           585:                 if (!vsp->open)
        !           586:                         return;         /* ignore on closed device */
        !           587: 
        !           588:                /* no event if inside box */
        !           589:                if (cur.y < vsb->vsioa.mbox.bottom &&
        !           590:                    cur.y >= vsb->vsioa.mbox.top &&
        !           591:                    cur.x < vsb->vsioa.mbox.right &&
        !           592:                    cur.x >= vsb->vsioa.mbox.left)
        !           593:                    return;
        !           594: 
        !           595:                /* trash box */
        !           596:                vsb->vsioa.mbox.bottom = 0;
        !           597: 
        !           598:                if (EVROUND(vsb->vsioa.itail+1) == vsb->vsioa.ihead)
        !           599:                    return;
        !           600:                i = EVROUND(vsb->vsioa.itail-1);
        !           601:                if ((vsb->vsioa.itail != vsb->vsioa.ihead) &&
        !           602:                    (i != vsb->vsioa.ihead)) {
        !           603:                    vep = &vsb->ibuff[i];
        !           604:                    if (vep->vse_type == VSE_MMOTION) {
        !           605:                        vep->vse_x = cur.x;
        !           606:                        vep->vse_y = cur.y;
        !           607:                        vep->vse_time = mfpr(TODR);
        !           608:                        return;
        !           609:                    }
        !           610:                }
        !           611:                /* put event into queue and do select */
        !           612:                vep = &vsb->ibuff[vsb->vsioa.itail];
        !           613:                vep->vse_type = VSE_MMOTION;
        !           614:                vep->vse_x = cur.x;
        !           615:                vep->vse_y = cur.y;
        !           616:                vep->vse_time = mfpr(TODR);
        !           617:                vsb->vsioa.itail = EVROUND(vsb->vsioa.itail+1);
        !           618:                if (vsp->rsel) {
        !           619:                        selwakeup(vsp->rsel, 0);
        !           620:                        vsp->rsel = 0;
        !           621:                }
        !           622:                break;
        !           623: 
        !           624:        case VS_INT_BE:                 /* button event */
        !           625:                if (!vsp->open)
        !           626:                        return;         /* ignore on closed device */
        !           627: 
        !           628:                if (vsp->krr.kbd_device == VSE_MOUSE) {
        !           629:                    vsb->vsioa.mouse.x = cur.x;
        !           630:                    vsb->vsioa.mouse.y = cur.y;
        !           631:                }
        !           632:                /* check for room in the queue */
        !           633:                if ((i = EVROUND(vsb->vsioa.itail+1)) == vsb->vsioa.ihead)
        !           634:                    return;
        !           635:                /* put event into queue and do select */
        !           636:                vep = &vsb->ibuff[vsb->vsioa.itail];
        !           637:                vep->vse_type = VSE_BUTTON; 
        !           638:                vep->vse_key = vsp->krr.kbd_key;
        !           639:                vep->vse_direction = vsp->krr.kbd_transition;
        !           640:                vep->vse_device = vsp->krr.kbd_device;
        !           641:                vep->vse_time = mfpr(TODR);
        !           642:                vep->vse_x = vsb->vsioa.mouse.x;
        !           643:                vep->vse_y = vsb->vsioa.mouse.y;
        !           644:                vsb->vsioa.itail = i;
        !           645:                if (vsp->rsel) {
        !           646:                        selwakeup(vsp->rsel, 0);
        !           647:                        vsp->rsel = 0;
        !           648:                }
        !           649:                break;
        !           650: 
        !           651:        case VS_INT_TM:                 /* tablet moved */
        !           652:                if (!vsp->open)
        !           653:                        return;         /* ignore on closed device */
        !           654: 
        !           655:                if (EVROUND(vsb->vsioa.itail+1) == vsb->vsioa.ihead)
        !           656:                    return;
        !           657:                i = EVROUND(vsb->vsioa.itail-1);
        !           658:                if ((vsb->vsioa.itail != vsb->vsioa.ihead) &&
        !           659:                    (i != vsb->vsioa.ihead)) {
        !           660:                    vep = &vsb->ibuff[i];
        !           661:                    if (vep->vse_type == VSE_TMOTION) {
        !           662:                        vep->vse_x = cur.x;
        !           663:                        vep->vse_y = cur.y;
        !           664:                        vep->vse_time = mfpr(TODR);
        !           665:                        return;
        !           666:                    }
        !           667:                }
        !           668:                /* put event into queue and do select */
        !           669:                vep = &vsb->ibuff[vsb->vsioa.itail];
        !           670:                vep->vse_type = VSE_TMOTION;
        !           671:                vep->vse_x = cur.x;
        !           672:                vep->vse_y = cur.y;
        !           673:                vep->vse_time = mfpr(TODR);
        !           674:                vsb->vsioa.itail = EVROUND(vsb->vsioa.itail+1);
        !           675:                if (vsp->rsel) {
        !           676:                        selwakeup(vsp->rsel, 0);
        !           677:                        vsp->rsel = 0;
        !           678:                }
        !           679:                break;
        !           680: 
        !           681:        case VS_INT_US:                 /* unsolicited */
        !           682:                vsp->stats.unsolIntr++;
        !           683:                return;
        !           684: 
        !           685:        case VS_INT_ID:                 /* Initialization done */
        !           686:                                        /* save offset from device */
        !           687:                vsp->offset.fparm_all = vsp->pr.fparm_all;
        !           688:                                        /* save rom version */
        !           689:                vsp->romVersion = cur.x;
        !           690:                vsp->inited = TRUE;
        !           691:                break;
        !           692: 
        !           693:        case VS_INT_SE:                 /* ucode started */
        !           694:                break;
        !           695: 
        !           696:        case VS_INT_PWR:                /* power up complete */
        !           697:                                        /* save rom version */
        !           698:                vsp->romVersion = cur.x;
        !           699:                vsp->inited = FALSE;
        !           700:                if (vsp->open && vsp->pgrp)
        !           701:                        gsignal(vsp->pgrp, SIGHUP);
        !           702:                break;
        !           703: 
        !           704:        default:
        !           705:                printI("vs%d: unknown interrupt %b\n", VSUNIT(dev),
        !           706:                        vsp->irr.intr_reason, VSIRR_BITS);
        !           707:                return;
        !           708:        }
        !           709:        wakeup((caddr_t) vsp);
        !           710: }
        !           711: 
        !           712: vsreset(uban)
        !           713: int uban;
        !           714: {
        !           715:        register int i;
        !           716:        register struct uba_device *uip;
        !           717:        register struct vs_softc *vsp = vs_softc;
        !           718: 
        !           719:        for (i = 0; i < NVS; i++, vsp++) {
        !           720:                if ((uip = vsdinfo[i]) == 0 || uip->ui_alive == 0 ||
        !           721:                    uip->ui_ubanum != uban || vsp->open == 0)
        !           722:                        continue;
        !           723:                printf(" vs%d", i);
        !           724:                vsp->inited = FALSE;
        !           725:                if (vsp->open && vsp->pgrp)
        !           726:                        gsignal(vsp->pgrp, SIGHUP);
        !           727:        }
        !           728: }
        !           729: 
        !           730: vsselect(dev, rw)
        !           731: dev_t dev;
        !           732: {
        !           733:        register struct vsBuffArea *vsb = &vsBuff[VSUNIT(dev)];
        !           734:        int s = spl5();
        !           735: 
        !           736:        switch(rw) {
        !           737:        case FREAD:
        !           738:                if (vsb->vsioa.ihead != vsb->vsioa.itail) {
        !           739:                    splx(s);
        !           740:                    return(1);
        !           741:                }
        !           742:                vs_softc[VSUNIT(dev)].rsel = u.u_procp;
        !           743:                splx(s);
        !           744:                return(0);
        !           745: 
        !           746:        default:
        !           747:                splx(s);
        !           748:                return(0);      /* can never write */
        !           749:        }
        !           750: }
        !           751: 
        !           752: /*
        !           753:  * Initialize VS100 or SBO.
        !           754:  * Set XMITON.  VS100 will respond with link available.  SBO won't, so
        !           755:  * don't wait forever; assume everything is OK and warn user.
        !           756:  */
        !           757: 
        !           758: vsInitFiber(dev)
        !           759: dev_t dev;
        !           760: {
        !           761:        struct vsdevice *vsaddr = (struct vsdevice *) vsdinfo[VSUNIT(dev)]->ui_addr;
        !           762:        register struct vs_softc *vsp = &vs_softc[VSUNIT(dev)];
        !           763:        int s, error;
        !           764: 
        !           765:        s = spl5();
        !           766:        vsaddr->vs_csr0 |= (VS_IE | VS_XMIT_ON);        /* turn link on */
        !           767:        error = tsleep((caddr_t) vsp, VSWAITPRI, SLP_VS_INITF, 2*hz);
        !           768:        splx(s);
        !           769:        if (error == EWOULDBLOCK)       /* timeout */
        !           770:                error = 0;
        !           771: #ifdef VSSBO
        !           772:        if (!vsp->linkAvail) {
        !           773:                uprintf("\007This had better be a vs125!\n");
        !           774:                printf("vs%d must be a vs125\n", VSUNIT(dev));
        !           775:                vsp->linkAvail = TRUE;
        !           776:        }
        !           777: #endif
        !           778:        return (error);
        !           779: }
        !           780: 
        !           781: vsInitDev(dev, retry)
        !           782: dev_t dev;
        !           783: int retry;
        !           784: {
        !           785:        register struct vsdevice *vsaddr;
        !           786:        register struct vs_softc *vsp;
        !           787:        int s, error;
        !           788: 
        !           789:        vsaddr = (struct vsdevice *) vsdinfo[VSUNIT(dev)]->ui_addr;
        !           790:        vsp = &vs_softc[VSUNIT(dev)];
        !           791: 
        !           792:        if (!vsp->linkAvail)
        !           793:                if (error = vsInitFiber(dev))
        !           794:                        return (error);
        !           795:        while (1) {
        !           796:                s = spl5();
        !           797:                vsaddr->vs_irr = 0;
        !           798:                vsaddr->vs_csr0 &= ~VS_FCN;
        !           799:                vsaddr->vs_csr0 |= (VS_IE | (VS_INIT << VS_FCSHIFT) | VS_GO);
        !           800:                error = tsleep((caddr_t) vsp, VSWAITPRI | PCATCH,
        !           801:                    devwait, retry ? 10*hz : 0);
        !           802:                splx(s);
        !           803:                if (error == EWOULDBLOCK)
        !           804:                        error = 0;
        !           805:                if (error)
        !           806:                        return (error);
        !           807:                if (vsp->inited)
        !           808:                        break;
        !           809:                printM("vs%d: VS_INIT fails\n", VSUNIT(dev));
        !           810:                uprintf("vsInitDev %x %x\n",vsaddr->vs_csr0, vsaddr->vs_csr1);
        !           811:        }
        !           812:        return (0);
        !           813: }
        !           814: 
        !           815: vsError(vsp)
        !           816:        register struct vs_softc *vsp;
        !           817: {
        !           818:        if (vsp->irr.intr_error) {
        !           819:                register int ret = vsp->irr.intr_reg;
        !           820: 
        !           821:                printD("\treturning 0x%x\n", ret);
        !           822:                vsp->irr.intr_reg = 0;
        !           823:                return(ret+128);
        !           824:        }
        !           825:        return(0);
        !           826: }
        !           827: #endif
        !           828: 

unix.superglobalmegacorp.com

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