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

unix.superglobalmegacorp.com

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