Annotation of researchv10no/sys/io/dz.c, revision 1.1

1.1     ! root        1: /*
        !             2:  *  DZ-11 Driver
        !             3:  */
        !             4: 
        !             5: /* Modified 4/84 by J. Wolitzky to allow dialout operation with smart modems */
        !             6: 
        !             7: #define        TRC(c)
        !             8: 
        !             9: #include "sys/param.h"
        !            10: #include "sys/stream.h"
        !            11: #include "sys/ttyio.h"
        !            12: #include "sys/ttyld.h"
        !            13: #include "sys/ubaddr.h"
        !            14: #include "sys/dz.h"
        !            15: #include "sys/conf.h"
        !            16: 
        !            17: #define        LPB     8       /* lines per board */
        !            18: #define        BOARD(d)        ((d)>>3)
        !            19: #define        LINE(d)         ((d)&07)
        !            20: 
        !            21: #define BITS7  020
        !            22: #define BITS8  030
        !            23: #define TWOSB  040
        !            24: #define PENABLE        0100
        !            25: #define OPAR   0200
        !            26: #define        CLR     020             /* Clear */
        !            27: #define MSE    040             /* Master Scan Enable */
        !            28: #define RIE    0100            /* Receiver Interrupt Enable */
        !            29: #define        SAE     010000          /* Silo Alarm Enable */
        !            30: #define TIE    040000          /* Transmit Interrupt Enable */
        !            31: #define        TRDY    0100000         /* Transmitter ready */
        !            32: #define DZ_IEN (MSE+RIE+TIE)
        !            33: #define PERROR 010000
        !            34: #define FRERROR        020000
        !            35: #define        OVERRUN 040000
        !            36: #define SSPEED B1200           /* std speed = 1200 baud */
        !            37: 
        !            38: #define        ISOPEN  02
        !            39: #define        WOPEN   04
        !            40: #define        TIMEOUT 010
        !            41: #define        CARR_ON 020
        !            42: #define        DZSTOP  040
        !            43: #define        HPCL    0100
        !            44: #define        BRKING  0200
        !            45: #define        DIALOUT 0400    /* set when used as dialout with smart modems */
        !            46: 
        !            47: #define        DZPRI   30
        !            48: 
        !            49: struct device {
        !            50:        short   dzcsr;
        !            51:        short   dzrbuf;
        !            52: #define        dzlpr   dzrbuf
        !            53:        char    dztcr;
        !            54:        char    dzdtr;
        !            55:        char    dztbuf;
        !            56: #define        dzrind  dztbuf
        !            57:        char    dzbrk;
        !            58: #define        dzmsr   dzbrk
        !            59: };
        !            60: 
        !            61: extern struct  dz dz[];                /* one per line */
        !            62: extern struct  ubaddr dzaddr[];        /* one per board */
        !            63: extern int dzcnt;              /* number of lines */
        !            64: int    dzoverrun;
        !            65: 
        !            66: char   dz_speeds[] = {
        !            67:        0, 020, 021, 022, 023, 024, 0, 025,
        !            68:        026, 027, 030, 032, 034, 036, 037, 0
        !            69: };
        !            70: 
        !            71: long   dzopen();
        !            72: int    dzclose(), dzoput();
        !            73: 
        !            74: static struct qinit dzrinit = { noput, NULL, dzopen, dzclose, 0, 0 };
        !            75:        struct qinit dzwinit = { dzoput, NULL, dzopen, dzclose, 200, 100 };
        !            76: struct streamtab dzinfo = { &dzrinit, &dzwinit };
        !            77: struct cdevsw dzcdev = cstrinit(&dzinfo);
        !            78: 
        !            79: int    dzmiss;
        !            80: 
        !            81: long
        !            82: dzopen(q, d)
        !            83: register struct queue *q;
        !            84: dev_t d;
        !            85: {
        !            86:        register dev;
        !            87:        register struct dz *dzp;
        !            88:        register int s;
        !            89:        static int onceinit = 0;
        !            90:  
        !            91:        dev = minor(d);
        !            92:        if (dev >= dzcnt)
        !            93:                return(0);
        !            94:        dzp = &dz[dev];
        !            95:        if ((dzp->addr = (struct device *)ubaddr(&dzaddr[BOARD(dev)])) == NULL
        !            96:        ||  ubbadaddr(dzaddr[BOARD(dev)].ubno, dzp->addr, sizeof(short))) {
        !            97:                printf("dz%d absent\n", BOARD(dev));
        !            98:                return (0);
        !            99:        }
        !           100:        dz[BOARD(dev)*LPB].addr = dzp->addr;    /* see intr code */
        !           101:        if (onceinit == 0) {
        !           102:                onceinit++;
        !           103:                dzscan((caddr_t)0);
        !           104:        }
        !           105:        dzp->board = BOARD(dev);
        !           106:        dzp->line = LINE(dev);
        !           107:        q->ptr = (caddr_t)dzp;
        !           108:        WR(q)->ptr = (caddr_t)dzp;
        !           109:        dzscan((caddr_t)1);                     /* update CARR_ON */
        !           110:        if ((dzp->state&ISOPEN)==0 || (dzp->state&CARR_ON)==0) {
        !           111:                s = spl5();
        !           112:                for (;;) {
        !           113:                        dzp->flags = F8BIT|ODDP|EVENP;
        !           114:                        dzp->speed = SSPEED;
        !           115:                        dzparam(dzp);
        !           116:                        if (dzp->state & CARR_ON)
        !           117:                                break;
        !           118: #if NOTDEF
        !           119:                        dzflag = dzboard[BOARD(dev)]->ui_flags;
        !           120:                        /* ignore carrier? */
        !           121:                        if (dzflag & (1 << (LINE(dev)))) {
        !           122:                                dzp->state |= (DIALOUT | CARR_ON);
        !           123:                                break;
        !           124:                        }
        !           125: #endif
        !           126:                        if (tsleep((caddr_t)dzp, DZPRI, 0) != TS_OK) {
        !           127:                                wakeup((caddr_t)dzp);
        !           128:                                dzp->speed = 0;
        !           129:                                dzparam(dzp);
        !           130:                                splx(s);
        !           131:                                return(0);
        !           132:                        }
        !           133:                }
        !           134:                dzp->rdq = q;
        !           135:                dzp->state |= ISOPEN;
        !           136:                splx(s);
        !           137:        }
        !           138:        TRC('o');
        !           139:        return(1);
        !           140: }
        !           141: 
        !           142: dzclose(q)
        !           143: register struct queue *q;
        !           144: {
        !           145:        register struct dz *dzp;
        !           146:        register s;
        !           147: 
        !           148:        dzp = (struct dz *)q->ptr;
        !           149:        s = spl5();
        !           150:        if (dzp->oblock) {
        !           151:                register struct block *bp = dzp->oblock;
        !           152:                dzp->oblock = NULL;
        !           153:                freeb(bp);
        !           154:        }
        !           155:        flushq(WR(q), 1);
        !           156:        dzp->rdq = NULL;
        !           157:        if (dzp->state&HPCL || (dzp->state&CARR_ON)==0) {
        !           158:                dzp->speed = 0;
        !           159:                dzparam(dzp);
        !           160:        }
        !           161:        dzp->state = 0;
        !           162:        splx(s);
        !           163:        TRC('c');
        !           164: }
        !           165: 
        !           166: /*
        !           167:  * DZ write put routine
        !           168:  */
        !           169: dzoput(q, bp)
        !           170: register struct queue *q;
        !           171: register struct block *bp;
        !           172: {
        !           173:        register struct dz *dzp = (struct dz *)q->ptr;
        !           174:        register s;
        !           175:        register struct ttydevb *tb;
        !           176:        register delaytime;
        !           177: 
        !           178:        TRC('p');
        !           179:        switch(bp->type) {
        !           180: 
        !           181:        case M_IOCTL:
        !           182:                TRC('i');
        !           183:                switch (stiocom(bp)) {
        !           184: 
        !           185:                case TIOCSDEV:
        !           186:                        tb = (struct ttydevb *)stiodata(bp);
        !           187:                        delaytime = 0;
        !           188:                        if (dzp->speed != tb->ispeed)
        !           189:                                delaytime = 20;
        !           190:                        dzp->speed = tb->ispeed;
        !           191:                        dzp->flags = tb->flags;
        !           192:                        bp->type = M_IOCACK;
        !           193:                        bp->wptr = bp->rptr;
        !           194:                        qreply(q, bp);
        !           195:                        qpctl1(q, M_DELAY, delaytime);  /* wait a bit */
        !           196:                        qpctl(q, M_CTL);                /* means do dzparam */
        !           197:                        dzstart(dzp);
        !           198:                        return;
        !           199: 
        !           200:                case TIOCGDEV:
        !           201:                        tb = (struct ttydevb *)stiodata(bp);
        !           202:                        tb->ispeed = tb->ospeed = dzp->speed;
        !           203:                        tb->flags = dzp->flags;
        !           204:                        bp->wptr = bp->rptr + sizeof(struct ttydevb) + STIOCHDR;
        !           205:                        bp->type = M_IOCACK;
        !           206:                        qreply(q, bp);
        !           207:                        return;
        !           208: 
        !           209:                case TIOCHPCL:
        !           210:                        dzp->state |= HPCL;
        !           211:                        bp->type = M_IOCACK;
        !           212:                        bp->wptr = bp->rptr;
        !           213:                        qreply(q, bp);
        !           214:                        return;
        !           215: 
        !           216:                default:
        !           217:                        bp->wptr = bp->rptr;
        !           218:                        bp->type = M_IOCNAK;
        !           219:                        qreply(q, bp);
        !           220:                        return;
        !           221:                }
        !           222: 
        !           223:        case M_STOP:
        !           224:                s = spl5();
        !           225:                dzp->state |= DZSTOP;
        !           226:                freeb(bp);
        !           227:                if (bp = dzp->oblock) {
        !           228:                        dzp->oblock = NULL;
        !           229:                        putbq(q, bp);
        !           230:                }
        !           231:                splx(s);
        !           232:                return;
        !           233: 
        !           234:        case M_START:
        !           235:                dzp->state &= ~DZSTOP;
        !           236:                dzstart(dzp);
        !           237:                break;
        !           238: 
        !           239:        case M_FLUSH:
        !           240:                flushq(q, 1);
        !           241:                freeb(bp);
        !           242:                s = spl5();
        !           243:                if (bp = dzp->oblock) {
        !           244:                        dzp->oblock = NULL;
        !           245:                        freeb(bp);
        !           246:                }
        !           247:                splx(s);
        !           248:                return;
        !           249: 
        !           250:        case M_BREAK:
        !           251:                qpctl1(q, M_DELAY, 10);
        !           252:                putq(q, bp);
        !           253:                qpctl1(q, M_DELAY, 10);
        !           254:                dzstart(dzp);
        !           255:                return;
        !           256: 
        !           257:        case M_HANGUP:
        !           258:                dzp->state &= ~DZSTOP;
        !           259:        case M_DELAY:
        !           260:        case M_DATA:
        !           261:                putq(q, bp);
        !           262:                TRC('d');
        !           263:                dzstart(dzp);
        !           264:                return;
        !           265: 
        !           266:        default:                /* not handled; just toss */
        !           267:                break;
        !           268:        }
        !           269:        freeb(bp);
        !           270: }
        !           271:  
        !           272: /*
        !           273:  * Receive interrupt.  Argument is DZ board number
        !           274:  */
        !           275: dz0int(dev)
        !           276: {
        !           277:        register struct dz *dzp;
        !           278:        register struct block *bp;
        !           279:        register struct device *dzaddr;
        !           280:        register int c;
        !           281:  
        !           282:        if (dev >= BOARD(dzcnt)) {
        !           283:                printf("dz%d bad rcv int\n", dev);
        !           284:                return;
        !           285:        }
        !           286:        dzaddr = dz[dev*LPB].addr;
        !           287:        while ((c = dzaddr->dzrbuf) < 0) {      /* char present */
        !           288:                dzp = &dz[dev*LPB + ((c>>8)&07)];
        !           289:                if (c&(OVERRUN/*|PERROR*/)) {
        !           290:                        if (c&OVERRUN)
        !           291:                                dzoverrun++;
        !           292:                        continue;
        !           293:                }
        !           294:                if (dzp->rdq == NULL)
        !           295:                        continue;
        !           296:                if (dzp->rdq->next->flag&QFULL) {
        !           297:                        dzmiss++;
        !           298:                        continue;
        !           299:                }
        !           300:                if ((bp = allocb(16)) == NULL)
        !           301:                        continue;                       /* no space */
        !           302:                if (c&FRERROR)                  /* frame err (break) */
        !           303:                        bp->type = M_BREAK;
        !           304:                else
        !           305:                        *bp->wptr++ = c;
        !           306:                (*dzp->rdq->next->qinfo->putp)(dzp->rdq->next, bp);
        !           307:        }
        !           308: }
        !           309:  
        !           310: /*
        !           311:  * set device parameters
        !           312:  */
        !           313: dzparam(dzp)
        !           314: register struct dz *dzp;
        !           315: {
        !           316:        register short lpr;
        !           317:        register struct device *dzaddr;
        !           318: 
        !           319:        dzaddr = dzp->addr; 
        !           320:        dzaddr->dzcsr = DZ_IEN;
        !           321:        if (dzp->speed == 0) {
        !           322:                dzaddr->dzdtr &= ~(1 << dzp->line);     /* hang up */
        !           323:                return;
        !           324:        }
        !           325:        dzaddr->dzdtr |= 1 << dzp->line;
        !           326:        lpr = (dz_speeds[dzp->speed]<<8) | dzp->line;
        !           327:        if (dzp->flags & F8BIT)
        !           328:                lpr |= BITS8;
        !           329:        else
        !           330:                lpr |= (BITS7|PENABLE);
        !           331:        if ((dzp->flags & EVENP) == 0)
        !           332:                lpr |= OPAR;
        !           333:        if (dzp->speed == 3)
        !           334:                lpr |= TWOSB;                   /* 110 baud: 2 stop bits */
        !           335:        dzaddr->dzlpr = lpr;
        !           336: }
        !           337:  
        !           338: /*
        !           339:  * Transmitter interrupt. dev is board number.
        !           340:  */
        !           341: dz1int(dev)
        !           342: {
        !           343:        register struct device *dzaddr;
        !           344:        register struct dz *dzp;
        !           345:        register struct block *bp;
        !           346:        register sts;
        !           347:  
        !           348:        if (dev >= BOARD(dzcnt)) {
        !           349:                printf("dz%d bad xmt int\n", dev);
        !           350:                return;
        !           351:        }
        !           352:        dzaddr = dz[dev*LPB].addr;
        !           353:        while ((sts = dzaddr->dzcsr) & TRDY) {
        !           354:                dzp = &dz[dev*LPB + ((sts>>8)&07)];
        !           355:                if (bp = dzp->oblock) {
        !           356:                        if (bp->rptr < bp->wptr) {
        !           357:                                dzaddr->dztbuf = *bp->rptr++;
        !           358:                                continue;
        !           359:                        }
        !           360:                        freeb(bp);
        !           361:                        dzp->oblock = NULL;
        !           362:                }
        !           363:                dzaddr->dztcr &= ~(1 << (dzp->line));
        !           364:                dzstart(dzp);
        !           365:        }
        !           366: }
        !           367: 
        !           368: dztimo(dzp)
        !           369: register struct dz *dzp;
        !           370: {
        !           371:        if (dzp->state&BRKING) {
        !           372:                dzp->brking &= ~(1 << dzp->line);
        !           373:                dzp->addr->dzbrk = dzp->brking;
        !           374:        }
        !           375:        dzp->state &= ~(TIMEOUT|BRKING);
        !           376:        dzstart(dzp);
        !           377: }
        !           378: 
        !           379: dzstart(dzp)
        !           380: register struct dz *dzp;
        !           381: {
        !           382:        register s = spl5();
        !           383:        register struct block *bp;
        !           384:        register struct device *dzaddr;
        !           385:  
        !           386:        TRC('s');
        !           387: again:
        !           388:        if (dzp->state & (TIMEOUT|DZSTOP|BRKING) || dzp->oblock) {
        !           389:                TRC('t');
        !           390:                goto out;
        !           391:        }
        !           392:        if (dzp->rdq == NULL)
        !           393:                goto out;
        !           394:        if ((bp = getq(WR(dzp->rdq))) == NULL) {
        !           395:                TRC('n');
        !           396:                goto out;
        !           397:        }
        !           398:        switch (bp->type) {
        !           399: 
        !           400:        case M_DATA:
        !           401:                dzp->oblock = bp;
        !           402:                dzaddr = dzp->addr;
        !           403:                dzaddr->dztcr |= 1 << (dzp->line);
        !           404:                break;
        !           405: 
        !           406:        case M_BREAK:
        !           407:                dzaddr = dzp->addr;
        !           408:                dzp->brking |= 1 << dzp->line;
        !           409:                dzaddr->dzbrk = dzp->brking;
        !           410:                dzp->state |= BRKING|TIMEOUT;
        !           411:                timeout(dztimo, (caddr_t)dzp, HZ/4);    /* about 250 ms */
        !           412:                freeb(bp);
        !           413:                break;
        !           414: 
        !           415:        case M_DELAY:
        !           416:                dzp->state |= TIMEOUT;
        !           417:                timeout(dztimo, (caddr_t)dzp, (int)*bp->rptr + 6);
        !           418:                freeb(bp);
        !           419:                break;
        !           420: 
        !           421:        case M_HANGUP:
        !           422:                dzp->speed = 0;
        !           423:        case M_CTL:
        !           424:                freeb(bp);
        !           425:                dzparam(dzp);
        !           426:                goto again;
        !           427: 
        !           428:        }
        !           429: out:
        !           430:        splx(s);
        !           431: }
        !           432:  
        !           433: dzscan(timo)
        !           434: caddr_t timo;
        !           435: {
        !           436:        register struct device *dzaddr;
        !           437:        register struct dz *dzp;
        !           438:        register i;
        !           439:  
        !           440:        for (i=0, dzp=dz; i<dzcnt; dzp++, i++) {
        !           441:                if (dzp->addr == 0)
        !           442:                        continue;
        !           443:                dzaddr = dzp->addr;
        !           444:                if (dzaddr->dzmsr & (1<<dzp->line)) {
        !           445:                        /* carrier present */
        !           446:                        if ((dzp->state & CARR_ON)==0)
        !           447:                                wakeup((caddr_t)dzp);
        !           448:                        dzp->state |= CARR_ON;
        !           449:                } else if ((dzp->state & CARR_ON) && !(dzp->state & DIALOUT)) {
        !           450:                        /* carrier lost */
        !           451:                        if (dzp->state&ISOPEN) {
        !           452:                                dzaddr->dzdtr &= ~(1<<dzp->line);
        !           453:                                if (dzp->rdq)
        !           454:                                        putctl(dzp->rdq->next,M_HANGUP);
        !           455:                        }
        !           456:                        dzp->state &= ~CARR_ON;
        !           457:                }
        !           458:        }
        !           459:        if (timo == 0)
        !           460:                timeout(dzscan, (caddr_t)0, 2*HZ);
        !           461: }

unix.superglobalmegacorp.com

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