Annotation of 41BSD/sys/dev/dh.c, revision 1.1

1.1     ! root        1: /*     dh.c    4.3     11/13/80        */
        !             2: 
        !             3: #include "../conf/dh.h"
        !             4: #if NDH11 > 0
        !             5: /*
        !             6:  * DH-11 driver
        !             7:  *
        !             8:  * Loaded with dhdm if there are DM-11's otherwise with dhfdm.
        !             9:  *
        !            10:  * NB: WE HAVEN'T TESTED dhdm CODE ON VAX.
        !            11:  */
        !            12: 
        !            13: #include "../h/param.h"
        !            14: #include "../h/conf.h"
        !            15: #include "../h/dir.h"
        !            16: #include "../h/user.h"
        !            17: #include "../h/tty.h"
        !            18: #include "../h/map.h"
        !            19: #include "../h/pte.h"
        !            20: #include "../h/uba.h"
        !            21: #include "../h/bk.h"
        !            22: #include "../h/clist.h"
        !            23: #include "../h/mx.h"
        !            24: 
        !            25: /*
        !            26:  * When running dz's using only SAE (silo alarm) on input
        !            27:  * it is necessary to call dzrint() at clock interrupt time.
        !            28:  * This is unsafe unless spl5()s in tty code are changed to
        !            29:  * spl6()s to block clock interrupts.  Note that the dh driver
        !            30:  * currently in use works the same way as the dz, even though
        !            31:  * we could try to more intelligently manage its silo.
        !            32:  * Thus don't take this out if you have no dz's unless you
        !            33:  * change clock.c and dhtimer().
        !            34:  */
        !            35: #define        spl5    spl6
        !            36: 
        !            37: #define        UBACVT(x) (cbase + (short)((x)-(char *)cfree))
        !            38: 
        !            39: struct tty dh11[NDH11];
        !            40: int    dhact;
        !            41: int    dhisilo;
        !            42: int    ndh11   = NDH11;
        !            43: int    dhstart();
        !            44: int    ttrstrt();
        !            45: int    dh_ubinfo;
        !            46: int    cbase;
        !            47: int    getcbase;
        !            48: 
        !            49: /*
        !            50:  * Hardware control bits
        !            51:  */
        !            52: #define        BITS6   01
        !            53: #define        BITS7   02
        !            54: #define        BITS8   03
        !            55: #define        TWOSB   04
        !            56: #define        PENABLE 020
        !            57: /* DEC manuals incorrectly say this bit causes generation of even parity. */
        !            58: #define        OPAR    040
        !            59: #define        HDUPLX  040000
        !            60: 
        !            61: #define        IENAB   030100
        !            62: #define        NXM     02000
        !            63: #define        CLRNXM  0400
        !            64: #define        PERROR  010000
        !            65: #define        FRERROR 020000
        !            66: #define        OVERRUN 040000
        !            67: #define        XINT    0100000
        !            68: #define        SSPEED  7       /* standard speed: 300 baud */
        !            69: 
        !            70: /*
        !            71:  * DM control bits
        !            72:  */
        !            73: #define        TURNON  03      /* CD lead + line enable */
        !            74: #define        TURNOFF 01      /* line enable */
        !            75: #define        DTR     02      /* data terminal ready */
        !            76: #define        RQS     04      /* request to send */
        !            77: 
        !            78: /*
        !            79:  * Software copy of last dhbar
        !            80:  */
        !            81: short  dhsar[(NDH11+15)/16];
        !            82: 
        !            83: struct device
        !            84: {
        !            85:        union {
        !            86:                short   dhcsr;
        !            87:                char    dhcsrl;
        !            88:        } un;
        !            89:        short   dhnxch;
        !            90:        short   dhlpr;
        !            91:        unsigned short  dhcar;
        !            92:        short   dhbcr;
        !            93:        unsigned short  dhbar;
        !            94:        short   dhbreak;
        !            95:        short   dhsilo;
        !            96: };
        !            97: 
        !            98: /*
        !            99:  * Open a DH11 line.
        !           100:  */
        !           101: /*ARGSUSED*/
        !           102: dhopen(dev, flag)
        !           103: {
        !           104:        register struct tty *tp;
        !           105:        register d;
        !           106:        register struct device *addr;
        !           107:        int s;
        !           108: 
        !           109:        d = minor(dev) & 0177;
        !           110:        if (d >= NDH11) {
        !           111:                u.u_error = ENXIO;
        !           112:                return;
        !           113:        }
        !           114:        tp = &dh11[d];
        !           115:        addr = DHADDR;
        !           116:        addr += d>>4;
        !           117:        tp->t_addr = (caddr_t)addr;
        !           118:        tp->t_oproc = dhstart;
        !           119:        tp->t_iproc = NULL;
        !           120:        tp->t_state |= WOPEN;
        !           121:        s = spl6();
        !           122:        if (!getcbase) {
        !           123:                getcbase++;
        !           124:                /* 512+ is a kludge to try to get around a hardware problem */
        !           125:                dh_ubinfo = uballoc((caddr_t)cfree, 512+NCLIST*sizeof(struct cblock), 0);
        !           126:                cbase = (short)dh_ubinfo;
        !           127:        }
        !           128:        splx(s);
        !           129:        addr->un.dhcsr |= IENAB;
        !           130:        dhact |= (1<<(d>>4));
        !           131:        if ((tp->t_state&ISOPEN) == 0) {
        !           132:                ttychars(tp);
        !           133:                if (tp->t_ispeed == 0) {
        !           134:                        tp->t_ispeed = SSPEED;
        !           135:                        tp->t_ospeed = SSPEED;
        !           136:                        tp->t_flags = ODDP|EVENP|ECHO;
        !           137:                }
        !           138:                dhparam(d);
        !           139:        }
        !           140:        if (tp->t_state&XCLUDE && u.u_uid!=0) {
        !           141:                u.u_error = EBUSY;
        !           142:                return;
        !           143:        }
        !           144:        dmopen(dev);
        !           145:        (*linesw[tp->t_line].l_open)(dev,tp);
        !           146: }
        !           147: 
        !           148: /*
        !           149:  * Close a DH11 line.
        !           150:  */
        !           151: /*ARGSUSED*/
        !           152: dhclose(dev, flag)
        !           153: dev_t dev;
        !           154: int  flag;
        !           155: {
        !           156:        register struct tty *tp;
        !           157:        register d;
        !           158: 
        !           159:        d = minor(dev) & 0177;
        !           160:        tp = &dh11[d];
        !           161:        (*linesw[tp->t_line].l_close)(tp);
        !           162:        if (tp->t_state&HUPCLS || (tp->t_state&ISOPEN)==0)
        !           163:                dmctl(d, TURNOFF, DMSET);
        !           164:        ttyclose(tp);
        !           165: }
        !           166: 
        !           167: /*
        !           168:  * Read from a DH11 line.
        !           169:  */
        !           170: dhread(dev)
        !           171: {
        !           172: register struct tty *tp;
        !           173: 
        !           174:        tp = &dh11[minor(dev) & 0177];
        !           175:        (*linesw[tp->t_line].l_read)(tp);
        !           176: }
        !           177: 
        !           178: /*
        !           179:  * write on a DH11 line
        !           180:  */
        !           181: dhwrite(dev)
        !           182: {
        !           183: register struct tty *tp;
        !           184: 
        !           185:        tp = &dh11[minor(dev) & 0177];
        !           186:        (*linesw[tp->t_line].l_write)(tp);
        !           187: }
        !           188: 
        !           189: /*
        !           190:  * DH11 receiver interrupt.
        !           191:  */
        !           192: dhrint(dev)
        !           193: {
        !           194:        register struct tty *tp;
        !           195:        register short c;
        !           196:        register struct device *addr;
        !           197:        register struct tty *tp0;
        !           198:        int s;
        !           199: 
        !           200:        s = spl6();     /* see comment in clock.c */
        !           201:        addr = DHADDR;
        !           202:        addr += minor(dev) & 0177;
        !           203:        tp0 = &dh11[((minor(dev)&0177)<<4)];
        !           204:        while ((c = addr->dhnxch) < 0) {        /* char. present */
        !           205:                tp = tp0 + ((c>>8)&017);
        !           206:                if (tp >= &dh11[NDH11])
        !           207:                        continue;
        !           208:                if((tp->t_state&ISOPEN)==0) {
        !           209:                        wakeup((caddr_t)tp);
        !           210:                        continue;
        !           211:                }
        !           212:                if (c&PERROR)
        !           213:                        if ((tp->t_flags&(EVENP|ODDP))==EVENP
        !           214:                         || (tp->t_flags&(EVENP|ODDP))==ODDP )
        !           215:                                continue;
        !           216:                if (c&OVERRUN)
        !           217:                        printf("O");
        !           218:                if (c&FRERROR)          /* break */
        !           219:                        if (tp->t_flags&RAW)
        !           220:                                c = 0;  /* null (for getty) */
        !           221:                        else
        !           222: #ifdef IIASA
        !           223:                                continue;
        !           224: #else
        !           225:                                c = tun.t_intrc;
        !           226: #endif
        !           227:                if (tp->t_line == NETLDISC) {
        !           228:                        c &= 0177;
        !           229:                        BKINPUT(c, tp);
        !           230:                } else
        !           231:                        (*linesw[tp->t_line].l_rint)(c,tp);
        !           232:        }
        !           233:        splx(s);
        !           234: }
        !           235: 
        !           236: /*
        !           237:  * stty/gtty for DH11
        !           238:  */
        !           239: /*ARGSUSED*/
        !           240: dhioctl(dev, cmd, addr, flag)
        !           241: caddr_t addr;
        !           242: {
        !           243:        register struct tty *tp;
        !           244: 
        !           245:        tp = &dh11[minor(dev) & 0177];
        !           246:        cmd = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr);
        !           247:        if (cmd==0)
        !           248:                return;
        !           249:        if (ttioctl(cmd, tp, addr, dev, flag)) {
        !           250:                if (cmd==TIOCSETP||cmd==TIOCSETN)
        !           251:                        dhparam(dev);
        !           252:        } else switch(cmd) {
        !           253:        case TIOCSBRK:
        !           254:                ((struct device *)(tp->t_addr))->dhbreak |= 1<<(minor(dev)&017);
        !           255:                break;
        !           256:        case TIOCCBRK:
        !           257:                ((struct device *)(tp->t_addr))->dhbreak &= ~(1<<(minor(dev)&017));
        !           258:                break;
        !           259:        case TIOCSDTR:
        !           260:                dmctl(minor(dev), DTR|RQS, DMBIS);
        !           261:                break;
        !           262:        case TIOCCDTR:
        !           263:                dmctl(minor(dev), DTR|RQS, DMBIC);
        !           264:                break;
        !           265:        default:
        !           266:                u.u_error = ENOTTY;
        !           267:        }
        !           268: }
        !           269: 
        !           270: /*
        !           271:  * Set parameters from open or stty into the DH hardware
        !           272:  * registers.
        !           273:  */
        !           274: dhparam(dev)
        !           275: {
        !           276:        register struct tty *tp;
        !           277:        register struct device *addr;
        !           278:        register d;
        !           279:        int s;
        !           280: 
        !           281:        d = minor(dev) & 0177;
        !           282:        tp = &dh11[d];
        !           283:        addr = (struct device *)tp->t_addr;
        !           284:        s = spl5();
        !           285:        addr->un.dhcsrl = (d&017) | IENAB;
        !           286:        /*
        !           287:         * Hang up line?
        !           288:         */
        !           289:        if ((tp->t_ispeed)==0) {
        !           290:                tp->t_state |= HUPCLS;
        !           291:                dmctl(d, TURNOFF, DMSET);
        !           292:                return;
        !           293:        }
        !           294:        d = ((tp->t_ospeed)<<10) | ((tp->t_ispeed)<<6);
        !           295:        if ((tp->t_ispeed) == 4)                /* 134.5 baud */
        !           296:                d |= BITS6|PENABLE|HDUPLX;
        !           297:        else if (tp->t_flags&RAW)
        !           298:                d |= BITS8;
        !           299:        else
        !           300:                d |= BITS7|PENABLE;
        !           301:        if ((tp->t_flags&EVENP) == 0)
        !           302:                d |= OPAR;
        !           303:        if ((tp->t_ospeed) == 3)        /* 110 baud */
        !           304:                d |= TWOSB;
        !           305:        addr->dhlpr = d;
        !           306:        splx(s);
        !           307: }
        !           308: 
        !           309: /*
        !           310:  * DH11 transmitter interrupt.
        !           311:  * Restart each line which used to be active but has
        !           312:  * terminated transmission since the last interrupt.
        !           313:  */
        !           314: dhxint(dev)
        !           315: {
        !           316:        register struct tty *tp;
        !           317:        register struct device *addr;
        !           318:        register d;
        !           319:        short ttybit, bar, *sbar;
        !           320:        int s;
        !           321: 
        !           322:        s = spl6();     /* block the clock */
        !           323:        d = minor(dev) & 0177;
        !           324:        addr = DHADDR + d;
        !           325:        addr->un.dhcsr &= (short)~XINT;
        !           326:        if (addr->un.dhcsr & NXM) {
        !           327:                addr->un.dhcsr |= CLRNXM;
        !           328:                printf("dh clr NXM\n");
        !           329:        }
        !           330:        sbar = &dhsar[d];
        !           331:        bar = *sbar & ~addr->dhbar;
        !           332:        d <<= 4; ttybit = 1;
        !           333: 
        !           334:        for(; bar; d++, ttybit <<= 1) {
        !           335:                if(bar&ttybit) {
        !           336:                        *sbar &= ~ttybit;
        !           337:                        bar &= ~ttybit;
        !           338:                        tp = &dh11[d];
        !           339:                        tp->t_state &= ~BUSY;
        !           340:                        if (tp->t_state&FLUSH)
        !           341:                                tp->t_state &= ~FLUSH;
        !           342:                        else {
        !           343:                                addr->un.dhcsrl = (d&017)|IENAB;
        !           344:                                ndflush(&tp->t_outq,
        !           345:                                    (int)(short)addr->dhcar-UBACVT(tp->t_outq.c_cf));
        !           346:                        }
        !           347:                        if (tp->t_line)
        !           348:                                (*linesw[tp->t_line].l_start)(tp);
        !           349:                        else
        !           350:                                dhstart(tp);
        !           351:                }
        !           352:        }
        !           353:        splx(s);
        !           354: }
        !           355: 
        !           356: /*
        !           357:  * Start (restart) transmission on the given DH11 line.
        !           358:  */
        !           359: dhstart(tp)
        !           360: register struct tty *tp;
        !           361: {
        !           362:        register struct device *addr;
        !           363:        register short nch;
        !           364:        int s, d;
        !           365: 
        !           366:        /*
        !           367:         * If it's currently active, or delaying,
        !           368:         * no need to do anything.
        !           369:         */
        !           370:        s = spl5();
        !           371:        d = tp-dh11;
        !           372:        addr = (struct device *)tp->t_addr;
        !           373:        if (tp->t_state&(TIMEOUT|BUSY|TTSTOP))
        !           374:                goto out;
        !           375: 
        !           376:        /*
        !           377:         * If the writer was sleeping on output overflow,
        !           378:         * wake him when low tide is reached.
        !           379:         */
        !           380:        if (tp->t_state&ASLEEP && tp->t_outq.c_cc<=TTLOWAT(tp)) {
        !           381:                tp->t_state &= ~ASLEEP;
        !           382:                if (tp->t_chan)
        !           383:                        mcstart(tp->t_chan, (caddr_t)&tp->t_outq);
        !           384:                else
        !           385:                        wakeup((caddr_t)&tp->t_outq);
        !           386:        }
        !           387: 
        !           388:        if (tp->t_outq.c_cc == 0)
        !           389:                goto out;
        !           390: 
        !           391:        /*
        !           392:         * Find number of characters to transfer.
        !           393:         */
        !           394:        if (tp->t_flags & RAW) {
        !           395:                nch = ndqb(&tp->t_outq, 0);
        !           396:        } else {
        !           397:                nch = ndqb(&tp->t_outq, 0200);
        !           398:                if (nch == 0) {
        !           399:                        nch = getc(&tp->t_outq);
        !           400:                        timeout(ttrstrt, (caddr_t)tp, (nch&0177)+6);
        !           401:                        tp->t_state |= TIMEOUT;
        !           402:                        goto out;
        !           403:                }
        !           404:        }
        !           405:        /*
        !           406:         * If any characters were set up, start transmission;
        !           407:         */
        !           408:        if (nch) {
        !           409:                addr->un.dhcsrl = (d&017)|IENAB;
        !           410:                addr->dhcar = UBACVT(tp->t_outq.c_cf);
        !           411:                addr->dhbcr = -nch;
        !           412:                nch = 1<<(d&017);
        !           413:                addr->dhbar |= nch;
        !           414:                dhsar[d>>4] |= nch;
        !           415:                tp->t_state |= BUSY;
        !           416:        }
        !           417:     out:
        !           418:        splx(s);
        !           419: }
        !           420: 
        !           421: /*
        !           422:  * Stop output on a line.
        !           423:  * Assume call is made at spl6.
        !           424:  */
        !           425: /*ARGSUSED*/
        !           426: dhstop(tp, flag)
        !           427: register struct tty *tp;
        !           428: {
        !           429:        register struct device *addr;
        !           430:        register d, s;
        !           431: 
        !           432:        addr = (struct device *)tp->t_addr;
        !           433:        s = spl6();
        !           434:        if (tp->t_state & BUSY) {
        !           435:                d = minor(tp->t_dev);
        !           436:                addr->un.dhcsrl = (d&017) | IENAB;
        !           437:                if ((tp->t_state&TTSTOP)==0)
        !           438:                        tp->t_state |= FLUSH;
        !           439:                addr->dhbcr = -1;
        !           440:        }
        !           441:        splx(s);
        !           442: }
        !           443: 
        !           444: int    dhsilo = 16;
        !           445: /*
        !           446:  * Silo control is fixed strategy
        !           447:  * here, paralleling only option available
        !           448:  * on DZ-11.
        !           449:  */
        !           450: /*ARGSUSED*/
        !           451: dhtimer()
        !           452: {
        !           453:        register d;
        !           454:        register struct device *addr;
        !           455: 
        !           456:        addr = DHADDR; d = 0;
        !           457:        do {
        !           458:                if (dhact & (1<<d)) {
        !           459:                        if ((dhisilo & (1<<d)) == 0) {
        !           460:                                addr->dhsilo = dhsilo;
        !           461:                                dhisilo |= 1<<d;
        !           462:                        }
        !           463:                        dhrint(d);
        !           464:                }
        !           465:                d++;
        !           466:                addr++;
        !           467:        } while (d < (NDH11+15)/16);
        !           468: }
        !           469: 
        !           470: /*
        !           471:  * Reset state of driver if UBA reset was necessary.
        !           472:  * Reset the csrl and lpr registers on open lines, and
        !           473:  * restart transmitters.
        !           474:  */
        !           475: dhreset()
        !           476: {
        !           477:        int d;
        !           478:        register struct tty *tp;
        !           479:        register struct device *addr;
        !           480: 
        !           481:        if (getcbase == 0)
        !           482:                return;
        !           483:        printf(" dh");
        !           484:        dhisilo = 0;
        !           485:        ubafree(dh_ubinfo);
        !           486:        dh_ubinfo = uballoc((caddr_t)cfree, NCLIST*sizeof (struct cblock), 0);
        !           487:        cbase = (short)dh_ubinfo;
        !           488:        d = 0;
        !           489:        do {
        !           490:                addr = DHADDR + d;
        !           491:                if (dhact & (1<<d))
        !           492:                        addr->un.dhcsr |= IENAB;
        !           493:                d++;
        !           494:        } while (d < (NDH11+15)/16);
        !           495:        for (d = 0; d < NDH11; d++) {
        !           496:                tp = &dh11[d];
        !           497:                if (tp->t_state & (ISOPEN|WOPEN)) {
        !           498:                        dhparam(d);
        !           499:                        dmctl(d, TURNON, DMSET);
        !           500:                        tp->t_state &= ~BUSY;
        !           501:                        dhstart(tp);
        !           502:                }
        !           503:        }
        !           504:        dhtimer();
        !           505: }
        !           506: #endif

unix.superglobalmegacorp.com

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