Annotation of cci/sys/vba/vcx.c, revision 1.1

1.1     ! root        1: #include "vx.h"
        !             2: #if NVX > 0
        !             3: /*
        !             4:  *     VIOC-X driver
        !             5:  */
        !             6: 
        !             7: #include "../h/param.h"
        !             8: #include "../h/ioctl.h"
        !             9: #include "../h/tty.h"
        !            10: #include "../h/dir.h"
        !            11: #include "../h/user.h"
        !            12: #include "../h/map.h"
        !            13: #include "../machine/pte.h"
        !            14: #include "../h/buf.h"
        !            15: #include "../vba/vbavar.h"
        !            16: #include "../h/conf.h"
        !            17: #include "../h/file.h"
        !            18: #include "../h/uio.h"
        !            19: #include "../vba/vioc.h"
        !            20: #ifdef VXPERF
        !            21: #include "../vba/scope.h"
        !            22: #endif VXPERF
        !            23: #include "vbsc.h"
        !            24: #if NVBSC > 0
        !            25: #include "../bsc/bscio.h"
        !            26: #include "../bsc/bsc.h"
        !            27: char bscport[NVXPORTS];
        !            28: long bscno = 0;
        !            29: #endif
        !            30: 
        !            31: #ifdef BSC_DEBUG
        !            32: #include "../bsc/bscdebug.h"
        !            33: #endif
        !            34: 
        !            35: #ifdef VX_DEBUG
        !            36: long vxintr4 = 0;
        !            37: long vxdebug = 0;
        !            38: #include "../vba/vxdebug.h"
        !            39: #endif
        !            40: 
        !            41: #define RSPquals       1
        !            42: 
        !            43: struct vcx     vcx[NVIOCX] ;
        !            44: struct tty     vx_tty[NVXPORTS];
        !            45: extern struct vcmds v_cmds[];
        !            46: extern long reinit;
        !            47: 
        !            48: int    vxstart() ;
        !            49: int    ttrstrt() ;
        !            50: caddr_t vtoph();
        !            51: struct vxcmd   *vobtain() ;
        !            52: struct vxcmd   *nextcmd() ;
        !            53: 
        !            54: /*
        !            55:  * Driver information for auto-configuration stuff.
        !            56:  * (not tested and probably should be changed)
        !            57:  */
        !            58: int    vxprobe(), vxattach(), vxrint();
        !            59: struct vba_device *vxinfo[NVIOCX];
        !            60: long   vxstd[] = { 0 };
        !            61: struct vba_driver vxdriver =
        !            62:        { vxprobe, 0, vxattach, 0, vxstd, "VIOC ", vxinfo };
        !            63: 
        !            64: char vxtype[NVIOCX];   /* 0: viox-x/vioc-b; 1: vioc-bop */
        !            65: char vxbbno = -1;
        !            66: char vxbopno[NVIOCX];  /* BOP board no. if indicated by vxtype[] */
        !            67: short vbtbl = -1;
        !            68: extern vbrall();
        !            69: 
        !            70: 
        !            71: vxprobe(reg)
        !            72:        caddr_t reg;
        !            73: {
        !            74:        register int br, cvec;
        !            75:        register struct vblok *vp = (struct vblok *)reg;
        !            76: 
        !            77: #ifdef lint
        !            78:        br = 0; cvec = br; br = cvec;
        !            79: #endif
        !            80: 
        !            81:        if(badaddr(vp, 1))
        !            82:                return(0);
        !            83:        vp->v_fault = 0 ;
        !            84:        vp->v_vioc = V_BSY ;
        !            85:        vp->v_hdwre = V_RESET ;         /* reset interrupt */
        !            86: 
        !            87:        DELAY(4000000);
        !            88:        return ( vp->v_fault == VREADY);
        !            89: }
        !            90: 
        !            91: vxattach(ui)
        !            92:        register struct vba_device *ui;
        !            93: {
        !            94:        VIOCBAS[ui->ui_unit] = ui->ui_addr;
        !            95:        vxinit(ui->ui_unit,1);
        !            96: }
        !            97: 
        !            98: /*
        !            99:  * Open a VX line.
        !           100:  */
        !           101: vxopen(dev, flag)
        !           102: {
        !           103:        register struct tty *tp;        /* pointer to tty struct for port */
        !           104:        register struct vcx *xp;        /* pointer to VIOC-X info/cmd buffer */
        !           105:        register d;                     /* minor device number */
        !           106:        register long jj;
        !           107: 
        !           108: 
        !           109:        d = minor(dev);                 /* get minor device number */
        !           110:        if (d >= NVXPORTS)              /* validate minor device number */
        !           111:                return ENXIO;           /* set errno to indicate bad port # */
        !           112:        tp = &vx_tty[d];                /* index the tty structure for port */
        !           113: 
        !           114:        xp = &vcx[d>>4];                        /* index VIOC-X info/cmd area */
        !           115:        d &= 017;
        !           116: 
        !           117:        /* If we did not find a board with the correct port number on
        !           118:           it, or the entry for the VIOC-X had no ports on it, inform the
        !           119:           caller that the port does not exist. */
        !           120:        if(!( xp->v_loport <= d && d <= xp->v_hiport )  /* home? */
        !           121:         || (xp->v_hiport - xp->v_loport)==0)
        !           122:                return ENXIO;   /* bad minor device number */
        !           123:        tp->t_addr = (caddr_t)xp;       /* store address of VIOC-X info */
        !           124:        tp->t_oproc = vxstart;          /* store address of startup routine */
        !           125:        tp->t_dev = dev;                /* store major/minor device numbers */
        !           126:        d = spl8();
        !           127:        tp->t_state |= TS_WOPEN;        /* mark device as waiting for open */
        !           128:        if ((tp->t_state&TS_ISOPEN) == 0)       /* is device already open? */
        !           129:        {                               /*  no, open it */
        !           130:                ttychars(tp);           /* set default control chars */
        !           131:                if (tp->t_ispeed == 0)  /* if no default speeds set them */
        !           132:                {
        !           133:                        tp->t_ispeed = SSPEED;  /* default input baud */
        !           134:                        tp->t_ospeed = SSPEED;  /* default output baud */
        !           135:                        tp->t_flags |= (ODDP|EVENP|ECHO); /* default modes */
        !           136:                }
        !           137:                vxparam(dev);           /* set parameters for this port */
        !           138:        }
        !           139:        splx(d);
        !           140:        /* ? if already open for exclusive use open fails unless caller is 
        !           141:             root. */
        !           142:        if (tp->t_state&TS_XCLUDE && u.u_uid!=0)
        !           143:                return EBUSY;   /* device is busy, sorry */
        !           144: 
        !           145:        /* wait for data carrier detect to go high */
        !           146:        d = spl8();
        !           147:        if( !vcmodem(dev,VMOD_ON) )
        !           148:                while( (tp->t_state&TS_CARR_ON) == 0 )
        !           149:                        sleep(&tp->t_canq,TTIPRI);
        !           150:        jj= (*linesw[tp->t_line].l_open)(dev,tp); /*let tty.c finish the open */
        !           151:        splx(d);        /* 1/2/85 : assures open complete */
        !           152:        return (jj);
        !           153: }
        !           154: 
        !           155: /*
        !           156:  * Close a VX line.
        !           157:  */
        !           158: vxclose(dev, flag)
        !           159: dev_t dev;
        !           160: int  flag;
        !           161: {
        !           162:        register struct tty *tp;
        !           163:        register d;
        !           164: 
        !           165:        d = minor(dev) & 0377;
        !           166:        tp = &vx_tty[d];
        !           167:        d = spl8();
        !           168:        (*linesw[tp->t_line].l_close)(tp);
        !           169:        if ((tp->t_state&TS_ISOPEN) && (tp->t_state&TS_HUPCLS))
        !           170:                if( !vcmodem(dev,VMOD_OFF) )
        !           171:                        tp->t_state &= ~TS_CARR_ON;
        !           172:        /* wait for the last response */
        !           173:        while(tp->t_state & TS_FLUSH)
        !           174:                sleep( (caddr_t)&tp->t_state, TTOPRI ) ;
        !           175:        ttyclose(tp);   /* let tty.c finish the close */
        !           176:        splx(d);
        !           177: }
        !           178: 
        !           179: /*
        !           180:  * Read from a VX line.
        !           181:  */
        !           182: vxread(dev, uio)
        !           183:        dev_t dev;
        !           184:        struct uio *uio;
        !           185: {
        !           186:        register struct tty *tp = &vx_tty[minor(dev) & 0377];
        !           187:        return (*linesw[tp->t_line].l_read)(tp, uio);
        !           188: }
        !           189: 
        !           190: /*
        !           191:  * write on a VX line
        !           192:  */
        !           193: vxwrite(dev, uio)
        !           194:        dev_t dev;
        !           195:        struct uio *uio;
        !           196: {
        !           197:        register struct tty *tp = &vx_tty[minor(dev) & 0377];
        !           198:        return (*linesw[tp->t_line].l_write)(tp, uio);
        !           199: }
        !           200: 
        !           201: /*
        !           202:  * VIOCX unsolicited interrupt.
        !           203:  */
        !           204: vxrint(n)
        !           205: register n;                            /* mux number */
        !           206: {
        !           207:        register struct tty *tp;
        !           208:        register struct vcx *xp;
        !           209:        register short *sp;
        !           210:        register struct vblok *kp;
        !           211:        register int i, c;
        !           212:        short *savsilo;
        !           213:        struct silo {
        !           214:                char    data;
        !           215:                char    port;
        !           216:        };
        !           217: 
        !           218:        kp = VBAS(n);
        !           219:        xp = &vcx[n];
        !           220: #if VX_TESTING
        !           221:        c = kp->v_uqual&037;
        !           222:        if (vx_test&VX_PROC_ERR_DEBUG)
        !           223:                c = 2;
        !           224:        else if (vx_test&VX_UQUAL_ERR_DEBUG)
        !           225:                c = 5;
        !           226:        switch (c) {
        !           227: #else
        !           228:        switch(kp->v_uqual&037) {
        !           229: #endif
        !           230:        case 0:
        !           231:                break;
        !           232:        case 2:
        !           233:                printf(" ERR NBR %x\n",kp->v_ustat);
        !           234:                vpanic("vc: VC PROC ERR");
        !           235:                vxstreset(n);
        !           236:                return(0);
        !           237:        case 3:
        !           238:                vcmintr(n);
        !           239:                return(1);
        !           240:        case 4:
        !           241:                return(1);
        !           242:        default:
        !           243:                printf(" ERR NBR %x\n",kp->v_uqual);
        !           244:                vpanic("vc: VC UQUAL ERR");
        !           245:                vxstreset(n);
        !           246:                return(0);
        !           247:        }
        !           248:        if(xp->v_vers == V_NEW) {
        !           249:                register short *aa ;
        !           250:                aa = (short *)kp->v_usdata;
        !           251:                sp = (short *)(*aa  + (char *)kp) ;
        !           252:        } else {
        !           253:                c = kp->v_usdata[0] << 6;
        !           254:                sp = (short *)((char *)kp + SILOBAS + c);
        !           255:        }
        !           256: nextsilo:
        !           257:        i = *(savsilo = sp);
        !           258:        if (i == 0) return(1);
        !           259:        if(xp->v_vers == V_NEW)
        !           260:                if( i > xp->v_silosiz ) {
        !           261:                        printf("vx: %d exceeds silo size\n",i) ;
        !           262:                        i = xp->v_silosiz;
        !           263:                }
        !           264:        for(sp++;i > 0;i--,sp++) {
        !           265:                c = ((struct silo *)sp)->port & 017;
        !           266:                tp = &vx_tty[c+n*16];
        !           267:                if(xp->v_loport > c || c > xp->v_hiport)
        !           268:                        continue;       /* port out of bounds */
        !           269:                if( (tp->t_state & TS_ISOPEN) == 0) {
        !           270:                        wakeup((caddr_t)&tp->t_rawq);
        !           271:                        continue;
        !           272:                }
        !           273:                c = ((struct silo *)sp)->data;
        !           274:                switch(((struct silo *)sp)->port&(PERROR|FERROR)) {
        !           275:                case PERROR:
        !           276:                case PERROR|FERROR:
        !           277:                        if( (tp->t_flags&(EVENP|ODDP)) == EVENP
        !           278:                        || (tp->t_flags & (EVENP|ODDP)) == ODDP )
        !           279:                                continue;
        !           280:                        if(!(((struct silo *)sp)->port&FERROR))
        !           281:                                break;
        !           282:                case FERROR:
        !           283:                        if(tp->t_flags & RAW) c = 0;
        !           284:                        else c = tp->t_intrc;
        !           285:                }
        !           286:                (*linesw[tp->t_line].l_rint)(c, tp);
        !           287:        }
        !           288:        *savsilo = 0;
        !           289:        return(1);
        !           290: }
        !           291: 
        !           292: /*
        !           293:  * stty/gtty for VX
        !           294:  */
        !           295: vxioctl(dev, cmd, data, flag)
        !           296: int    dev;                    /* major, minor device numbers */
        !           297: int    cmd;                    /* command */
        !           298: caddr_t        data;
        !           299: int    flag;
        !           300: {
        !           301:        register struct tty     *tp;
        !           302:        register error;
        !           303: 
        !           304:        tp = &vx_tty[minor(dev) & 0377];
        !           305:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        !           306:        if (error == 0)
        !           307:                return error;
        !           308:        if((error = ttioctl(tp, cmd, data, flag)) >= 0)
        !           309:        {
        !           310:                if (cmd==TIOCSETP||cmd==TIOCSETN)
        !           311:                        vxparam(dev);
        !           312:                return error;
        !           313:        } else
        !           314:                return ENOTTY;
        !           315: }
        !           316: 
        !           317: 
        !           318: vxparam(dev)
        !           319: dev_t  dev;
        !           320: {
        !           321:        vxcparam(dev, 1);
        !           322: }
        !           323: 
        !           324: /*
        !           325:  * Set parameters from open or stty into the VX hardware
        !           326:  * registers.
        !           327:  */
        !           328: vxcparam(dev, wait)
        !           329: dev_t  dev;                    /* major, minor device numbers */
        !           330: int wait;                      /* nonzero if we should wait for finish */
        !           331: {
        !           332:        register struct tty     *tp;
        !           333:        register struct vcx     *xp;
        !           334:        register struct vxcmd   *cp;
        !           335:        register s;
        !           336: 
        !           337:        tp = &vx_tty[minor(dev)];       /* pointer to tty structure for port */
        !           338:        xp = (struct vcx *)tp->t_addr;  /* pointer to VIOCX info/cmd buffer */
        !           339:        cp = vobtain(xp);
        !           340:        s = spl8();
        !           341:        cp->cmd = LPARAX;               /* set command to "load parameters" */
        !           342:        cp->par[1] = minor(dev)&017;    /* port number */
        !           343: 
        !           344:        cp->par[2] = (tp->t_flags&RAW)? 0 : tp->t_startc;       /* XON char */
        !           345:        cp->par[3] = (tp->t_flags&RAW)? 0 : tp->t_stopc;        /* XOFF char */
        !           346: 
        !           347:        if(tp->t_flags&(RAW|LITOUT) ||
        !           348:          (tp->t_flags&(EVENP|ODDP)) == (EVENP|ODDP)) {
        !           349:                cp->par[4] = 0xc0;      /* 8 bits of data */
        !           350:                cp->par[7] = 0;         /* no parity */
        !           351:        } else {
        !           352:                cp->par[4] = 0x40;      /* 7 bits of data */
        !           353:                if((tp->t_flags&(EVENP|ODDP)) == ODDP)
        !           354:                        cp->par[7] = 1;         /* odd parity */
        !           355:                else if((tp->t_flags&(EVENP|ODDP)) == EVENP)
        !           356:                        cp->par[7] = 3;         /* even parity */
        !           357:                else
        !           358:                        cp->par[7] = 0;         /* no parity */
        !           359:        }
        !           360:        cp->par[5] = (tp->t_stopbits == 0) ? 4 : tp->t_stopbits;
        !           361:        cp->par[6] = tp->t_ospeed;
        !           362: 
        !           363:        if (vcmd(xp->v_nbr, &cp->cmd) && wait)
        !           364:                sleep(cp,TTIPRI);
        !           365:        splx(s);
        !           366: }
        !           367: 
        !           368: /*
        !           369:  * VIOCX command response interrupt.
        !           370:  * For transmission, restart output to any active port.
        !           371:  * For all other commands, just clean up.
        !           372:  */
        !           373: vxxint(n,cp)
        !           374: register int n;                        /* VIOC number */
        !           375: register struct vxcmd  *cp;    /* command structure */
        !           376: {
        !           377:        register struct vxmit   *vp, *pvp;
        !           378:        register struct tty     *tp;
        !           379:        register struct vcx     *xp;
        !           380:        register struct tty     *hp;
        !           381:        register long port;
        !           382: 
        !           383:        xp = &vcx[n];
        !           384:        cp = (struct vxcmd *)( (long *)cp - 1);
        !           385: #if NVBSC > 0
        !           386:        switch(cp->cmd) {
        !           387:        case MDMCTL1: case HUNTMD1: case LPARAX1:
        !           388:                vrelease(xp, cp);
        !           389:                wakeup(cp);
        !           390:                return;
        !           391:        }
        !           392: #endif
        !           393:        switch(cp->cmd&0xff00) {
        !           394:        case LIDENT:    /* initialization complete */
        !           395:                if (xp->v_state & V_RESETTING) {
        !           396:                        vxfnreset(n,cp);
        !           397:                        vinthandl(n,((V_BSY | RSPquals) << 8) | V_INTR);
        !           398:                }
        !           399:                cp->cmd++;
        !           400:                return;
        !           401:        case XMITDTA: case XMITIMM:
        !           402:                break;
        !           403:        case LPARAX:
        !           404:                wakeup(cp);
        !           405:        default:        /* MDMCTL or FDTATOX */
        !           406:                vrelease(xp, cp);
        !           407:                if (xp->v_state & V_RESETTING) {
        !           408:                        vinthandl(n,((V_BSY | RSPquals) << 8) | V_INTR);
        !           409:                }
        !           410:                return;
        !           411:        }
        !           412:        for(vp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizvxmit);
        !           413:            vp >= (struct vxmit *)cp->par;
        !           414:            vp = (struct vxmit *) ((char *)vp - sizvxmit) )
        !           415:        {
        !           416:                tp = &vx_tty[(vp->line & 017)+n*16];
        !           417: 
        !           418: #if NVBSC > 0
        !           419: /*             ======= BSC code ================
        !           420: */
        !           421:                port = vp->line;
        !           422:                if (tp->t_line == LDISP) {
        !           423:                        vrelease(xp, cp) ;
        !           424:                        /* Call bsctxd with logical bscport no; 0,1..4,5 */
        !           425:                        /* v_xmtcnt was set to BISYNC ctlr no in vxinit() */
        !           426:                        bsctxd((xp->v_xmtcnt*NBSC)+port);
        !           427:                        return ;
        !           428:                }
        !           429:                if (bscport[(n<<4)+port] == BISYNC) {
        !           430:                        printf("\nvxxint: int. after line closed. (cmd:%lx)",
        !           431:                                cp->cmd&0xff);
        !           432:                        vrelease(xp, cp) ;
        !           433:                        return ;
        !           434:                }
        !           435: /*             ==================================
        !           436: */
        !           437: #endif
        !           438:                pvp = vp;
        !           439:                tp->t_state &= ~TS_BUSY;
        !           440:                if(tp->t_state & TS_FLUSH) {
        !           441:                        tp->t_state &= ~TS_FLUSH;
        !           442:                        wakeup( (caddr_t)&tp->t_state ) ;
        !           443:                }
        !           444:                else
        !           445:                        ndflush(&tp->t_outq, vp->bcount+1);
        !           446:        }
        !           447:        xp->v_xmtcnt--;
        !           448:        vrelease(xp,cp);
        !           449:        if(xp->v_vers == V_NEW) {
        !           450:                vp = pvp;
        !           451:                xp->v_actport[(vp->line & 017) - xp->v_loport] |= 1 ;
        !           452:                if(vxstart(tp) && (cp = nextcmd(xp)) != NULL)
        !           453:                {
        !           454:                        xp->v_xmtcnt++;
        !           455:                        vcmd(n, &cp->cmd);
        !           456:                        return ;
        !           457:                }
        !           458:                xp->v_actport[(vp->line & 017) - xp->v_loport] = 0 ;
        !           459:                return ;
        !           460:        }
        !           461:        xp->v_actflg = 1;
        !           462:        hp = &vx_tty[xp->v_hiport+n*16];
        !           463:        for(tp = &vx_tty[xp->v_loport+n*16];tp <= hp;tp++)
        !           464:                if(vxstart(tp) && (cp = nextcmd(xp)) != NULL)
        !           465:                {
        !           466:                        xp->v_xmtcnt++;
        !           467:                        vcmd(n, &cp->cmd);
        !           468:                }
        !           469:        if( (cp = nextcmd(xp)) != NULL )                /* command to send ? */
        !           470:        {
        !           471:                xp->v_xmtcnt++;
        !           472:                vcmd(n,&cp->cmd);
        !           473:        }
        !           474:        xp->v_actflg = 0;
        !           475: }
        !           476: 
        !           477: /*
        !           478:  * Force out partial XMIT command after timeout
        !           479:  */
        !           480: vxforce(xp)
        !           481: register struct vcx    *xp;
        !           482: {
        !           483:        register struct vxcmd   *cp;
        !           484:        register int s;
        !           485: 
        !           486:        s = spl8();
        !           487:        if((cp = nextcmd(xp)) != NULL) {
        !           488:                xp->v_xmtcnt++;
        !           489:                vcmd(xp->v_nbr, &cp->cmd);
        !           490:        }
        !           491:        splx(s);
        !           492: }
        !           493: 
        !           494: /*
        !           495:  * Start (restart) transmission on the given VX line.
        !           496:  */
        !           497: vxstart(tp)
        !           498: register struct tty *tp;
        !           499: {
        !           500:        register short nch;
        !           501:        register struct vcx     *xp;
        !           502:        register char *outb;
        !           503:        register full = 0;
        !           504:        int k, s, port;
        !           505: 
        !           506:        s = spl8();
        !           507:        port = minor(tp->t_dev) & 017;
        !           508:        xp = (struct vcx *)tp->t_addr;
        !           509:        if (!(tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))) {
        !           510:                if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
        !           511:                        if (tp->t_state&TS_ASLEEP) {
        !           512:                                tp->t_state &= ~TS_ASLEEP;
        !           513:                                wakeup((caddr_t)&tp->t_outq);
        !           514:                        }
        !           515:                        if (tp->t_wsel) {
        !           516:                                selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           517:                                tp->t_wsel = 0;
        !           518:                                tp->t_state &= ~TS_WCOLL;
        !           519:                        }
        !           520:                }
        !           521:                if(tp->t_outq.c_cc == 0) {
        !           522:                        splx(s);
        !           523:                        return(0);
        !           524:                }
        !           525: #ifdef VXPERF
        !           526:        scope_out(3);
        !           527: #endif VXPERF
        !           528:                if(!(tp->t_flags&(RAW|LITOUT)))  
        !           529:                        full = 0200;
        !           530:                if((nch = ndqb(&tp->t_outq, full)) == 0)   {
        !           531:                        if(full) {
        !           532:                                nch = getc(&tp->t_outq);
        !           533:                                timeout(ttrstrt, (caddr_t)tp, (nch&0177) +6);
        !           534:                                tp->t_state |= TS_TIMEOUT;
        !           535:                                full = 0;
        !           536:                        }
        !           537:                } else {
        !           538:                        outb = (char *)tp->t_outq.c_cf;
        !           539:                        tp->t_state |= TS_BUSY;
        !           540:                        if(xp->v_vers == V_NEW)
        !           541:                                k = xp->v_actport[port - xp->v_loport] ;
        !           542:                        else
        !           543:                                k = xp->v_actflg ;
        !           544: 
        !           545:                        full = vsetq(xp, port, outb, nch);
        !           546: 
        !           547:                        if( (k&1) == 0 ) {      /* not called from vxxint */
        !           548:                                if(full || xp->v_xmtcnt == 0) {
        !           549:                                        outb = (char *)(&nextcmd(xp)->cmd);
        !           550:                                        xp->v_xmtcnt++;
        !           551:                                        vcmd(xp->v_nbr, outb );
        !           552:                                } else
        !           553:                                        timeout(vxforce,xp,3);
        !           554:                        }
        !           555:                }
        !           556:        }
        !           557:        splx(s);
        !           558:        return(full);   /* indicate if max commands or not */
        !           559: }
        !           560: 
        !           561: /*
        !           562:  * Stop output on a line.
        !           563:  */
        !           564: vxstop(tp)
        !           565: register struct tty *tp;
        !           566: {
        !           567:        register  s;
        !           568: 
        !           569:        s = spl8();
        !           570:        if (tp->t_state & TS_BUSY) {
        !           571:                if ((tp->t_state&TS_TTSTOP)==0) {
        !           572:                        tp->t_state |= TS_FLUSH;
        !           573:                }
        !           574:        }
        !           575:        splx(s);
        !           576: }
        !           577: 
        !           578: /*
        !           579:  * VIOCX Initialization.  Makes free lists of command buffers.
        !           580:  * Resets all viocx's.  Issues a LIDENT command to each
        !           581:  * viocx which establishes interrupt vectors and logical
        !           582:  * port numbers
        !           583:  */
        !           584: vxinit(i,wait) 
        !           585: register int   i;
        !           586: long wait;
        !           587: {
        !           588:        register struct vcx     *xp;    /* ptr to VIOC-X info/cmd buffer */
        !           589:        register struct vblok   *kp;    /* pointer to VIOC-X control block */
        !           590:        register struct vxcmd   *cp;    /* pointer to a command buffer */
        !           591:        register char   *resp;          /* pointer to response buffer */
        !           592:        register int    j,ix;
        !           593:        register struct vcmds   *cpp;
        !           594:        char type;
        !           595:        register struct bsc     *bp;    /* bsc change */
        !           596:        extern   struct bsc     bsc[];
        !           597: 
        !           598:        if (vbtbl) {
        !           599:                for(j=0;j<NVIOCX;j++) vxbopno[j] = (char)-1;
        !           600:                vbtbl = 0;
        !           601:        }
        !           602: 
        !           603:        kp = VBAS(i);           /* get base adr of cntl blok for VIOC */
        !           604: 
        !           605:        xp = &vcx[i];           /* index info/command buffers */
        !           606:        cpp = &v_cmds[i];
        !           607:        type = kp->v_ident;
        !           608:        vxtype[i] =  0;         /* Type is Viox-x */
        !           609:        switch(type) {
        !           610:        case VIOCX:
        !           611:                {
        !           612:                xp->v_vers = V_OLD ;
        !           613:                /* set DCD for printer ports */
        !           614:                for(j = 0;j < 16;j++)
        !           615:                        if (kp->v_portyp[j] == 4 )
        !           616:                                kp->v_dcd |= 1 << j ;
        !           617:                }
        !           618:                break ;
        !           619:        case NWVIOCX:
        !           620:                {
        !           621:                xp->v_vers = V_NEW ;
        !           622:                xp->v_silosiz = kp->v_maxsilo ;
        !           623:                /* set DCD for printer ports */
        !           624:                for(j = 0;j < 16;j++)
        !           625:                        if (kp->v_portyp[j] == 4 )
        !           626:                                kp->v_dcd |= 1 << j ;
        !           627:                }
        !           628:                break ;
        !           629:        case PVIOCX:
        !           630:                xp->v_vers = V_OLD ;
        !           631:                break ;
        !           632:        case NPVIOCX:
        !           633:                xp->v_vers = V_NEW ;
        !           634:                xp->v_silosiz = kp->v_maxsilo ;
        !           635:                break ;
        !           636: #ifdef VIOCB
        !           637:        case VIOCB:     /* old f/w, Bisync board */
        !           638:                if (wait)               /* Just boot up */
        !           639:                        if (bscno >= MXVIOC_B) {
        !           640:                                printf("\nvxinit: exceed max no of VIOC-B:%ld",
        !           641:                                        MXVIOC_B);
        !           642:                                break;
        !           643:                }
        !           644:                printf("(kp:%lx)(xp:%lx): %lx---%x OLD VIOC-B, ",
        !           645:                                        (long)kp, (long)xp,(int)kp->v_ident,
        !           646:                                        (int)kp->v_fault);
        !           647:                xp->v_vers = V_OLD ;
        !           648:                /* save device specific info */
        !           649:                /*for(bp = &bsc[0]; bp <= &bsc[NBSC-1]; bp++)
        !           650:                        bp->b_devregs = (caddr_t)xp ;
        !           651:                */
        !           652: 
        !           653:                if (wait)                               /* Use v_xmtcnt to */
        !           654:                        xp->v_xmtcnt = (char)bscno;     /* save VIOC-B ctlrno */
        !           655:                else bscno = (long)xp->v_xmtcnt & 0x7f;
        !           656: 
        !           657:                bp = &bsc[0+(bscno*4)];
        !           658:                for(ix=0;ix<4;ix++,bp++)
        !           659:                        bp->b_devregs = (caddr_t)xp ;
        !           660:                bscno++;
        !           661:                bscport[(i*16)+0] = BISYNC;
        !           662:                bscport[(i*16)+1] = BISYNC;
        !           663:                bscport[(i*16)+2] = BISYNC;
        !           664:                bscport[(i*16)+3] = BISYNC;
        !           665:                printf(",BSC no %d initialized.\n",bscno-1);
        !           666:                break ;
        !           667: #endif
        !           668: 
        !           669: #ifdef NWVIOCB
        !           670:        case NWVIOCB:   /* new f/w, Bisync board */
        !           671:                if (wait)               /* Just boot up */
        !           672:                        if (bscno >= MXVIOC_B) {
        !           673:                                printf("\nvxinit: exceed max no of VIOC-B:%ld",
        !           674:                                        MXVIOC_B);
        !           675:                                break;
        !           676:                        }
        !           677:                printf("(kp:%lx)(xp:%lx): %lx---%x 16K VIOC-B",
        !           678:                                        (long)kp, (long)xp,(int)kp->v_ident,
        !           679:                                        (int)kp->v_fault);
        !           680:                xp->v_vers = V_NEW ;
        !           681:                xp->v_silosiz = kp->v_maxsilo ;
        !           682:                /* save device specific info */
        !           683: 
        !           684:                if (wait)                               /* Use v_xmtcnt to */
        !           685:                        xp->v_xmtcnt = (char)bscno;     /* save VIOC-B ctlrno */
        !           686:                else bscno = (long)xp->v_xmtcnt & 0x7f;
        !           687: 
        !           688:                bp = &bsc[bscno*4];
        !           689:                for(ix=0;ix<4;ix++,bp++)
        !           690:                        bp->b_devregs = (caddr_t)xp ;
        !           691:                bscno++;
        !           692:                bscport[(i*16)+0] = BISYNC;
        !           693:                bscport[(i*16)+1] = BISYNC;
        !           694:                bscport[(i*16)+2] = BISYNC;
        !           695:                bscport[(i*16)+3] = BISYNC;
        !           696:                printf(",BSC no %d initialized.\n",bscno-1);
        !           697:                if(CBSIZE > kp->v_maxxmt)
        !           698:                        printf("vxinit: Warning CBSIZE > maxxmt\n") ;
        !           699:                break ;
        !           700: #endif
        !           701:        case VBOPID:            /* VIOC-BOP */
        !           702:                vxbbno++;
        !           703:                vxtype[i] = 1;
        !           704:                vxbopno[i] = vxbbno;
        !           705:                printf("VIOC-BOP no. %d at %lx\n",vxbopno[i],VIOCBAS[i]);
        !           706:        default:
        !           707:                return ;        /* Not a viocx type */
        !           708:        }
        !           709:        xp->v_nbr = -1;         /* no number for it yet */
        !           710:        xp->v_maxcmd = xp->v_vers == V_NEW ? 24 : 4;
        !           711: 
        !           712:        for(j=0; j<NVCXBUFS; j++)       /* init all cmd buffers */
        !           713:        {
        !           714:                cp = &xp->vx_lst[j];    /* index a buffer */
        !           715:                cp->c_fwd = &xp->vx_lst[j+1];   /* point to next buf */
        !           716:        }
        !           717:        xp->vx_avail = &xp->vx_lst[0];  /* set idx to 1st free buf */
        !           718:        cp->c_fwd = (struct vxcmd *)0;  /* mark last buf in free list */
        !           719: 
        !           720:        cp = vobtain(xp);       /* grap the control block */
        !           721:        cp->cmd = LIDENT;       /* set command type */
        !           722:        cp->par[0] = i * 4 + VCVECT;    /* ack vector */
        !           723:        cp->par[1] = cp->par[0] + 1;    /* cmd resp vector */
        !           724:        cp->par[3] = cp->par[0] + 2;    /* unsol intr vector */
        !           725:        cp->par[4] = 15;        /* max ports, no longer used */
        !           726:        cp->par[5] = 0;         /* set 1st port number */
        !           727:        vcmd(i, &cp->cmd);      /* initialize the VIOC-X */
        !           728: 
        !           729:        if (!wait) return;
        !           730:        while(cp->cmd == LIDENT);    /* wait for command completion */
        !           731: 
        !           732:        /* calculate address of response buffer */
        !           733:        resp = (char *)kp;
        !           734:        resp += kp->v_rspoff & 0x3FFF;
        !           735:  
        !           736:        if(resp[0] != 0 && (resp[0]&0177) != 3) /* did init work? */
        !           737:        {
        !           738:                vrelease(xp,cp);        /* init failed */
        !           739:                return;                 /* try next VIOC-X */
        !           740:        }
        !           741: 
        !           742:        xp->v_loport = cp->par[5];      /* save low port number */
        !           743:        xp->v_hiport = cp->par[7];/* VIOC knows high port numbr */
        !           744:        vrelease(xp,cp);        /* done with this control block */
        !           745:        xp->v_nbr = i;          /* assign VIOC-X board number */
        !           746: }
        !           747: 
        !           748: /*
        !           749:  * Obtain a command buffer
        !           750:  */
        !           751: struct vxcmd *
        !           752: vobtain(xp)
        !           753: register struct        vcx     *xp;
        !           754: {
        !           755: 
        !           756:        register struct vxcmd   *p;
        !           757:        register s;
        !           758: 
        !           759:        s = spl8();
        !           760:        p = xp->vx_avail;
        !           761:        if(p == (struct vxcmd *)0) {
        !           762: #ifdef VX_DEBUG
        !           763:                if (vxintr4 & VXNOBUF) vxintr4 &= ~VXNOBUF;
        !           764: #endif
        !           765:                vpanic("vx: no buffs");
        !           766:                vxstreset(xp - vcx);
        !           767:                splx(s);
        !           768:                return(vobtain(xp));
        !           769:        }
        !           770:        xp->vx_avail = (xp->vx_avail)->c_fwd;
        !           771:        splx(s);
        !           772:        return( (struct vxcmd *)p);
        !           773: }
        !           774: 
        !           775: /*
        !           776:  * Release a command buffer
        !           777:  */
        !           778: vrelease(xp,cp)
        !           779: register struct        vcx     *xp;
        !           780: register struct        vxcmd   *cp;
        !           781: {
        !           782: 
        !           783:        register s;
        !           784: 
        !           785: #ifdef VX_DEBUG
        !           786:        if (vxintr4 & VXNOBUF) return;
        !           787: #endif
        !           788:        s = spl8();
        !           789:        cp->c_fwd = xp->vx_avail;
        !           790:        xp->vx_avail = cp;
        !           791:        splx(s);
        !           792: }
        !           793: 
        !           794: /*
        !           795:  * vxcmd - 
        !           796:  *
        !           797:  */
        !           798: struct vxcmd   *
        !           799: nextcmd(xp)
        !           800: register struct        vcx     *xp;
        !           801: {
        !           802:        register struct vxcmd   *cp;
        !           803:        register int    s;
        !           804: 
        !           805:        s = spl8();
        !           806:        cp = xp->vx_build;
        !           807:        xp->vx_build = (struct vxcmd *)0;
        !           808:        splx(s);
        !           809:        return(cp);
        !           810: }
        !           811: 
        !           812: /*
        !           813:  * assemble transmits into a multiple command.
        !           814:  * up to 8 transmits to 8 lines can be assembled together
        !           815:  */
        !           816: vsetq(xp ,d ,addr, cnt)
        !           817: register struct        vcx     *xp;
        !           818: caddr_t        addr;
        !           819: {
        !           820: 
        !           821:        register struct vxcmd   *cp;
        !           822:        register struct vxmit   *mp;
        !           823:        register char   *p;
        !           824:        register i;
        !           825: 
        !           826:        cp = xp->vx_build;
        !           827:        if(cp == (struct vxcmd *)0) {
        !           828:                cp = vobtain(xp);
        !           829:                xp->vx_build = cp;
        !           830:                cp->cmd = XMITDTA;
        !           831:        } else {
        !           832:                if((cp->cmd & 07) == 07) {
        !           833:                        vpanic("vx: vsetq overflow");
        !           834:                        vxstreset(xp->v_nbr);
        !           835:                        return(0);
        !           836:                }
        !           837:                cp->cmd++;
        !           838:        }
        !           839: 
        !           840:        mp = (struct vxmit *)(cp->par + (cp->cmd & 07)*sizvxmit);
        !           841:        mp->bcount = cnt-1;
        !           842: 
        !           843:        mp->line = d;
        !           844:        if((xp->v_vers == V_NEW) && (cnt <= 6)) {
        !           845:                cp->cmd = XMITIMM ;
        !           846:                p = addr;
        !           847:                /* bcopy(addr, &(char *)mp->ostream, cnt) ; */
        !           848:        } else {
        !           849:                addr = vtoph(0, (caddr_t)addr) ; /* should be a sys address */
        !           850:                p = (char *)&addr;
        !           851:                cnt = sizeof addr;
        !           852:                /* mp->ostream = addr ; */
        !           853:        }
        !           854:        for(i=0; i<cnt; i++)
        !           855:                mp->ostream[i] = *p++;
        !           856:        if(xp->v_vers == V_NEW)
        !           857:                return(1) ;
        !           858:        else
        !           859:                return((cp->cmd&07) == 7) ;     /* Indicate if full */
        !           860: }
        !           861: #endif

unix.superglobalmegacorp.com

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