Annotation of 40BSD/sys/dev/mx2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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