Annotation of researchv8dc/sys/dev/sn.c, revision 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.