Annotation of researchv10no/sys/io/dz.c, revision 1.1.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.