Annotation of researchv9/sys/sundev/zs.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  ZS driver
                      3:  */
                      4: #include "zs.h"
                      5: #define        TRC(c)
                      6: 
                      7: #include "../h/param.h"
                      8: #include "../h/stream.h"
                      9: #include "../h/ttyio.h"
                     10: #include "../h/ttyld.h"
                     11: #include "../machine/pte.h"
                     12: #include "../h/map.h"
                     13: #include "../h/buf.h"
                     14: #include "../h/systm.h"
                     15: #include "../h/conf.h"
                     16: 
                     17: #include "../sundev/mbvar.h"
                     18: #include "../sundev/zsreg.h"
                     19: #include "../sundev/zscom.h"
                     20: #include "../sundev/zsvar.h"
1.1.1.2 ! root       21: #include "../sun/fbio.h"
1.1       root       22: 
                     23: #define        ZSWR1_INIT      (ZSWR1_SIE|ZSWR1_TIE|ZSWR1_RIE)
                     24: #define        ZS_ON   (ZSWR5_DTR|ZSWR5_RTS)
                     25: #define        ZS_OFF  0
                     26: 
                     27: #define        NZSLINE         (NZS*2)
                     28: #define        SSPEED          B9600           /* std speed = 9600 baud */
                     29: 
                     30: #define        EXISTS  01
                     31: #define        ISOPEN  02
                     32: #define        WOPEN   04
                     33: #define        TIMEOUT 010
                     34: #define        CARR_ON 020
                     35: #define        ZSSTOP  040
                     36: #define        HPCL    0100
                     37: #define        BRKING  0200
                     38: #define        DIALOUT 0400    /* set when used as dialout with smart modems */
                     39: 
                     40: #define        ZSPRI   30
                     41: 
                     42: /*
                     43:  * Modem control commands.
                     44:  */
                     45: #define        DMSET           0
                     46: #define        DMBIS           1
                     47: #define        DMBIC           2
                     48: #define        DMGET           3
                     49: 
                     50: /*
                     51:  * One structure per line.
                     52:  * Includes communication between H/W level 6 interrupts
                     53:  * and software interrupts
                     54:  */
                     55: #define ZSIBUFSZ       256
                     56: struct zsaline {
                     57: /* from v9 dz.c */
                     58:        short   state;
                     59:        short   flags;
                     60:        struct  block   *oblock;
                     61:        struct  queue   *rdq;
                     62:        char    speed;
                     63: /* from SUN zsasync.c */
                     64:        short   za_needsoft;            /* need for software interrupt */
                     65:        short   za_break;               /* break occurred */
                     66:        short   za_overrun;             /* overrun (either hw or sw) */
                     67:        short   za_ext;                 /* modem status change */
                     68:        short   za_work;                /* work to do */
                     69:        u_char  za_rr0;                 /* for break detection */
                     70:        u_char  za_ibuf[ZSIBUFSZ];      /* circular input buffer */
                     71:        short   za_iptr;                /* producing ptr for input */
                     72:        short   za_sptr;                /* consuming ptr for input */
                     73: /* additions */
                     74:        dev_t   za_dev;
                     75:        struct  zscom *za_addr;
                     76: } zsaline[NZSLINE];
                     77: 
                     78: extern int zssoftflags[NZSLINE];
                     79: 
                     80: int    zsopen(), zsclose(), zsoput(), nodev();
                     81: 
                     82: static struct qinit zsrinit = { nodev, NULL, zsopen, zsclose, 0, 0 };
                     83:        struct qinit zswinit = { zsoput, NULL, zsopen, zsclose, 200, 100 };
                     84: struct streamtab zsinfo = { &zsrinit, &zswinit };
                     85: 
                     86: 
                     87: #define        PCLK    (19660800/4)    /* basic clock rate for UARTs */
                     88: #define        ZSPEED(n)       ZSTimeConst(PCLK, n)
                     89: #define        NSPEED  16      /* max # of speeds */
                     90: u_short        zs_speeds[NSPEED] = {
                     91:        0,
                     92:        ZSPEED(50),
                     93:        ZSPEED(75),
                     94:        ZSPEED(110),
                     95: #ifdef lint
                     96:        ZSPEED(134),
                     97: #else
                     98:        ZSPEED(134.5),
                     99: #endif
                    100:        ZSPEED(150),
                    101:        ZSPEED(200),
                    102:        ZSPEED(300),
                    103:        ZSPEED(600),
                    104:        ZSPEED(1200),
                    105:        ZSPEED(1800),
                    106:        ZSPEED(2400),
                    107:        ZSPEED(4800),
                    108:        ZSPEED(9600),
                    109:        ZSPEED(19200),
                    110:        ZSPEED(38400),
                    111: };
                    112: 
                    113: int zsticks = 3;               /* polling frequency */
                    114: 
                    115: /*
                    116:  * The async zs protocol
                    117:  */
                    118: int    zsa_attach(), zsa_txint(), zsa_xsint(), zsa_rxint(), zsa_srint(),
                    119:        zsa_softint();
                    120: 
                    121: struct zsops zsops_async = {
                    122:        zsa_attach,
                    123:        zsa_txint,
                    124:        zsa_xsint,
                    125:        zsa_rxint,
                    126:        zsa_srint,
                    127:        zsa_softint,
                    128: };
                    129: 
                    130: zsa_attach(zs)
                    131:        register struct zscom *zs;
                    132: {
                    133:        register struct zsaline *za = &zsaline[zs->zs_unit];
                    134: 
                    135:        za->za_addr = zs;
                    136:        za->za_dev = zs->zs_unit;
                    137:        za->state = EXISTS;
                    138: }
                    139: 
                    140: /*
                    141:  * Get the current speed of the console and turn it into something
                    142:  * UNIX knows about - used to preserve console speed when UNIX comes up
                    143:  */
                    144: zsgetspeed(dev)
                    145:        dev_t dev;
                    146: {
                    147:        struct zscom *zs;
                    148:        register struct zsaline *za;
                    149:        int uspeed, zspeed;
                    150: 
                    151:        dev = minor(dev);
                    152:        if (dev >= NZSLINE)
                    153:                return(SSPEED);
                    154:        za = &zsaline[dev];
                    155:        zs = za->za_addr;
                    156:        zspeed = ZREAD(12);
                    157:        zspeed |= ZREAD(13) << 8;
                    158:        for (uspeed = 0; uspeed < NSPEED; uspeed++)
                    159:                if (zs_speeds[uspeed] == zspeed)
                    160:                        return (uspeed);
                    161:        return (SSPEED);
                    162: }
                    163: 
                    164: /*ARGSUSED*/
                    165: zsopen(q, d, flag)
                    166: register struct queue *q;
                    167: {
                    168:        register dev;
                    169:        register struct zsaline *za;
                    170:        struct zscom *zs;
                    171:        int s;
                    172:        static int first = 1;
                    173:        int zspoll();
                    174:  
                    175:        if (q->ptr)                     /* already attached */
                    176:                return(1);
                    177:        dev = minor(d);
                    178:        za = &zsaline[dev];
                    179:        if (dev >= NZSLINE || (za->state&EXISTS)==0)
                    180:                return(0);
                    181:        zs = za->za_addr;
                    182:        q->ptr = (caddr_t)za;
                    183:        WR(q)->ptr = (caddr_t)za;
                    184:        s = splzs();
                    185:        zs->zs_priv = (caddr_t)za;
                    186:        zsopinit(zs, &zsops_async);
                    187:        (void) splx(s);
                    188:        if (first) {
                    189:                first = 0;
                    190:                timeout(zspoll, (caddr_t)0, zsticks);
                    191:        }
                    192:        if ((za->state&ISOPEN)==0 || (za->state&CARR_ON)==0) {
                    193:                register s = spl5();
                    194:                /* clear any stale input */
                    195:                za->za_iptr = 0;
                    196:                za->za_sptr = 0;
                    197:                za->za_overrun = 0;
                    198:                zsmctl(zs, ZS_ON, DMSET);
                    199:                for (;;) {
                    200:                        za->flags = F8BIT|ODDP|EVENP;
                    201:                        if (zssoftflags[dev] & ZS_KBDMS)
                    202:                                za->speed = zsgetspeed(dev);
                    203:                        else
                    204:                                za->speed = SSPEED;
                    205:                        zsparam(za);
                    206:                        if (za->state & CARR_ON)
                    207:                                break;
                    208:                        /* ignore carrier? */
                    209:                        if (zssoftflags[dev] & 1) {
                    210:                                za->state |= (DIALOUT | CARR_ON);
                    211:                                break;
                    212:                        }
                    213:                        if (tsleep((caddr_t)za, ZSPRI, 0) != TS_OK) {
                    214:                                wakeup((caddr_t)za);
                    215:                                za->speed = 0;
                    216:                                zsparam(za);
                    217:                                splx(s);
                    218:                                return(0);
                    219:                        }
                    220:                }
                    221:                za->rdq = q;
                    222:                za->state |= ISOPEN;
                    223:                splx(s);
                    224:        }
                    225:        TRC('o');
                    226:        return(1);
                    227: }
                    228: 
                    229: zsclose(q, d)
                    230: register struct queue *q;
                    231: {
                    232:        register struct zsaline *za;
                    233:        register s;
                    234:        int s1;
                    235: 
                    236:        za = (struct zsaline *)q->ptr;
                    237:        s = spl5();
                    238:        s1 = splzs();
                    239:        if (za->oblock) {
                    240:                register struct block *bp = za->oblock;
                    241:                za->oblock = NULL;
                    242:                splx(s1);
                    243:                freeb(bp);
                    244:        }
                    245:        flushq(WR(q), 1);
                    246:        za->rdq = NULL;
                    247:        if (za->state&HPCL || (za->state&CARR_ON)==0) {
                    248:                za->speed = 0;
                    249:                zsparam(za);
                    250:        }
                    251:        za->state &= EXISTS;
                    252:        splx(s);
                    253:        TRC('c');
                    254: }
                    255: 
                    256: /*
                    257:  * ZS write put routine
                    258:  */
                    259: zsoput(q, bp)
                    260: register struct queue *q;
                    261: register struct block *bp;
                    262: {
                    263:        register struct zsaline *za = (struct zsaline *)q->ptr;
                    264:        register union stmsg *sp;
                    265:        register s;
                    266:        int s1;
                    267:        int delaytime;
                    268: 
                    269:        TRC('p');
                    270:        switch(bp->type) {
                    271: 
                    272:        case M_IOCTL:
                    273:                TRC('i');
                    274:                sp = (union stmsg *)bp->rptr;
                    275:                switch (sp->ioc0.com) {
                    276: 
                    277:                case TIOCSDEV:
                    278:                        delaytime = 0;
                    279:                        if (za->speed != sp->ioc3.sb.ispeed)
                    280:                                delaytime = 20;
                    281:                        za->speed = sp->ioc3.sb.ispeed;
                    282:                        za->flags = sp->ioc3.sb.flags;
                    283:                        bp->type = M_IOCACK;
                    284:                        bp->wptr = bp->rptr;
                    285:                        qreply(q, bp);
                    286:                        qpctl1(q, M_DELAY, delaytime);  /* wait a bit */
                    287:                        qpctl(q, M_CTL);                /* means do zsparam */
                    288:                        zsstart(za);
                    289:                        return;
                    290: 
                    291:                case TIOCGDEV:
                    292:                        sp->ioc3.sb.ispeed =
                    293:                          sp->ioc3.sb.ospeed = za->speed;
                    294:                        sp->ioc3.sb.flags = za->flags;
                    295:                        bp->type = M_IOCACK;
                    296:                        qreply(q, bp);
                    297:                        return;
                    298: 
                    299:                case TIOCHPCL:
                    300:                        za->state |= HPCL;
                    301:                        bp->type = M_IOCACK;
                    302:                        bp->wptr = bp->rptr;
                    303:                        qreply(q, bp);
                    304:                        return;
                    305: 
1.1.1.2 ! root      306:                case KBIOISKBD:
        !           307:                        s = za - zsaline;
        !           308:                        if ((zssoftflags[s] & ZS_KBDMS) && !(s & 1))
        !           309:                                bp->type = M_IOCACK;
        !           310:                        else
        !           311:                                bp->type = M_IOCNAK;
        !           312:                        bp->wptr = bp->rptr;
        !           313:                        qreply(q, bp);
        !           314:                        return;
        !           315:                
1.1       root      316:                default:
                    317:                        bp->wptr = bp->rptr;
                    318:                        bp->type = M_IOCNAK;
                    319:                        qreply(q, bp);
                    320:                        return;
                    321:                }
                    322: 
                    323:        case M_STOP:
                    324:                s = spl5();
                    325:                za->state |= ZSSTOP;
                    326:                freeb(bp);
                    327:                s1 = splzs();
                    328:                if (bp = za->oblock) {
                    329:                        za->oblock = NULL;
                    330:                        splx(s1);
                    331:                        putbq(q, bp);
                    332:                }
                    333:                splx(s);
                    334:                return;
                    335: 
                    336:        case M_START:
                    337:                za->state &= ~ZSSTOP;
                    338:                zsstart(za);
                    339:                break;
                    340: 
                    341:        case M_FLUSH:
                    342:                flushq(q, 1);
                    343:                freeb(bp);
                    344:                s = spl5();
                    345:                s1 = splzs();
                    346:                if (bp = za->oblock) {
                    347:                        za->oblock = NULL;
                    348:                        splx(s1);
                    349:                        freeb(bp);
                    350:                }
                    351:                splx(s);
                    352:                return;
                    353: 
                    354:        case M_BREAK:
                    355:                qpctl1(q, M_DELAY, 10);
                    356:                putq(q, bp);
                    357:                qpctl1(q, M_DELAY, 10);
                    358:                zsstart(za);
                    359:                return;
                    360: 
                    361:        case M_HANGUP:
                    362:                za->state &= ~ZSSTOP;
                    363:        case M_DELAY:
                    364:        case M_DATA:
                    365:                putq(q, bp);
                    366:                TRC('d');
                    367:                zsstart(za);
                    368:                return;
                    369: 
                    370:        default:                /* not handled; just toss */
                    371:                break;
                    372:        }
                    373:        freeb(bp);
                    374: }
                    375:  
                    376: /*
                    377:  * set device parameters
                    378:  */
                    379: zsparam(za)
                    380:        register struct zsaline *za;
                    381: {
                    382:        register struct zscom *zs = za->za_addr;
                    383:        register int wr1, wr3, wr4, wr5, speed;
                    384:        int loops;
                    385:        int s;
                    386:        char c;
                    387:  
                    388:        if (za->speed == 0) {
                    389:                (void) zsmctl(zs, ZS_OFF, DMSET);       /* hang up line */
                    390:                return;
                    391:        }
                    392:        wr1 = ZSWR1_INIT;
                    393:        wr3 = ZSWR3_RX_ENABLE;
                    394:        wr4 = ZSWR4_X16_CLK;
                    395:        wr5 = (zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR)) | ZSWR5_TX_ENABLE;
                    396:        if (za->speed == B134) {        /* what a joke! */
                    397:                wr1 |= ZSWR1_PARITY_SPECIAL;
                    398:                wr3 |= ZSWR3_RX_6;
                    399:                wr4 |= ZSWR4_PARITY_ENABLE | ZSWR4_PARITY_EVEN;
                    400:                wr5 |= ZSWR5_TX_6;
                    401:        } else if (za->flags&(F8BIT)) {
                    402:                wr3 |= ZSWR3_RX_8;
                    403:                wr5 |= ZSWR5_TX_8;
                    404:        } else switch (za->flags & (EVENP|ODDP)) {
                    405:        case 0:
                    406:                wr3 |= ZSWR3_RX_8;
                    407:                wr5 |= ZSWR5_TX_8;
                    408:                break;
                    409: 
                    410:        case EVENP:
                    411:                wr1 |= ZSWR1_PARITY_SPECIAL;
                    412:                wr3 |= ZSWR3_RX_7;
                    413:                wr4 |= ZSWR4_PARITY_ENABLE + ZSWR4_PARITY_EVEN;
                    414:                wr5 |= ZSWR5_TX_7;
                    415:                break;
                    416: 
                    417:        case ODDP:
                    418:                wr1 |= ZSWR1_PARITY_SPECIAL;
                    419:                wr3 |= ZSWR3_RX_7;
                    420:                wr4 |= ZSWR4_PARITY_ENABLE;
                    421:                wr5 |= ZSWR5_TX_7;
                    422:                break;
                    423: 
                    424:        case EVENP|ODDP:
                    425:                wr3 |= ZSWR3_RX_7;
                    426:                wr4 |= ZSWR4_PARITY_ENABLE + ZSWR4_PARITY_EVEN;
                    427:                wr5 |= ZSWR5_TX_7;
                    428:                break;
                    429:        }
                    430:        if (za->speed == B110)
                    431:                wr4 |= ZSWR4_2_STOP;
                    432:        else if (za->speed == B134)
                    433:                wr4 |= ZSWR4_1_5_STOP;
                    434:        else
                    435:                wr4 |= ZSWR4_1_STOP;
                    436:        speed = zs->zs_wreg[12] + (zs->zs_wreg[13] << 8);
                    437:        if (wr1 != zs->zs_wreg[1] || wr3 != zs->zs_wreg[3] ||
                    438:            wr4 != zs->zs_wreg[4] || wr5 != zs->zs_wreg[5] ||
                    439:            speed != zs_speeds[za->speed&017]) {
                    440:                /* 
                    441:                 * Wait for that last damn character to get out the
                    442:                 * door.  At most 1000 loops of 100 usec each is worst
                    443:                 * case of 110 baud.  If something appears on the output
                    444:                 * queue then somebody higher up isn't synchronized
                    445:                 * and we give up.
                    446:                 */
                    447:                s = splzs();
                    448:                loops = 1000;
                    449:                while ((ZREAD(1) & ZSRR1_ALL_SENT) == 0 && --loops > 0) {
                    450:                        (void) splx(s);
                    451:                        DELAY(100);
                    452:                        s = splzs();
                    453:                }
                    454:                ZWRITE(3, 0);   /* disable receiver while setting parameters */
                    455:                zs->zs_addr->zscc_control = ZSWR0_RESET_STATUS;
                    456:                zs->zs_addr->zscc_control = ZSWR0_RESET_ERRORS;
                    457:                c = zs->zs_addr->zscc_data; /* swallow junk */
                    458:                c = zs->zs_addr->zscc_data; /* swallow junk */
                    459:                c = zs->zs_addr->zscc_data; /* swallow junk */
                    460:                ZWRITE(1, wr1);
                    461:                ZWRITE(4, wr4);
                    462:                ZWRITE(3, wr3);
                    463:                ZWRITE(5, wr5);
                    464:                speed = zs_speeds[za->speed&017];
                    465:                ZWRITE(11, ZSWR11_TXCLK_BAUD + ZSWR11_RXCLK_BAUD);
                    466:                ZWRITE(14, ZSWR14_BAUD_FROM_PCLK);
                    467:                ZWRITE(12, speed);
                    468:                ZWRITE(13, speed >> 8);
                    469:                ZWRITE(14, ZSWR14_BAUD_ENA + ZSWR14_BAUD_FROM_PCLK);
                    470:                (void) splx(s);
                    471:        }
                    472: }
                    473:  
                    474: zstimo(za)
                    475: register struct zsaline *za;
                    476: {
                    477:        register struct zscom *zs = za->za_addr;
                    478:        int s;
                    479: 
                    480:        if (za->state&BRKING) {
                    481:                s =  splzs();
                    482:                ZBIC(5, ZSWR5_BREAK);
                    483:                splx(s);
                    484:        }
                    485:        za->state &= ~(TIMEOUT|BRKING);
                    486:        zsstart(za);
                    487: }
                    488: 
                    489: zsstart(za)
                    490: register struct zsaline *za;
                    491: {
                    492:        register struct zscom *zs = za->za_addr;
                    493:        register s = spl5();
                    494:        register struct block *bp;
                    495:        int s1;
                    496:  
                    497:        TRC('s');
                    498: again:
                    499:        if (za->state & (TIMEOUT|ZSSTOP|BRKING) || za->oblock) {
                    500:                TRC('t');
                    501:                goto out;
                    502:        }
                    503:        if (za->rdq == NULL)
                    504:                goto out;
                    505:        if ((bp = getq(WR(za->rdq))) == NULL) {
                    506:                TRC('n');
                    507:                goto out;
                    508:        }
                    509:        switch (bp->type) {
                    510: 
                    511:        case M_DATA:
                    512:                za->oblock = bp;
                    513:                if (zs->zs_addr->zscc_control & ZSRR0_TX_READY)
                    514:                        zs->zs_addr->zscc_data = *bp->rptr++;
                    515:                break;
                    516: 
                    517:        case M_BREAK:
                    518:                s1 = splzs();
                    519:                ZBIS(5, ZSWR5_BREAK);
                    520:                splx(s1);
                    521:                za->state |= BRKING|TIMEOUT;
                    522:                timeout(zstimo, (caddr_t)za, 15);       /* about 250 ms */
                    523:                freeb(bp);
                    524:                break;
                    525: 
                    526:        case M_DELAY:
                    527:                za->state |= TIMEOUT;
                    528:                timeout(zstimo, (caddr_t)za, (int)*bp->rptr + 6);
                    529:                freeb(bp);
                    530:                break;
                    531: 
                    532:        case M_HANGUP:
                    533:                za->speed = 0;
                    534:        case M_CTL:
                    535:                freeb(bp);
                    536:                zsparam(za);
                    537:                goto again;
                    538: 
                    539:        }
                    540: out:
                    541:        splx(s);
                    542: }
                    543:  
                    544: zsmctl(zs, bits, how)
                    545:        register struct zscom *zs;
                    546:        int bits, how;
                    547: {
                    548:        register int mbits, s;
                    549: 
                    550:        s = splzs();
                    551:        mbits = zs->zs_wreg[5] & (ZSWR5_RTS|ZSWR5_DTR);
                    552:        zs->zs_addr->zscc_control = ZSWR0_RESET_STATUS;
                    553:        DELAY(2);
                    554:        mbits |= zs->zs_addr->zscc_control & (ZSRR0_CD|ZSRR0_CTS);
                    555:        switch (how) {
                    556:        case DMSET:
                    557:                mbits = bits;
                    558:                break;
                    559: 
                    560:        case DMBIS:
                    561:                mbits |= bits;
                    562:                break;
                    563: 
                    564:        case DMBIC:
                    565:                mbits &= ~bits;
                    566:                break;
                    567: 
                    568:        case DMGET:
                    569:                (void) splx(s);
                    570:                return (mbits);
                    571:        }
                    572:        zs->zs_wreg[5] &= ~(ZSWR5_RTS|ZSWR5_DTR);
                    573:        ZBIS(5, mbits & (ZSWR5_RTS|ZSWR5_DTR));
                    574:        (void) splx(s);
                    575:        return (mbits);
                    576: }
                    577: 
                    578: zsa_txint(zs)
                    579:        register struct zscom *zs;
                    580: {
                    581:        register struct zsaline *za = (struct zsaline *)zs->zs_priv;
                    582:        register struct zscc_device *zsaddr = zs->zs_addr;
                    583:        register struct block *bp;
                    584: 
                    585:        if ((bp = za->oblock) && bp->rptr < bp->wptr &&
                    586:            (zsaddr->zscc_control & ZSRR0_TX_READY)) {
                    587:                zsaddr->zscc_data = *bp->rptr++;
                    588:        } else {
                    589:                za->za_work++;
                    590:                zsaddr->zscc_control = ZSWR0_RESET_TXINT;
                    591:                ZSSETSOFT(zs);
                    592:        }
                    593: }
                    594: 
                    595: zsa_xsint(zs)
                    596:        register struct zscom *zs;
                    597: {
                    598:        register struct zsaline *za = (struct zsaline *)zs->zs_priv;
                    599:        register struct zscc_device *zsaddr = zs->zs_addr;
                    600:        register u_char s0, x0, c;
                    601: 
                    602:        s0 = zsaddr->zscc_control;
                    603:        x0 = s0 ^ za->za_rr0;
                    604:        za->za_rr0 = s0;
                    605:        zsaddr->zscc_control = ZSWR0_RESET_STATUS;
                    606:        if ((x0 & ZSRR0_BREAK) && (s0 & ZSRR0_BREAK) == 0) {
                    607:                za->za_break++;
                    608:                c = zsaddr->zscc_data; /* swallow null */
                    609: #ifdef lint
                    610:                c = c;
                    611: #endif
                    612:                zsaddr->zscc_control = ZSWR0_RESET_ERRORS;
                    613: /*
                    614:                if (za->za_dev == kbddev)
                    615:                        montrap(*romp->v_abortent);
                    616: */
                    617:        }
                    618:        za->za_work++;
                    619:        za->za_ext++;
                    620:        ZSSETSOFT(zs);
                    621: }
                    622: 
