Annotation of 41BSD/4.0.upgrade/sys/dev/mx2.c, revision 1.1.1.1

1.1       root        1: /*     mx2.c   4.7     81/09/11        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/systm.h"
                      5: #include "../h/dir.h"
                      6: #include "../h/user.h"
                      7: #include "../h/proc.h"
                      8: #include "../h/tty.h"
                      9: #include "../h/inode.h"
                     10: #include "../h/mx.h"
                     11: #include "../h/file.h"
                     12: #include "../h/conf.h"
                     13: #include "../h/buf.h"
                     14: /*
                     15:  * multiplexor driver
                     16:  */
                     17: struct chan    chans[NCHANS];
                     18: struct group   *groups[NGROUPS];
                     19: int    mpxline;
                     20: 
                     21: short  cmask[16]       ={
                     22:        01,     02,     04,
                     23:        010,    020,    040,
                     24:        0100,   0200,   0400,
                     25:        01000,  02000,  04000,
                     26:        010000, 020000, 040000, 0100000
                     27: };
                     28: 
                     29: #define        IOMOVE  iomove
                     30: struct chan *xcp(),*addch(),*nextcp();
                     31: 
                     32: #define        HIQ     100
                     33: #define        LOQ     20
                     34: #define        FP      ((struct file *)cp)
                     35: 
                     36: char mcdebugs[NDEBUGS];
                     37: 
                     38: struct group *
                     39: getmpx(dev)
                     40: dev_t dev;
                     41: {
                     42:        register d;
                     43: 
                     44:        d = minor(dev);
                     45:        if (d >= NGROUPS) {
                     46:                u.u_error = ENXIO;
                     47:                return(NULL);
                     48:        }
                     49:        return(groups[d]);
                     50: }
                     51: 
                     52: 
                     53: /*ARGSUSED*/
                     54: mxopen(dev, flag)
                     55: {
                     56:        register struct group *gp;
                     57:        register struct file *fp;
                     58:        register struct chan *cp;
                     59:        int     msg;
                     60: 
                     61:        if ((gp=getmpx(dev)) == NULL) {
                     62:                return;
                     63:        }
                     64:        if (!(gp->g_state&INUSE)) {
                     65:                u.u_error = ENXIO;
                     66:                return;
                     67:        }
                     68:        fp = u.u_ofile[u.u_r.r_val1];
                     69:        if (fp->f_inode != gp->g_inode) {
                     70:                u.u_error = ENXIO;
                     71:                return;
                     72:        }
                     73:        if ((cp=addch(gp->g_inode,0)) == NULL) {
                     74:                u.u_error = ENXIO;
                     75:                return;
                     76:        }
                     77: 
                     78:        cp->c_flags = XGRP;
                     79:        cp->c_ottyp = cp->c_ttyp = (struct tty *)cp;
                     80:        cp->c_line = cp->c_oline = mpxline;
                     81: 
                     82:        fp->f_flag |= FMPY;
                     83:        fp->f_flag |= FREAD+FWRITE;
                     84:        fp->f_un.f_chan = cp;
                     85: 
                     86:        if (gp->g_inode == mpxip) {
                     87:                plock(mpxip);
                     88:                mpxname(cp);
                     89:                msg = M_OPEN;
                     90:        } else
                     91:                msg = M_WATCH;
                     92: 
                     93:        scontrol(cp, msg+(cp->c_index<<8), u.u_uid);
                     94:        sleep((caddr_t)cp,TTIPRI);
                     95:        if (cp->c_flags&NMBUF)
                     96:                prele(mpxip);
                     97:        if (cp->c_flags & WCLOSE) {
                     98:                chdrain(cp);
                     99:                chfree(cp);
                    100:                u.u_error = ENXIO;
                    101:                return;
                    102:        }
                    103:        cp->c_fy = fp;
                    104:        cp->c_pgrp = u.u_procp->p_pgrp;
                    105: }
                    106: 
                    107: 
                    108: char   mxnmbuf[NMSIZE];
                    109: int    nmsize;
                    110: 
                    111: mpxname(cp)
                    112: register struct chan *cp;
                    113: {
                    114:        register char *np;
                    115:        register c;
                    116: 
                    117:        np = mxnmbuf;
                    118:        u.u_dirp = (caddr_t)u.u_arg[0];
                    119:        
                    120:        while (np < &mxnmbuf[NMSIZE]) {
                    121:                c = uchar();
                    122:                if (c <= 0)
                    123:                        break;
                    124:                *np++ = c;
                    125:        }
                    126:        *np++ = '\0';
                    127:        nmsize = np - mxnmbuf;
                    128: 
                    129:        cp->c_flags |= NMBUF;
                    130: }
                    131: 
                    132: 
                    133: mxclose(dev, flag, fp)
                    134: dev_t  dev;
                    135: register struct file *fp;
                    136: {
                    137: register struct chan *cp = fp->f_un.f_chan;
                    138: register struct group *gp;
                    139: register struct inode *ip;
                    140: int    i, fmp;
                    141: 
                    142:        fmp = flag&FMP;
                    143:        if ((gp=getmpx(dev)) == NULL)
                    144:                return;
                    145: 
                    146:        ip = gp->g_inode;
                    147:        if (ip==NULL || (ip->i_mode&IFMT)!=IFMPC) {
                    148:                return;
                    149:        }
                    150: 
                    151:        /*
                    152:         * close a channel
                    153:         */
                    154:        if (cp!=NULL && fmp && fmp!=FMP) {
                    155:                for(fp=file; fp< fileNFILE; fp++)
                    156:                    if(fp->f_count && fp->f_flag&FMP && fp->f_un.f_chan==cp){
                    157:                                return;
                    158:                        }
                    159:                chdrain(cp);
                    160:                if ((cp->c_flags&WCLOSE)==0) {
                    161:                        scontrol(cp, M_CLOSE, 0);
                    162:                        cp->c_flags |= WCLOSE;
                    163:                } else {
                    164:                        chfree(cp);
                    165:                }
                    166:                goto out;
                    167:        }
                    168: 
                    169: 
                    170:        for(fp=file; fp < fileNFILE; fp++) {
                    171:                if (fp->f_count && (fp->f_flag&FMP)==FMP && fp->f_inode==ip)
                    172:                        return;
                    173:        }
                    174: 
                    175:        if (ip == mpxip) {
                    176:                mpxip = NULL;
                    177:                prele(ip);
                    178:        }
                    179: 
                    180:        for(i=0;i<NINDEX;i++)
                    181:                (void) detach(gp->g_chans[i]);
                    182: 
                    183: out:
                    184:        plock(ip);
                    185:        if (ip->i_count == 1) {
                    186:                groups[minor(dev)] = NULL;
                    187:                zero((caddr_t)gp, sizeof (struct group));
                    188:                ip->i_mode = IFREG + 0666;
                    189:                ip->i_un.i_rdev = 0;
                    190:                ip->i_flag |= IUPD|ICHG;
                    191:                iput(ip);
                    192:                return;
                    193:        }
                    194:        prele(ip);
                    195: }
                    196: 
                    197: zero(s, cc)
                    198: register char *s;
                    199: register cc;
                    200: {
                    201:        while (cc--)
                    202:                *s++ = 0;
                    203: }
                    204: 
                    205: char   m_eot[] ={ M_EOT, 0, 0, 0};
                    206: 
                    207: /*
                    208:  * Mxread + mxwrite are entered from cdevsw
                    209:  * for all read/write calls.  Operations on
                    210:  * an mpx file are handled here.
                    211:  * Calls are made through linesw to handle actual
                    212:  * data movement.
                    213:  */
                    214: mxread(dev)
                    215: {
                    216:        register struct group *gp;
                    217:        register struct chan *cp;
                    218:        register esc;
                    219:        struct rh h;
                    220:        caddr_t base;
                    221:        unsigned count;
                    222:        int s, xfr, more, fmp;
                    223: 
                    224:        if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) {
                    225:                u.u_error = ENXIO;
                    226:                return;
                    227:        }
                    228: 
                    229:        fmp = FP->f_flag & FMP;
                    230:        if (fmp != FMP) {
                    231:                if (u.u_count == 0)
                    232:                        return;
                    233:                msread(fmp, FP->f_un.f_chan);
                    234:                return;
                    235:        }
                    236: 
                    237:        if ((int)u.u_base & 1) {
                    238:                u.u_error = ENXIO;
                    239:                return;
                    240:        }
                    241: 
                    242:        s = spl6();
                    243:        if (u.u_count == 0)
                    244:        {
                    245:                if (gp->g_datq == 0)
                    246:                        u.u_error = ENXIO;
                    247:                splx(s);
                    248:                return;
                    249:        }
                    250:        while (gp->g_datq == 0) {
                    251:                sleep((caddr_t)&gp->g_datq, TTIPRI);
                    252:        }
                    253:        splx(s);
                    254: 
                    255:        while (gp->g_datq && u.u_count >= CNTLSIZ + 2) {
                    256:                esc = 0;
                    257:                cp = nextcp(gp);
                    258:                if (cp==NULL) {
                    259:                        continue;
                    260:                }
                    261:                h.index = cpx(cp);
                    262:                if (count = cp->c_ctlx.c_cc) {
                    263:                        count += CNTLSIZ;
                    264:                        if (cp->c_flags&NMBUF)
                    265:                                count += nmsize;
                    266:                        if (count > u.u_count) {
                    267:                                (void) sdata(cp);
                    268:                                return;
                    269:                        }
                    270:                        esc++;
                    271:                }
                    272:                base = u.u_base;
                    273:                count = u.u_count;
                    274:                u.u_base += sizeof h;
                    275:                u.u_count -= sizeof h;
                    276:                xfr = u.u_count;
                    277:                if (esc) {
                    278:                        more = mcread(cp);
                    279:                } else {
                    280:                        more = (*linesw[cp->c_line].l_read)(cp->c_ttyp);
                    281:                }
                    282:                if (more > 0)
                    283:                        (void) sdata(cp);
                    284:                if (more < 0)
                    285:                        scontrol(cp, M_CLOSE, 0);
                    286:                (void) spl0();
                    287:                if (xfr == u.u_count) {
                    288:                        esc++;
                    289:                        IOMOVE((caddr_t)m_eot, sizeof m_eot, B_READ);
                    290:                }
                    291:                xfr -= u.u_count;
                    292:                if (esc) {
                    293:                        h.count = 0;
                    294:                        h.ccount = xfr;
                    295:                } else {
                    296:                        h.count = xfr;
                    297:                        h.ccount = 0;
                    298:                        mxrstrt(cp, &cp->cx.datq, BLOCK|ALT);
                    299:                }
                    300:                if (u.u_count && (xfr&1)) {
                    301:                        u.u_base++;
                    302:                        u.u_count--;
                    303:                }
                    304:                (void) copyout((caddr_t)&h, base, sizeof h);
                    305: 
                    306:        }
                    307: }
                    308: 
                    309: 
                    310: mxwrite(dev)
                    311: {
                    312: register struct chan *cp;
                    313: struct wh h;
                    314: struct group *gp;
                    315: int    ucount, esc, fmp, burpcount;
                    316: caddr_t        ubase, hbase;
                    317: 
                    318:        if ((gp=getmpx(dev))==NULL || (FP=getf(u.u_arg[0]))==NULL) {
                    319:                return;
                    320:        }
                    321:        fmp = FP->f_flag & FMP;
                    322:        if (fmp != FMP) {
                    323:                mswrite(fmp, FP->f_un.f_chan);
                    324:                return;
                    325:        }
                    326: 
                    327:        burpcount = 0;
                    328:        while (u.u_count >= sizeof h) {
                    329:                hbase = u.u_base;
                    330:                IOMOVE((caddr_t)&h, sizeof h, B_WRITE);
                    331:                if (u.u_error)
                    332:                        return;
                    333:                esc = 0;
                    334:                if (h.count==0) {
                    335:                        esc++;
                    336:                        h.count = h.ccount;
                    337:                }
                    338:                cp = xcp(gp, h.index);
                    339:                if (cp==NULL || cp->c_flags&ISGRP) {
                    340:                        u.u_error = ENXIO;
                    341:                        return;
                    342:                }
                    343:                ucount = u.u_count;
                    344:                ubase = u.u_base;
                    345:                u.u_count = h.count;
                    346:                u.u_base = h.data;
                    347: 
                    348:                if (esc==0) {
                    349:                        struct tty *tp;
                    350:                        caddr_t waddr;
                    351:                        int line;
                    352: 
                    353:                        if (cp->c_flags&PORT) {
                    354:                                line = cp->c_line;
                    355:                                tp = cp->c_ttyp;
                    356:                        } else {
                    357:                                line = cp->c_oline;
                    358:                                tp = cp->c_ottyp;
                    359:                        }
                    360:                loop:
                    361:                        waddr = (caddr_t)(*linesw[line].l_write)(tp);
                    362:                        if (u.u_count) {
                    363:                                if (gp->g_state&ENAMSG) {
                    364:                                        burpcount++;
                    365:                                        cp->c_flags |= BLKMSG;
                    366: /*
                    367:                                        scontrol(cp, M_BLK, u.u_count);
                    368: */
                    369:                                        h.ccount = -1;
                    370:                                        h.count = u.u_count;
                    371:                                        h.data = u.u_base;
                    372:                                        (void) copyout((caddr_t)&h, hbase, sizeof h);
                    373:                                } else {
                    374:                                        if(waddr == 0) {
                    375:                                                u.u_error = ENXIO;
                    376:                                                return;
                    377:                                        }
                    378:                                        sleep(waddr, TTOPRI);
                    379:                                        goto loop;
                    380:                                }
                    381:                        }
                    382:                } else {
                    383:                        mxwcontrol(cp); 
                    384:                }
                    385:                u.u_count = ucount;
                    386:                u.u_base = ubase;
                    387:        }
                    388:        u.u_count = burpcount;
                    389: }
                    390: 
                    391: 
                    392: 
                    393: /*
                    394:  * Mcread and mcwrite move data on an mpx file.
                    395:  * Transfer addr and length is controlled by mxread/mxwrite.
                    396:  * Kernel-to-Kernel and other special transfers are not
                    397:  * yet in.
                    398:  */
                    399: mcread(cp)
                    400: register struct chan *cp;
                    401: {
                    402: register struct clist *q;
                    403: register char *np;
                    404: 
                    405: 
                    406:        q = (cp->c_ctlx.c_cc) ? &cp->c_ctlx : &cp->cx.datq;
                    407:        (void) mxmove(q, B_READ);
                    408: 
                    409:        if (cp->c_flags&NMBUF && q == &cp->c_ctlx) {
                    410:                np = mxnmbuf;
                    411:                while (nmsize--)
                    412:                        (void) passc(*np++);
                    413:                cp->c_flags &= ~NMBUF;
                    414:                prele(mpxip);
                    415:        }
                    416:        if (cp->c_flags&PORT)
                    417:                return(cp->c_ctlx.c_cc + cp->c_ttyp->t_rawq.c_cc); else
                    418:                return(cp->c_ctlx.c_cc + cp->cx.datq.c_cc);
                    419: 
                    420: }
                    421: 
                    422: 
                    423: caddr_t
                    424: mcwrite(cp)
                    425: register struct chan *cp;
                    426: {
                    427: register struct clist *q;
                    428: int    s;
                    429: 
                    430:        q = &cp->cy.datq;
                    431:        while (u.u_count) {
                    432:                s = spl6();
                    433:                if (q->c_cc > HIQ || (cp->c_flags&EOTMARK)) {
                    434:                        cp->c_flags |= SIGBLK;
                    435:                        splx(s);
                    436:                        break;
                    437:                }
                    438:                splx(s);
                    439:                (void) mxmove(q, B_WRITE);
                    440:        }
                    441:        wakeup((caddr_t)q);
                    442:        return((caddr_t)q);
                    443: }
                    444: 
                    445: 
                    446: /*
                    447:  * Msread and mswrite move bytes
                    448:  * between user and non-multiplexed channel.
                    449:  */
                    450: msread(fmp, cp)
                    451: register struct chan *cp;
                    452: {
                    453: register struct clist *q;
                    454: int s;
                    455: 
                    456:        q = (fmp&FMPX) ? &cp->cx.datq : &cp->cy.datq;
                    457:        s = spl6();
                    458:        while (q->c_cc == 0) {
                    459:                if (cp->c_flags&WCLOSE) {
                    460:                        u.u_error = ENXIO;
                    461:                        goto out;
                    462:                }
                    463:                if (cp->c_flags & EOTMARK) {
                    464:                        cp->c_flags &= ~EOTMARK;
                    465:                        if(msgenab(cp))
                    466:                                scontrol(cp, M_UBLK, 0);
                    467:                        else {
                    468:                                wakeup((caddr_t)cp);
                    469:                                wakeup((caddr_t)q);
                    470:                        }
                    471:                        goto out;
                    472:                }
                    473:                sleep((caddr_t)q,TTIPRI);
                    474:        }
                    475:        if (cp->c_flags&WCLOSE) {
                    476:                u.u_error = ENXIO;
                    477:                goto out;
                    478:        }
                    479:        splx(s);
                    480:        while (mxmove(q, B_READ) > 0)
                    481:                ;
                    482:        mxrstrt(cp, q, SIGBLK);
                    483:        return;
                    484: out:
                    485:        splx(s);
                    486: }
                    487: 
                    488: 
                    489: mswrite(fmp, cp)
                    490: register struct chan *cp;
                    491: {
                    492:        register struct clist *q;
                    493:        register int cc;
                    494: 
                    495:        q = (fmp&FMPX) ? &cp->cy.datq : &cp->cx.datq;
                    496:        while (u.u_count) {
                    497:                (void) spl6();
                    498:                if (cp->c_flags&WCLOSE) {
                    499:                        gsignal(cp->c_pgrp, SIGPIPE);
                    500:                        (void) spl0();
                    501:                        return;
                    502:                }
                    503:                if (q->c_cc>= HIQ || cp->c_flags&FBLOCK) {
                    504:                        if (cp->c_flags&WCLOSE) {
                    505:                                gsignal(cp->c_pgrp, SIGPIPE);
                    506:                                (void) spl0();
                    507:                                return;
                    508:                        }
                    509:                        (void) sdata(cp);
                    510:                        cp->c_flags |= BLOCK;
                    511:                        sleep((caddr_t)q+1,TTOPRI);
                    512:                        (void) spl0();
                    513:                        continue;
                    514:                }
                    515:                (void) spl0();
                    516:                cc = mxmove(q, B_WRITE);
                    517:                if (cc < 0)
                    518:                        break;
                    519:        }
                    520:        if (fmp&FMPX) {
                    521:                if (cp->c_flags&YGRP)  (void) sdata(cp);
                    522:                else                   wakeup((caddr_t)q);
                    523:        } else {
                    524:                if (cp->c_flags&XGRP)  (void) sdata(cp);
                    525:                else                   wakeup((caddr_t)q);
                    526:        }
                    527: }
                    528: 
                    529: 
                    530: /*
                    531:  * move chars between clist and user space.
                    532:  */
                    533: 
                    534: mxmove(q, dir)
                    535: register struct clist *q;
                    536: register dir;
                    537: {
                    538: register cc;
                    539: char cbuf[HIQ];
                    540: 
                    541:        cc = MIN(u.u_count, sizeof cbuf);
                    542:        if (dir == B_READ) 
                    543:                cc = q_to_b(q, cbuf, cc);
                    544:        if (cc <= 0)
                    545:                return(cc);
                    546:        IOMOVE((caddr_t)cbuf, (unsigned)cc, dir);
                    547:        if (dir == B_WRITE)
                    548:                cc = b_to_q(cbuf, cc, q);
                    549:        return(cc);
                    550: }
                    551: 
                    552: 
                    553: 
                    554: mxrstrt(cp, q, b)
                    555: register struct chan *cp;
                    556: register struct clist *q;
                    557: register b;
                    558: {
                    559: int s;
                    560: 
                    561:        s = spl6();
                    562:        if (cp->c_flags&b && q->c_cc<LOQ) {
                    563:                cp->c_flags &= ~b;
                    564:                if (b&ALT)
                    565:                        wakeup((caddr_t)q+1); else
                    566:                        if (b&(BLKMSG))
                    567:                                scontrol(cp, M_UBLK, 0); else
                    568:                                wakeup((caddr_t)q);
                    569:        }
                    570:        if (cp->c_flags&WFLUSH)
                    571:                wakeup((caddr_t)q+2);
                    572:        splx(s);
                    573: }
                    574: 
                    575: 
                    576: 
                    577: /*
                    578:  * called from driver start or xint routines
                    579:  * to wakeup output sleeper.
                    580:  */
                    581: mcstart(cp, q)
                    582: register struct chan *cp;
                    583: register caddr_t q;
                    584: {
                    585: 
                    586:        if (cp->c_flags&(BLKMSG)) {
                    587:                cp->c_flags &= ~BLKMSG;
                    588:                scontrol(cp, M_UBLK, 0);
                    589:        } else
                    590:                wakeup((caddr_t)q);
                    591: }
                    592: 
                    593: 
                    594: mxwcontrol(cp)
                    595: register struct chan *cp;
                    596: {
                    597: short cmd;
                    598: struct sgttyb vec;
                    599: int    s;
                    600: 
                    601:        IOMOVE((caddr_t)&cmd, sizeof cmd, B_WRITE);
                    602:        if (u.u_error)
                    603:                return;
                    604:        switch(cmd) {
                    605:        /*
                    606:         * not ready to queue this up yet.
                    607:         */
                    608:        case M_EOT:
                    609:                s = spl6();
                    610:                while (cp->c_flags & EOTMARK)
                    611:                        if(msgenab(cp)){
                    612:                                scontrol(cp, M_BLK, 0);
                    613:                                goto out;
                    614:                        } else
                    615:                                sleep((caddr_t)cp, TTOPRI);
                    616:                                cp->c_flags |= EOTMARK;
                    617:        out:
                    618:                wakeup((caddr_t)&cp->cy.datq);
                    619:                splx(s);
                    620:                break;
                    621:        case M_IOCTL:
                    622:                break;
                    623:        case M_IOANS:
                    624:                if (cp->c_flags&SIOCTL) {
                    625:                        IOMOVE((caddr_t)&vec, sizeof vec, B_WRITE);
                    626:                        (void) b_to_q((caddr_t)&vec, sizeof vec, &cp->c_ctly);
                    627:                        cp->c_flags &= ~SIOCTL;
                    628:                        wakeup((caddr_t)cp);
                    629:                }
                    630:                break;
                    631:        case M_BLK:
                    632:                cp->c_flags |= FBLOCK;
                    633:                break;
                    634:        case M_UBLK:
                    635:                cp->c_flags &= ~FBLOCK;
                    636:                chwake(cp);
                    637:                break;
                    638:        default:
                    639:                u.u_error = ENXIO;
                    640:        }
                    641: }
                    642: 
                    643: 
                    644: 
                    645: /*ARGSUSED*/
                    646: mxioctl(dev, cmd, addr, flag)
                    647: caddr_t addr;
                    648: {
                    649: struct group *gp;
                    650: int fmp;
                    651: struct file *fp;
                    652: struct {
                    653:        short c_ctl;
                    654:        short c_cmd;
                    655:        struct sgttyb c_vec;
                    656: } ctlbuf;
                    657: 
                    658:        if ((gp=getmpx(dev))==NULL || (fp=getf(u.u_arg[0]))==NULL) {
                    659:                return;
                    660:        }
                    661: 
                    662:        fmp = fp->f_flag & FMP;
                    663:        if (fmp == FMP) {
                    664:                switch(cmd) {
                    665: 
                    666:                case MXLSTN:
                    667:                        if (mpxip == NULL) {
                    668:                                mpxip = gp->g_inode;
                    669:                        } else {
                    670:                                u.u_error = ENXIO;
                    671:                                return;
                    672:                        }
                    673:                        break;
                    674: 
                    675:                case MXNBLK:
                    676:                        gp->g_state |= ENAMSG;
                    677:                        break;
                    678: 
                    679:                default:
                    680:                        u.u_error = ENXIO;
                    681:                        return;
                    682:                }
                    683:        } else {
                    684:                ctlbuf.c_ctl = M_IOCTL;
                    685:                ctlbuf.c_cmd = cmd;
                    686:                (void) copyin(addr, (caddr_t)&ctlbuf.c_vec, sizeof (struct sgttyb));
                    687:                sioctl(fp->f_un.f_chan, (char *)&ctlbuf, sizeof ctlbuf);
                    688:                (void) copyout((caddr_t)&ctlbuf, addr, sizeof (struct sgttyb));
                    689:        }
                    690: }
                    691: 
                    692: 
                    693: chdrain(cp)
                    694: register struct chan *cp;
                    695: {
                    696: register struct tty *tp;
                    697: int wflag;
                    698: 
                    699:        chwake(cp);
                    700: 
                    701:        wflag = (cp->c_flags&WCLOSE)==0;
                    702:        tp = cp->c_ttyp;
                    703:        if (tp == NULL)         /* prob not required */
                    704:                return;
                    705:        if (cp->c_flags&PORT && tp->t_chan == cp) {
                    706:                cp->c_ttyp = NULL;
                    707:                tp->t_chan = NULL;
                    708:                return;
                    709:        }
                    710:        if (wflag) 
                    711:                wflush(cp,&cp->cx.datq); else
                    712:                flush(&cp->cx.datq);
                    713:        if (!(cp->c_flags&YGRP)) {
                    714:                flush(&cp->cy.datq);
                    715:        }
                    716: }
                    717: 
                    718: chwake(cp)
                    719: register struct chan *cp;
                    720: {
                    721: register char *p;
                    722: 
                    723:        wakeup((caddr_t)cp);
                    724:        flush(&cp->c_ctlx);
                    725:        p = (char *)&cp->cx.datq;
                    726:        wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p);
                    727:        p = (char *)&cp->cy.datq;
                    728:        wakeup((caddr_t)p); wakeup((caddr_t)++p); wakeup((caddr_t)++p);
                    729: }
                    730: 
                    731: 
                    732: chfree(cp)
                    733: register struct chan *cp;
                    734: {
                    735: register struct group *gp;
                    736: register i;
                    737: 
                    738:        gp = cp->c_group;
                    739:        if (gp==NULL)
                    740:                return;
                    741:        i = cp->c_index;
                    742:        if (cp == gp->g_chans[i]) {
                    743:                gp->g_chans[i] = NULL;
                    744:        }
                    745:        cp->c_group = NULL;
                    746:        wakeup((caddr_t)gp);
                    747: }
                    748: 
                    749: 
                    750: flush(q)
                    751: register struct clist *q;
                    752: {
                    753: 
                    754:        while(q->c_cc)
                    755:                (void) getc(q);
                    756: }
                    757: 
                    758: 
                    759: wflush(cp,q)
                    760: register struct chan *cp;
                    761: register struct clist *q;
                    762: {
                    763: register s;
                    764: 
                    765:        s = spl6();
                    766:        if(q->c_cc && (cp->c_flags&WCLOSE) == 0) {
                    767:                cp->c_flags |= WFLUSH;
                    768:                (void) sdata(cp);
                    769:                (void) tsleep((caddr_t)q+2, TTOPRI, 30);
                    770:        }
                    771:        flush(q);
                    772:        cp->c_flags &= ~WFLUSH;
                    773:        splx(s);
                    774: }
                    775: 
                    776: 
                    777: scontrol(cp,event,value)
                    778: register struct chan *cp;
                    779: short event,value;
                    780: {
                    781: register struct clist *q;
                    782: int s;
                    783: 
                    784:        q = &cp->c_ctlx;
                    785:        s = spl6();
                    786:        if (sdata(cp) == NULL)
                    787:                return;
                    788:        (void) putw(event,q);
                    789:        (void) putw(value,q);
                    790:        splx(s);
                    791: }
                    792: 
                    793: 
                    794: 
                    795: sioctl(cp, vec, cc)
                    796: register struct chan *cp;
                    797: char *vec;
                    798: {
                    799: register s;
                    800: register struct clist *q;
                    801: 
                    802:        s = spl6();
                    803:        q = &cp->cx.datq;
                    804:        while (q->c_cc) {
                    805:                cp->c_flags |= BLOCK;
                    806:                if (sdata(cp)==NULL) {
                    807:                        u.u_error = ENXIO;
                    808:                        return;
                    809:                }
                    810:                sleep((caddr_t)q+1, TTOPRI);
                    811:        }
                    812:        (void) b_to_q(vec, cc, &cp->c_ctlx);
                    813:        cp->c_flags |= SIOCTL;
                    814:        while (cp->c_flags&SIOCTL) {
                    815:                if (cp->c_ctlx.c_cc)
                    816:                        if (sdata(cp)==NULL) {
                    817:                                u.u_error = ENXIO;
                    818:                                return;
                    819:                        }
                    820:                sleep((caddr_t)cp, TTOPRI);
                    821:        }
                    822:        (void) q_to_b(&cp->c_ctly, vec, cp->c_ctly.c_cc);
                    823:        splx(s);
                    824: }
                    825: 
                    826: sdata(cp)
                    827: struct chan *cp;
                    828: {
                    829:        register struct group *gp = (struct group *)cp;
                    830:        register struct group *ngp;
                    831:        register int    s;
                    832: 
                    833:        ngp = gp->g_group;
                    834:        if (ngp==NULL || (ngp->g_state&ISGRP)==0)
                    835:                return(NULL);
                    836: 
                    837:        s = spl6();
                    838:        do {
                    839:                ngp->g_datq |= cmask[gp->g_index];
                    840:                wakeup((caddr_t)&ngp->g_datq);
                    841:                gp = ngp;
                    842:        } while(ngp=ngp->g_group);
                    843:        splx(s);
                    844:        return((int)gp);
                    845: }
                    846: 
                    847: 
                    848: 
                    849: struct chan *
                    850: xcp(gp, x)
                    851: register struct group *gp;
                    852: register short x;
                    853: {
                    854:        register int i;
                    855: 
                    856:        while (gp->g_group) gp=gp->g_group;
                    857:        for (i=0;i<NLEVELS;i++) {
                    858:                if ((x&017) >= NINDEX)
                    859:                        break;
                    860:                if (gp==NULL || (gp->g_state&ISGRP)==0)
                    861:                        return((struct chan *)NULL);
                    862:                gp = (struct group *)gp->g_chans[x&017];
                    863:                x >>= 4;
                    864:        }
                    865:        return((struct chan *)gp);
                    866: }
                    867: 
                    868: cpx(cp)
                    869: register struct chan *cp;
                    870: {
                    871:        register x;
                    872:        register struct group *gp;
                    873: 
                    874:        x = (-1<<4) + cp->c_index;
                    875:        gp = cp->c_group;
                    876:        while (gp->g_group) {
                    877:                x <<= 4;
                    878:                x |= gp->g_index;
                    879:                gp = gp->g_group;
                    880:        }
                    881:        return(x);
                    882: }
                    883: 
                    884: 
                    885: struct chan *
                    886: nextcp(gp)
                    887: register struct group *gp;
                    888: {
                    889:        register struct group *lgp, *ngp;
                    890: 
                    891:        do {
                    892:                while ((gp->g_datq & cmask[gp->g_rot]) == 0) {
                    893:                        gp->g_rot = (gp->g_rot+1)%NINDEX;
                    894:                }
                    895:                lgp = gp;
                    896:                gp = (struct group *)gp->g_chans[gp->g_rot];
                    897:        } while (gp!=NULL && gp->g_state&ISGRP);
                    898: 
                    899:        lgp->g_datq &= ~cmask[lgp->g_rot];
                    900:        lgp->g_rot  =  (lgp->g_rot+1)%NINDEX;
                    901: 
                    902:        while (ngp=lgp->g_group) {
                    903:                ngp->g_datq &= ~cmask[lgp->g_index];
                    904:                if (ngp->g_datq)
                    905:                        break;
                    906:                lgp = ngp;
                    907:        }
                    908:        return((struct chan *)gp);
                    909: }
                    910: 
                    911: 
                    912: 
                    913: msgenab(cp)
                    914: register struct chan *cp;
                    915: {
                    916:        register struct group *gp;
                    917: 
                    918:        for(gp=cp->c_group;gp;gp=gp->g_group)
                    919:                if(gp->g_state & ENAMSG)return(1);
                    920:        return(0);
                    921: }

unix.superglobalmegacorp.com

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