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

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

unix.superglobalmegacorp.com

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