Annotation of 43BSD/sys/vaxuba/dhu.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1985, 1986 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  *
        !             6:  *     @(#)dhu.c       7.1 (Berkeley) 6/5/86
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * based on    dh.c 6.3        84/03/15
        !            11:  * and on      dmf.c   6.2     84/02/16
        !            12:  *
        !            13:  * Dave Johnson, Brown University Computer Science
        !            14:  *     ddj%brown@csnet-relay
        !            15:  */
        !            16: 
        !            17: #include "dhu.h"
        !            18: #if NDHU > 0
        !            19: /*
        !            20:  * DHU-11 driver
        !            21:  */
        !            22: #include "../machine/pte.h"
        !            23: 
        !            24: #include "bk.h"
        !            25: #include "param.h"
        !            26: #include "conf.h"
        !            27: #include "dir.h"
        !            28: #include "user.h"
        !            29: #include "proc.h"
        !            30: #include "ioctl.h"
        !            31: #include "tty.h"
        !            32: #include "map.h"
        !            33: #include "buf.h"
        !            34: #include "vm.h"
        !            35: #include "kernel.h"
        !            36: #include "syslog.h"
        !            37: 
        !            38: #include "uba.h"
        !            39: #include "ubareg.h"
        !            40: #include "ubavar.h"
        !            41: #include "dhureg.h"
        !            42: 
        !            43: #include "bkmac.h"
        !            44: #include "clist.h"
        !            45: #include "file.h"
        !            46: #include "uio.h"
        !            47: 
        !            48: /*
        !            49:  * Definition of the driver for the auto-configuration program.
        !            50:  */
        !            51: int    dhuprobe(), dhuattach(), dhurint(), dhuxint();
        !            52: struct uba_device *dhuinfo[NDHU];
        !            53: u_short dhustd[] = { 160440, 160500, 0 };      /* some common addresses */
        !            54: struct uba_driver dhudriver =
        !            55:        { dhuprobe, 0, dhuattach, 0, dhustd, "dhu", dhuinfo };
        !            56: 
        !            57: #define        NDHULINE        (NDHU*16)
        !            58: 
        !            59: #define        UNIT(x) (minor(x))
        !            60: 
        !            61: #ifndef PORTSELECTOR
        !            62: #define ISPEED B9600
        !            63: #define IFLAGS (EVENP|ODDP|ECHO)
        !            64: #else
        !            65: #define ISPEED B4800
        !            66: #define IFLAGS (EVENP|ODDP)
        !            67: #endif
        !            68: 
        !            69: /*
        !            70:  * default receive silo timeout value -- valid values are 2..255
        !            71:  * number of ms. to delay between first char received and receive interrupt
        !            72:  *
        !            73:  * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0
        !            74:  */
        !            75: #define        DHU_DEF_TIMO    20
        !            76: 
        !            77: /*
        !            78:  * Other values for silo timeout register defined here but not used:
        !            79:  * receive interrupt only on modem control or silo alarm (3/4 full)
        !            80:  */
        !            81: #define DHU_POLL_TIMO  0
        !            82: /*
        !            83:  * receive interrupt immediately on receive character
        !            84:  */
        !            85: #define DHU_NO_TIMO    1
        !            86: 
        !            87: /*
        !            88:  * Local variables for the driver
        !            89:  */
        !            90: /*
        !            91:  * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B".
        !            92:  *     EXTA => 19200 baud
        !            93:  *     EXTB => 2000 baud
        !            94:  */
        !            95: char   dhu_speeds[] =
        !            96:        { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 };
        !            97: 
        !            98: short  dhusoftCAR[NDHU];
        !            99: 
        !           100: struct tty dhu_tty[NDHULINE];
        !           101: int    ndhu = NDHULINE;
        !           102: int    dhuact;                         /* mask of active dhu's */
        !           103: int    dhustart(), ttrstrt();
        !           104: 
        !           105: /*
        !           106:  * The clist space is mapped by the driver onto each UNIBUS.
        !           107:  * The UBACVT macro converts a clist space address for unibus uban
        !           108:  * into an i/o space address for the DMA routine.
        !           109:  */
        !           110: int    dhu_ubinfo[NUBA];       /* info about allocated unibus map */
        !           111: int    cbase[NUBA];            /* base address in unibus map */
        !           112: #define UBACVT(x, uban)        (cbase[uban] + ((x)-(char *)cfree))
        !           113: 
        !           114: /*
        !           115:  * Routine for configuration to force a dhu to interrupt.
        !           116:  */
        !           117: /*ARGSUSED*/
        !           118: dhuprobe(reg)
        !           119:        caddr_t reg;
        !           120: {
        !           121:        register int br, cvec;          /* these are ``value-result'' */
        !           122:        register struct dhudevice *dhuaddr = (struct dhudevice *)reg;
        !           123:        int i;
        !           124: 
        !           125: #ifdef lint
        !           126:        br = 0; cvec = br; br = cvec;
        !           127:        if (ndhu == 0) ndhu = 1;
        !           128:        dhurint(0); dhuxint(0);
        !           129: #endif
        !           130:        /*
        !           131:         * The basic idea here is:
        !           132:         *      do a self-test by setting the Master-Reset bit
        !           133:         *      if this fails, then return
        !           134:         *      if successful, there will be 8 diagnostic codes in RX FIFO
        !           135:         *      therefore ask for a  Received-Data-Available interrupt
        !           136:         *      wait for it...
        !           137:         *      reset the interrupt-enable bit and flush out the diag. codes
        !           138:         */
        !           139:        dhuaddr->dhucsr = DHU_CS_MCLR;
        !           140:        for (i = 0; i < 1000; i++) {
        !           141:                DELAY(10000);
        !           142:                if ((dhuaddr->dhucsr&DHU_CS_MCLR) == 0)
        !           143:                        break;
        !           144:        }
        !           145:        if (dhuaddr->dhucsr&DHU_CS_MCLR)
        !           146:                return(0);
        !           147:        if (dhuaddr->dhucsr&DHU_CS_DFAIL)
        !           148:                return(0);
        !           149:        dhuaddr->dhucsr = DHU_CS_RIE;
        !           150:        DELAY(1000);
        !           151:        dhuaddr->dhucsr = 0;
        !           152:        while (dhuaddr->dhurbuf < 0)
        !           153:                /* void */;
        !           154:        return (sizeof(struct dhudevice));
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Routine called to attach a dhu.
        !           159:  */
        !           160: dhuattach(ui)
        !           161:        struct uba_device *ui;
        !           162: {
        !           163: 
        !           164:        dhusoftCAR[ui->ui_unit] = ui->ui_flags;
        !           165:        cbase[ui->ui_ubanum] = -1;
        !           166: }
        !           167: 
        !           168: /*
        !           169:  * Open a DHU11 line, mapping the clist onto the uba if this
        !           170:  * is the first dhu on this uba.  Turn on this dhu if this is
        !           171:  * the first use of it.
        !           172:  */
        !           173: /*ARGSUSED*/
        !           174: dhuopen(dev, flag)
        !           175:        dev_t dev;
        !           176: {
        !           177:        register struct tty *tp;
        !           178:        register int unit, dhu;
        !           179:        register struct dhudevice *addr;
        !           180:        register struct uba_device *ui;
        !           181:        int s;
        !           182: 
        !           183:        unit = UNIT(dev);
        !           184:        dhu = unit >> 4;
        !           185:        if (unit >= NDHULINE || (ui = dhuinfo[dhu])== 0 || ui->ui_alive == 0)
        !           186:                return (ENXIO);
        !           187:        tp = &dhu_tty[unit];
        !           188:        if (tp->t_state & TS_XCLUDE && u.u_uid != 0)
        !           189:                return (EBUSY);
        !           190:        addr = (struct dhudevice *)ui->ui_addr;
        !           191:        tp->t_addr = (caddr_t)addr;
        !           192:        tp->t_oproc = dhustart;
        !           193:        /*
        !           194:         * While setting up state for this uba and this dhu,
        !           195:         * block uba resets which can clear the state.
        !           196:         */
        !           197:        s = spl5();
        !           198:        if (cbase[ui->ui_ubanum] == -1) {
        !           199:                dhu_ubinfo[ui->ui_ubanum] =
        !           200:                    uballoc(ui->ui_ubanum, (caddr_t)cfree,
        !           201:                        nclist*sizeof(struct cblock), 0);
        !           202:                cbase[ui->ui_ubanum] = UBAI_ADDR(dhu_ubinfo[ui->ui_ubanum]);
        !           203:        }
        !           204:        if ((dhuact&(1<<dhu)) == 0) {
        !           205:                addr->dhucsr = DHU_SELECT(0) | DHU_IE;
        !           206:                addr->dhutimo = DHU_DEF_TIMO;
        !           207:                dhuact |= (1<<dhu);
        !           208:                /* anything else to configure whole board */
        !           209:        }
        !           210:        (void) splx(s);
        !           211:        /*
        !           212:         * If this is first open, initialize tty state to default.
        !           213:         */
        !           214:        if ((tp->t_state&TS_ISOPEN) == 0) {
        !           215:                ttychars(tp);
        !           216: #ifndef PORTSELECTOR
        !           217:                if (tp->t_ispeed == 0) {
        !           218: #else
        !           219:                        tp->t_state |= TS_HUPCLS;
        !           220: #endif PORTSELECTOR
        !           221:                        tp->t_ispeed = ISPEED;
        !           222:                        tp->t_ospeed = ISPEED;
        !           223:                        tp->t_flags = IFLAGS;
        !           224: #ifndef PORTSELECTOR
        !           225:                }
        !           226: #endif PORTSELECTOR
        !           227:                tp->t_dev = dev;
        !           228:                dhuparam(unit);
        !           229:        }
        !           230:        /*
        !           231:         * Wait for carrier, then process line discipline specific open.
        !           232:         */
        !           233:        s = spl5();
        !           234:        if ((dhumctl(dev, DHU_ON, DMSET) & DHU_CAR) ||
        !           235:            (dhusoftCAR[dhu] & (1<<(unit&0xf))))
        !           236:                tp->t_state |= TS_CARR_ON;
        !           237:        while ((tp->t_state & TS_CARR_ON) == 0) {
        !           238:                tp->t_state |= TS_WOPEN;
        !           239:                sleep((caddr_t)&tp->t_rawq, TTIPRI);
        !           240:        }
        !           241:        (void) splx(s);
        !           242:        return ((*linesw[tp->t_line].l_open)(dev, tp));
        !           243: }
        !           244: 
        !           245: /*
        !           246:  * Close a DHU11 line, turning off the modem control.
        !           247:  */
        !           248: /*ARGSUSED*/
        !           249: dhuclose(dev, flag)
        !           250:        dev_t dev;
        !           251:        int flag;
        !           252: {
        !           253:        register struct tty *tp;
        !           254:        register unit;
        !           255: 
        !           256:        unit = UNIT(dev);
        !           257:        tp = &dhu_tty[unit];
        !           258:        (*linesw[tp->t_line].l_close)(tp);
        !           259:        (void) dhumctl(unit, DHU_BRK, DMBIC);
        !           260:        if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0)
        !           261: #ifdef PORTSELECTOR
        !           262:        {
        !           263:                extern int wakeup();
        !           264: 
        !           265:                (void) dhumctl(unit, DHU_OFF, DMSET);
        !           266:                /* Hold DTR low for 0.5 seconds */
        !           267:                timeout(wakeup, (caddr_t) &tp->t_dev, hz/2);
        !           268:                sleep((caddr_t) &tp->t_dev, PZERO);
        !           269:        }
        !           270: #else
        !           271:                (void) dhumctl(unit, DHU_OFF, DMSET);
        !           272: #endif PORTSELECTOR
        !           273:        ttyclose(tp);
        !           274: }
        !           275: 
        !           276: dhuread(dev, uio)
        !           277:        dev_t dev;
        !           278:        struct uio *uio;
        !           279: {
        !           280:        register struct tty *tp = &dhu_tty[UNIT(dev)];
        !           281: 
        !           282:        return ((*linesw[tp->t_line].l_read)(tp, uio));
        !           283: }
        !           284: 
        !           285: dhuwrite(dev, uio)
        !           286:        dev_t dev;
        !           287:        struct uio *uio;
        !           288: {
        !           289:        register struct tty *tp = &dhu_tty[UNIT(dev)];
        !           290: 
        !           291:        return ((*linesw[tp->t_line].l_write)(tp, uio));
        !           292: }
        !           293: 
        !           294: /*
        !           295:  * DHU11 receiver interrupt.
        !           296:  */
        !           297: dhurint(dhu)
        !           298:        int dhu;
        !           299: {
        !           300:        register struct tty *tp;
        !           301:        register c;
        !           302:        register struct dhudevice *addr;
        !           303:        register struct tty *tp0;
        !           304:        register struct uba_device *ui;
        !           305:        register line;
        !           306:        int overrun = 0;
        !           307: 
        !           308: #ifdef VAX630
        !           309:        (void) spl5();
        !           310: #endif
        !           311:        ui = dhuinfo[dhu];
        !           312:        if (ui == 0 || ui->ui_alive == 0)
        !           313:                return;
        !           314:        addr = (struct dhudevice *)ui->ui_addr;
        !           315:        tp0 = &dhu_tty[dhu<<4];
        !           316:        /*
        !           317:         * Loop fetching characters from the silo for this
        !           318:         * dhu until there are no more in the silo.
        !           319:         */
        !           320:        while ((c = addr->dhurbuf) < 0) {       /* (c & DHU_RB_VALID) == on */
        !           321:                line = DHU_RX_LINE(c);
        !           322:                tp = tp0 + line;
        !           323:                if ((c & DHU_RB_STAT) == DHU_RB_STAT) {
        !           324:                        /*
        !           325:                         * modem changed or diag info
        !           326:                         */
        !           327:                        if (c & DHU_RB_DIAG) {
        !           328:                                /* decode diagnostic messages */
        !           329:                                continue;
        !           330:                        }
        !           331:                        if (c & DHU_ST_DCD)
        !           332:                                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        !           333:                        else if ((dhusoftCAR[dhu] & (1<<line)) == 0 &&
        !           334:                            (*linesw[tp->t_line].l_modem)(tp, 0) == 0)
        !           335:                                (void) dhumctl((dhu<<4)|line, DHU_OFF, DMSET);
        !           336:                        continue;
        !           337:                }
        !           338:                if ((tp->t_state&TS_ISOPEN) == 0) {
        !           339:                        wakeup((caddr_t)&tp->t_rawq);
        !           340: #ifdef PORTSELECTOR
        !           341:                        if ((tp->t_state&TS_WOPEN) == 0)
        !           342: #endif
        !           343:                                continue;
        !           344:                }
        !           345:                if (c & DHU_RB_PE)
        !           346:                        if ((tp->t_flags&(EVENP|ODDP)) == EVENP ||
        !           347:                            (tp->t_flags&(EVENP|ODDP)) == ODDP)
        !           348:                                continue;
        !           349:                if ((c & DHU_RB_DO) && overrun == 0) {
        !           350:                        log(LOG_WARNING, "dhu%d: silo overflow\n", dhu);
        !           351:                        overrun = 1;
        !           352:                }
        !           353:                if (c & DHU_RB_FE)
        !           354:                        /*
        !           355:                         * At framing error (break) generate
        !           356:                         * a null (in raw mode, for getty), or a
        !           357:                         * interrupt (in cooked/cbreak mode).
        !           358:                         */
        !           359:                        if (tp->t_flags&RAW)
        !           360:                                c = 0;
        !           361:                        else
        !           362:                                c = tp->t_intrc;
        !           363: #if NBK > 0
        !           364:                if (tp->t_line == NETLDISC) {
        !           365:                        c &= 0x7f;
        !           366:                        BKINPUT(c, tp);
        !           367:                } else
        !           368: #endif
        !           369:                        (*linesw[tp->t_line].l_rint)(c, tp);
        !           370:        }
        !           371: }
        !           372: 
        !           373: /*
        !           374:  * Ioctl for DHU11.
        !           375:  */
        !           376: /*ARGSUSED*/
        !           377: dhuioctl(dev, cmd, data, flag)
        !           378:        caddr_t data;
        !           379: {
        !           380:        register struct tty *tp;
        !           381:        register int unit = UNIT(dev);
        !           382:        int error;
        !           383: 
        !           384:        tp = &dhu_tty[unit];
        !           385:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        !           386:        if (error >= 0)
        !           387:                return (error);
        !           388:        error = ttioctl(tp, cmd, data, flag);
        !           389:        if (error >= 0) {
        !           390:                if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLSET ||
        !           391:                    cmd == TIOCLBIC || cmd == TIOCLBIS)
        !           392:                        dhuparam(unit);
        !           393:                return (error);
        !           394:        }
        !           395: 
        !           396:        switch (cmd) {
        !           397:        case TIOCSBRK:
        !           398:                (void) dhumctl(unit, DHU_BRK, DMBIS);
        !           399:                break;
        !           400: 
        !           401:        case TIOCCBRK:
        !           402:                (void) dhumctl(unit, DHU_BRK, DMBIC);
        !           403:                break;
        !           404: 
        !           405:        case TIOCSDTR:
        !           406:                (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIS);
        !           407:                break;
        !           408: 
        !           409:        case TIOCCDTR:
        !           410:                (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIC);
        !           411:                break;
        !           412: 
        !           413:        case TIOCMSET:
        !           414:                (void) dhumctl(dev, dmtodhu(*(int *)data), DMSET);
        !           415:                break;
        !           416: 
        !           417:        case TIOCMBIS:
        !           418:                (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS);
        !           419:                break;
        !           420: 
        !           421:        case TIOCMBIC:
        !           422:                (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC);
        !           423:                break;
        !           424: 
        !           425:        case TIOCMGET:
        !           426:                *(int *)data = dhutodm(dhumctl(dev, 0, DMGET));
        !           427:                break;
        !           428:        default:
        !           429:                return (ENOTTY);
        !           430:        }
        !           431:        return (0);
        !           432: }
        !           433: 
        !           434: dmtodhu(bits)
        !           435:        register int bits;
        !           436: {
        !           437:        register int b = 0;
        !           438: 
        !           439:        if (bits & DML_RTS) b |= DHU_RTS;
        !           440:        if (bits & DML_DTR) b |= DHU_DTR;
        !           441:        if (bits & DML_LE) b |= DHU_LE;
        !           442:        return(b);
        !           443: }
        !           444: 
        !           445: dhutodm(bits)
        !           446:        register int bits;
        !           447: {
        !           448:        register int b = 0;
        !           449: 
        !           450:        if (bits & DHU_DSR) b |= DML_DSR;
        !           451:        if (bits & DHU_RNG) b |= DML_RNG;
        !           452:        if (bits & DHU_CAR) b |= DML_CAR;
        !           453:        if (bits & DHU_CTS) b |= DML_CTS;
        !           454:        if (bits & DHU_RTS) b |= DML_RTS;
        !           455:        if (bits & DHU_DTR) b |= DML_DTR;
        !           456:        if (bits & DHU_LE) b |= DML_LE;
        !           457:        return(b);
        !           458: }
        !           459: 
        !           460: 
        !           461: /*
        !           462:  * Set parameters from open or stty into the DHU hardware
        !           463:  * registers.
        !           464:  */
        !           465: dhuparam(unit)
        !           466:        register int unit;
        !           467: {
        !           468:        register struct tty *tp;
        !           469:        register struct dhudevice *addr;
        !           470:        register int lpar;
        !           471:        int s;
        !           472: 
        !           473:        tp = &dhu_tty[unit];
        !           474:        addr = (struct dhudevice *)tp->t_addr;
        !           475:        /*
        !           476:         * Block interrupts so parameters will be set
        !           477:         * before the line interrupts.
        !           478:         */
        !           479:        s = spl5();
        !           480:        if ((tp->t_ispeed) == 0) {
        !           481:                tp->t_state |= TS_HUPCLS;
        !           482:                (void)dhumctl(unit, DHU_OFF, DMSET);
        !           483:                splx(s);
        !           484:                return;
        !           485:        }
        !           486:        lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8);
        !           487:        if ((tp->t_ispeed) == B134)
        !           488:                lpar |= DHU_LP_BITS6|DHU_LP_PENABLE;
        !           489:        else if (tp->t_flags & (RAW|LITOUT|PASS8))
        !           490:                lpar |= DHU_LP_BITS8;
        !           491:        else
        !           492:                lpar |= DHU_LP_BITS7|DHU_LP_PENABLE;
        !           493:        if (tp->t_flags&EVENP)
        !           494:                lpar |= DHU_LP_EPAR;
        !           495:        if ((tp->t_ospeed) == B110)
        !           496:                lpar |= DHU_LP_TWOSB;
        !           497:        addr->dhucsr = DHU_SELECT(unit) | DHU_IE;
        !           498:        addr->dhulpr = lpar;
        !           499:        splx(s);
        !           500: }
        !           501: 
        !           502: /*
        !           503:  * DHU11 transmitter interrupt.
        !           504:  * Restart each line which used to be active but has
        !           505:  * terminated transmission since the last interrupt.
        !           506:  */
        !           507: dhuxint(dhu)
        !           508:        int dhu;
        !           509: {
        !           510:        register struct tty *tp;
        !           511:        register struct dhudevice *addr;
        !           512:        register struct tty *tp0;
        !           513:        register struct uba_device *ui;
        !           514:        register int line, t;
        !           515:        u_short cntr;
        !           516: 
        !           517: #ifdef VAX630
        !           518:        (void) spl5();
        !           519: #endif
        !           520:        ui = dhuinfo[dhu];
        !           521:        tp0 = &dhu_tty[dhu<<4];
        !           522:        addr = (struct dhudevice *)ui->ui_addr;
        !           523:        while ((t = addr->dhucsrh) & DHU_CSH_TI) {
        !           524:                line = DHU_TX_LINE(t);
        !           525:                tp = tp0 + line;
        !           526:                tp->t_state &= ~TS_BUSY;
        !           527:                if (t & DHU_CSH_NXM) {
        !           528:                        printf("dhu(%d,%d): NXM fault\n", dhu, line);
        !           529:                        /* SHOULD RESTART OR SOMETHING... */
        !           530:                }
        !           531:                if (tp->t_state&TS_FLUSH)
        !           532:                        tp->t_state &= ~TS_FLUSH;
        !           533:                else {
        !           534:                        addr->dhucsrl = DHU_SELECT(line) | DHU_IE;
        !           535:                        /*
        !           536:                         * Do arithmetic in a short to make up
        !           537:                         * for lost 16&17 bits.
        !           538:                         */
        !           539:                        cntr = addr->dhubar1 -
        !           540:                            UBACVT(tp->t_outq.c_cf, ui->ui_ubanum);
        !           541:                        ndflush(&tp->t_outq, (int)cntr);
        !           542:                }
        !           543:                if (tp->t_line)
        !           544:                        (*linesw[tp->t_line].l_start)(tp);
        !           545:                else
        !           546:                        dhustart(tp);
        !           547:        }
        !           548: }
        !           549: 
        !           550: /*
        !           551:  * Start (restart) transmission on the given DHU11 line.
        !           552:  */
        !           553: dhustart(tp)
        !           554:        register struct tty *tp;
        !           555: {
        !           556:        register struct dhudevice *addr;
        !           557:        register int car, dhu, unit, nch;
        !           558:        int s;
        !           559: 
        !           560:        unit = minor(tp->t_dev);
        !           561:        dhu = unit >> 4;
        !           562:        unit &= 0xf;
        !           563:        addr = (struct dhudevice *)tp->t_addr;
        !           564: 
        !           565:        /*
        !           566:         * Must hold interrupts in following code to prevent
        !           567:         * state of the tp from changing.
        !           568:         */
        !           569:        s = spl5();
        !           570:        /*
        !           571:         * If it's currently active, or delaying, no need to do anything.
        !           572:         */
        !           573:        if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
        !           574:                goto out;
        !           575:        /*
        !           576:         * If there are sleepers, and output has drained below low
        !           577:         * water mark, wake up the sleepers..
        !           578:         */
        !           579:        if (tp->t_outq.c_cc<=TTLOWAT(tp)) {
        !           580:                if (tp->t_state&TS_ASLEEP) {
        !           581:                        tp->t_state &= ~TS_ASLEEP;
        !           582:                        wakeup((caddr_t)&tp->t_outq);
        !           583:                }
        !           584:                if (tp->t_wsel) {
        !           585:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           586:                        tp->t_wsel = 0;
        !           587:                        tp->t_state &= ~TS_WCOLL;
        !           588:                }
        !           589:        }
        !           590:        /*
        !           591:         * Now restart transmission unless the output queue is
        !           592:         * empty.
        !           593:         */
        !           594:        if (tp->t_outq.c_cc == 0)
        !           595:                goto out;
        !           596:        if (tp->t_flags & (RAW|LITOUT))
        !           597:                nch = ndqb(&tp->t_outq, 0);
        !           598:        else {
        !           599:                nch = ndqb(&tp->t_outq, 0200);
        !           600:                /*
        !           601:                 * If first thing on queue is a delay process it.
        !           602:                 */
        !           603:                if (nch == 0) {
        !           604:                        nch = getc(&tp->t_outq);
        !           605:                        timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
        !           606:                        tp->t_state |= TS_TIMEOUT;
        !           607:                        goto out;
        !           608:                }
        !           609:        }
        !           610:        /*
        !           611:         * If characters to transmit, restart transmission.
        !           612:         */
        !           613:        if (nch) {
        !           614:                car = UBACVT(tp->t_outq.c_cf, dhuinfo[dhu]->ui_ubanum);
        !           615:                addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
        !           616:                addr->dhulcr &= ~DHU_LC_TXABORT;
        !           617:                addr->dhubcr = nch;
        !           618:                addr->dhubar1 = car;
        !           619:                addr->dhubar2 = ((car >> DHU_XBA_SHIFT) & DHU_BA2_XBA) |
        !           620:                                        DHU_BA2_DMAGO;
        !           621:                tp->t_state |= TS_BUSY;
        !           622:        }
        !           623: out:
        !           624:        splx(s);
        !           625: }
        !           626: 
        !           627: /*
        !           628:  * Stop output on a line, e.g. for ^S/^Q or output flush.
        !           629:  */
        !           630: /*ARGSUSED*/
        !           631: dhustop(tp, flag)
        !           632:        register struct tty *tp;
        !           633: {
        !           634:        register struct dhudevice *addr;
        !           635:        register int unit, s;
        !           636: 
        !           637:        addr = (struct dhudevice *)tp->t_addr;
        !           638:        /*
        !           639:         * Block input/output interrupts while messing with state.
        !           640:         */
        !           641:        s = spl5();
        !           642:        if (tp->t_state & TS_BUSY) {
        !           643:                /*
        !           644:                 * Device is transmitting; stop output
        !           645:                 * by selecting the line and setting the
        !           646:                 * abort xmit bit.  We will get an xmit interrupt,
        !           647:                 * where we will figure out where to continue the
        !           648:                 * next time the transmitter is enabled.  If
        !           649:                 * TS_FLUSH is set, the outq will be flushed.
        !           650:                 * In either case, dhustart will clear the TXABORT bit.
        !           651:                 */
        !           652:                unit = minor(tp->t_dev);
        !           653:                addr->dhucsrl = DHU_SELECT(unit) | DHU_IE;
        !           654:                addr->dhulcr |= DHU_LC_TXABORT;
        !           655:                if ((tp->t_state&TS_TTSTOP)==0)
        !           656:                        tp->t_state |= TS_FLUSH;
        !           657:        }
        !           658:        (void) splx(s);
        !           659: }
        !           660: 
        !           661: /*
        !           662:  * DHU11 modem control
        !           663:  */
        !           664: dhumctl(dev, bits, how)
        !           665:        dev_t dev;
        !           666:        int bits, how;
        !           667: {
        !           668:        register struct dhudevice *dhuaddr;
        !           669:        register int unit, mbits;
        !           670:        int s;
        !           671: 
        !           672:        unit = UNIT(dev);
        !           673:        dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr);
        !           674:        unit &= 0xf;
        !           675:        s = spl5();
        !           676:        dhuaddr->dhucsr = DHU_SELECT(unit) | DHU_IE;
        !           677:        /*
        !           678:         * combine byte from stat register (read only, bits 16..23)
        !           679:         * with lcr register (read write, bits 0..15).
        !           680:         */
        !           681:        mbits = dhuaddr->dhulcr | (dhuaddr->dhustat << 16);
        !           682:        switch (how) {
        !           683:        case DMSET:
        !           684:                mbits = (mbits & 0xff0000) | bits;
        !           685:                break;
        !           686: 
        !           687:        case DMBIS:
        !           688:                mbits |= bits;
        !           689:                break;
        !           690: 
        !           691:        case DMBIC:
        !           692:                mbits &= ~bits;
        !           693:                break;
        !           694: 
        !           695:        case DMGET:
        !           696:                (void) splx(s);
        !           697:                return(mbits);
        !           698:        }
        !           699:        dhuaddr->dhulcr = (mbits & 0xffff) | DHU_LC_RXEN;
        !           700:        dhuaddr->dhulcr2 = DHU_LC2_TXEN;
        !           701:        (void) splx(s);
        !           702:        return(mbits);
        !           703: }
        !           704: 
        !           705: /*
        !           706:  * Reset state of driver if UBA reset was necessary.
        !           707:  * Reset the line and modem control registers.
        !           708:  * restart transmitters.
        !           709:  */
        !           710: dhureset(uban)
        !           711:        int uban;
        !           712: {
        !           713:        register int dhu, unit;
        !           714:        register struct tty *tp;
        !           715:        register struct uba_device *ui;
        !           716:        register struct dhudevice *addr;
        !           717:        int i;
        !           718: 
        !           719:        for (dhu = 0; dhu < NDHU; dhu++) {
        !           720:                ui = dhuinfo[dhu];
        !           721:                if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban)
        !           722:                        continue;
        !           723:                printf(" dhu%d", dhu);
        !           724:                if (dhu_ubinfo[uban]) {
        !           725:                        dhu_ubinfo[uban] = uballoc(uban, (caddr_t)cfree,
        !           726:                                            nclist*sizeof (struct cblock), 0);
        !           727:                        cbase[uban] = UBAI_ADDR(dhu_ubinfo[uban]);
        !           728:                }
        !           729:                addr = (struct dhudevice *)ui->ui_addr;
        !           730:                addr->dhucsr = DHU_SELECT(0) | DHU_IE;
        !           731:                addr->dhutimo = DHU_DEF_TIMO;
        !           732:                unit = dhu * 16;
        !           733:                for (i = 0; i < 16; i++) {
        !           734:                        tp = &dhu_tty[unit];
        !           735:                        if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
        !           736:                                dhuparam(unit);
        !           737:                                (void)dhumctl(unit, DHU_ON, DMSET);
        !           738:                                tp->t_state &= ~TS_BUSY;
        !           739:                                dhustart(tp);
        !           740:                        }
        !           741:                        unit++;
        !           742:                }
        !           743:        }
        !           744: }
        !           745: #endif

unix.superglobalmegacorp.com

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