Annotation of 43BSD/sys/vaxuba/vs.c, revision 1.1.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.