Annotation of cci/sys/vba/vcx.c, revision 1.1.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.