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