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

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

unix.superglobalmegacorp.com

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