Annotation of 43BSDReno/sys/vaxuba/dmx.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 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:  *     @(#)dmx.c       7.4 (Berkeley) 6/28/90
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * Common code for DMF32 and DMZ32 drivers
        !            11:  */
        !            12: #include "dmf.h"
        !            13: #include "dmz.h"
        !            14: #if NDMF + NDMZ > 0
        !            15: 
        !            16: #include "machine/pte.h"
        !            17: 
        !            18: #include "uba.h"
        !            19: #include "param.h"
        !            20: #include "conf.h"
        !            21: #include "user.h"
        !            22: #include "proc.h"
        !            23: #include "ioctl.h"
        !            24: #include "tty.h"
        !            25: #include "map.h"
        !            26: #include "buf.h"
        !            27: #include "vm.h"
        !            28: #include "bkmac.h"
        !            29: #include "clist.h"
        !            30: #include "file.h"
        !            31: #include "uio.h"
        !            32: #include "kernel.h"
        !            33: #include "syslog.h"
        !            34: 
        !            35: #include "dmx.h"
        !            36: #include "ubareg.h"
        !            37: #include "ubavar.h"
        !            38: #include "dmxreg.h"
        !            39: #include "dmreg.h"
        !            40: 
        !            41: #ifndef        PORTSELECTOR
        !            42: #define        ISPEED  TTYDEF_SPEED
        !            43: #define        LFLAG   TTYDEF_LFLAG
        !            44: #else
        !            45: #define        ISPEED  B4800
        !            46: #define        IFLAGS  (TTYDEF_LFLAG&~ECHO)
        !            47: #endif
        !            48: 
        !            49: #ifndef DMX_TIMEOUT
        !            50: #define DMX_TIMEOUT    10
        !            51: #endif
        !            52: int    dmx_timeout = DMX_TIMEOUT;              /* silo timeout, in ms */
        !            53: int    dmx_mindma = 4;                 /* don't dma below this point */
        !            54: 
        !            55: struct speedtab dmxspeedtab[] = {
        !            56:        0,      0,
        !            57:        75,     1,
        !            58:        110,    2,
        !            59:        134,    3,
        !            60:        150,    4,
        !            61:        300,    5,
        !            62:        600,    6,
        !            63:        1200,   7,
        !            64:        1800,   010,
        !            65:        2400,   012,
        !            66:        4800,   014,
        !            67:        9600,   016,
        !            68:        19200,  017,
        !            69:        EXTA,   017,
        !            70:        -1,     -1
        !            71: };
        !            72: /*
        !            73:  * The clist space is mapped by the drivers onto each UNIBUS.
        !            74:  * The UBACVT macro converts a clist space address for unibus uban
        !            75:  * into an I/O space address for the DMA routine.
        !            76:  */
        !            77: int    cbase[NUBA];                    /* base address in unibus map */
        !            78: #define        UBACVT(x, uban)         (cbase[uban] + ((x)-(char *)cfree))
        !            79: 
        !            80: int    ttrstrt();
        !            81: 
        !            82: /*
        !            83:  * DMF/DMZ open common code
        !            84:  */
        !            85: dmxopen(tp, sc, flag)
        !            86:        register struct tty *tp;
        !            87:        register struct dmx_softc *sc;
        !            88: {
        !            89:        int s, unit, error = 0;
        !            90:        int dmxparam();
        !            91: 
        !            92:        s = spltty();
        !            93:        if ((sc->dmx_flags & DMX_ACTIVE) == 0) {
        !            94:                sc->dmx_octet->csr |= DMF_IE;
        !            95:                sc->dmx_flags |= DMX_ACTIVE;
        !            96:                sc->dmx_octet->rsp = dmx_timeout;
        !            97:        }
        !            98:        splx(s);
        !            99:        if (tp->t_state & TS_XCLUDE && u.u_uid != 0)
        !           100:                return (EBUSY);
        !           101:        /*
        !           102:         * If this is first open, initialize tty state to default.
        !           103:         */
        !           104:        if ((tp->t_state&TS_ISOPEN) == 0) {
        !           105:                tp->t_state |= TS_WOPEN;
        !           106:                ttychars(tp);
        !           107: #ifndef PORTSELECTOR
        !           108:                if (tp->t_ispeed == 0) {
        !           109: #endif
        !           110:                        tp->t_iflag = TTYDEF_IFLAG;
        !           111:                         tp->t_oflag = TTYDEF_OFLAG;
        !           112:                         tp->t_cflag = TTYDEF_CFLAG;
        !           113:                         tp->t_lflag = LFLAG;
        !           114:                         tp->t_ispeed = tp->t_ospeed = ISPEED;
        !           115: #ifdef PORTSELECTOR
        !           116:                        tp->t_cflag |= HUPCL;
        !           117: #else
        !           118:                }
        !           119: #endif
        !           120:        }
        !           121:        dmxparam(tp, &tp->t_termios);
        !           122: 
        !           123:        unit = minor(tp->t_dev) & 07;
        !           124:        /*
        !           125:         * Wait for carrier, then process line discipline specific open.
        !           126:         */
        !           127:        s = spltty();
        !           128:        for (;;) {
        !           129:                if ((dmxmctl(tp, DMF_ON, DMSET) & DMF_CAR) ||
        !           130:                    (sc->dmx_softCAR & (1 << unit)))
        !           131:                        tp->t_state |= TS_CARR_ON;
        !           132:                if (tp->t_state&TS_CARR_ON || flag&O_NONBLOCK ||
        !           133:                    tp->t_cflag&CLOCAL)
        !           134:                        break;
        !           135:                tp->t_state |= TS_WOPEN;
        !           136:                if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
        !           137:                    ttopen, 0))
        !           138:                        break;
        !           139:        }
        !           140:        splx(s);
        !           141:        if (error)
        !           142:                return (error);
        !           143:        return ((*linesw[tp->t_line].l_open)(tp->t_dev, tp));
        !           144: }
        !           145: 
        !           146: dmxclose(tp)
        !           147:        register struct tty *tp;
        !           148: {
        !           149: 
        !           150:        (*linesw[tp->t_line].l_close)(tp);
        !           151:        (void) dmxmctl(tp, DMF_BRK, DMBIC);
        !           152:        if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)
        !           153:                (void) dmxmctl(tp, DMF_OFF, DMSET);
        !           154:        return (ttyclose(tp));
        !           155: }
        !           156: 
        !           157: dmxrint(sc)
        !           158:        register struct dmx_softc *sc;
        !           159: {
        !           160:        register c, cc;
        !           161:        register struct tty *tp;
        !           162:        register struct dmx_octet *addr;
        !           163:        int unit;
        !           164:        int overrun = 0;
        !           165: 
        !           166:        addr = (struct dmx_octet *)sc->dmx_octet;
        !           167:        /*
        !           168:         * Loop fetching characters from the silo for this
        !           169:         * octet until there are no more in the silo.
        !           170:         */
        !           171:        while ((c = addr->rbuf) < 0) {
        !           172:                cc = c&0xff;
        !           173:                unit = (c >> 8) & 07;
        !           174:                tp = sc->dmx_tty + unit;
        !           175:                if (c & DMF_DSC) {
        !           176:                        addr->csr = DMF_IE | DMFIR_RMSTSC | unit;
        !           177:                        if (addr->rmstsc & DMF_CAR)
        !           178:                                (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        !           179:                        else if ((sc->dmx_softCAR & (1 << unit)) == 0 &&
        !           180:                            (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
        !           181:                                addr->csr = DMF_IE | DMFIR_LCR | unit;
        !           182:                                addr->lctms = DMF_ENA;
        !           183:                        }
        !           184:                        continue;
        !           185:                }
        !           186:                if ((tp->t_state&TS_ISOPEN) == 0) {
        !           187:                        wakeup((caddr_t)&tp->t_rawq);
        !           188: #ifdef PORTSELECTOR
        !           189:                        if ((tp->t_state & TS_WOPEN) == 0)
        !           190: #endif
        !           191:                                continue;
        !           192:                }
        !           193:                if (c & (DMF_PE|DMF_DO|DMF_FE)) {
        !           194:                        if (c & DMF_PE)
        !           195:                                cc |= TTY_PE;
        !           196:                        if ((c & DMF_DO) && overrun == 0) {
        !           197:                                log(LOG_WARNING,
        !           198:                                    "dm%c%d: silo overflow, line %d\n",
        !           199:                                    sc->dmx_type, sc->dmx_unit,
        !           200:                                    sc->dmx_unit0 + unit);
        !           201:                                overrun = 1;
        !           202:                        }
        !           203:                        if (c & DMF_FE)
        !           204:                                cc |= TTY_FE;
        !           205:                }
        !           206:                (*linesw[tp->t_line].l_rint)(cc, tp);
        !           207:        }
        !           208: }
        !           209: 
        !           210: dmxioctl(tp, cmd, data, flag)
        !           211:        register struct tty *tp;
        !           212:        caddr_t data;
        !           213: {
        !           214:        int error;
        !           215: 
        !           216:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        !           217:        if (error >= 0)
        !           218:                return (error);
        !           219:        error = ttioctl(tp, cmd, data, flag);
        !           220:        if (error >= 0)
        !           221:                return (error);
        !           222: 
        !           223:        switch (cmd) {
        !           224: 
        !           225:        case TIOCSBRK:
        !           226:                (void) dmxmctl(tp, DMF_BRK, DMBIS);
        !           227:                break;
        !           228: 
        !           229:        case TIOCCBRK:
        !           230:                (void) dmxmctl(tp, DMF_BRK, DMBIC);
        !           231:                break;
        !           232: 
        !           233:        case TIOCSDTR:
        !           234:                (void) dmxmctl(tp, DMF_DTR|DMF_RTS, DMBIS);
        !           235:                break;
        !           236: 
        !           237:        case TIOCCDTR:
        !           238:                (void) dmxmctl(tp, DMF_DTR|DMF_RTS, DMBIC);
        !           239:                break;
        !           240: 
        !           241:        case TIOCMSET:
        !           242:                (void) dmxmctl(tp, dmtodmx(*(int *)data), DMSET);
        !           243:                break;
        !           244: 
        !           245:        case TIOCMBIS:
        !           246:                (void) dmxmctl(tp, dmtodmx(*(int *)data), DMBIS);
        !           247:                break;
        !           248: 
        !           249:        case TIOCMBIC:
        !           250:                (void) dmxmctl(tp, dmtodmx(*(int *)data), DMBIC);
        !           251:                break;
        !           252: 
        !           253:        case TIOCMGET:
        !           254:                *(int *)data = dmxmctl(tp, 0, DMGET);
        !           255:                break;
        !           256: 
        !           257:        default:
        !           258:                return (ENOTTY);
        !           259:        }
        !           260:        return (0);
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * modem control
        !           265:  * "bits" are dmf/dmz lcr format;
        !           266:  * return of DMGET is DM11 format.
        !           267:  */
        !           268: dmxmctl(tp, bits, how)
        !           269:        struct tty *tp;
        !           270:        int bits, how;
        !           271: {
        !           272:        register struct dmx_octet *addr;
        !           273:        register int unit, mbits, lcr;
        !           274:        int s;
        !           275: 
        !           276:        unit = minor(tp->t_dev) & 07;
        !           277:        addr = (struct dmx_octet *)(tp->t_addr);
        !           278: 
        !           279:        s = spltty();
        !           280:        addr->csr = DMF_IE | DMFIR_RMSTSC | unit;
        !           281:        mbits = addr->rmstsc & 0xff00;
        !           282:        addr->csr = DMF_IE | DMFIR_LCR | unit;
        !           283:        lcr = addr->lctms;
        !           284: 
        !           285:        switch (how) {
        !           286:        case DMSET:
        !           287:                lcr = bits;
        !           288:                break;
        !           289: 
        !           290:        case DMBIS:
        !           291:                lcr |= bits;
        !           292:                break;
        !           293: 
        !           294:        case DMBIC:
        !           295:                lcr &= ~bits;
        !           296:                break;
        !           297: 
        !           298:        case DMGET:
        !           299:                splx(s);
        !           300:                return (dmxtodm(mbits, lcr));
        !           301:        }
        !           302:        addr->lctms = lcr;
        !           303:        (void) splx(s);
        !           304:        return (mbits);
        !           305: }
        !           306: 
        !           307: /*
        !           308:  * Routine to convert modem status from dm to dmf/dmz lctmr format.
        !           309:  */
        !           310: dmtodmx(bits)
        !           311:        register int bits;
        !           312: {
        !           313:        register int lcr = DMF_ENA;
        !           314: 
        !           315:        if (bits & DML_DTR)
        !           316:                lcr |= DMF_DTR;
        !           317:        if (bits & DML_RTS)
        !           318:                lcr |= DMF_RTS;
        !           319:        if (bits & DML_ST)
        !           320:                lcr |= DMF_SRTS;
        !           321:        if (bits & DML_USR)
        !           322:                lcr |= DMF_USRW;
        !           323:        return (lcr);
        !           324: }
        !           325: 
        !           326: /*
        !           327:  * Routine to convert modem status from dmf/dmz receive modem status
        !           328:  * and line control register to dm format.
        !           329:  * If dmf/dmz user modem read bit set, set DML_USR.
        !           330:  */
        !           331: dmxtodm(mstat, lcr)
        !           332:        register int mstat, lcr;
        !           333: {
        !           334: 
        !           335:        mstat = ((mstat & (DMF_DSR|DMF_RNG|DMF_CAR|DMF_CTS|DMF_SR)) >> 7) | 
        !           336:                ((mstat & DMF_USRR) >> 1) | DML_LE;
        !           337:        if (lcr & DMF_DTR)
        !           338:                mstat |= DML_DTR;
        !           339:        if (lcr & DMF_SRTS)
        !           340:                mstat |= DML_ST;
        !           341:        if (lcr & DMF_RTS)
        !           342:                mstat |= DML_RTS;
        !           343:        return (mstat);
        !           344: }
        !           345:  
        !           346: 
        !           347: /*
        !           348:  * Set parameters from open or ioctl into the hardware registers.
        !           349:  */
        !           350: dmxparam(tp, t)
        !           351:        register struct tty *tp;
        !           352:        register struct termios *t;
        !           353: {
        !           354:        register struct dmx_octet *addr;
        !           355:        register int lpar, lcr;
        !           356:        register int cflag = t->c_cflag;
        !           357:        int s, unit;
        !           358:        int ispeed = ttspeedtab(t->c_ispeed, dmxspeedtab);
        !           359:         int ospeed = ttspeedtab(t->c_ospeed, dmxspeedtab);
        !           360: 
        !           361:         /* check requested parameters */
        !           362:         if (ospeed < 0 || ispeed < 0 || (cflag&CSIZE) == CS5)
        !           363:                 return(EINVAL);
        !           364:         if (ispeed == 0)
        !           365:                 ispeed = ospeed;
        !           366:         /* and copy to tty */
        !           367:         tp->t_ispeed = t->c_ispeed;
        !           368:         tp->t_ospeed = t->c_ospeed;
        !           369:         tp->t_cflag = cflag;
        !           370: 
        !           371:        addr = (struct dmx_octet *)tp->t_addr;
        !           372:        unit = minor(tp->t_dev) & 07;
        !           373:        /*
        !           374:         * Block interrupts so parameters will be set
        !           375:         * before the line interrupts.
        !           376:         */
        !           377:        s = spltty();
        !           378:        addr->csr = unit | DMFIR_LCR | DMF_IE;
        !           379:        if (ospeed == 0) {
        !           380:                tp->t_cflag |= HUPCL;
        !           381:                (void) dmxmctl(tp, DMF_OFF, DMSET);
        !           382:                splx(s);
        !           383:                return;
        !           384:        }
        !           385:        lpar = (ospeed<<12) | (ispeed<<8);
        !           386:        lcr = DMF_ENA;
        !           387:        switch (cflag&CSIZE) {
        !           388:         case CS6:       lpar |= BITS6; break;
        !           389:         case CS7:       lpar |= BITS7; break;
        !           390:         case CS8:       lpar |= BITS8; break;
        !           391:         }
        !           392:         if (cflag&PARENB)
        !           393:                 lpar |= PENABLE;
        !           394:         if (!(cflag&PARODD))
        !           395:                 lpar |= EPAR;
        !           396:         if (cflag&CSTOPB)
        !           397:                 lpar |= TWOSB;
        !           398: 
        !           399:        lpar |= (unit&07);
        !           400:        addr->lpr = lpar;
        !           401:        addr->lctms = (addr->lctms &~ 0xff) | lcr;
        !           402:        splx(s);
        !           403:        return 0;
        !           404: }
        !           405: 
        !           406: /*
        !           407:  * Process a transmit interrupt on an octet.
        !           408:  */
        !           409: dmxxint(sc)
        !           410:        register struct dmx_softc *sc;
        !           411: {
        !           412:        register struct tty *tp;
        !           413:        register struct dmx_octet *addr;
        !           414:        register int t;
        !           415: 
        !           416:        addr = (struct dmx_octet *)sc->dmx_octet;
        !           417:        while ((t = addr->csr) & DMF_TI) {
        !           418:                if (t & DMF_NXM)
        !           419:                        /* SHOULD RESTART OR SOMETHING... */
        !           420:                        printf("dm%c%d: NXM line %d\n", sc->dmx_type,
        !           421:                            sc->dmx_unit, sc->dmx_unit0 + (t >> 8 & 7));
        !           422:                t = t >> 8 & 7;
        !           423:                tp = sc->dmx_tty + t;
        !           424:                tp->t_state &= ~TS_BUSY;
        !           425:                if (tp->t_state & TS_FLUSH)
        !           426:                        tp->t_state &= ~TS_FLUSH;
        !           427: #define new
        !           428: #ifndef new
        !           429:                else if (sc->dmx_dmacount[t]) {
        !           430:                        short cntr;
        !           431: 
        !           432:                        /*
        !           433:                         * Do arithmetic in a short to make up
        !           434:                         * for lost 16&17 bits.
        !           435:                         */
        !           436:                        addr->csr = DMFIR_TBA | DMF_IE | t;
        !           437:                        cntr = addr->tba -
        !           438:                            UBACVT(tp->t_outq.c_cf, sc->dmx_ubanum);
        !           439:                        ndflush(&tp->t_outq, (int)cntr);
        !           440:                }
        !           441: #else
        !           442:                else if (sc->dmx_dmacount[t])
        !           443:                        ndflush(&tp->t_outq, sc->dmx_dmacount[t]);
        !           444:                sc->dmx_dmacount[t] = 0;
        !           445: #endif
        !           446:                (*linesw[tp->t_line].l_start)(tp);
        !           447:        }
        !           448: }
        !           449: 
        !           450: dmxstart(tp, sc)
        !           451:        register struct tty *tp;
        !           452:        struct dmx_softc *sc;
        !           453: {
        !           454:        register struct dmx_octet *addr;
        !           455:        register int unit, nch;
        !           456:        int s;
        !           457: 
        !           458:        unit = minor(tp->t_dev) & 07;
        !           459:        addr = (struct dmx_octet *)tp->t_addr;
        !           460: 
        !           461:        /*
        !           462:         * Must hold interrupts in following code to prevent
        !           463:         * state of the tp from changing.
        !           464:         */
        !           465:        s = spltty();
        !           466:        /*
        !           467:         * If it's currently active, or delaying, no need to do anything.
        !           468:         */
        !           469:        if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
        !           470:                goto out;
        !           471:        /*
        !           472:         * If there are still characters to dma or in the silo,
        !           473:         * just reenable the transmitter.
        !           474:         */
        !           475:        addr->csr = DMF_IE | DMFIR_TBUF | unit;
        !           476: #ifdef new
        !           477:        if (addr->tsc || sc->dmx_dmacount[unit]) {
        !           478: #else
        !           479:        if (addr->tsc) {
        !           480: #endif
        !           481:                addr->csr = DMF_IE | DMFIR_LCR | unit;
        !           482:                addr->lctms = addr->lctms | DMF_TE;
        !           483:                tp->t_state |= TS_BUSY;
        !           484:                goto out;
        !           485:        }
        !           486:        /*
        !           487:         * If there are sleepers, and output has drained below low
        !           488:         * water mark, wake up the sleepers.
        !           489:         */
        !           490:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           491:                if (tp->t_state & TS_ASLEEP) {
        !           492:                        tp->t_state &= ~TS_ASLEEP;
        !           493:                        wakeup((caddr_t)&tp->t_outq);
        !           494:                }
        !           495:                if (tp->t_wsel) {
        !           496:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           497:                        tp->t_wsel = 0;
        !           498:                        tp->t_state &= ~TS_WCOLL;
        !           499:                }
        !           500:        }
        !           501:        /*
        !           502:         * Now restart transmission unless the output queue is
        !           503:         * empty.
        !           504:         */
        !           505:        if (tp->t_outq.c_cc == 0)
        !           506:                goto out;
        !           507:        if (1 || !(tp->t_oflag&OPOST))  /*XXX*/
        !           508:                nch = ndqb(&tp->t_outq, 0);
        !           509:        else {
        !           510:                if ((nch = ndqb(&tp->t_outq, 0200)) == 0) {
        !           511:                        /*
        !           512:                        * If first thing on queue is a delay process it.
        !           513:                        */
        !           514:                        nch = getc(&tp->t_outq);
        !           515:                        timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
        !           516:                        tp->t_state |= TS_TIMEOUT;
        !           517:                        goto out;
        !           518:                }
        !           519:        }
        !           520:        /*
        !           521:         * If characters to transmit, restart transmission.
        !           522:         */
        !           523:        if (nch >= dmx_mindma) {
        !           524:                register car;
        !           525: 
        !           526:                sc->dmx_dmacount[unit] = nch;
        !           527:                addr->csr = DMF_IE | DMFIR_LCR | unit;
        !           528:                addr->lctms = addr->lctms | DMF_TE;
        !           529:                car = UBACVT(tp->t_outq.c_cf, sc->dmx_ubanum);
        !           530:                addr->csr = DMF_IE | DMFIR_TBA | unit;
        !           531:                addr->tba = car;
        !           532:                addr->tcc = ((car >> 2) & 0xc000) | nch;
        !           533:                tp->t_state |= TS_BUSY;
        !           534:        } else if (nch) {
        !           535:                register char *cp = tp->t_outq.c_cf;
        !           536:                register int i;
        !           537: 
        !           538: #ifndef new
        !           539:                sc->dmx_dmacount[unit] = 0;
        !           540: #endif
        !           541:                nch = MIN(nch, DMF_SILOCNT);
        !           542:                addr->csr = DMF_IE | DMFIR_LCR | unit;
        !           543:                addr->lctms = addr->lctms | DMF_TE;
        !           544:                addr->csr = DMF_IE | DMFIR_TBUF | unit;
        !           545:                for (i = 0; i < nch; i++)
        !           546:                        addr->tbuf = *cp++;
        !           547:                ndflush(&tp->t_outq, nch);
        !           548:                tp->t_state |= TS_BUSY;
        !           549:        }
        !           550: out:
        !           551:        splx(s);
        !           552: }
        !           553: 
        !           554: dmxstop(tp, sc, flag)
        !           555:        register struct tty *tp;
        !           556:        struct dmx_softc *sc;
        !           557: {
        !           558:        register struct dmx_octet *addr;
        !           559:        register unit = minor(tp->t_dev) & 7;
        !           560:        int s;
        !           561: 
        !           562:        addr = (struct dmx_octet *)tp->t_addr;
        !           563:        /*
        !           564:         * Block input/output interrupts while messing with state.
        !           565:         */
        !           566:        s = spltty();
        !           567:        if (flag) {
        !           568:                addr->csr = DMF_IE | DMFIR_TBUF | unit;
        !           569:                if (addr->tsc) {
        !           570:                        /*
        !           571:                         * Flush regardless of whether we're transmitting
        !           572:                         * (TS_BUSY), if the silo contains untransmitted
        !           573:                         * characters.
        !           574:                         */
        !           575:                        addr->csr = DMFIR_LCR | unit | DMF_IE;
        !           576:                        addr->lctms = addr->lctms | DMF_TE | DMF_FLUSH;
        !           577:                        /* this will interrupt so let dmxxint handle the rest */
        !           578:                        tp->t_state |= TS_FLUSH|TS_BUSY;
        !           579:                }
        !           580: /*#ifdef new*/
        !           581:                sc->dmx_dmacount[unit] = 0;
        !           582: /*#endif*/
        !           583:        } else {
        !           584:                /*
        !           585:                 * Stop transmission by disabling
        !           586:                 * the transmitter.  We'll pick up where we
        !           587:                 * left off by reenabling in dmxstart.
        !           588:                 */
        !           589:                addr->csr = DMFIR_LCR | unit | DMF_IE;
        !           590:                addr->lctms = addr->lctms &~ DMF_TE;
        !           591:                /* no interrupt here */
        !           592:                tp->t_state &= ~TS_BUSY;
        !           593:        }
        !           594:        splx(s);
        !           595: }
        !           596: #endif NDMF + NDMZ

unix.superglobalmegacorp.com

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