1.1.1.2 ! root      623: zsa_rxint(zs, d0)
1.1       root      624:        register struct zscom *zs;
                    625: {
1.1.1.2 ! root      626:        struct lregs {
        !           627:                int r[4];       /* d0, d1, a0, a1 */
        !           628:                u_short sr;
        !           629:                int pc;
        !           630:        } *lp;
        !           631:        extern struct zscom zscom[];
1.1       root      632:        register struct zsaline *za = (struct zsaline *)zs->zs_priv;
                    633:        register struct zscc_device *zsaddr = zs->zs_addr;
                    634:        register u_char c;
                    635: 
                    636:        c = zsaddr->zscc_data;
1.1.1.2 ! root      637:        if (zs == &zscom[2] && c == 1) { /* A no nonsense abort */
        !           638:                lp = (struct lregs *)&d0;
        !           639:                printf("kernel aborted\n");
        !           640:                printf("pc = 0x%x, sr= 0x%x, &pc = 0x%x\n", lp->pc, lp->sr,
        !           641:                        (int)&lp->pc);
        !           642:                panic("abort");
        !           643:        }
1.1       root      644:        if (c == 0 && (za->za_rr0 & ZSRR0_BREAK))
                    645:                return;
                    646:        za->za_ibuf[za->za_iptr++] = c;
                    647:        if (za->za_iptr >= ZSIBUFSZ)
                    648:                za->za_iptr = 0;
                    649:        if (za->za_iptr == za->za_sptr)
                    650:                za->za_overrun++;
                    651:        za->za_work++;
                    652:        if (++za->za_needsoft > 20) {
                    653:                za->za_needsoft = 0;
                    654:                ZSSETSOFT(zs);
                    655:        }
                    656: }
                    657: 
                    658: zsa_srint(zs)
                    659:        register struct zscom *zs;
                    660: {
                    661:        register struct zsaline *za = (struct zsaline *)zs->zs_priv;
                    662:        register struct zscc_device *zsaddr = zs->zs_addr;
                    663:        register short s1;
                    664:        register u_char c;
                    665: 
                    666:        s1 = ZREAD(1);
                    667:        c = zsaddr->zscc_data;  /* swallow bad char */
                    668: #ifdef lint
                    669:        c = c;
                    670: #endif
                    671:        zsaddr->zscc_control = ZSWR0_RESET_ERRORS;
                    672:        if (s1 & ZSRR1_DO) {
                    673:                za->za_overrun++;
                    674:                za->za_work++;
                    675:                ZSSETSOFT(zs);
                    676:        }
                    677: }
                    678: /*
                    679:  * Handle a software interrupt 
                    680:  */
                    681: zsa_softint(zs)
                    682:        register struct zscom *zs;
                    683: {
                    684:        register struct zsaline *za = (struct zsaline *)zs->zs_priv;
                    685: 
                    686:        if (zsa_process(za))    /* true if too much work at once */
                    687:                zspoll(1);
                    688:        return (0);
                    689: }
                    690: 
                    691: /*
                    692:  * Poll for events in the zscom structures
                    693:  * This routine is called at level 1, we jack up to 3 to lock
                    694:  * out zsa_softint.
                    695:  */
                    696: zspoll(direct)
                    697: {
                    698:        register struct zsaline *za;
                    699:        register short more;
                    700:        register int s;
                    701: 
                    702:        do {
                    703:                more = 0;
                    704:                for (za = &zsaline[0]; za < &zsaline[NZSLINE]; za++)
                    705:                if (za->za_work) {
                    706:                        za->za_work = 0;
                    707:                        s = spl3();
                    708:                        if (zsa_process(za)) {
                    709:                                za->za_work++;
                    710:                                more++;
                    711:                        }
                    712:                        (void) splx(s);
                    713:                }
                    714:        } while (more);
                    715:        if (!direct)
                    716:                timeout(zspoll, (caddr_t)0, zsticks);
                    717: }
                    718: 
                    719: /* 
                    720:  * Process software interrupts (or poll)
                    721:  * Crucial points:
                    722:  * 1.  Inner loop gives equal priority to input and output so that
                    723:  *     in TANDEM mode the stop character has a chance of being sent
                    724:  *     before enough input arrives to exceed TTYHOG.  This has happened
                    725:  *     in very busy systems.
                    726:  * 2.  The inner loop is executed at most 20 times before the next line
                    727:  *     is serviced -- this "schedules" more fairly among lines.
                    728:  * 3.  BUG - breaks are handled "out-of-band" - their relative position
                    729:  *     among input events is lost, as well as multiple breaks together.
                    730:  *     This is probably not a problem in practice.
                    731:  */
                    732: zsa_process(za)
                    733:        register struct zsaline *za;
                    734: {
                    735:        register struct zscc_device *zsaddr = za->za_addr->zs_addr;
                    736:        register struct block *bp;
                    737:        register short i;
                    738:        register u_char c;
                    739: 
                    740:        if (za->za_ext) {
                    741:                za->za_ext = 0;
                    742:                /* carrier up? */
                    743:                if (zsaddr->zscc_control & ZSRR0_CD) {
                    744:                        /* carrier present */
                    745:                        if ((za->state & CARR_ON)==0)
                    746:                                wakeup((caddr_t)za);
                    747:                        za->state |= CARR_ON;
                    748:                } else if ((za->state & CARR_ON) && !(za->state & DIALOUT)) {
                    749:                        /* carrier lost */
                    750:                        if (za->state & ISOPEN) {
                    751:                                (void) zsmctl(za->za_addr, ZSWR5_DTR, DMBIC);
                    752:                                if (za->rdq)
                    753:                                        putctl(za->rdq->next,M_HANGUP);
                    754:                        }
                    755:                        za->state &= ~CARR_ON;
                    756:                }
                    757:        }
                    758:        if (za->za_overrun) {
                    759:                za->za_overrun = 0;
                    760:                za->za_iptr = 0;
                    761:                za->za_sptr = 0;
                    762:                if (za->state & ISOPEN)
                    763:                        printf("zs%d: silo overflow\n", minor(za->za_dev));
                    764:        }
                    765:        if (za->za_break && (zsaddr->zscc_control & ZSRR0_BREAK) == 0) {
                    766:                za->za_break = 0;
                    767:                if (za->rdq != NULL && !(za->rdq->next->flag&QFULL) &&
                    768:                   (bp = allocb(16)) != NULL) {
                    769:                        bp->type = M_BREAK;
                    770:                        (*za->rdq->next->qinfo->putp)(za->rdq->next, bp);
                    771:                }
                    772:        }
                    773:        /* need to handle I & O in same loop to make TANDEM mode work */
                    774:        i = 0;
                    775:        do {
                    776:                if (za->za_sptr != za->za_iptr) {
                    777:                        c = za->za_ibuf[za->za_sptr++];
                    778:                        if (za->za_sptr >= ZSIBUFSZ)
                    779:                                za->za_sptr = 0;
                    780:                        if (za->rdq != NULL && !(za->rdq->next->flag&QFULL) &&
                    781:                           (bp = allocb(16)) != NULL) {
                    782:                              *bp->wptr++ = c;
                    783:                              (*za->rdq->next->qinfo->putp)(za->rdq->next, bp);
                    784:                        }
                    785:                }
                    786:                if ((bp = za->oblock) && bp->rptr >= bp->wptr) {
                    787:                        freeb(bp);
                    788:                        za->oblock = NULL;
                    789:                        zsstart(za);
                    790:                }
                    791:        } while (za->za_sptr != za->za_iptr && ++i < 20);
                    792:        return (i >= 20);
                    793: }

unix.superglobalmegacorp.com

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