Annotation of researchv8dc/sys/dev/sn.c, revision 1.1.1.1

1.1       root        1: #define BSD41
                      2: #define        VAXONE
                      3: #define TIMEOUT
                      4: 
                      5: #ifdef MARVIN
                      6: #define TXDRIVER
                      7: #endif
                      8: #ifdef CANTOR
                      9: #define TXDRIVER
                     10: #endif
                     11: #ifdef HILBERT
                     12: #define TXDRIVER
                     13: #endif
                     14: #ifdef DAISY
                     15: #define TXDRIVER
                     16: #endif
                     17: 
                     18: #ifdef USG5
                     19: #define NSN 1
                     20: #else
                     21: #include "sn.h"
                     22: #endif
                     23: #if NSN > 0
                     24: 
                     25: #ifdef BSD41
                     26: #include "../h/param.h"
                     27: #include "../h/systm.h"
                     28: #include "../h/buf.h"
                     29: #include "../h/conf.h"
                     30: #include "../h/dir.h"
                     31: #include "../h/user.h"
                     32: #include "../h/pte.h"
                     33: #include "../h/map.h"
                     34: #include "../h/vm.h"
                     35: #include "../h/dk.h"
                     36: #include "../h/cmap.h"
                     37: #include "../h/ubareg.h"
                     38: #include "../h/ubavar.h"
                     39: #include "../h/cpu.h"
                     40: #include "../h/proc.h"
                     41: #include "../h/snet.h"
                     42: #include "../h/packet.h"
                     43: #include "../h/channel.h"
                     44: #include "../h/status.h"
                     45: #endif
                     46: 
                     47: #ifdef SNDEBUG
                     48: int sndebug = 1;
                     49: #else
                     50: int sndebug = 0;
                     51: #endif
                     52: 
                     53: /* flags for status */
                     54: #define INPUT  1
                     55: #define OUTPUT 2
                     56: 
                     57: #define min(x,y) ((x) < (y) ? (x) : (y))
                     58: #define swab(x) (unsigned short)((((x)>>8)&0xff) | ((x) << 8))
                     59: 
                     60: #define SNPRI  28
                     61: 
                     62: #define CHKINIT 0xbf37
                     63: 
                     64: struct device {
                     65:        short drcs;
                     66:        short drout;
                     67:        short drin;
                     68: };
                     69: 
                     70: /* Command and Status word */
                     71: #define CSR0 0x1
                     72: #define CSR1 0x2
                     73: #define RIE 0x20
                     74: #define TIE 0x40
                     75: #define TEMPTY 0x80
                     76: #define RFULL 0x8000
                     77: 
                     78: /*
                     79:  *     CSR1 CSR0
                     80:  *      0    0         Write Data
                     81:  *      0    1         Write EOP
                     82:  *      1    0         Write Command
                     83:  *      1    1         Read Status
                     84:  */
                     85: #define DATA_MODE      (RIE)
                     86: #define EOP_MODE       (CSR0 | RIE)
                     87: #define CMD_MODE       (CSR1 | RIE)
                     88: #define STATUS_MODE    (CSR0 | CSR1 | RIE)
                     89: 
                     90: /* Command word format
                     91:  *
                     92:  *     +-----------------------------------------------+
                     93:  *     |  |B |R |A |           |              |        |
                     94:  *     |  |C |S |B |    DID    |              |  FCN   |
                     95:  *     |  |T |T |T |           |              |        |
                     96:  *     +-----------------------------------------------+
                     97:  *      15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
                     98:  */
                     99: /* Function codes */
                    100: #define NOP    0x0
                    101: #define BOARD_RESET    0x5
                    102: #define MASTER_CLEAR   0x6
                    103: 
                    104: #define ABORT(did)     (0x1000 | (did))
                    105: #define RESET(did)     (0x2000 | (did))
                    106: #define BROAD_CAST(did)        (0x4000 | (did))
                    107: 
                    108: 
                    109: /* SNET status word bits
                    110:  *
                    111:  *     +-----------------------------------------------+
                    112:  *     |                             |E |S |I |O |  |  |
                    113:  *     |                             |O |N |B |B |  |  |
                    114:  *     |                             |P |K |E |E |  |  |
                    115:  *     +-----------------------------------------------+
                    116:  *      15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0
                    117:  */    
                    118: #define OUTBUF_E       0x4
                    119: #define INBUF_E        0x8
                    120: #define SNACK  0x10    /* transmitter error */
                    121: #define EOP    0x20    /* we have read and EOP frame */
                    122: 
                    123: static int sn_multiplex;
                    124: 
                    125: struct openwait sn_openwait[NUMDEV];
                    126: struct openwait *sn_owhead, *sn_owtail;
                    127: 
                    128: #define SNFILE(dev)  (minor(dev) & 0x3f)
                    129: #define SNUNIT(dev) ((minor(dev) & 0xc0) >> 6)
                    130: 
                    131: struct chdat sn_chans[NUMLCH];
                    132: #define MAXMSGLEN (512+8)
                    133: struct sn_buffers {
                    134:        short inbuf[MAXMSGLEN];
                    135:        short outbuf[MAXMSGLEN];
                    136: } sn_buffers[NUMLCH];
                    137: 
                    138: #define NOPDID -1
                    139: 
                    140: #ifdef TIMEOUT
                    141: #define CKFUZZ         4       /* number of timeouts we wait for a response */
                    142: #ifdef USG5
                    143: #define CKTICKS        (HZ/4)  /* number of ticks per timeout */
                    144: #else
                    145: #define CKTICKS        (hz/4)  /* number of ticks per timeout */
                    146: #endif
                    147: 
                    148: int sn_state;
                    149: #define        OPEN 1          /* set if at least one sn? is open */
                    150: #define        TIMER 2         /* set if at timer is running */
                    151: 
                    152: int cktimchk();
                    153: int sn_opncnt;
                    154: #endif TIMEOUT
                    155: 
                    156: struct snmach snmach[NUMDEV] = {
                    157:        { 1, 255 },
                    158:        { 2, 254 },
                    159:        { 3, 253 },
                    160:        { 4, 252 },
                    161:        { 5, 251 },
                    162:        { 6, 250 },
                    163:        { 7, 249 },
                    164:        { 8, 248 } };
                    165: 
                    166: int sn_once;
                    167: 
                    168: #ifdef BSD42
                    169: #define RETURN(x)      {return(x);}
                    170: #define ARGS(x)                args->x
                    171: #else
                    172: #define RETURN(x)      {u.u_error = x; return;}
                    173: #define ARGS(x)                args.x
                    174: #endif
                    175: 
                    176: #ifdef USG5
                    177: extern struct sninfo sn_sninfo[];
                    178: extern int sn_cnt;
                    179: extern struct device *sn_addr[];
                    180: #else
                    181: struct sninfo sn_sninfo[NSN];
                    182: int    snprobe(), snattach();
                    183: struct uba_device *sndinfo[NSN];
                    184: u_short        snstd[] = {0};
                    185: struct uba_driver sndriver =
                    186:        { snprobe, 0, snattach, 0, snstd, "sn", sndinfo};
                    187: 
                    188: snprobe(reg)
                    189: caddr_t reg;
                    190: {
                    191:        register int br, cvec;  /* value result */
                    192:        register struct device *snaddr = (struct device *)reg;
                    193: 
                    194:        br = 0x15;
                    195: #ifdef VAXONE
                    196:        cvec = 0510;
                    197: #else
                    198: #ifdef CANTOR
                    199:        if (((int)snaddr & 017777) == 007770)
                    200:                cvec = 0504;
                    201:        if (((int)snaddr & 017777) == 007750)
                    202:                cvec = 0464;
                    203: #else
                    204:        cvec = 0504;
                    205: #endif
                    206: #endif
                    207: #ifdef BSD41
                    208:        return(1);
                    209: #endif
                    210: #ifdef BSD42
                    211:        return(sizeof(struct device));
                    212: #endif
                    213: }
                    214: 
                    215: /*ARGSUSED*/
                    216: snattach(ui)
                    217: register struct uba_device *ui;
                    218: {
                    219: }
                    220: #endif
                    221: 
                    222: snopen(dev, rw)
                    223: dev_t dev;
                    224: int rw;
                    225: {
                    226:        register struct device *draddr;
                    227: #ifndef USG5
                    228:        struct uba_device *ui;
                    229: #endif
                    230:        register struct sninfo *sninfop;
                    231:        int mdev = SNFILE(dev);
                    232:        int unit = SNUNIT(dev);
                    233: 
                    234:        if( sndebug )
                    235:                printf("snopen(%x,%x)\n", dev, rw);
                    236: 
                    237: #ifdef USG5
                    238:        if ( mdev > NUMDEV || unit >= sn_cnt) {
                    239:                RETURN ( ENXIO );
                    240:        }
                    241:        draddr = sn_addr[unit];
                    242: #else
                    243:        if (mdev > NUMDEV || unit >= NSN ||
                    244:            (ui = sndinfo[unit]) == 0 || ui->ui_alive == 0) {
                    245:                RETURN ( ENXIO );
                    246:        }
                    247:        draddr = (struct device *)ui->ui_addr;
                    248: #endif
                    249: 
                    250:        if ( sn_once == 0 ) {
                    251:                struct chdat *cp = sn_chans;
                    252: 
                    253:                sn_once++;
                    254:                for( ; cp<&sn_chans[NUMLCH]; cp++) {
                    255:                        cp->lchnum = -1;
                    256:                        cp->dlchnum = -1;
                    257:                }
                    258:                sn_owhead = sn_owtail = sn_openwait;
                    259:        }
                    260: 
                    261:        sninfop = &sn_sninfo[unit];
                    262:        spl6();
                    263:        if (sninfop->sndevlock[mdev]++ != 0) {
                    264:                spl0();
                    265:                RETURN ( EBUSY );
                    266:        }
                    267: #ifdef TIMEOUT
                    268:        sn_opncnt++;
                    269:        sn_state |= OPEN;
                    270:        if ((sn_state & TIMER) == 0) {
                    271:                sn_state |= TIMER;
                    272:                timeout(cktimchk, (caddr_t)0, CKTICKS);
                    273:        }
                    274: #endif TIMEOUT
                    275:        if( sninfop->snlock++ == 0 ) {
                    276: #ifdef TXDRIVER
                    277:                {
                    278:                extern struct txinfo tx_sninfo[];
                    279: 
                    280:                if (tx_sninfo[unit].snlock != 0) {
                    281:                        spl0();
                    282:                        return;
                    283:                }
                    284:                }
                    285: #endif
                    286:                draddr->drcs = CMD_MODE;
                    287:                draddr->drout = 0;
                    288:                draddr->drout = BOARD_RESET;
                    289:                draddr->drout = 0;
                    290:                draddr->drcs = DATA_MODE;
                    291:        }
                    292: 
                    293:        spl0();
                    294:        return(0);
                    295: }
                    296: 
                    297: snclose(dev)
                    298: {
                    299:        register struct chdat *cp;
                    300: #ifndef USG5
                    301:        struct uba_device *ui;
                    302: #endif
                    303:        register struct sninfo *sninfop;
                    304:        register struct device *draddr;
                    305:        int mdev = SNFILE(dev);
                    306:        int unit = SNUNIT(dev);
                    307:        int resetmachno;
                    308:        struct openwait *curtail;
                    309:        
                    310:        if( sndebug )
                    311:                printf("snclose(%x)\n", dev);
                    312: #ifdef USG5
                    313:        if ( unit >= sn_cnt) {
                    314:                RETURN ( ENXIO );
                    315:        }
                    316:        draddr = sn_addr[unit];
                    317: #else
                    318:        if ( unit >= NSN) {
                    319:                RETURN ( ENXIO );
                    320:        }
                    321:        ui = sndinfo[unit];
                    322:        draddr = (struct device *)ui->ui_addr;
                    323: #endif
                    324: 
                    325:        sninfop = &sn_sninfo[unit];
                    326:        spl6();
                    327:        if( sninfop->snlock == 0 || mdev > NUMDEV 
                    328:                        || sninfop->sndevlock[mdev] == 0 ) {
                    329:                spl0();
                    330:                RETURN ( ENXIO );
                    331:        }
                    332: 
                    333:        resetmachno = -1;
                    334:        for(cp=sninfop->snlink[mdev]; cp; cp=cp->link) {
                    335:                if (cp->pdid == NOPDID)
                    336:                        resetmachno = cp->machno;
                    337:                chclose(cp);
                    338:        }
                    339:        if (resetmachno != -1) {
                    340:                for(cp=sn_chans; cp < &sn_chans[NUMLCH]; cp++) {
                    341:                        if (cp->pdid == NOPDID && cp->machno == resetmachno)
                    342:                                goto noreset;
                    343:                }
                    344:                draddr->drcs = CMD_MODE;
                    345:                draddr->drout =  RESET(resetmachno << 8);
                    346:                draddr->drcs = EOP_MODE;
                    347:                draddr->drout = 0;
                    348:                draddr->drcs = DATA_MODE;
                    349:        }
                    350: 
                    351: noreset:
                    352:        for (curtail = sn_owtail; curtail != sn_owhead; 
                    353:                        curtail = ownext(curtail)) {
                    354:                if (curtail->pid == u.u_procp->p_pid) {
                    355:                        curtail->pid = 0;
                    356:                        goto nowakeup;
                    357:                }
                    358:        }
                    359:        while (sn_owtail != sn_owhead) {
                    360:                curtail = sn_owtail;
                    361:                sn_owtail = ownext(sn_owtail);
                    362:                if (curtail->pid) {
                    363:                        wakeup(curtail);
                    364:                        break;
                    365:                }
                    366:        }
                    367: 
                    368: nowakeup:
                    369:        sninfop->snlink[mdev] = 0;
                    370:        sninfop->sndevlock[mdev] = 0;
                    371: #ifdef TIMEOUT
                    372:        if (--sn_opncnt <= 0) {
                    373:                sn_state &= ~OPEN;
                    374:                sn_opncnt = 0;
                    375:        }
                    376: #endif TIMEOUT
                    377:        if (--sninfop->snlock == 0 ) {
                    378: #ifdef TXDRIVER
                    379:                {
                    380:                if (tx_sninfo[unit].snlock != 0)
                    381:                        return;
                    382:                }
                    383: #endif
                    384:                draddr->drcs &= ~RIE;
                    385:        }
                    386:        spl0();
                    387:        return(0);
                    388: }
                    389: 
                    390: static short ratshole[MAXMSGLEN];
                    391: static struct chdat ratschan;
                    392: 
                    393: #ifdef USG5
                    394: snintr(unit)
                    395: #else
                    396: snrint(unit)
                    397: #endif
                    398: int unit;
                    399: {
                    400:        register struct chdat *cp;
                    401:        register short *sp, *dp;
                    402:        register int i;
                    403:        register struct sninfo *sninfop;
                    404:        register struct device *draddr;
                    405:        unsigned short chksum, xchk;
                    406:        short len;
                    407:        unsigned short chan;
                    408:        short *osp;
                    409: #ifndef USG5
                    410:        struct uba_device *ui;
                    411: #endif
                    412: 
                    413: #ifdef USG5
                    414:        draddr = sn_addr[unit];
                    415: #else
                    416:        ui = sndinfo[unit];
                    417:        draddr = (struct device *)ui->ui_addr;
                    418: #endif
                    419:        dp = &draddr->drin;
                    420: 
                    421:        sninfop = &sn_sninfo[unit];
                    422:        sninfop->snrcnt++;
                    423: 
                    424: loop:
                    425:        chksum = CHKINIT;
                    426: 
                    427:        chan = *dp;
                    428: #ifdef TXDRIVER
                    429:        /* unusual process numbers go to tx driver */
                    430:        if ((chan & 0xff) <= 200 || ((unsigned int)chan) >= 0x2000 ) {
                    431:                txintrmt(unit, chan);
                    432:                goto getstatus;
                    433:        }
                    434: #endif
                    435:        chksum ^= chan;
                    436:        chan = swab(chan);
                    437:        len = *dp;
                    438:        chksum ^= len;
                    439:        len = swab(len);
                    440:        if( len > MAXMSGLEN ) {
                    441:                sninfop->snnbadlen++;
                    442:                goto getstatus;
                    443:        }
                    444:        sninfop->sninbytes += len+4;
                    445: 
                    446:        for(cp=sn_chans; cp < &sn_chans[NUMLCH]; cp++)
                    447:                if( cp->xchan == chan && cp->snunit == unit ) {
                    448:                        if( cp->input.done == 0 && len <= cp->input.len )
                    449:                                osp = sp = cp->input.buf;
                    450:                        else
                    451:                                osp = sp = ratshole;
                    452:                        goto found;
                    453:                }
                    454:        osp = sp = ratshole;
                    455:        cp = &ratschan;
                    456:        sninfop->snnnolc++;
                    457: found:
                    458:                        
                    459:        for(i=len; i>0; i-=8) {
                    460:                switch( i ) {
                    461:                default:
                    462:                        *sp = *dp;
                    463:                        chksum ^= *sp++;
                    464:                case 7:
                    465:                        *sp = *dp;
                    466:                        chksum ^= *sp++;
                    467:                case 6:
                    468:                        *sp = *dp;
                    469:                        chksum ^= *sp++;
                    470:                case 5:
                    471:                        *sp = *dp;
                    472:                        chksum ^= *sp++;
                    473:                case 4:
                    474:                        *sp = *dp;
                    475:                        chksum ^= *sp++;
                    476:                case 3:
                    477:                        *sp = *dp;
                    478:                        chksum ^= *sp++;
                    479:                case 2:
                    480:                        *sp = *dp;
                    481:                        chksum ^= *sp++;
                    482:                case 1:
                    483:                        *sp = *dp;
                    484:                        chksum ^= *sp++;
                    485:                }
                    486:        }
                    487:        if( (i = ((len < 0 ? 0 : len) + 3)&0xf) != 0 ) {
                    488:                for(i^=0xf; i-->=0; )
                    489:                        chksum ^= *dp;
                    490:        }
                    491:        if( chksum != (xchk = *dp) ) {
                    492:                sninfop->snnchksum++;
                    493:                if( sndebug ) {
                    494:                        short *usp = osp;
                    495:                        int x = len;
                    496: 
                    497:                        printf("snchksum (%x, %x):", chan, len);
                    498:                        for(; --x>=0; )
                    499:                                printf(" %x", *usp++);
                    500:                        printf(" %x (%x)\n", xchk, chksum);
                    501:                }
                    502:        } else if( len > 0 ) {
                    503:                if( osp == ratshole ) {
                    504:                        cp->flags |= SENTRNR;
                    505:                        snxstart(unit, cp, RNR);
                    506:                        sninfop->snsrnr++;
                    507:                } else {
                    508:                        sninfop->snndata++;
                    509:                        cp->input.done = 1;
                    510:                        cp->input.len = len;
                    511:                        snxstart(unit, cp, ACK);
                    512:                        sninfop->snsack++;
                    513:                        wakeup((caddr_t)cp->input.buf);
                    514:                        if( cp->flags&MULTIPLEX )
                    515:                                wakeup((caddr_t)&sn_multiplex);
                    516:                }
                    517:        } else {
                    518:                switch( len ) {
                    519:                case ACK:
                    520:                        sninfop->snnack++;
                    521:                        cp->flags &= ~SENTDATA;
                    522:                        cp->output.done = 1;
                    523:                        wakeup((caddr_t)cp->output.buf);
                    524:                        break;
                    525: 
                    526:                case RDY:
                    527:                        sninfop->snnrdy++;
                    528:                        snxstart(unit, cp, RACK);
                    529:                        if( cp->output.done == 0 && cp->output.len > 0 ) {
                    530:                                snxstart(unit, cp, DATA);
                    531:                                sninfop->snrout++;
                    532:                        }
                    533:                        break;
                    534: 
                    535:                case RNR:
                    536:                        sninfop->snnrnr++;
                    537:                        cp->flags &= ~SENTDATA;
                    538:                        break;
                    539: 
                    540:                case RACK:
                    541:                        sninfop->snnrack++;
                    542:                        cp->flags &= ~SENTRDY;
                    543:                        break;
                    544: 
                    545:                default:
                    546:                        printf("snrint: unit %d, bad type %d\n", unit, len);
                    547:                        break;
                    548:                }
                    549:        }
                    550: 
                    551: getstatus:
                    552:        draddr->drcs = STATUS_MODE;
                    553:        i = *dp;
                    554:        draddr->drcs = DATA_MODE;
                    555:        if ((i&INBUF_E) == 0) {
                    556:                sninfop->sninloop++;
                    557:                goto loop;
                    558:        }
                    559: }
                    560: 
                    561: snxstart(unit, cp, type)
                    562: int unit;
                    563: register struct chdat *cp;
                    564: int type;
                    565: {
                    566:        register short *sp, *dp;
                    567:        register struct sninfo *sninfop;
                    568:        register struct device *draddr;
                    569:        register int i;
                    570:        unsigned short chksum;
                    571: #ifndef USG5
                    572:        struct uba_device *ui;
                    573: #endif
                    574:        int len, numretry;
                    575: 
                    576: #ifdef USG5
                    577:        draddr = sn_addr[unit];
                    578: #else
                    579:        ui = sndinfo[unit];
                    580:        draddr = (struct device *)ui->ui_addr;
                    581: #endif
                    582:        dp = &draddr->drout;
                    583: 
                    584:        sninfop = &sn_sninfo[unit];
                    585: 
                    586:        if( type == DATA )  {
                    587:                len = cp->output.len;
                    588:                sninfop->snoutbytes += len+4;
                    589:        } else {
                    590:                len = type;
                    591:                sninfop->snoutbytes += 4;
                    592:        }
                    593:        draddr->drcs = STATUS_MODE;
                    594: 
                    595:        i = draddr->drin;
                    596:        if ( (i&OUTBUF_E) == 0 ) {
                    597:                sninfop->snoutfull++;
                    598:                do {
                    599:                        i = draddr->drin;
                    600:                        sninfop->sncntoutfull++;
                    601:                } while( (i&OUTBUF_E) == 0 );
                    602:        }
                    603:        
                    604:        numretry = 0;
                    605:        sninfop->snxcnt++;
                    606: retry:
                    607:        sp = cp->output.buf;
                    608:        chksum = CHKINIT;
                    609:        if (cp->pdid == NOPDID) {
                    610:                draddr->drcs = CMD_MODE;
                    611:                *dp = cp->machno<<8;
                    612:                draddr->drcs = DATA_MODE;
                    613:                *dp = i = swab(cp->dlchnum);
                    614:        } else {
                    615:                draddr->drcs = CMD_MODE;
                    616:                *dp = cp->pdid<<8;
                    617:                draddr->drcs = DATA_MODE;
                    618:                *dp = i = (cp->dlchnum<<8) | cp->machno;
                    619:        }
                    620:        chksum ^= (unsigned short)i;
                    621:        *dp = i = swab(len);
                    622:        chksum ^= (unsigned short)i;
                    623:        for( i=len; i>0; i-=8 ) {
                    624:                switch( i ) {
                    625:                default:
                    626:                        chksum ^= *sp;
                    627:                        *dp = *sp++;
                    628:                case 7:
                    629:                        chksum ^= *sp;
                    630:                        *dp = *sp++;
                    631:                case 6:
                    632:                        chksum ^= *sp;
                    633:                        *dp = *sp++;
                    634:                case 5:
                    635:                        chksum ^= *sp;
                    636:                        *dp = *sp++;
                    637:                case 4:
                    638:                        chksum ^= *sp;
                    639:                        *dp = *sp++;
                    640:                case 3:
                    641:                        chksum ^= *sp;
                    642:                        *dp = *sp++;
                    643:                case 2:
                    644:                        chksum ^= *sp;
                    645:                        *dp = *sp++;
                    646:                case 1:
                    647:                        chksum ^= *sp;
                    648:                        *dp = *sp++;
                    649:                }
                    650:        }
                    651:        if( (i = ((len < 0 ? 0 : len) + 3)&0xf) != 0 ) {
                    652:                for(i^=0xf; i-->=0; )
                    653:                        *dp = 0;
                    654:        }
                    655:        draddr->drcs = EOP_MODE;
                    656:        *dp = chksum;
                    657:        draddr->drcs = STATUS_MODE;
                    658:        i = draddr->drin;
                    659:        draddr->drcs = DATA_MODE;
                    660:        if( i&SNACK ) {
                    661:                sninfop->snsnack++;
                    662:                if( ++numretry < 100 )
                    663:                        goto retry;
                    664:                sninfop->snlost++;
                    665:        }
                    666:        cp->ckticks = CKFUZZ;
                    667:        if( type == DATA )  {
                    668:                cp->flags |= SENTDATA;
                    669:        }
                    670: }
                    671: 
                    672: snioctl(dev, cmd, addr, flag)
                    673: caddr_t addr;
                    674: dev_t dev;
                    675: {
                    676:        register struct chdat *cp;
                    677:        register struct reqinfo *rp;
                    678:        register struct sninfo *sninfop;
                    679:        register struct bufinfo *bp;
                    680:        register struct chdat *dp;
                    681:        struct status status;
                    682:        int i;
                    683:        struct status *ustatus;
                    684:        char *usaddr;
                    685:        int ulen;
                    686:        int error;
                    687:        int mdev = SNFILE(dev);
                    688:        int unit = SNUNIT(dev);
                    689: 
                    690: #ifdef USG5
                    691:        if ( unit >= sn_cnt) {
                    692:                RETURN ( ENXIO );
                    693:        }
                    694: #else
                    695:        if ( unit >= NSN) {
                    696:                RETURN ( ENXIO );
                    697:        }
                    698: #endif
                    699:        sninfop = &sn_sninfo[unit];
                    700: 
                    701:        switch( cmd ) {
                    702:        case NIOOPEN: {
                    703: #ifdef BSD42
                    704:                struct oargs *args = (struct oargs *)addr;
                    705: #else
                    706:                struct oargs args;
                    707: 
                    708:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                    709:                        RETURN ( EFAULT );
                    710:                }
                    711: #endif
                    712:                spl6();
                    713:                for(cp=sn_chans; cp<&sn_chans[NUMLCH]; cp++)
                    714:                        if( cp->lchnum == -1 && cp->dlchnum == -1 )
                    715:                                break;
                    716:                if( cp >= &sn_chans[NUMLCH] ) {
                    717:                        spl0();
                    718:                        RETURN(  ENFILE );
                    719:                }
                    720:                for(dp=sn_chans; dp<&sn_chans[NUMLCH]; dp++)
                    721:                        if( dp->lchnum != -1 && dp->lmachno == ARGS(lmachno)
                    722:                           && dp->lchnum == ARGS(lchno)
                    723:                           && dp->snunit == unit ) {
                    724:                                spl0();
                    725:                                RETURN(  EEXIST );
                    726:                        }
                    727:                cp->lchnum = ARGS(lchno);
                    728:                cp->dlchnum = ARGS(dlchno);
                    729:                spl0();
                    730:                cp->lmachno = ARGS(lmachno);
                    731:                cp->machno = ARGS(dmachno);
                    732:                cp->xchan = (cp->lmachno<<8)|cp->lchnum;
                    733:                cp->snunit = unit;
                    734:                cp->pdid = NOPDID;
                    735:                bp = &cp->input;
                    736:                i = cp-sn_chans;
                    737:                bp->buf = sn_buffers[i].inbuf;
                    738:                bp->len = MAXMSGLEN;
                    739:                bp->done = 0;
                    740:                bp = &cp->output;
                    741:                bp->buf = sn_buffers[i].outbuf;
                    742:                bp->len = bp->done = 0;
                    743:                cp->flags = 0;
                    744:                cp->link = sninfop->snlink[mdev];
                    745:                sninfop->snlink[mdev] = cp;
                    746:                return(0);
                    747:            }
                    748: 
                    749:        case NIOXOPEN: {
                    750:                struct snmach *snmachp;
                    751:                struct openwait *nexthead, *thishead;
                    752: #ifdef BSD42
                    753:                struct oargs *args = (struct oargs *)addr;
                    754: #else
                    755:                struct oargs args;
                    756: 
                    757:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                    758:                        RETURN ( EFAULT );
                    759:                }
                    760: #endif
                    761:                for (;;) {
                    762:                        for (snmachp = &snmach[0];
                    763:                                        snmachp < &snmach[NUMDEV] &&
                    764:                                                snmachp->machno;
                    765:                                        snmachp++) {
                    766:                                spl6();
                    767:                                for (cp=sn_chans; cp<&sn_chans[NUMLCH]; cp++)
                    768:                                        if( cp->lchnum == -1 && 
                    769:                                                        cp->dlchnum == -1 )
                    770:                                                break;
                    771:                                if( cp >= &sn_chans[NUMLCH] ) {
                    772:                                        goto xopensleep;
                    773:                                }
                    774:                                for(dp=sn_chans; dp<&sn_chans[NUMLCH]; dp++) {
                    775:                                        if( dp->lchnum != -1
                    776:                                           && dp->lmachno == snmachp->lmachno
                    777:                                           && dp->lchnum == ARGS(lchno)
                    778:                                           && dp->snunit == unit ) {
                    779:                                                /* Channel already in use */
                    780:                                                break;
                    781:                                        }
                    782:                                }
                    783:                                if( dp >= &sn_chans[NUMLCH] ) 
                    784:                                        goto okmachp;
                    785:                                spl0();
                    786:                        }
                    787: xopensleep:
                    788:                        nexthead = ownext(sn_owhead);
                    789:                        if (nexthead == sn_owtail) {
                    790:                                RETURN ( ENXIO );
                    791:                        }
                    792:                        thishead = sn_owhead;
                    793:                        thishead->pid = u.u_procp->p_pid;
                    794:                        sn_owhead = nexthead;
                    795:                        sleep((caddr_t)thishead, SNPRI);
                    796:                }
                    797: okmachp:
                    798:                cp->lchnum = ARGS(lchno);
                    799:                cp->lmachno = snmachp->lmachno;
                    800:                spl0();
                    801:                cp->dlchnum = ARGS(dlchno);
                    802:                cp->machno = snmachp->machno;
                    803:                cp->xchan = (cp->lmachno<<8)|cp->lchnum;
                    804:                cp->snunit = unit;
                    805:                cp->pdid = NOPDID;
                    806:                bp = &cp->input;
                    807:                i = cp-sn_chans;
                    808:                bp->buf = sn_buffers[i].inbuf;
                    809:                bp->len = MAXMSGLEN;
                    810:                bp->done = 0;
                    811:                bp = &cp->output;
                    812:                bp->buf = sn_buffers[i].outbuf;
                    813:                bp->len = bp->done = 0;
                    814:                cp->flags = 0;
                    815:                cp->link = sninfop->snlink[mdev];
                    816:                sninfop->snlink[mdev] = cp;
                    817: 
                    818:                ARGS(lmachno) = snmachp->lmachno;
                    819:                ARGS(dmachno) = snmachp->machno;
                    820: #ifndef BSD42
                    821:                if (copyout((caddr_t)&args, addr, sizeof(args))) {
                    822:                        RETURN ( EFAULT );
                    823:                }
                    824: #endif
                    825:                return(0);
                    826:            }
                    827: 
                    828:        case NIOPOPEN: {
                    829: #ifdef BSD42
                    830:                struct voargs *args = (struct voargs *)addr;
                    831: #else
                    832:                struct voargs args;
                    833: 
                    834:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                    835:                        RETURN ( EFAULT );
                    836:                }
                    837: #endif
                    838:                spl6();
                    839:                for(cp=sn_chans; cp<&sn_chans[NUMLCH]; cp++)
                    840:                        if( cp->lchnum == -1 && cp->dlchnum == -1 )
                    841:                                break;
                    842:                if( cp >= &sn_chans[NUMLCH] ) {
                    843:                        spl0();
                    844:                        RETURN(  ENFILE );
                    845:                }
                    846:                for(dp=sn_chans; dp<&sn_chans[NUMLCH]; dp++)
                    847:                        if( dp->lchnum != -1 && dp->lmachno == ARGS(lmachno)
                    848:                           && dp->lchnum == ARGS(lchno)
                    849:                           && dp->snunit == unit ) {
                    850:                                spl0();
                    851:                                RETURN(  EEXIST );
                    852:                        }
                    853:                cp->lchnum = ARGS(lchno);
                    854:                cp->lmachno = ARGS(lmachno);
                    855:                spl0();
                    856:                cp->dlchnum = ARGS(dlchno);
                    857:                cp->machno = ARGS(dmachno);
                    858:                cp->xchan = (cp->lmachno<<8)|cp->lchnum;
                    859:                cp->snunit = unit;
                    860:                cp->pdid = ARGS(pdid);
                    861:                bp = &cp->input;
                    862:                i = cp-sn_chans;
                    863:                bp->buf = sn_buffers[i].inbuf;
                    864:                bp->len = MAXMSGLEN;
                    865:                bp->done = 0;
                    866:                bp = &cp->output;
                    867:                bp->buf = sn_buffers[i].outbuf;
                    868:                bp->len = bp->done = 0;
                    869:                cp->flags = 0;
                    870:                cp->link = sninfop->snlink[mdev];
                    871:                sninfop->snlink[mdev] = cp;
                    872:                return(0);
                    873:            }
                    874: 
                    875:        case NIOCLOSE: {
                    876: #ifdef BSD42
                    877:                struct cargs *args = (struct cargs *)addr;
                    878: #else
                    879:                struct cargs args;
                    880: 
                    881:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                    882:                        RETURN ( EFAULT );
                    883:                }
                    884: #endif
                    885:                for(cp=sninfop->snlink[mdev], dp=0; cp; dp=cp, cp=cp->link)
                    886:                        if( cp->lmachno == ARGS(lmachno)
                    887:                            && cp->lchnum == ARGS(lchno) ) {
                    888:                                /* TIMING !!! */
                    889:                                if( dp )
                    890:                                        dp->link = cp->link;
                    891:                                else
                    892:                                        sninfop->snlink[mdev] = cp->link;
                    893:                                chclose(cp);
                    894:                                return(0);
                    895:                        }
                    896:                RETURN( EBADF );
                    897:                }
                    898: 
                    899:        case NIOGET:
                    900:        case NIOPUT:
                    901:        {
                    902: #ifdef BSD42
                    903:                struct gpargs *args = (struct gpargs *)addr;
                    904: #else
                    905:                struct gpargs args;
                    906: 
                    907:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                    908:                        RETURN ( EFAULT );
                    909:                }
                    910: #endif
                    911:                status.lchdir = (cmd == NIOGET ? INPUT : OUTPUT);
                    912:                status.lchnum = ARGS(lch);
                    913:                ustatus = ARGS(status);
                    914:                usaddr = ARGS(addr);
                    915:                ulen = ARGS(len);
                    916:                for(cp=sninfop->snlink[mdev]; cp; cp=cp->link) {
                    917:                        if( cp->lchnum == ARGS(lch)
                    918:                            && cp->lmachno == ARGS(lmachno)) {
                    919: do_getput:
                    920:                                bp = (cmd == NIOGET ? &cp->input : &cp->output);
                    921:                                if( cmd == NIOPUT ) {
                    922:                                        copyin(usaddr, bp->buf, ulen);
                    923:                                        spl5();
                    924:                                        bp->len = (ulen+1)/2;
                    925:                                        snxstart(unit, cp, DATA);
                    926:                                        sninfop->snsdata++;
                    927:                                } else {
                    928:                                        spl5();
                    929:                                        /*
                    930:                                         * The following may be
                    931:                                         * unnecessary in light of
                    932:                                         * the later check.
                    933:                                         */
                    934:                                        if( bp->done == 0 && cp->flags&SENTRNR ) {
                    935:                                                cp->flags &= ~SENTRNR;
                    936:                                                cp->flags |= SENTRDY;
                    937:                                                snxstart(unit, cp, RDY);
                    938:                                                sninfop->sns1rdy++;
                    939:                                        }
                    940:                                }
                    941:                                for (;;) {
                    942:                                        spl5();
                    943:                                        if (bp->done) break;
                    944:                                        sleep((caddr_t)bp->buf, SNPRI);
                    945: #ifdef TIMEOUT
                    946:                                        spl6();
                    947:                                        if (cp->flags & RETRY) {
                    948:                                                cp->flags &= ~RETRY;
                    949:                                                sninfop->sntimeout++;
                    950:                                                snxstart(unit, cp, (cp->flags&SENTDATA) ? DATA : RDY);
                    951:                                        }
                    952: #endif TIMEOUT
                    953:                                }
                    954:                                status.code = ST_OK;
                    955:                                status.len = 2*bp->len;
                    956:                                if( cmd == NIOGET ) {
                    957:                                        spl0();
                    958:                                        copyout(bp->buf, usaddr, 2*bp->len);
                    959:                                        spl5();
                    960:                                        bp->len = MAXMSGLEN;
                    961:                                        /*
                    962:                                         * Believe it or not, we must check
                    963:                                         * this here.  This is because
                    964:                                         * we lowered the ipl to do the
                    965:                                         * copyout().  During that time
                    966:                                         * another message may have tried
                    967:                                         * to sneak in.
                    968:                                         */
                    969:                                        if( cp->flags&SENTRNR ) {
                    970:                                                cp->flags &= ~SENTRNR;
                    971:                                                snxstart(unit, cp, RDY);
                    972:                                                sninfop->snsrdy++;
                    973:                                        }
                    974:                                } else
                    975:                                        bp->len = 0;
                    976:                                bp->done = 0;
                    977:                                spl0();
                    978:                                error = 0;
                    979:                                goto cpyout;
                    980:                        }
                    981:                }
                    982:                status.code = ST_IARGS;
                    983:                error = EIO;
                    984: cpyout:
                    985:                copyout((caddr_t)&status, (caddr_t)ustatus, sizeof(status));
                    986:                RETURN ( error );
                    987:        }
                    988: 
                    989:        case NIOGETM:
                    990:        {
                    991:                struct pair pair;
                    992:                struct chdat *lchns[MAXMUX+1];
                    993:                register struct chdat **chp = lchns, **chpe = lchns;
                    994: #ifdef BSD42
                    995:                struct gmargs *args = (struct gmargs *)addr;
                    996: #else
                    997:                struct gmargs args;
                    998: 
                    999:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                   1000:                        RETURN ( EFAULT );
                   1001:                }
                   1002: #endif
                   1003:                status.lchdir = INPUT;
                   1004:                ustatus = ARGS(status);
                   1005:                usaddr = ARGS(addr);
                   1006:                ulen = ARGS(len);
                   1007:                for(i=0; i<MAXMUX; i++) {
                   1008:                        if (copyin((caddr_t)ARGS(pairp++), (caddr_t)&pair,
                   1009:                                        sizeof(struct pair))) {
                   1010:                                RETURN ( EFAULT );
                   1011:                        }
                   1012:                        if( pair.lchno == -1 )
                   1013:                                break;
                   1014:                        if (pair.lchno < 0 || pair.lchno >= 512
                   1015:                            || pair.lmachno < 0 || pair.lmachno >= 512) {
                   1016:                                RETURN ( EBADF );
                   1017:                        }
                   1018:                        for(cp=sninfop->snlink[mdev]; cp; cp=cp->link) {
                   1019:                                if( cp->lchnum == pair.lchno
                   1020:                                    && cp->lmachno == pair.lmachno ) {
                   1021:                                        *chpe++ = cp;
                   1022:                                        break;
                   1023:                                }
                   1024:                        }
                   1025:                        if( cp >= &sn_chans[NUMLCH] ) {
                   1026:                                RETURN ( EBADF );
                   1027:                        }
                   1028:                }
                   1029:                spl5();
                   1030:                for(chp=lchns; chp<chpe; chp++) {
                   1031:                        if( (*chp)->flags&MULTIPLEX ) {
                   1032:                                spl0();
                   1033:                                RETURN ( EBUSY );
                   1034:                        }
                   1035:                }
                   1036:                for(chp=lchns; chp<chpe; chp++)
                   1037:                        (*chp)->flags |= MULTIPLEX;
                   1038: 
                   1039: loop:
                   1040:                spl5();
                   1041:                for(chp=lchns; chp<chpe; chp++) {
                   1042:                        if( (*chp)->input.done ) {
                   1043:                                goto gotone;
                   1044:                        }
                   1045:                }
                   1046:                sleep((caddr_t)&sn_multiplex, SNPRI);
                   1047:                goto loop;
                   1048: 
                   1049: gotone:
                   1050:                cp = *chp;
                   1051:                for(chp=lchns; chp<chpe; chp++)
                   1052:                        (*chp)->flags &= ~MULTIPLEX;
                   1053:                spl0();
                   1054:                status.lchnum = cp->lchnum;
                   1055:                cmd = NIOGET;
                   1056:                goto do_getput;
                   1057:        }
                   1058: 
                   1059:        case NIOABORT:
                   1060:        case NIORESET: {
                   1061:                struct device *draddr;
                   1062: #ifndef USG5
                   1063:                struct uba_device *ui;
                   1064: #endif
                   1065: #ifdef BSD42
                   1066:                struct raargs *args = (struct raargs *)addr;
                   1067: #else
                   1068:                struct raargs args;
                   1069: 
                   1070:                if (copyin(addr, (caddr_t)&args, sizeof(args))) {
                   1071:                        RETURN ( EFAULT );
                   1072:                }
                   1073: #endif
                   1074: 
                   1075: #ifdef USG5
                   1076:                draddr = sn_addr[unit];
                   1077: #else
                   1078:                ui = sndinfo[unit];
                   1079:                draddr = (struct device *)ui->ui_addr;
                   1080: #endif
                   1081:                
                   1082:                spl5();
                   1083:                i = ARGS(machno) << 8;
                   1084:                draddr->drcs = CMD_MODE;
                   1085:                draddr->drout = (cmd == NIOABORT ? ABORT(i) : RESET(i));
                   1086:                draddr->drcs = EOP_MODE;
                   1087:                draddr->drout = 0;
                   1088:                draddr->drcs = DATA_MODE;
                   1089:                spl0();
                   1090:                return(0);
                   1091:        }
                   1092: 
                   1093:        case NIOREADSTATUS:
                   1094: #ifdef BSD42
                   1095:                copyout((caddr_t)sninfop, *(caddr_t *)addr, 
                   1096:                        sizeof sn_sninfo[0]);
                   1097: #else
                   1098:                copyout((caddr_t)sninfop, (caddr_t)addr, 
                   1099:                        sizeof sn_sninfo[0]);
                   1100: #endif
                   1101:                return(0);
                   1102: 
                   1103:        case NIOCHSTATUS: {
                   1104: 
                   1105:                struct chinfo chinfo;
                   1106: 
                   1107:                chinfo.numlch = NUMLCH;
                   1108:                chinfo.chanaddr = &sn_chans[0];
                   1109: #ifdef BSD42
                   1110:                copyout((caddr_t)&chinfo, *(caddr_t *)addr, 
                   1111:                        sizeof chinfo);
                   1112:                copyout((caddr_t)chinfo.chanaddr,
                   1113:                        (*(caddr_t *)addr)+sizeof chinfo,
                   1114:                        NUMLCH*sizeof sn_chans[0]);
                   1115: #else
                   1116:                copyout((caddr_t)&chinfo, (caddr_t)addr, 
                   1117:                        sizeof chinfo);
                   1118:                copyout((caddr_t)chinfo.chanaddr, 
                   1119:                        (caddr_t)(addr+sizeof chinfo), 
                   1120:                        NUMLCH*sizeof sn_chans[0]);
                   1121: #endif
                   1122:                return(0);
                   1123:        }
                   1124: 
                   1125:        case NIOSETMACH:
                   1126: #ifdef BSD42
                   1127:                copyin(*(caddr_t *)addr, (caddr_t)snmach, sizeof snmach);
                   1128: #else
                   1129:                copyin((caddr_t)addr, (caddr_t)snmach, sizeof snmach);
                   1130: #endif
                   1131:                return(0);
                   1132: 
                   1133: 
                   1134:        case NIOGETMACH:
                   1135: #ifdef BSD42
                   1136:                copyout((caddr_t)snmach, *(caddr_t *)addr, sizeof snmach);
                   1137: #else
                   1138:                copyout((caddr_t)snmach, (caddr_t)addr, sizeof snmach);
                   1139: #endif
                   1140:                return(0);
                   1141: 
                   1142: 
                   1143:        case NIOQSTATUS: {
                   1144:                struct openinfo openinfo;
                   1145: 
                   1146:                openinfo.owaddr = sn_openwait;
                   1147:                openinfo.head = sn_owhead;
                   1148:                openinfo.tail = sn_owtail;
                   1149: 
                   1150: #ifdef BSD42
                   1151:                copyout((caddr_t)&openinfo, *(caddr_t *)addr, sizeof openinfo);
                   1152:                copyout((caddr_t)sn_openwait, 
                   1153:                        (*(caddr_t *)addr)+sizeof openinfo,
                   1154:                        NUMDEV*sizeof sn_openwait[0]);
                   1155: #else
                   1156:                copyout((caddr_t)&openinfo, (caddr_t)addr, sizeof openinfo);
                   1157:                copyout((caddr_t)sn_openwait, (caddr_t)(addr+sizeof openinfo),
                   1158:                        NUMDEV*sizeof sn_openwait[0]);
                   1159: #endif
                   1160:                return(0);
                   1161:        }
                   1162: 
                   1163:        case NIOZEROSTAT:
                   1164:        {
                   1165: 
                   1166:                register char *p, *low, *high;
                   1167: 
                   1168:                low = (char *) &sn_sninfo[0];
                   1169: #ifdef USG5
                   1170:                high = low + sn_cnt*sizeof (struct sninfo);
                   1171: #else
                   1172:                high = low + NSN*sizeof (struct sninfo);
                   1173: #endif
                   1174: 
                   1175:                for (p=low; p<high; p++)
                   1176:                        *p = '\0';
                   1177:                return(0);
                   1178:        }
                   1179:        case NIOCHECK:
                   1180:        case NIOWAIT:
                   1181:        case NIOPURGE:
                   1182:        case NIOSETVEC:
                   1183:                ;
                   1184:        }
                   1185: }
                   1186: 
                   1187: static
                   1188: chclose(cp)
                   1189: register struct chdat *cp;
                   1190: {
                   1191:        cp->lchnum = cp->dlchnum = cp->machno = -1;
                   1192:        cp->flags = cp->xchan = cp->input.len = 0;
                   1193: }
                   1194: 
                   1195: #ifdef TIMEOUT
                   1196: cktimchk()
                   1197: {
                   1198:        register struct chdat *cp;
                   1199:        register struct sninfo *sninfop;
                   1200:        int unit;
                   1201:        int s;
                   1202: 
                   1203:        for(cp=sn_chans; cp < &sn_chans[NUMLCH]; cp++) {
                   1204:                if( cp->flags&(SENTDATA|SENTRDY) && --cp->ckticks == 0 ) {
                   1205:                        unit = cp->snunit;
                   1206:                        sninfop = &sn_sninfo[unit];
                   1207:                        sninfop->snsched++;
                   1208:                        sninfop->snenqlost[cp->machno]++;
                   1209:                        cp->flags |= RETRY;
                   1210:                        if (cp->flags & SENTDATA) {
                   1211:                                wakeup((caddr_t)cp->output.buf);
                   1212:                        } else {
                   1213:                                wakeup((caddr_t)cp->input.buf);
                   1214:                        }
                   1215:                }
                   1216:        }
                   1217:        s = spl6();
                   1218:        if (sn_state & OPEN) {
                   1219:                timeout(cktimchk, (caddr_t)0, CKTICKS);
                   1220:        } else {
                   1221:                sn_state &= ~TIMER;
                   1222:        }
                   1223:        splx(s);
                   1224: }
                   1225: #endif TIMEOUT
                   1226: 
                   1227: #endif

unix.superglobalmegacorp.com

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