Annotation of 43BSDReno/sys/hpdev/dca.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution is only permitted until one year after the first shipment
        !             6:  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
        !             7:  * binary forms are permitted provided that: (1) source distributions retain
        !             8:  * this entire copyright notice and comment, and (2) distributions including
        !             9:  * binaries display the following acknowledgement:  This product includes
        !            10:  * software developed by the University of California, Berkeley and its
        !            11:  * contributors'' in the documentation or other materials provided with the
        !            12:  * distribution and in all advertising materials mentioning features or use
        !            13:  * of this software.  Neither the name of the University nor the names of
        !            14:  * its contributors may be used to endorse or promote products derived from
        !            15:  * this software without specific prior written permission.
        !            16:  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            17:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            18:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            19:  *
        !            20:  *     @(#)dca.c       7.7 (Berkeley) 6/30/90
        !            21:  */
        !            22: 
        !            23: #include "dca.h"
        !            24: #if NDCA > 0
        !            25: /*
        !            26:  *  98626/98644/internal serial interface
        !            27:  */
        !            28: #include "param.h"
        !            29: #include "systm.h"
        !            30: #include "ioctl.h"
        !            31: #include "tty.h"
        !            32: #include "user.h"
        !            33: #include "conf.h"
        !            34: #include "file.h"
        !            35: #include "uio.h"
        !            36: #include "kernel.h"
        !            37: #include "syslog.h"
        !            38: 
        !            39: #include "device.h"
        !            40: #include "dcareg.h"
        !            41: #include "machine/cpu.h"
        !            42: #include "machine/isr.h"
        !            43: 
        !            44: int    dcaprobe();
        !            45: struct driver dcadriver = {
        !            46:        dcaprobe, "dca",
        !            47: };
        !            48: 
        !            49: int    dcastart(), dcaparam(), dcaintr();
        !            50: int    dcasoftCAR;
        !            51: int    dca_active;
        !            52: int    ndca = NDCA;
        !            53: int    dcaconsole = -1;
        !            54: int    dcadefaultrate = TTYDEF_SPEED;
        !            55: struct dcadevice *dca_addr[NDCA];
        !            56: struct tty dca_tty[NDCA];
        !            57: struct isr dcaisr[NDCA];
        !            58: 
        !            59: struct speedtab dcaspeedtab[] = {
        !            60:        0,      0,
        !            61:        50,     DCABRD(50),
        !            62:        75,     DCABRD(75),
        !            63:        110,    DCABRD(110),
        !            64:        134,    DCABRD(134),
        !            65:        150,    DCABRD(150),
        !            66:        200,    DCABRD(200),
        !            67:        300,    DCABRD(300),
        !            68:        600,    DCABRD(600),
        !            69:        1200,   DCABRD(1200),
        !            70:        1800,   DCABRD(1800),
        !            71:        2400,   DCABRD(2400),
        !            72:        4800,   DCABRD(4800),
        !            73:        9600,   DCABRD(9600),
        !            74:        19200,  DCABRD(19200),
        !            75:        38400,  DCABRD(38400),
        !            76:        -1,     -1
        !            77: };
        !            78: 
        !            79: extern struct tty *constty;
        !            80: #ifdef KGDB
        !            81: extern int kgdb_dev;
        !            82: extern int kgdb_rate;
        !            83: extern int kgdb_debug_init;
        !            84: #endif
        !            85: 
        !            86: #define        UNIT(x)         minor(x)
        !            87: 
        !            88: dcaprobe(hd)
        !            89:        register struct hp_device *hd;
        !            90: {
        !            91:        register struct dcadevice *dca;
        !            92:        register int unit;
        !            93: 
        !            94:        dca = (struct dcadevice *)hd->hp_addr;
        !            95:        if (dca->dca_irid != DCAID0 &&
        !            96:            dca->dca_irid != DCAREMID0 &&
        !            97:            dca->dca_irid != DCAID1 &&
        !            98:            dca->dca_irid != DCAREMID1)
        !            99:                return (0);
        !           100:        unit = hd->hp_unit;
        !           101:        if (unit == dcaconsole)
        !           102:                DELAY(100000);
        !           103:        dca->dca_irid = 0xFF;
        !           104:        DELAY(100);
        !           105: 
        !           106:        hd->hp_ipl = DCAIPL(dca->dca_ic);
        !           107:        dcaisr[unit].isr_ipl = hd->hp_ipl;
        !           108:        dcaisr[unit].isr_arg = unit;
        !           109:        dcaisr[unit].isr_intr = dcaintr;
        !           110:        dca_addr[unit] = dca;
        !           111:        dca_active |= 1 << unit;
        !           112:        dcasoftCAR = hd->hp_flags;
        !           113:        isrlink(&dcaisr[unit]);
        !           114: #ifdef KGDB
        !           115:        if (kgdb_dev == makedev(1, unit)) {
        !           116:                if (dcaconsole == unit)
        !           117:                        kgdb_dev = -1;  /* can't debug over console port */
        !           118:                else {
        !           119:                        (void) dcainit(unit);
        !           120:                        dcaconsole = -2; /* XXX */
        !           121:                        if (kgdb_debug_init) {
        !           122:                                printf("dca%d: kgdb waiting...", unit);
        !           123:                                /* trap into kgdb */
        !           124:                                asm("trap #15;");
        !           125:                                printf("connected.\n");
        !           126:                        } else
        !           127:                                printf("dca%d: kgdb enabled\n", unit);
        !           128:                }
        !           129:        }
        !           130: #endif
        !           131:        dca->dca_ic = IC_IE;
        !           132:        /*
        !           133:         * Need to reset baud rate, etc. of next print so reset dcaconsole.
        !           134:         * Also make sure console is always "hardwired"
        !           135:         */
        !           136:        if (unit == dcaconsole) {
        !           137:                dcaconsole = -1;
        !           138:                dcasoftCAR |= (1 << unit);
        !           139:        }
        !           140:        return (1);
        !           141: }
        !           142: 
        !           143: dcaopen(dev, flag)
        !           144:        dev_t dev;
        !           145: {
        !           146:        register struct tty *tp;
        !           147:        register int unit;
        !           148:        int error = 0;
        !           149:  
        !           150:        unit = UNIT(dev);
        !           151:        if (unit >= NDCA || (dca_active & (1 << unit)) == 0)
        !           152:                return (ENXIO);
        !           153:        tp = &dca_tty[unit];
        !           154:        tp->t_oproc = dcastart;
        !           155:        tp->t_param = dcaparam;
        !           156:        tp->t_dev = dev;
        !           157:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           158:                tp->t_state |= TS_WOPEN;
        !           159:                ttychars(tp);
        !           160:                tp->t_iflag = TTYDEF_IFLAG;
        !           161:                tp->t_oflag = TTYDEF_OFLAG;
        !           162:                tp->t_cflag = TTYDEF_CFLAG;
        !           163:                tp->t_lflag = TTYDEF_LFLAG;
        !           164:                tp->t_ispeed = tp->t_ospeed = dcadefaultrate;
        !           165:                dcaparam(tp, &tp->t_termios);
        !           166:                ttsetwater(tp);
        !           167:        } else if (tp->t_state&TS_XCLUDE && u.u_uid != 0)
        !           168:                return (EBUSY);
        !           169:        (void) dcamctl(dev, MCR_DTR | MCR_RTS, DMSET);
        !           170:        if ((dcasoftCAR & (1 << unit)) || (dcamctl(dev, 0, DMGET) & MSR_DCD))
        !           171:                tp->t_state |= TS_CARR_ON;
        !           172:        (void) spltty();
        !           173:        while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
        !           174:               (tp->t_state & TS_CARR_ON) == 0) {
        !           175:                tp->t_state |= TS_WOPEN;
        !           176:                if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
        !           177:                    ttopen, 0))
        !           178:                        break;
        !           179:        }
        !           180:        (void) spl0();
        !           181:        if (error == 0)
        !           182:                error = (*linesw[tp->t_line].l_open)(dev, tp);
        !           183:        return (error);
        !           184: }
        !           185:  
        !           186: /*ARGSUSED*/
        !           187: dcaclose(dev, flag)
        !           188:        dev_t dev;
        !           189: {
        !           190:        register struct tty *tp;
        !           191:        register struct dcadevice *dca;
        !           192:        register int unit;
        !           193:  
        !           194:        unit = UNIT(dev);
        !           195:        dca = dca_addr[unit];
        !           196:        tp = &dca_tty[unit];
        !           197:        (*linesw[tp->t_line].l_close)(tp);
        !           198:        dca->dca_cfcr &= ~CFCR_SBREAK;
        !           199: #ifdef KGDB
        !           200:        /* do not disable interrupts if debugging */
        !           201:        if (kgdb_dev != makedev(1, unit))
        !           202: #endif
        !           203:        dca->dca_ier = 0;
        !           204:        if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 
        !           205:            (tp->t_state&TS_ISOPEN) == 0)
        !           206:                (void) dcamctl(dev, 0, DMSET);
        !           207:        ttyclose(tp);
        !           208:        return(0);
        !           209: }
        !           210:  
        !           211: dcaread(dev, uio, flag)
        !           212:        dev_t dev;
        !           213:        struct uio *uio;
        !           214: {
        !           215:        register struct tty *tp = &dca_tty[UNIT(dev)];
        !           216:  
        !           217:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
        !           218: }
        !           219:  
        !           220: dcawrite(dev, uio, flag)
        !           221:        dev_t dev;
        !           222:        struct uio *uio;
        !           223: {
        !           224:        int unit = UNIT(dev);
        !           225:        register struct tty *tp = &dca_tty[unit];
        !           226:  
        !           227:        /*
        !           228:         * (XXX) We disallow virtual consoles if the physical console is
        !           229:         * a serial port.  This is in case there is a display attached that
        !           230:         * is not the console.  In that situation we don't need/want the X
        !           231:         * server taking over the console.
        !           232:         */
        !           233:        if (constty && unit == dcaconsole)
        !           234:                constty = NULL;
        !           235:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        !           236: }
        !           237:  
        !           238: dcaintr(unit)
        !           239:        register int unit;
        !           240: {
        !           241:        register struct dcadevice *dca;
        !           242:        register u_char code;
        !           243:        register struct tty *tp;
        !           244: 
        !           245:        dca = dca_addr[unit];
        !           246:        if ((dca->dca_ic & IC_IR) == 0)
        !           247:                return(0);
        !           248:        while (1) {
        !           249:                code = dca->dca_iir;
        !           250:                switch (code) {
        !           251:                case IIR_NOPEND:
        !           252:                        return (1);
        !           253:                case IIR_RXRDY:
        !           254:                        /* do time-critical read in-line */
        !           255:                        tp = &dca_tty[unit];
        !           256:                        code = dca->dca_data;
        !           257:                        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           258: #ifdef KGDB
        !           259:                                if (kgdb_dev == makedev(1, unit) &&
        !           260:                                    code == '!') {
        !           261:                                        printf("kgdb trap from dca%d\n", unit);
        !           262:                                        /* trap into kgdb */
        !           263:                                        asm("trap #15;");
        !           264:                                }
        !           265: #endif
        !           266:                        } else
        !           267:                                (*linesw[tp->t_line].l_rint)(code, tp);
        !           268:                        break;
        !           269:                case IIR_TXRDY:
        !           270:                        tp = &dca_tty[unit];
        !           271:                        tp->t_state &=~ (TS_BUSY|TS_FLUSH);
        !           272:                        if (tp->t_line)
        !           273:                                (*linesw[tp->t_line].l_start)(tp);
        !           274:                        else
        !           275:                                dcastart(tp);
        !           276:                        break;
        !           277:                case IIR_RLS:
        !           278:                        dcaeint(unit, dca);
        !           279:                        break;
        !           280:                default:
        !           281:                        if (code & IIR_NOPEND)
        !           282:                                return (1);
        !           283:                        log(LOG_WARNING, "dca%d: weird interrupt: 0x%x\n",
        !           284:                            unit, code);
        !           285:                        /* fall through */
        !           286:                case IIR_MLSC:
        !           287:                        dcamint(unit, dca);
        !           288:                        break;
        !           289:                }
        !           290:        }
        !           291: }
        !           292: 
        !           293: dcaeint(unit, dca)
        !           294:        register int unit;
        !           295:        register struct dcadevice *dca;
        !           296: {
        !           297:        register struct tty *tp;
        !           298:        register int stat, c;
        !           299: 
        !           300:        tp = &dca_tty[unit];
        !           301:        stat = dca->dca_lsr;
        !           302:        c = dca->dca_data;
        !           303:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           304: #ifdef KGDB
        !           305:                /* we don't care about parity errors */
        !           306:                if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&
        !           307:                    kgdb_dev == makedev(1, unit) && c == '!') {
        !           308:                        printf("kgdb trap from dca%d\n", unit);
        !           309:                        /* trap into kgdb */
        !           310:                        asm("trap #15;");
        !           311:                }
        !           312: #endif
        !           313:                return;
        !           314:        }
        !           315:        if (stat & (LSR_BI | LSR_FE))
        !           316:                c |= TTY_FE;
        !           317:        else if (stat & LSR_PE)
        !           318:                c |= TTY_PE;
        !           319:        else if (stat & LSR_OE)
        !           320:                log(LOG_WARNING, "dca%d: silo overflow\n", unit);
        !           321:        (*linesw[tp->t_line].l_rint)(c, tp);
        !           322: }
        !           323: 
        !           324: dcamint(unit, dca)
        !           325:        register int unit;
        !           326:        register struct dcadevice *dca;
        !           327: {
        !           328:        register struct tty *tp;
        !           329:        register int stat;
        !           330: 
        !           331:        tp = &dca_tty[unit];
        !           332:        stat = dca->dca_msr;
        !           333:        if ((stat & MSR_DDCD) && (dcasoftCAR & (1 << unit)) == 0) {
        !           334:                if (stat & MSR_DCD)
        !           335:                        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        !           336:                else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
        !           337:                        dca->dca_mcr &= ~(MCR_DTR | MCR_RTS);
        !           338:        } else if ((stat & MSR_DCTS) && (tp->t_state & TS_ISOPEN) &&
        !           339:                   (tp->t_flags & CRTSCTS)) {
        !           340:                /* the line is up and we want to do rts/cts flow control */
        !           341:                if (stat & MSR_CTS) {
        !           342:                        tp->t_state &=~ TS_TTSTOP;
        !           343:                        ttstart(tp);
        !           344:                } else
        !           345:                        tp->t_state |= TS_TTSTOP;
        !           346:        }
        !           347: }
        !           348: 
        !           349: dcaioctl(dev, cmd, data, flag)
        !           350:        dev_t dev;
        !           351:        caddr_t data;
        !           352: {
        !           353:        register struct tty *tp;
        !           354:        register int unit = UNIT(dev);
        !           355:        register struct dcadevice *dca;
        !           356:        register int error;
        !           357:  
        !           358:        tp = &dca_tty[unit];
        !           359:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        !           360:        if (error >= 0)
        !           361:                return (error);
        !           362:        error = ttioctl(tp, cmd, data, flag);
        !           363:        if (error >= 0)
        !           364:                return (error);
        !           365: 
        !           366:        dca = dca_addr[unit];
        !           367:        switch (cmd) {
        !           368: 
        !           369:        case TIOCSBRK:
        !           370:                dca->dca_cfcr |= CFCR_SBREAK;
        !           371:                break;
        !           372: 
        !           373:        case TIOCCBRK:
        !           374:                dca->dca_cfcr &= ~CFCR_SBREAK;
        !           375:                break;
        !           376: 
        !           377:        case TIOCSDTR:
        !           378:                (void) dcamctl(dev, MCR_DTR | MCR_RTS, DMBIS);
        !           379:                break;
        !           380: 
        !           381:        case TIOCCDTR:
        !           382:                (void) dcamctl(dev, MCR_DTR | MCR_RTS, DMBIC);
        !           383:                break;
        !           384: 
        !           385:        case TIOCMSET:
        !           386:                (void) dcamctl(dev, *(int *)data, DMSET);
        !           387:                break;
        !           388: 
        !           389:        case TIOCMBIS:
        !           390:                (void) dcamctl(dev, *(int *)data, DMBIS);
        !           391:                break;
        !           392: 
        !           393:        case TIOCMBIC:
        !           394:                (void) dcamctl(dev, *(int *)data, DMBIC);
        !           395:                break;
        !           396: 
        !           397:        case TIOCMGET:
        !           398:                *(int *)data = dcamctl(dev, 0, DMGET);
        !           399:                break;
        !           400: 
        !           401:        default:
        !           402:                return (ENOTTY);
        !           403:        }
        !           404:        return (0);
        !           405: }
        !           406: 
        !           407: dcaparam(tp, t)
        !           408:        register struct tty *tp;
        !           409:        register struct termios *t;
        !           410: {
        !           411:        register struct dcadevice *dca;
        !           412:        register int cfcr, cflag = t->c_cflag;
        !           413:        int unit = UNIT(tp->t_dev);
        !           414:        int ospeed = ttspeedtab(t->c_ospeed, dcaspeedtab);
        !           415:  
        !           416:        /* check requested parameters */
        !           417:         if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
        !           418:                 return(EINVAL);
        !           419:         /* and copy to tty */
        !           420:         tp->t_ispeed = t->c_ispeed;
        !           421:         tp->t_ospeed = t->c_ospeed;
        !           422:         tp->t_cflag = cflag;
        !           423: 
        !           424:        dca = dca_addr[unit];
        !           425:        dca->dca_ier = IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC;
        !           426:        if (ospeed == 0) {
        !           427:                (void) dcamctl(unit, 0, DMSET); /* hang up line */
        !           428:                return(0);
        !           429:        }
        !           430:        dca->dca_cfcr |= CFCR_DLAB;
        !           431:        dca->dca_data = ospeed & 0xFF;
        !           432:        dca->dca_ier = ospeed >> 8;
        !           433:        switch (cflag&CSIZE) {
        !           434:        case CS5:
        !           435:                cfcr = CFCR_5BITS; break;
        !           436:        case CS6:
        !           437:                cfcr = CFCR_6BITS; break;
        !           438:        case CS7:
        !           439:                cfcr = CFCR_7BITS; break;
        !           440:        case CS8:
        !           441:                cfcr = CFCR_8BITS; break;
        !           442:        }
        !           443:        if (cflag&PARENB) {
        !           444:                cfcr |= CFCR_PENAB;
        !           445:                if ((cflag&PARODD) == 0)
        !           446:                        cfcr |= CFCR_PEVEN;
        !           447:        }
        !           448:        if (cflag&CSTOPB)
        !           449:                cfcr |= CFCR_STOPB;
        !           450:        dca->dca_cfcr = cfcr;
        !           451:        return(0);
        !           452: }
        !           453:  
        !           454: dcastart(tp)
        !           455:        register struct tty *tp;
        !           456: {
        !           457:        register struct dcadevice *dca;
        !           458:        int s, unit, c;
        !           459:  
        !           460:        unit = UNIT(tp->t_dev);
        !           461:        dca = dca_addr[unit];
        !           462:        s = spltty();
        !           463:        if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
        !           464:                goto out;
        !           465:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           466:                if (tp->t_state&TS_ASLEEP) {
        !           467:                        tp->t_state &= ~TS_ASLEEP;
        !           468:                        wakeup((caddr_t)&tp->t_outq);
        !           469:                }
        !           470:                if (tp->t_wsel) {
        !           471:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           472:                        tp->t_wsel = 0;
        !           473:                        tp->t_state &= ~TS_WCOLL;
        !           474:                }
        !           475:        }
        !           476:        if (tp->t_outq.c_cc == 0)
        !           477:                goto out;
        !           478:        if (dca->dca_lsr & LSR_TXRDY) {
        !           479:                c = getc(&tp->t_outq);
        !           480:                tp->t_state |= TS_BUSY;
        !           481:                dca->dca_data = c;
        !           482:        }
        !           483: out:
        !           484:        splx(s);
        !           485: }
        !           486:  
        !           487: /*
        !           488:  * Stop output on a line.
        !           489:  */
        !           490: /*ARGSUSED*/
        !           491: dcastop(tp, flag)
        !           492:        register struct tty *tp;
        !           493: {
        !           494:        register int s;
        !           495: 
        !           496:        s = spltty();
        !           497:        if (tp->t_state & TS_BUSY) {
        !           498:                if ((tp->t_state&TS_TTSTOP)==0)
        !           499:                        tp->t_state |= TS_FLUSH;
        !           500:        }
        !           501:        splx(s);
        !           502: }
        !           503:  
        !           504: dcamctl(dev, bits, how)
        !           505:        dev_t dev;
        !           506:        int bits, how;
        !           507: {
        !           508:        register struct dcadevice *dca;
        !           509:        register int unit;
        !           510:        int s;
        !           511: 
        !           512:        unit = UNIT(dev);
        !           513:        dca = dca_addr[unit];
        !           514:        s = spltty();
        !           515:        switch (how) {
        !           516: 
        !           517:        case DMSET:
        !           518:                dca->dca_mcr = bits;
        !           519:                break;
        !           520: 
        !           521:        case DMBIS:
        !           522:                dca->dca_mcr |= bits;
        !           523:                break;
        !           524: 
        !           525:        case DMBIC:
        !           526:                dca->dca_mcr &= ~bits;
        !           527:                break;
        !           528: 
        !           529:        case DMGET:
        !           530:                bits = dca->dca_msr;
        !           531:                break;
        !           532:        }
        !           533:        (void) splx(s);
        !           534:        return(bits);
        !           535: }
        !           536: 
        !           537: /*
        !           538:  * Following are all routines needed for DCA to act as console
        !           539:  */
        !           540: #include "machine/cons.h"
        !           541: 
        !           542: dcacnprobe(cp)
        !           543:        struct consdev *cp;
        !           544: {
        !           545:        int unit, i;
        !           546:        extern int dcaopen();
        !           547: 
        !           548:        /* XXX: ick */
        !           549:        unit = CONUNIT;
        !           550:        dca_addr[CONUNIT] = CONADDR;
        !           551: 
        !           552:        /* make sure hardware exists */
        !           553:        if (badaddr((short *)dca_addr[unit])) {
        !           554:                cp->cn_pri = CN_DEAD;
        !           555:                return;
        !           556:        }
        !           557: 
        !           558:        /* locate the major number */
        !           559:        for (i = 0; i < nchrdev; i++)
        !           560:                if (cdevsw[i].d_open == dcaopen)
        !           561:                        break;
        !           562: 
        !           563:        /* initialize required fields */
        !           564:        cp->cn_dev = makedev(i, unit);
        !           565:        cp->cn_tp = &dca_tty[unit];
        !           566:        switch (dca_addr[unit]->dca_irid) {
        !           567:        case DCAID0:
        !           568:        case DCAID1:
        !           569:                cp->cn_pri = CN_NORMAL;
        !           570:                break;
        !           571:        case DCAREMID0:
        !           572:        case DCAREMID1:
        !           573:                cp->cn_pri = CN_REMOTE;
        !           574:                break;
        !           575:        default:
        !           576:                cp->cn_pri = CN_DEAD;
        !           577:                break;
        !           578:        }
        !           579: }
        !           580: 
        !           581: dcacninit(cp)
        !           582:        struct consdev *cp;
        !           583: {
        !           584:        int unit = UNIT(cp->cn_dev);
        !           585: 
        !           586:        dcainit(unit);
        !           587:        dcaconsole = unit;
        !           588: }
        !           589: 
        !           590: dcainit(unit)
        !           591:        int unit;
        !           592: {
        !           593:        register struct dcadevice *dca;
        !           594:        int s, rate;
        !           595:        short stat;
        !           596: 
        !           597: #ifdef lint
        !           598:        stat = unit; if (stat) return;
        !           599: #endif
        !           600:        dca = dca_addr[unit];
        !           601:        s = splhigh();
        !           602:        dca->dca_irid = 0xFF;
        !           603:        DELAY(100);
        !           604:        dca->dca_ic = IC_IE;
        !           605:        dca->dca_cfcr = CFCR_DLAB;
        !           606:        rate = ttspeedtab(dcadefaultrate, dcaspeedtab);
        !           607:        dca->dca_data = rate & 0xFF;
        !           608:        dca->dca_ier = rate >> 8;
        !           609:        dca->dca_cfcr = CFCR_8BITS;
        !           610:        dca->dca_ier = IER_ERXRDY | IER_ETXRDY;
        !           611:        stat = dca->dca_iir;
        !           612:        splx(s);
        !           613: }
        !           614: 
        !           615: dcacngetc(dev)
        !           616: {
        !           617:        register struct dcadevice *dca = dca_addr[UNIT(dev)];
        !           618:        short stat;
        !           619:        int c, s;
        !           620: 
        !           621: #ifdef lint
        !           622:        stat = dev; if (stat) return(0);
        !           623: #endif
        !           624:        s = splhigh();
        !           625:        while (((stat = dca->dca_lsr) & LSR_RXRDY) == 0)
        !           626:                ;
        !           627:        c = dca->dca_data;
        !           628:        stat = dca->dca_iir;
        !           629:        splx(s);
        !           630:        return(c);
        !           631: }
        !           632: 
        !           633: /*
        !           634:  * Console kernel output character routine.
        !           635:  */
        !           636: dcacnputc(dev, c)
        !           637:        dev_t dev;
        !           638:        register int c;
        !           639: {
        !           640:        register struct dcadevice *dca = dca_addr[UNIT(dev)];
        !           641:        register int timo;
        !           642:        short stat;
        !           643:        int s = splhigh();
        !           644: 
        !           645: #ifdef lint
        !           646:        stat = dev; if (stat) return;
        !           647: #endif
        !           648:        if (dcaconsole == -1) {
        !           649:                (void) dcainit(UNIT(dev));
        !           650:                dcaconsole = UNIT(dev);
        !           651:        }
        !           652:        /* wait for any pending transmission to finish */
        !           653:        timo = 50000;
        !           654:        while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)
        !           655:                ;
        !           656:        dca->dca_data = c;
        !           657:        /* wait for this transmission to complete */
        !           658:        timo = 1500000;
        !           659:        while (((stat = dca->dca_lsr) & LSR_TXRDY) == 0 && --timo)
        !           660:                ;
        !           661:        /* clear any interrupts generated by this transmission */
        !           662:        stat = dca->dca_iir;
        !           663:        splx(s);
        !           664: }
        !           665: #endif

unix.superglobalmegacorp.com

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