Annotation of Net2/arch/i386/isa/com.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1991 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  *
        !            33:  *     @(#)com.c       7.5 (Berkeley) 5/16/91
        !            34:  */
        !            35: 
        !            36: #include "com.h"
        !            37: #if NCOM > 0
        !            38: /*
        !            39:  * COM driver, based on HP dca driver
        !            40:  * uses National Semiconductor NS16450/NS16550AF UART
        !            41:  */
        !            42: #include "param.h"
        !            43: #include "systm.h"
        !            44: #include "ioctl.h"
        !            45: #include "tty.h"
        !            46: #include "proc.h"
        !            47: #include "user.h"
        !            48: #include "conf.h"
        !            49: #include "file.h"
        !            50: #include "uio.h"
        !            51: #include "kernel.h"
        !            52: #include "syslog.h"
        !            53: 
        !            54: #include "i386/isa/isa_device.h"
        !            55: #include "i386/isa/comreg.h"
        !            56: #include "i386/isa/ic/ns16550.h"
        !            57: 
        !            58: int    comprobe(), comattach(), comintr(), comstart(), comparam();
        !            59: 
        !            60: struct isa_driver comdriver = {
        !            61:        comprobe, comattach, "com"
        !            62: };
        !            63: 
        !            64: int    comsoftCAR;
        !            65: int    com_active;
        !            66: int    com_hasfifo;
        !            67: int    ncom = NCOM;
        !            68: #ifdef COMCONSOLE
        !            69: int    comconsole = COMCONSOLE;
        !            70: #else
        !            71: int    comconsole = -1;
        !            72: #endif
        !            73: int    comconsinit;
        !            74: int    comdefaultrate = TTYDEF_SPEED;
        !            75: int    commajor;
        !            76: short com_addr[NCOM];
        !            77: struct tty com_tty[NCOM];
        !            78: 
        !            79: struct speedtab comspeedtab[] = {
        !            80:        0,      0,
        !            81:        50,     COMBRD(50),
        !            82:        75,     COMBRD(75),
        !            83:        110,    COMBRD(110),
        !            84:        134,    COMBRD(134),
        !            85:        150,    COMBRD(150),
        !            86:        200,    COMBRD(200),
        !            87:        300,    COMBRD(300),
        !            88:        600,    COMBRD(600),
        !            89:        1200,   COMBRD(1200),
        !            90:        1800,   COMBRD(1800),
        !            91:        2400,   COMBRD(2400),
        !            92:        4800,   COMBRD(4800),
        !            93:        9600,   COMBRD(9600),
        !            94:        19200,  COMBRD(19200),
        !            95:        38400,  COMBRD(38400),
        !            96:        57600,  COMBRD(57600),
        !            97:        -1,     -1
        !            98: };
        !            99: 
        !           100: extern struct tty *constty;
        !           101: #ifdef KGDB
        !           102: #include "machine/remote-sl.h"
        !           103: 
        !           104: extern int kgdb_dev;
        !           105: extern int kgdb_rate;
        !           106: extern int kgdb_debug_init;
        !           107: #endif
        !           108: 
        !           109: #define        UNIT(x)         minor(x)
        !           110: 
        !           111: comprobe(dev)
        !           112: struct isa_device *dev;
        !           113: {
        !           114:        /* force access to id reg */
        !           115:        outb(dev->id_iobase+com_cfcr, 0);
        !           116:        outb(dev->id_iobase+com_iir, 0);
        !           117:        if ((inb(dev->id_iobase+com_iir) & 0x38) == 0)
        !           118:                return(1);
        !           119:        return(1);
        !           120: 
        !           121: }
        !           122: 
        !           123: 
        !           124: int
        !           125: comattach(isdp)
        !           126: struct isa_device *isdp;
        !           127: {
        !           128:        struct  tty     *tp;
        !           129:        u_char          unit;
        !           130:        int             port = isdp->id_iobase;
        !           131: 
        !           132:        unit = isdp->id_unit;
        !           133:        if (unit == comconsole)
        !           134:                DELAY(100000);
        !           135:        com_addr[unit] = port;
        !           136:        com_active |= 1 << unit;
        !           137:        comsoftCAR |= 1 << unit;        /* XXX */
        !           138: 
        !           139:        /* look for a NS 16550AF UART with FIFOs */
        !           140:        outb(port+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14);
        !           141:        DELAY(100);
        !           142:        if ((inb(port+com_iir) & IIR_FIFO_MASK) == IIR_FIFO_MASK)
        !           143:                com_hasfifo |= 1 << unit;
        !           144: 
        !           145:        outb(port+com_ier, 0);
        !           146:        outb(port+com_mcr, 0 | MCR_IENABLE);
        !           147: #ifdef KGDB
        !           148:        if (kgdb_dev == makedev(commajor, unit)) {
        !           149:                if (comconsole == unit)
        !           150:                        kgdb_dev = -1;  /* can't debug over console port */
        !           151:                else {
        !           152:                        (void) cominit(unit, kgdb_rate);
        !           153:                        if (kgdb_debug_init) {
        !           154:                                /*
        !           155:                                 * Print prefix of device name,
        !           156:                                 * let kgdb_connect print the rest.
        !           157:                                 */
        !           158:                                printf("com%d: ", unit);
        !           159:                                kgdb_connect(1);
        !           160:                        } else
        !           161:                                printf("com%d: kgdb enabled\n", unit);
        !           162:                }
        !           163:        }
        !           164: #endif
        !           165:        /*
        !           166:         * Need to reset baud rate, etc. of next print so reset comconsinit.
        !           167:         * Also make sure console is always "hardwired"
        !           168:         */
        !           169:        if (unit == comconsole) {
        !           170:                comconsinit = 0;
        !           171:                comsoftCAR |= (1 << unit);
        !           172:        }
        !           173:        return (1);
        !           174: }
        !           175: 
        !           176: /* ARGSUSED */
        !           177: #ifdef __STDC__
        !           178: comopen(dev_t dev, int flag, int mode, struct proc *p)
        !           179: #else
        !           180: comopen(dev, flag, mode, p)
        !           181:        dev_t dev;
        !           182:        int flag, mode;
        !           183:        struct proc *p;
        !           184: #endif
        !           185: {
        !           186:        register struct tty *tp;
        !           187:        register int unit;
        !           188:        int error = 0;
        !           189:  
        !           190:        unit = UNIT(dev);
        !           191:        if (unit >= NCOM || (com_active & (1 << unit)) == 0)
        !           192:                return (ENXIO);
        !           193:        tp = &com_tty[unit];
        !           194:        tp->t_oproc = comstart;
        !           195:        tp->t_param = comparam;
        !           196:        tp->t_dev = dev;
        !           197:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           198:                tp->t_state |= TS_WOPEN;
        !           199:                ttychars(tp);
        !           200:                if (tp->t_ispeed == 0) {
        !           201:                        tp->t_iflag = TTYDEF_IFLAG;
        !           202:                        tp->t_oflag = TTYDEF_OFLAG;
        !           203:                        tp->t_cflag = TTYDEF_CFLAG;
        !           204:                        tp->t_lflag = TTYDEF_LFLAG;
        !           205:                        tp->t_ispeed = tp->t_ospeed = comdefaultrate;
        !           206:                }
        !           207:                comparam(tp, &tp->t_termios);
        !           208:                ttsetwater(tp);
        !           209:        } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0)
        !           210:                return (EBUSY);
        !           211:        (void) spltty();
        !           212:        (void) commctl(dev, MCR_DTR | MCR_RTS, DMSET);
        !           213:        if ((comsoftCAR & (1 << unit)) || (commctl(dev, 0, DMGET) & MSR_DCD))
        !           214:                tp->t_state |= TS_CARR_ON;
        !           215:        while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 &&
        !           216:               (tp->t_state & TS_CARR_ON) == 0) {
        !           217:                tp->t_state |= TS_WOPEN;
        !           218:                if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH,
        !           219:                    ttopen, 0))
        !           220:                        break;
        !           221:        }
        !           222:        (void) spl0();
        !           223:        if (error == 0)
        !           224:                error = (*linesw[tp->t_line].l_open)(dev, tp);
        !           225:        return (error);
        !           226: }
        !           227:  
        !           228: /*ARGSUSED*/
        !           229: comclose(dev, flag, mode, p)
        !           230:        dev_t dev;
        !           231:        int flag, mode;
        !           232:        struct proc *p;
        !           233: {
        !           234:        register struct tty *tp;
        !           235:        register com;
        !           236:        register int unit;
        !           237:  
        !           238:        unit = UNIT(dev);
        !           239:        com = com_addr[unit];
        !           240:        tp = &com_tty[unit];
        !           241:        (*linesw[tp->t_line].l_close)(tp, flag);
        !           242:        outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK);
        !           243: #ifdef KGDB
        !           244:        /* do not disable interrupts if debugging */
        !           245:        if (kgdb_dev != makedev(commajor, unit))
        !           246: #endif
        !           247:        outb(com+com_ier, 0);
        !           248:        if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 
        !           249:            (tp->t_state&TS_ISOPEN) == 0)
        !           250:                (void) commctl(dev, 0, DMSET);
        !           251:        ttyclose(tp);
        !           252:        return(0);
        !           253: }
        !           254:  
        !           255: comread(dev, uio, flag)
        !           256:        dev_t dev;
        !           257:        struct uio *uio;
        !           258: {
        !           259:        register struct tty *tp = &com_tty[UNIT(dev)];
        !           260:  
        !           261:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
        !           262: }
        !           263:  
        !           264: comwrite(dev, uio, flag)
        !           265:        dev_t dev;
        !           266:        struct uio *uio;
        !           267: {
        !           268:        int unit = UNIT(dev);
        !           269:        register struct tty *tp = &com_tty[unit];
        !           270:  
        !           271:        /*
        !           272:         * (XXX) We disallow virtual consoles if the physical console is
        !           273:         * a serial port.  This is in case there is a display attached that
        !           274:         * is not the console.  In that situation we don't need/want the X
        !           275:         * server taking over the console.
        !           276:         */
        !           277:        if (constty && unit == comconsole)
        !           278:                constty = NULL;
        !           279:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
        !           280: }
        !           281:  
        !           282: comintr(unit)
        !           283:        register int unit;
        !           284: {
        !           285:        register com;
        !           286:        register u_char code;
        !           287:        register struct tty *tp;
        !           288: 
        !           289:        com = com_addr[unit];
        !           290:        while (1) {
        !           291:                code = inb(com+com_iir);
        !           292:                switch (code & IIR_IMASK) {
        !           293:                case IIR_NOPEND:
        !           294:                        return (1);
        !           295:                case IIR_RXTOUT:
        !           296:                case IIR_RXRDY:
        !           297:                        tp = &com_tty[unit];
        !           298: /*
        !           299:  * Process received bytes.  Inline for speed...
        !           300:  */
        !           301: #ifdef KGDB
        !           302: #define        RCVBYTE() \
        !           303:                        code = inb(com+com_data); \
        !           304:                        if ((tp->t_state & TS_ISOPEN) == 0) { \
        !           305:                                if (kgdb_dev == makedev(commajor, unit) && \
        !           306:                                    code == FRAME_END) \
        !           307:                                        kgdb_connect(0); /* trap into kgdb */ \
        !           308:                        } else \
        !           309:                                (*linesw[tp->t_line].l_rint)(code, tp)
        !           310: #else
        !           311: #define        RCVBYTE() \
        !           312:                        code = inb(com+com_data); \
        !           313:                        if (tp->t_state & TS_ISOPEN) \
        !           314:                                (*linesw[tp->t_line].l_rint)(code, tp)
        !           315: #endif
        !           316: 
        !           317:                        RCVBYTE();
        !           318: 
        !           319:                        if (com_hasfifo & (1 << unit))
        !           320:                                while ((code = inb(com+com_lsr)) & LSR_RCV_MASK) {
        !           321:                                        if (code == LSR_RXRDY) {
        !           322:                                                RCVBYTE();
        !           323:                                        } else
        !           324:                                                comeint(unit, code, com);
        !           325:                                }
        !           326:                        break;
        !           327:                case IIR_TXRDY:
        !           328:                        tp = &com_tty[unit];
        !           329:                        tp->t_state &=~ (TS_BUSY|TS_FLUSH);
        !           330:                        if (tp->t_line)
        !           331:                                (*linesw[tp->t_line].l_start)(tp);
        !           332:                        else
        !           333:                                comstart(tp);
        !           334:                        break;
        !           335:                case IIR_RLS:
        !           336:                        comeint(unit, inb(com+com_lsr), com);
        !           337:                        break;
        !           338:                default:
        !           339:                        if (code & IIR_NOPEND)
        !           340:                                return (1);
        !           341:                        log(LOG_WARNING, "com%d: weird interrupt: 0x%x\n",
        !           342:                            unit, code);
        !           343:                        /* fall through */
        !           344:                case IIR_MLSC:
        !           345:                        commint(unit, com);
        !           346:                        break;
        !           347:                }
        !           348:        }
        !           349: }
        !           350: 
        !           351: comeint(unit, stat, com)
        !           352:        register int unit, stat;
        !           353:        register com;
        !           354: {
        !           355:        register struct tty *tp;
        !           356:        register int c;
        !           357: 
        !           358:        tp = &com_tty[unit];
        !           359:        c = inb(com+com_data);
        !           360:        if ((tp->t_state & TS_ISOPEN) == 0) {
        !           361: #ifdef KGDB
        !           362:                /* we don't care about parity errors */
        !           363:                if (((stat & (LSR_BI|LSR_FE|LSR_PE)) == LSR_PE) &&
        !           364:                    kgdb_dev == makedev(commajor, unit) && c == FRAME_END)
        !           365:                        kgdb_connect(0); /* trap into kgdb */
        !           366: #endif
        !           367:                return;
        !           368:        }
        !           369:        if (stat & (LSR_BI | LSR_FE))
        !           370:                c |= TTY_FE;
        !           371:        else if (stat & LSR_PE)
        !           372:                c |= TTY_PE;
        !           373:        else if (stat & LSR_OE)
        !           374:                log(LOG_WARNING, "com%d: silo overflow\n", unit);
        !           375:        (*linesw[tp->t_line].l_rint)(c, tp);
        !           376: }
        !           377: 
        !           378: commint(unit, com)
        !           379:        register int unit;
        !           380:        register com;
        !           381: {
        !           382:        register struct tty *tp;
        !           383:        register int stat;
        !           384: 
        !           385:        tp = &com_tty[unit];
        !           386:        stat = inb(com+com_msr);
        !           387:        if ((stat & MSR_DDCD) && (comsoftCAR & (1 << unit)) == 0) {
        !           388:                if (stat & MSR_DCD)
        !           389:                        (void)(*linesw[tp->t_line].l_modem)(tp, 1);
        !           390:                else if ((*linesw[tp->t_line].l_modem)(tp, 0) == 0)
        !           391:                        outb(com+com_mcr,
        !           392:                                inb(com+com_mcr) & ~(MCR_DTR | MCR_RTS) | MCR_IENABLE);
        !           393:        } else if ((stat & MSR_DCTS) && (tp->t_state & TS_ISOPEN) &&
        !           394:                   (tp->t_flags & CRTSCTS)) {
        !           395:                /* the line is up and we want to do rts/cts flow control */
        !           396:                if (stat & MSR_CTS) {
        !           397:                        tp->t_state &=~ TS_TTSTOP;
        !           398:                        ttstart(tp);
        !           399:                } else
        !           400:                        tp->t_state |= TS_TTSTOP;
        !           401:        }
        !           402: }
        !           403: 
        !           404: comioctl(dev, cmd, data, flag)
        !           405:        dev_t dev;
        !           406:        caddr_t data;
        !           407: {
        !           408:        register struct tty *tp;
        !           409:        register int unit = UNIT(dev);
        !           410:        register com;
        !           411:        register int error;
        !           412:  
        !           413:        tp = &com_tty[unit];
        !           414:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
        !           415:        if (error >= 0)
        !           416:                return (error);
        !           417:        error = ttioctl(tp, cmd, data, flag);
        !           418:        if (error >= 0)
        !           419:                return (error);
        !           420: 
        !           421:        com = com_addr[unit];
        !           422:        switch (cmd) {
        !           423: 
        !           424:        case TIOCSBRK:
        !           425:                outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_SBREAK);
        !           426:                break;
        !           427: 
        !           428:        case TIOCCBRK:
        !           429:                outb(com+com_cfcr, inb(com+com_cfcr) & ~CFCR_SBREAK);
        !           430:                break;
        !           431: 
        !           432:        case TIOCSDTR:
        !           433:                (void) commctl(dev, MCR_DTR | MCR_RTS, DMBIS);
        !           434:                break;
        !           435: 
        !           436:        case TIOCCDTR:
        !           437:                (void) commctl(dev, MCR_DTR | MCR_RTS, DMBIC);
        !           438:                break;
        !           439: 
        !           440:        case TIOCMSET:
        !           441:                (void) commctl(dev, *(int *)data, DMSET);
        !           442:                break;
        !           443: 
        !           444:        case TIOCMBIS:
        !           445:                (void) commctl(dev, *(int *)data, DMBIS);
        !           446:                break;
        !           447: 
        !           448:        case TIOCMBIC:
        !           449:                (void) commctl(dev, *(int *)data, DMBIC);
        !           450:                break;
        !           451: 
        !           452:        case TIOCMGET:
        !           453:                *(int *)data = commctl(dev, 0, DMGET);
        !           454:                break;
        !           455: 
        !           456:        default:
        !           457:                return (ENOTTY);
        !           458:        }
        !           459:        return (0);
        !           460: }
        !           461: 
        !           462: comparam(tp, t)
        !           463:        register struct tty *tp;
        !           464:        register struct termios *t;
        !           465: {
        !           466:        register com;
        !           467:        register int cfcr, cflag = t->c_cflag;
        !           468:        int unit = UNIT(tp->t_dev);
        !           469:        int ospeed = ttspeedtab(t->c_ospeed, comspeedtab);
        !           470:  
        !           471:        /* check requested parameters */
        !           472:         if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed))
        !           473:                 return(EINVAL);
        !           474:         /* and copy to tty */
        !           475:         tp->t_ispeed = t->c_ispeed;
        !           476:         tp->t_ospeed = t->c_ospeed;
        !           477:         tp->t_cflag = cflag;
        !           478: 
        !           479:        com = com_addr[unit];
        !           480:        outb(com+com_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS /*| IER_EMSC*/);
        !           481:        if (ospeed == 0) {
        !           482:                (void) commctl(unit, 0, DMSET); /* hang up line */
        !           483:                return(0);
        !           484:        }
        !           485:        outb(com+com_cfcr, inb(com+com_cfcr) | CFCR_DLAB);
        !           486:        outb(com+com_data, ospeed & 0xFF);
        !           487:        outb(com+com_ier, ospeed >> 8);
        !           488:        switch (cflag&CSIZE) {
        !           489:        case CS5:
        !           490:                cfcr = CFCR_5BITS; break;
        !           491:        case CS6:
        !           492:                cfcr = CFCR_6BITS; break;
        !           493:        case CS7:
        !           494:                cfcr = CFCR_7BITS; break;
        !           495:        case CS8:
        !           496:                cfcr = CFCR_8BITS; break;
        !           497:        }
        !           498:        if (cflag&PARENB) {
        !           499:                cfcr |= CFCR_PENAB;
        !           500:                if ((cflag&PARODD) == 0)
        !           501:                        cfcr |= CFCR_PEVEN;
        !           502:        }
        !           503:        if (cflag&CSTOPB)
        !           504:                cfcr |= CFCR_STOPB;
        !           505:        outb(com+com_cfcr, cfcr);
        !           506: 
        !           507:        if (com_hasfifo & (1 << unit))
        !           508:                outb(com+com_fifo, FIFO_ENABLE | FIFO_TRIGGER_14);
        !           509: 
        !           510:        return(0);
        !           511: }
        !           512:  
        !           513: comstart(tp)
        !           514:        register struct tty *tp;
        !           515: {
        !           516:        register com;
        !           517:        int s, unit, c;
        !           518:  
        !           519:        unit = UNIT(tp->t_dev);
        !           520:        com = com_addr[unit];
        !           521:        s = spltty();
        !           522:        if (tp->t_state & (TS_TIMEOUT|TS_TTSTOP))
        !           523:                goto out;
        !           524:        if (tp->t_outq.c_cc <= tp->t_lowat) {
        !           525:                if (tp->t_state&TS_ASLEEP) {
        !           526:                        tp->t_state &= ~TS_ASLEEP;
        !           527:                        wakeup((caddr_t)&tp->t_outq);
        !           528:                }
        !           529:                if (tp->t_wsel) {
        !           530:                        selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
        !           531:                        tp->t_wsel = 0;
        !           532:                        tp->t_state &= ~TS_WCOLL;
        !           533:                }
        !           534:        }
        !           535:        if (tp->t_outq.c_cc == 0)
        !           536:                goto out;
        !           537:        if (inb(com+com_lsr) & LSR_TXRDY) {
        !           538:                c = getc(&tp->t_outq);
        !           539:                tp->t_state |= TS_BUSY;
        !           540:                outb(com+com_data, c);
        !           541:                if (com_hasfifo & (1 << unit))
        !           542:                        for (c = 1; c < 16 && tp->t_outq.c_cc; ++c)
        !           543:                                outb(com+com_data, getc(&tp->t_outq));
        !           544:        }
        !           545: out:
        !           546:        splx(s);
        !           547: }
        !           548:  
        !           549: /*
        !           550:  * Stop output on a line.
        !           551:  */
        !           552: /*ARGSUSED*/
        !           553: comstop(tp, flag)
        !           554:        register struct tty *tp;
        !           555: {
        !           556:        register int s;
        !           557: 
        !           558:        s = spltty();
        !           559:        if (tp->t_state & TS_BUSY) {
        !           560:                if ((tp->t_state&TS_TTSTOP)==0)
        !           561:                        tp->t_state |= TS_FLUSH;
        !           562:        }
        !           563:        splx(s);
        !           564: }
        !           565:  
        !           566: commctl(dev, bits, how)
        !           567:        dev_t dev;
        !           568:        int bits, how;
        !           569: {
        !           570:        register com;
        !           571:        register int unit;
        !           572:        int s;
        !           573: 
        !           574:        unit = UNIT(dev);
        !           575:        com = com_addr[unit];
        !           576:        s = spltty();
        !           577:        switch (how) {
        !           578: 
        !           579:        case DMSET:
        !           580:                outb(com+com_mcr, bits | MCR_IENABLE);
        !           581:                break;
        !           582: 
        !           583:        case DMBIS:
        !           584:                outb(com+com_mcr, inb(com+com_mcr) | bits | MCR_IENABLE);
        !           585:                break;
        !           586: 
        !           587:        case DMBIC:
        !           588:                outb(com+com_mcr, inb(com+com_mcr) & ~bits | MCR_IENABLE);
        !           589:                break;
        !           590: 
        !           591:        case DMGET:
        !           592:                bits = inb(com+com_msr);
        !           593:                break;
        !           594:        }
        !           595:        (void) splx(s);
        !           596:        return(bits);
        !           597: }
        !           598: 
        !           599: /*
        !           600:  * Following are all routines needed for COM to act as console
        !           601:  */
        !           602: #include "i386/i386/cons.h"
        !           603: 
        !           604: comcnprobe(cp)
        !           605:        struct consdev *cp;
        !           606: {
        !           607:        int unit;
        !           608: 
        !           609:        /* locate the major number */
        !           610:        for (commajor = 0; commajor < nchrdev; commajor++)
        !           611:                if (cdevsw[commajor].d_open == comopen)
        !           612:                        break;
        !           613: 
        !           614:        /* XXX: ick */
        !           615:        unit = CONUNIT;
        !           616:        com_addr[CONUNIT] = CONADDR;
        !           617: 
        !           618:        /* make sure hardware exists?  XXX */
        !           619: 
        !           620:        /* initialize required fields */
        !           621:        cp->cn_dev = makedev(commajor, unit);
        !           622:        cp->cn_tp = &com_tty[unit];
        !           623: #ifdef COMCONSOLE
        !           624:        cp->cn_pri = CN_REMOTE;         /* Force a serial port console */
        !           625: #else
        !           626:        cp->cn_pri = CN_NORMAL;
        !           627: #endif
        !           628: }
        !           629: 
        !           630: comcninit(cp)
        !           631:        struct consdev *cp;
        !           632: {
        !           633:        int unit = UNIT(cp->cn_dev);
        !           634: 
        !           635:        cominit(unit, comdefaultrate);
        !           636:        comconsole = unit;
        !           637:        comconsinit = 1;
        !           638: }
        !           639: 
        !           640: cominit(unit, rate)
        !           641:        int unit, rate;
        !           642: {
        !           643:        register int com;
        !           644:        int s;
        !           645:        short stat;
        !           646: 
        !           647: #ifdef lint
        !           648:        stat = unit; if (stat) return;
        !           649: #endif
        !           650:        com = com_addr[unit];
        !           651:        s = splhigh();
        !           652:        outb(com+com_cfcr, CFCR_DLAB);
        !           653:        rate = ttspeedtab(comdefaultrate, comspeedtab);
        !           654:        outb(com+com_data, rate & 0xFF);
        !           655:        outb(com+com_ier, rate >> 8);
        !           656:        outb(com+com_cfcr, CFCR_8BITS);
        !           657:        outb(com+com_ier, IER_ERXRDY | IER_ETXRDY);
        !           658:        outb(com+com_fifo, FIFO_ENABLE|FIFO_RCV_RST|FIFO_XMT_RST|FIFO_TRIGGER_14);
        !           659:        stat = inb(com+com_iir);
        !           660:        splx(s);
        !           661: }
        !           662: 
        !           663: comcngetc(dev)
        !           664: {
        !           665:        register com = com_addr[UNIT(dev)];
        !           666:        short stat;
        !           667:        int c, s;
        !           668: 
        !           669: #ifdef lint
        !           670:        stat = dev; if (stat) return(0);
        !           671: #endif
        !           672:        s = splhigh();
        !           673:        while (((stat = inb(com+com_lsr)) & LSR_RXRDY) == 0)
        !           674:                ;
        !           675:        c = inb(com+com_data);
        !           676:        stat = inb(com+com_iir);
        !           677:        splx(s);
        !           678:        return(c);
        !           679: }
        !           680: 
        !           681: /*
        !           682:  * Console kernel output character routine.
        !           683:  */
        !           684: comcnputc(dev, c)
        !           685:        dev_t dev;
        !           686:        register int c;
        !           687: {
        !           688:        register com = com_addr[UNIT(dev)];
        !           689:        register int timo;
        !           690:        short stat;
        !           691:        int s = splhigh();
        !           692: 
        !           693: #ifdef lint
        !           694:        stat = dev; if (stat) return;
        !           695: #endif
        !           696: #ifdef KGDB
        !           697:        if (dev != kgdb_dev)
        !           698: #endif
        !           699:        if (comconsinit == 0) {
        !           700:                (void) cominit(UNIT(dev), comdefaultrate);
        !           701:                comconsinit = 1;
        !           702:        }
        !           703:        /* wait for any pending transmission to finish */
        !           704:        timo = 50000;
        !           705:        while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)
        !           706:                ;
        !           707:        outb(com+com_data, c);
        !           708:        /* wait for this transmission to complete */
        !           709:        timo = 1500000;
        !           710:        while (((stat = inb(com+com_lsr)) & LSR_TXRDY) == 0 && --timo)
        !           711:                ;
        !           712:        /* clear any interrupts generated by this transmission */
        !           713:        stat = inb(com+com_iir);
        !           714:        splx(s);
        !           715: }
        !           716: #endif

unix.superglobalmegacorp.com

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