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

unix.superglobalmegacorp.com

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