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

unix.superglobalmegacorp.com

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