Annotation of 43BSDTahoe/sys/vaxuba/dhu.c, revision 1.1.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.