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

unix.superglobalmegacorp.com

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