[BACK]Return to com.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / ic

Annotation of src/sys/dev/ic/com.c, Revision 1.138

1.138   ! mycroft     1: /*     $NetBSD: com.c,v 1.137 1998/02/19 09:33:33 mycroft Exp $        */
1.38      cgd         2:
1.1       cgd         3: /*-
1.99      mycroft     4:  * Copyright (c) 1993, 1994, 1995, 1996, 1997
1.71      mycroft     5:  *     Charles M. Hannum.  All rights reserved.
1.99      mycroft     6:  *
                      7:  * Interrupt processing and hardware flow control partly based on code from
                      8:  * Onno van der Linden and Gordon Ross.
                      9:  *
                     10:  * Redistribution and use in source and binary forms, with or without
                     11:  * modification, are permitted provided that the following conditions
                     12:  * are met:
                     13:  * 1. Redistributions of source code must retain the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer.
                     15:  * 2. Redistributions in binary form must reproduce the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer in the
                     17:  *    documentation and/or other materials provided with the distribution.
                     18:  * 3. All advertising materials mentioning features or use of this software
                     19:  *    must display the following acknowledgement:
                     20:  *     This product includes software developed by Charles M. Hannum.
                     21:  * 4. The name of the author may not be used to endorse or promote products
                     22:  *    derived from this software without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     25:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     26:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     27:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     28:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     29:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     30:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     32:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     33:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35:
                     36: /*
1.1       cgd        37:  * Copyright (c) 1991 The Regents of the University of California.
                     38:  * All rights reserved.
                     39:  *
                     40:  * Redistribution and use in source and binary forms, with or without
                     41:  * modification, are permitted provided that the following conditions
                     42:  * are met:
                     43:  * 1. Redistributions of source code must retain the above copyright
                     44:  *    notice, this list of conditions and the following disclaimer.
                     45:  * 2. Redistributions in binary form must reproduce the above copyright
                     46:  *    notice, this list of conditions and the following disclaimer in the
                     47:  *    documentation and/or other materials provided with the distribution.
                     48:  * 3. All advertising materials mentioning features or use of this software
                     49:  *    must display the following acknowledgement:
                     50:  *     This product includes software developed by the University of
                     51:  *     California, Berkeley and its contributors.
                     52:  * 4. Neither the name of the University nor the names of its contributors
                     53:  *    may be used to endorse or promote products derived from this software
                     54:  *    without specific prior written permission.
                     55:  *
                     56:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     57:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     58:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     59:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     60:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     61:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     62:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     63:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     64:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     65:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     66:  * SUCH DAMAGE.
                     67:  *
1.38      cgd        68:  *     @(#)com.c       7.5 (Berkeley) 5/16/91
1.1       cgd        69:  */
                     70:
                     71: /*
1.99      mycroft    72:  * COM driver, uses National Semiconductor NS16450/NS16550AF UART
1.116     fvdl       73:  * Supports automatic hardware flow control on StarTech ST16C650A UART
1.1       cgd        74:  */
1.115     explorer   75:
                     76: #include "rnd.h"
                     77: #if NRND > 0 && defined(RND_COM)
                     78: #include <sys/rnd.h>
                     79: #endif
                     80:
1.14      mycroft    81: #include <sys/param.h>
                     82: #include <sys/systm.h>
                     83: #include <sys/ioctl.h>
                     84: #include <sys/select.h>
                     85: #include <sys/tty.h>
                     86: #include <sys/proc.h>
                     87: #include <sys/user.h>
                     88: #include <sys/conf.h>
                     89: #include <sys/file.h>
                     90: #include <sys/uio.h>
                     91: #include <sys/kernel.h>
                     92: #include <sys/syslog.h>
                     93: #include <sys/types.h>
1.21      mycroft    94: #include <sys/device.h>
1.127     mycroft    95: #include <sys/malloc.h>
1.14      mycroft    96:
1.99      mycroft    97: #include <machine/intr.h>
1.82      mycroft    98: #include <machine/bus.h>
1.14      mycroft    99:
1.113     thorpej   100: #include <dev/ic/comreg.h>
                    101: #include <dev/ic/comvar.h>
1.60      cgd       102: #include <dev/ic/ns16550reg.h>
1.116     fvdl      103: #include <dev/ic/st16650reg.h>
1.65      christos  104: #ifdef COM_HAYESP
                    105: #include <dev/ic/hayespreg.h>
                    106: #endif
1.62      mycroft   107: #define        com_lcr com_cfcr
1.106     drochner  108: #include <dev/cons.h>
1.14      mycroft   109:
1.77      cgd       110: #include "com.h"
                    111:
1.65      christos  112: #ifdef COM_HAYESP
1.99      mycroft   113: int comprobeHAYESP __P((bus_space_handle_t hayespioh, struct com_softc *sc));
1.65      christos  114: #endif
1.102     thorpej   115:
1.104     drochner  116: #if defined(DDB) || defined(KGDB)
                    117: static void com_enable_debugport __P((struct com_softc *));
                    118: #endif
1.99      mycroft   119: void   com_attach_subr __P((struct com_softc *sc));
1.131     marc      120: void   com_config      __P((struct com_softc *));
1.109     is        121: int    comspeed        __P((long, long));
1.106     drochner  122: static u_char  cflag2lcr __P((tcflag_t));
1.80      christos  123: int    comparam        __P((struct tty *, struct termios *));
                    124: void   comstart        __P((struct tty *));
1.99      mycroft   125: void   comstop         __P((struct tty *, int));
                    126: int    comhwiflow      __P((struct tty *, int));
                    127:
                    128: void   com_loadchannelregs __P((struct com_softc *));
1.101     mycroft   129: void   com_hwiflow     __P((struct com_softc *));
1.99      mycroft   130: void   com_break       __P((struct com_softc *, int));
                    131: void   com_modem       __P((struct com_softc *, int));
                    132: void   com_iflush      __P((struct com_softc *));
1.80      christos  133:
1.102     thorpej   134: int    com_common_getc __P((bus_space_tag_t, bus_space_handle_t));
                    135: void   com_common_putc __P((bus_space_tag_t, bus_space_handle_t, int));
                    136:
1.80      christos  137: /* XXX: These belong elsewhere */
                    138: cdev_decl(com);
                    139: bdev_decl(com);
                    140:
                    141: int    comcngetc       __P((dev_t));
                    142: void   comcnputc       __P((dev_t, int));
                    143: void   comcnpollc      __P((dev_t, int));
                    144:
1.99      mycroft   145: #define        integrate       static inline
1.127     mycroft   146: #ifdef __GENERIC_SOFT_INTERRUPTS
                    147: void   comsoft         __P((void *));
                    148: #else
1.133     cgd       149: #ifndef __NO_SOFT_SERIAL_INTERRUPT
1.127     mycroft   150: void   comsoft         __P((void));
                    151: #else
                    152: void   comsoft         __P((void *));
                    153: #endif
                    154: #endif
                    155: integrate void com_rxsoft      __P((struct com_softc *, struct tty *));
                    156: integrate void com_txsoft      __P((struct com_softc *, struct tty *));
                    157: integrate void com_stsoft      __P((struct com_softc *, struct tty *));
1.101     mycroft   158: integrate void com_schedrx     __P((struct com_softc *));
1.127     mycroft   159: void   comdiag         __P((void *));
                    160:
1.130     thorpej   161: extern struct cfdriver com_cd;
1.76      thorpej   162:
1.127     mycroft   163: /*
                    164:  * Make this an option variable one can patch.
                    165:  * But be warned:  this must be a power of 2!
                    166:  */
                    167: u_int com_rbuf_size = COM_RING_SIZE;
                    168:
                    169: /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
                    170: u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4;
                    171: u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4;
                    172:
1.106     drochner  173: static int     comconsaddr;
                    174: static bus_space_tag_t comconstag;
                    175: static bus_space_handle_t comconsioh;
                    176: static int     comconsattached;
                    177: static int comconsrate;
                    178: static tcflag_t comconscflag;
1.99      mycroft   179:
1.111     christos  180: static u_char tiocm_xxx2mcr __P((int));
                    181:
1.99      mycroft   182: #ifndef __GENERIC_SOFT_INTERRUPTS
1.133     cgd       183: #ifdef __NO_SOFT_SERIAL_INTERRUPT
1.99      mycroft   184: volatile int   com_softintr_scheduled;
                    185: #endif
                    186: #endif
1.1       cgd       187:
                    188: #ifdef KGDB
1.102     thorpej   189: #include <sys/kgdb.h>
1.106     drochner  190:
                    191: static int com_kgdb_addr;
                    192: static bus_space_tag_t com_kgdb_iot;
                    193: static bus_space_handle_t com_kgdb_ioh;
                    194: static int com_kgdb_attached;
1.102     thorpej   195:
                    196: int    com_kgdb_getc __P((void *));
                    197: void   com_kgdb_putc __P((void *, int));
                    198: #endif /* KGDB */
1.1       cgd       199:
1.21      mycroft   200: #define        COMUNIT(x)      (minor(x))
1.1       cgd       201:
1.21      mycroft   202: int
1.109     is        203: comspeed(speed, frequency)
                    204:        long speed, frequency;
1.1       cgd       205: {
1.21      mycroft   206: #define        divrnd(n, q)    (((n)*2/(q)+1)/2)       /* divide and round off */
                    207:
                    208:        int x, err;
                    209:
1.99      mycroft   210: #if 0
1.21      mycroft   211:        if (speed == 0)
1.99      mycroft   212:                return (0);
                    213: #endif
                    214:        if (speed <= 0)
                    215:                return (-1);
1.109     is        216:        x = divrnd(frequency / 16, speed);
1.21      mycroft   217:        if (x <= 0)
1.99      mycroft   218:                return (-1);
1.114     is        219:        err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000;
1.21      mycroft   220:        if (err < 0)
                    221:                err = -err;
                    222:        if (err > COM_TOLERANCE)
1.99      mycroft   223:                return (-1);
                    224:        return (x);
1.21      mycroft   225:
                    226: #undef divrnd(n, q)
                    227: }
                    228:
1.99      mycroft   229: #ifdef COM_DEBUG
1.101     mycroft   230: int    com_debug = 0;
                    231:
1.99      mycroft   232: void comstatus __P((struct com_softc *, char *));
                    233: void
                    234: comstatus(sc, str)
                    235:        struct com_softc *sc;
                    236:        char *str;
                    237: {
                    238:        struct tty *tp = sc->sc_tty;
                    239:
                    240:        printf("%s: %s %sclocal  %sdcd %sts_carr_on %sdtr %stx_stopped\n",
                    241:            sc->sc_dev.dv_xname, str,
                    242:            ISSET(tp->t_cflag, CLOCAL) ? "+" : "-",
                    243:            ISSET(sc->sc_msr, MSR_DCD) ? "+" : "-",
                    244:            ISSET(tp->t_state, TS_CARR_ON) ? "+" : "-",
                    245:            ISSET(sc->sc_mcr, MCR_DTR) ? "+" : "-",
                    246:            sc->sc_tx_stopped ? "+" : "-");
                    247:
1.101     mycroft   248:        printf("%s: %s %scrtscts %scts %sts_ttstop  %srts %xrx_flags\n",
1.99      mycroft   249:            sc->sc_dev.dv_xname, str,
                    250:            ISSET(tp->t_cflag, CRTSCTS) ? "+" : "-",
                    251:            ISSET(sc->sc_msr, MSR_CTS) ? "+" : "-",
                    252:            ISSET(tp->t_state, TS_TTSTOP) ? "+" : "-",
                    253:            ISSET(sc->sc_mcr, MCR_RTS) ? "+" : "-",
1.101     mycroft   254:            sc->sc_rx_flags);
1.99      mycroft   255: }
                    256: #endif
                    257:
1.21      mycroft   258: int
1.91      thorpej   259: comprobe1(iot, ioh, iobase)
                    260:        bus_space_tag_t iot;
                    261:        bus_space_handle_t ioh;
1.41      mycroft   262:        int iobase;
1.21      mycroft   263: {
                    264:
1.1       cgd       265:        /* force access to id reg */
1.91      thorpej   266:        bus_space_write_1(iot, ioh, com_lcr, 0);
                    267:        bus_space_write_1(iot, ioh, com_iir, 0);
                    268:        if (bus_space_read_1(iot, ioh, com_iir) & 0x38)
1.99      mycroft   269:                return (0);
1.21      mycroft   270:
1.99      mycroft   271:        return (1);
1.1       cgd       272: }
                    273:
1.65      christos  274: #ifdef COM_HAYESP
                    275: int
1.75      cgd       276: comprobeHAYESP(hayespioh, sc)
1.91      thorpej   277:        bus_space_handle_t hayespioh;
1.64      christos  278:        struct com_softc *sc;
                    279: {
1.65      christos  280:        char    val, dips;
1.64      christos  281:        int     combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
1.91      thorpej   282:        bus_space_tag_t iot = sc->sc_iot;
1.64      christos  283:
                    284:        /*
                    285:         * Hayes ESP cards have two iobases.  One is for compatibility with
                    286:         * 16550 serial chips, and at the same ISA PC base addresses.  The
                    287:         * other is for ESP-specific enhanced features, and lies at a
1.65      christos  288:         * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
1.64      christos  289:         */
                    290:
                    291:        /* Test for ESP signature */
1.91      thorpej   292:        if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
1.99      mycroft   293:                return (0);
1.64      christos  294:
                    295:        /*
                    296:         * ESP is present at ESP enhanced base address; unknown com port
                    297:         */
                    298:
                    299:        /* Get the dip-switch configurations */
1.91      thorpej   300:        bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
                    301:        dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
1.64      christos  302:
                    303:        /* Determine which com port this ESP card services: bits 0,1 of  */
                    304:        /*  dips is the port # (0-3); combaselist[val] is the com_iobase */
1.65      christos  305:        if (sc->sc_iobase != combaselist[dips & 0x03])
1.99      mycroft   306:                return (0);
1.65      christos  307:
1.90      christos  308:        printf(": ESP");
1.64      christos  309:
1.65      christos  310:        /* Check ESP Self Test bits. */
1.64      christos  311:        /* Check for ESP version 2.0: bits 4,5,6 == 010 */
1.91      thorpej   312:        bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
1.99      mycroft   313:        val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */
1.91      thorpej   314:        val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
1.64      christos  315:        if ((val & 0x70) < 0x20) {
1.90      christos  316:                printf("-old (%o)", val & 0x70);
1.64      christos  317:                /* we do not support the necessary features */
1.99      mycroft   318:                return (0);
1.64      christos  319:        }
                    320:
                    321:        /* Check for ability to emulate 16550: bit 8 == 1 */
                    322:        if ((dips & 0x80) == 0) {
1.90      christos  323:                printf(" slave");
1.64      christos  324:                /* XXX Does slave really mean no 16550 support?? */
1.99      mycroft   325:                return (0);
1.64      christos  326:        }
                    327:
                    328:        /*
                    329:         * If we made it this far, we are a full-featured ESP v2.0 (or
                    330:         * better), at the correct com port address.
                    331:         */
                    332:
1.65      christos  333:        SET(sc->sc_hwflags, COM_HW_HAYESP);
1.90      christos  334:        printf(", 1024 byte fifo\n");
1.99      mycroft   335:        return (1);
1.64      christos  336: }
1.65      christos  337: #endif
1.64      christos  338:
1.104     drochner  339: #if defined(DDB) || defined(KGDB)
                    340: static void
                    341: com_enable_debugport(sc)
                    342:        struct com_softc *sc;
                    343: {
                    344:        int s;
                    345:
                    346:        /* Turn on line break interrupt, set carrier. */
                    347:        s = splserial();
                    348:        sc->sc_ier = IER_ERXRDY;
                    349:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
                    350:        SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
                    351:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
                    352:        splx(s);
                    353: }
                    354: #endif
1.1       cgd       355:
1.29      mycroft   356: void
1.99      mycroft   357: com_attach_subr(sc)
                    358:        struct com_softc *sc;
1.29      mycroft   359: {
1.99      mycroft   360:        int iobase = sc->sc_iobase;
                    361:        bus_space_tag_t iot = sc->sc_iot;
                    362:        bus_space_handle_t ioh = sc->sc_ioh;
1.127     mycroft   363:        struct tty *tp;
1.118     fvdl      364: #ifdef COM16650
1.116     fvdl      365:        u_int8_t lcr;
1.118     fvdl      366: #endif
1.65      christos  367: #ifdef COM_HAYESP
                    368:        int     hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
                    369:        int     *hayespp;
                    370: #endif
1.117     mycroft   371:
                    372:        /* Disable interrupts before configuring the device. */
                    373:        sc->sc_ier = 0;
1.131     marc      374:        bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1.1       cgd       375:
1.106     drochner  376:        if (iot == comconstag && iobase == comconsaddr) {
1.105     drochner  377:                comconsattached = 1;
                    378:
1.96      mycroft   379:                /* Make sure the console is always "hardwired". */
1.75      cgd       380:                delay(1000);                    /* wait for output to finish */
                    381:                SET(sc->sc_hwflags, COM_HW_CONSOLE);
1.99      mycroft   382:                SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
1.75      cgd       383:        }
1.26      cgd       384:
1.65      christos  385: #ifdef COM_HAYESP
                    386:        /* Look for a Hayes ESP board. */
1.75      cgd       387:        for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
1.91      thorpej   388:                bus_space_handle_t hayespioh;
1.75      cgd       389:
                    390: #define        HAYESP_NPORTS   8                       /* XXX XXX XXX ??? ??? ??? */
1.92      cgd       391:                if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
1.75      cgd       392:                        continue;
                    393:                if (comprobeHAYESP(hayespioh, sc)) {
                    394:                        sc->sc_hayespioh = hayespioh;
1.99      mycroft   395:                        sc->sc_fifolen = 1024;
                    396:
1.65      christos  397:                        break;
                    398:                }
1.91      thorpej   399:                bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
1.75      cgd       400:        }
1.65      christos  401:        /* No ESP; look for other things. */
1.131     marc      402:        if (!ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
1.65      christos  403: #endif
1.99      mycroft   404:        sc->sc_fifolen = 1;
1.1       cgd       405:        /* look for a NS 16550AF UART with FIFOs */
1.91      thorpej   406:        bus_space_write_1(iot, ioh, com_fifo,
1.21      mycroft   407:            FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
1.20      mycroft   408:        delay(100);
1.99      mycroft   409:        if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK)
                    410:            == IIR_FIFO_MASK)
                    411:                if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14)
                    412:                    == FIFO_TRIGGER_14) {
1.62      mycroft   413:                        SET(sc->sc_hwflags, COM_HW_FIFO);
1.116     fvdl      414:
1.118     fvdl      415: #ifdef COM16650
1.116     fvdl      416:                        /*
                    417:                         * IIR changes into the EFR if LCR is set to LCR_EERS
                    418:                         * on 16650s. We also know IIR != 0 at this point.
                    419:                         * Write 0 into the EFR, and read it. If the result
                    420:                         * is 0, we have a 16650.
                    421:                         *
                    422:                         * Older 16650s were broken; the test to detect them
                    423:                         * is taken from the Linux driver. Apparently
                    424:                         * setting DLAB enable gives access to the EFR on
                    425:                         * these chips.
                    426:                         */
                    427:                        lcr = bus_space_read_1(iot, ioh, com_lcr);
                    428:                        bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
                    429:                        bus_space_write_1(iot, ioh, com_efr, 0);
                    430:                        if (bus_space_read_1(iot, ioh, com_efr) == 0) {
                    431:                                bus_space_write_1(iot, ioh, com_lcr,
                    432:                                    lcr | LCR_DLAB);
                    433:                                if (bus_space_read_1(iot, ioh, com_efr) == 0) {
                    434:                                        CLR(sc->sc_hwflags, COM_HW_FIFO);
                    435:                                        sc->sc_fifolen = 0;
                    436:                                } else {
                    437:                                        SET(sc->sc_hwflags, COM_HW_FLOW);
                    438:                                        sc->sc_fifolen = 32;
                    439:                                }
1.118     fvdl      440:                        } else
                    441: #endif
1.116     fvdl      442:                                sc->sc_fifolen = 16;
                    443:
1.118     fvdl      444: #ifdef COM16650
1.119     drochner  445:                        bus_space_write_1(iot, ioh, com_lcr, lcr);
                    446:                        if (sc->sc_fifolen == 0)
                    447:                                printf(": st16650, broken fifo\n");
                    448:                        else if (sc->sc_fifolen == 32)
                    449:                                printf(": st16650a, working fifo\n");
                    450:                        else
1.118     fvdl      451: #endif
1.119     drochner  452:                                printf(": ns16550a, working fifo\n");
1.21      mycroft   453:                } else
1.90      christos  454:                        printf(": ns16550, broken fifo\n");
1.21      mycroft   455:        else
1.90      christos  456:                printf(": ns8250 or ns16450, no fifo\n");
1.91      thorpej   457:        bus_space_write_1(iot, ioh, com_fifo, 0);
1.65      christos  458: #ifdef COM_HAYESP
                    459:        }
                    460: #endif
1.21      mycroft   461:
1.127     mycroft   462:        tp = ttymalloc();
                    463:        tp->t_oproc = comstart;
                    464:        tp->t_param = comparam;
                    465:        tp->t_hwiflow = comhwiflow;
                    466:        tty_attach(tp);
                    467:
                    468:        sc->sc_tty = tp;
                    469:        sc->sc_rbuf = malloc(com_rbuf_size << 1, M_DEVBUF, M_WAITOK);
                    470:        sc->sc_ebuf = sc->sc_rbuf + (com_rbuf_size << 1);
                    471:
1.99      mycroft   472:        if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
                    473:                SET(sc->sc_mcr, MCR_IENABLE);
1.30      mycroft   474:
1.96      mycroft   475:        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1.106     drochner  476:                int maj;
                    477:
                    478:                /* locate the major number */
                    479:                for (maj = 0; maj < nchrdev; maj++)
                    480:                        if (cdevsw[maj].d_open == comopen)
                    481:                                break;
                    482:
                    483:                cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
1.131     marc      484:
1.96      mycroft   485:                printf("%s: console\n", sc->sc_dev.dv_xname);
                    486:        }
                    487:
1.1       cgd       488: #ifdef KGDB
1.102     thorpej   489:        /*
                    490:         * Allow kgdb to "take over" this port.  If this is
                    491:         * the kgdb device, it has exclusive use.
                    492:         */
1.106     drochner  493:        if (iot == com_kgdb_iot && iobase == com_kgdb_addr) {
                    494:                com_kgdb_attached = 1;
                    495:
1.104     drochner  496:                SET(sc->sc_hwflags, COM_HW_KGDB);
1.103     drochner  497:                printf("%s: kgdb\n", sc->sc_dev.dv_xname);
                    498:        }
1.99      mycroft   499: #endif
                    500:
                    501: #ifdef __GENERIC_SOFT_INTERRUPTS
                    502:        sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc);
1.1       cgd       503: #endif
1.115     explorer  504:
                    505: #if NRND > 0 && defined(RND_COM)
                    506:        rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
                    507:                          RND_TYPE_TTY);
                    508: #endif
1.131     marc      509:
                    510:        /* if there are no enable/disable functions, assume the device
                    511:           is always enabled */
                    512:        if (!sc->enable)
                    513:                sc->enabled = 1;
                    514:
                    515:        com_config(sc);
1.132     cgd       516:
                    517:        SET(sc->sc_hwflags, COM_HW_DEV_OK);
1.131     marc      518: }
                    519:
                    520: void
                    521: com_config(sc)
                    522:        struct com_softc *sc;
                    523: {
                    524:        bus_space_tag_t iot = sc->sc_iot;
                    525:        bus_space_handle_t ioh = sc->sc_ioh;
                    526:
                    527:        /* Disable interrupts before configuring the device. */
                    528:        sc->sc_ier = 0;
                    529:        bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
                    530:
                    531: #ifdef COM_HAYESP
                    532:        /* Look for a Hayes ESP board. */
                    533:        if (ISSET(sc->sc_hwflags, COM_HW_HAYESP)) {
                    534:                sc->sc_fifolen = 1024;
                    535:
                    536:                /* Set 16550 compatibility mode */
                    537:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
                    538:                                  HAYESP_SETMODE);
                    539:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    540:                                  HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
                    541:                                  HAYESP_MODE_SCALE);
                    542:
                    543:                /* Set RTS/CTS flow control */
                    544:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
                    545:                                  HAYESP_SETFLOWTYPE);
                    546:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    547:                                  HAYESP_FLOW_RTS);
                    548:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    549:                                  HAYESP_FLOW_CTS);
                    550:
                    551:                /* Set flow control levels */
                    552:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
                    553:                                  HAYESP_SETRXFLOW);
                    554:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    555:                                  HAYESP_HIBYTE(HAYESP_RXHIWMARK));
                    556:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    557:                                  HAYESP_LOBYTE(HAYESP_RXHIWMARK));
                    558:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    559:                                  HAYESP_HIBYTE(HAYESP_RXLOWMARK));
                    560:                bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
                    561:                                  HAYESP_LOBYTE(HAYESP_RXLOWMARK));
                    562:        }
                    563: #endif
                    564:
                    565: #ifdef DDB
                    566:        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
                    567:                com_enable_debugport(sc);
                    568: #endif
                    569:
                    570: #ifdef KGDB
                    571:        /*
                    572:         * Allow kgdb to "take over" this port.  If this is
                    573:         * the kgdb device, it has exclusive use.
                    574:         */
                    575:        if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
                    576:                com_enable_debugport(sc);
                    577: #endif
1.1       cgd       578: }
                    579:
1.21      mycroft   580: int
                    581: comopen(dev, flag, mode, p)
                    582:        dev_t dev;
                    583:        int flag, mode;
                    584:        struct proc *p;
1.1       cgd       585: {
1.21      mycroft   586:        int unit = COMUNIT(dev);
                    587:        struct com_softc *sc;
                    588:        struct tty *tp;
1.99      mycroft   589:        int s, s2;
1.1       cgd       590:        int error = 0;
                    591:
1.76      thorpej   592:        if (unit >= com_cd.cd_ndevs)
1.99      mycroft   593:                return (ENXIO);
1.76      thorpej   594:        sc = com_cd.cd_devs[unit];
1.132     cgd       595:        if (!sc || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
1.99      mycroft   596:                return (ENXIO);
1.21      mycroft   597:
1.102     thorpej   598: #ifdef KGDB
                    599:        /*
                    600:         * If this is the kgdb port, no other use is permitted.
                    601:         */
                    602:        if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
                    603:                return (EBUSY);
                    604: #endif
                    605:
1.120     mycroft   606:        tp = sc->sc_tty;
1.21      mycroft   607:
1.99      mycroft   608:        if (ISSET(tp->t_state, TS_ISOPEN) &&
                    609:            ISSET(tp->t_state, TS_XCLUDE) &&
                    610:            p->p_ucred->cr_uid != 0)
                    611:                return (EBUSY);
                    612:
                    613:        s = spltty();
                    614:
                    615:        /* We need to set this early for the benefit of comsoft(). */
                    616:        SET(tp->t_state, TS_WOPEN);
                    617:
                    618:        /*
                    619:         * Do the following iff this is a first open.
                    620:         */
1.62      mycroft   621:        if (!ISSET(tp->t_state, TS_ISOPEN)) {
1.99      mycroft   622:                struct termios t;
                    623:
1.127     mycroft   624:                tp->t_dev = dev;
                    625:
1.120     mycroft   626:                s2 = splserial();
                    627:
1.131     marc      628:                if (sc->enable) {
                    629:                        if ((*sc->enable)(sc)) {
1.134     enami     630:                                splx(s);
1.131     marc      631:                                printf("%s: device enable failed\n",
                    632:                                       sc->sc_dev.dv_xname);
                    633:                                return (EIO);
                    634:                        }
                    635:                        sc->enabled = 1;
                    636:                        com_config(sc);
                    637:                }
                    638:
1.99      mycroft   639:                /* Turn on interrupts. */
                    640:                sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
                    641:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
                    642:
                    643:                /* Fetch the current modem control status, needed later. */
                    644:                sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
                    645:
1.120     mycroft   646:                splx(s2);
1.99      mycroft   647:
                    648:                /*
                    649:                 * Initialize the termios status to the defaults.  Add in the
                    650:                 * sticky bits from TIOCSFLAGS.
                    651:                 */
                    652:                t.c_ispeed = 0;
1.98      mycroft   653:                if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
1.99      mycroft   654:                        t.c_ospeed = comconsrate;
                    655:                        t.c_cflag = comconscflag;
1.98      mycroft   656:                } else {
1.99      mycroft   657:                        t.c_ospeed = TTYDEF_SPEED;
                    658:                        t.c_cflag = TTYDEF_CFLAG;
1.98      mycroft   659:                }
1.99      mycroft   660:                if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
                    661:                        SET(t.c_cflag, CLOCAL);
                    662:                if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
                    663:                        SET(t.c_cflag, CRTSCTS);
                    664:                if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
                    665:                        SET(t.c_cflag, MDMBUF);
1.129     mycroft   666:                /* Make sure comparam() will do something. */
                    667:                tp->t_ospeed = 0;
1.120     mycroft   668:                (void) comparam(tp, &t);
1.99      mycroft   669:                tp->t_iflag = TTYDEF_IFLAG;
                    670:                tp->t_oflag = TTYDEF_OFLAG;
1.16      ws        671:                tp->t_lflag = TTYDEF_LFLAG;
1.99      mycroft   672:                ttychars(tp);
1.1       cgd       673:                ttsetwater(tp);
1.21      mycroft   674:
1.136     mycroft   675:                s2 = splserial();
                    676:
1.99      mycroft   677:                /*
                    678:                 * Turn on DTR.  We must always do this, even if carrier is not
                    679:                 * present, because otherwise we'd have to use TIOCSDTR
1.121     mycroft   680:                 * immediately after setting CLOCAL, which applications do not
                    681:                 * expect.  We always assert DTR while the device is open
                    682:                 * unless explicitly requested to deassert it.
1.99      mycroft   683:                 */
                    684:                com_modem(sc, 1);
1.65      christos  685:
1.99      mycroft   686:                /* Clear the input ring, and unblock. */
1.127     mycroft   687:                sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
                    688:                sc->sc_rbavail = com_rbuf_size;
1.99      mycroft   689:                com_iflush(sc);
1.101     mycroft   690:                CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
                    691:                com_hwiflow(sc);
1.65      christos  692:
1.99      mycroft   693: #ifdef COM_DEBUG
1.101     mycroft   694:                if (com_debug)
                    695:                        comstatus(sc, "comopen  ");
1.65      christos  696: #endif
1.21      mycroft   697:
1.99      mycroft   698:                splx(s2);
                    699:        }
                    700:        error = 0;
1.21      mycroft   701:
1.99      mycroft   702:        /* If we're doing a blocking open... */
1.62      mycroft   703:        if (!ISSET(flag, O_NONBLOCK))
1.99      mycroft   704:                /* ...then wait for carrier. */
                    705:                while (!ISSET(tp->t_state, TS_CARR_ON) &&
                    706:                    !ISSET(tp->t_cflag, CLOCAL | MDMBUF)) {
1.62      mycroft   707:                        error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
                    708:                            ttopen, 0);
1.21      mycroft   709:                        if (error) {
1.99      mycroft   710:                                /*
                    711:                                 * If the open was interrupted and nobody
                    712:                                 * else has the device open, then hang up.
                    713:                                 */
                    714:                                if (!ISSET(tp->t_state, TS_ISOPEN)) {
1.136     mycroft   715:                                        s2 = splserial();
                    716:
                    717:                                        /* Hang up. */
1.99      mycroft   718:                                        com_modem(sc, 0);
1.136     mycroft   719:
1.99      mycroft   720:                                        CLR(tp->t_state, TS_WOPEN);
                    721:                                        ttwakeup(tp);
1.136     mycroft   722:
                    723:                                        splx(s2);
1.99      mycroft   724:                                }
                    725:                                break;
1.21      mycroft   726:                        }
1.99      mycroft   727:                        SET(tp->t_state, TS_WOPEN);
1.21      mycroft   728:                }
1.99      mycroft   729:
1.21      mycroft   730:        splx(s);
1.99      mycroft   731:        if (error == 0)
                    732:                error = (*linesw[tp->t_line].l_open)(dev, tp);
                    733:        return (error);
1.1       cgd       734: }
                    735:
1.21      mycroft   736: int
1.1       cgd       737: comclose(dev, flag, mode, p)
                    738:        dev_t dev;
                    739:        int flag, mode;
                    740:        struct proc *p;
                    741: {
1.127     mycroft   742:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
1.50      mycroft   743:        struct tty *tp = sc->sc_tty;
1.57      mycroft   744:        int s;
                    745:
                    746:        /* XXX This is for cons.c. */
1.62      mycroft   747:        if (!ISSET(tp->t_state, TS_ISOPEN))
1.99      mycroft   748:                return (0);
1.21      mycroft   749:
1.1       cgd       750:        (*linesw[tp->t_line].l_close)(tp, flag);
                    751:        ttyclose(tp);
1.99      mycroft   752:
1.120     mycroft   753:        s = splserial();
                    754:
1.99      mycroft   755:        /* If we were asserting flow control, then deassert it. */
1.101     mycroft   756:        SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
                    757:        com_hwiflow(sc);
1.122     mycroft   758:
1.99      mycroft   759:        /* Clear any break condition set with TIOCSBRK. */
                    760:        com_break(sc, 0);
1.120     mycroft   761:
1.99      mycroft   762:        /*
                    763:         * Hang up if necessary.  Wait a bit, so the other side has time to
                    764:         * notice even if we immediately open the port again.
                    765:         */
                    766:        if (ISSET(tp->t_cflag, HUPCL)) {
                    767:                com_modem(sc, 0);
                    768:                (void) tsleep(sc, TTIPRI, ttclos, hz);
1.21      mycroft   769:        }
1.99      mycroft   770:
                    771:        /* Turn off interrupts. */
1.104     drochner  772: #ifdef DDB
1.122     mycroft   773:        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE))
1.104     drochner  774:                sc->sc_ier = IER_ERXRDY; /* interrupt on break */
                    775:        else
1.127     mycroft   776: #endif
1.104     drochner  777:                sc->sc_ier = 0;
1.99      mycroft   778:        bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
1.120     mycroft   779:
1.131     marc      780:        if (sc->disable) {
                    781:                if (sc->enabled) {
                    782:                        (*sc->disable)(sc);
                    783:                        sc->enabled = 0;
                    784:                }
                    785:        }
                    786:
1.99      mycroft   787:        splx(s);
                    788:
                    789:        return (0);
1.1       cgd       790: }
                    791:
1.21      mycroft   792: int
1.1       cgd       793: comread(dev, uio, flag)
                    794:        dev_t dev;
                    795:        struct uio *uio;
1.21      mycroft   796:        int flag;
1.1       cgd       797: {
1.76      thorpej   798:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
1.52      mycroft   799:        struct tty *tp = sc->sc_tty;
1.1       cgd       800:
                    801:        return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
                    802: }
                    803:
1.21      mycroft   804: int
1.1       cgd       805: comwrite(dev, uio, flag)
                    806:        dev_t dev;
                    807:        struct uio *uio;
1.21      mycroft   808:        int flag;
1.1       cgd       809: {
1.76      thorpej   810:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
1.52      mycroft   811:        struct tty *tp = sc->sc_tty;
1.1       cgd       812:
                    813:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
                    814: }
1.50      mycroft   815:
                    816: struct tty *
                    817: comtty(dev)
                    818:        dev_t dev;
                    819: {
1.76      thorpej   820:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
1.52      mycroft   821:        struct tty *tp = sc->sc_tty;
1.50      mycroft   822:
1.52      mycroft   823:        return (tp);
1.50      mycroft   824: }
1.111     christos  825:
                    826: static u_char
                    827: tiocm_xxx2mcr(data)
                    828:        int data;
                    829: {
                    830:        u_char m = 0;
                    831:
                    832:        if (ISSET(data, TIOCM_DTR))
                    833:                SET(m, MCR_DTR);
                    834:        if (ISSET(data, TIOCM_RTS))
                    835:                SET(m, MCR_RTS);
                    836:        return m;
                    837: }
1.1       cgd       838:
1.21      mycroft   839: int
1.19      mycroft   840: comioctl(dev, cmd, data, flag, p)
1.1       cgd       841:        dev_t dev;
1.39      cgd       842:        u_long cmd;
1.1       cgd       843:        caddr_t data;
1.19      mycroft   844:        int flag;
                    845:        struct proc *p;
1.1       cgd       846: {
1.127     mycroft   847:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(dev)];
1.50      mycroft   848:        struct tty *tp = sc->sc_tty;
1.21      mycroft   849:        int error;
1.136     mycroft   850:        int s;
1.21      mycroft   851:
1.19      mycroft   852:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p);
1.1       cgd       853:        if (error >= 0)
1.99      mycroft   854:                return (error);
                    855:
1.19      mycroft   856:        error = ttioctl(tp, cmd, data, flag, p);
1.1       cgd       857:        if (error >= 0)
1.99      mycroft   858:                return (error);
1.138   ! mycroft   859:
        !           860:        error = 0;
1.1       cgd       861:
1.136     mycroft   862:        s = splserial();
                    863:
1.1       cgd       864:        switch (cmd) {
                    865:        case TIOCSBRK:
1.99      mycroft   866:                com_break(sc, 1);
1.1       cgd       867:                break;
1.99      mycroft   868:
1.1       cgd       869:        case TIOCCBRK:
1.99      mycroft   870:                com_break(sc, 0);
1.1       cgd       871:                break;
1.99      mycroft   872:
1.1       cgd       873:        case TIOCSDTR:
1.99      mycroft   874:                com_modem(sc, 1);
1.1       cgd       875:                break;
1.99      mycroft   876:
1.1       cgd       877:        case TIOCCDTR:
1.99      mycroft   878:                com_modem(sc, 0);
1.1       cgd       879:                break;
1.99      mycroft   880:
                    881:        case TIOCGFLAGS:
                    882:                *(int *)data = sc->sc_swflags;
                    883:                break;
                    884:
                    885:        case TIOCSFLAGS:
                    886:                error = suser(p->p_ucred, &p->p_acflag);
                    887:                if (error)
1.136     mycroft   888:                        break;
1.99      mycroft   889:                sc->sc_swflags = *(int *)data;
                    890:                break;
                    891:
1.1       cgd       892:        case TIOCMSET:
1.111     christos  893:                CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
                    894:                /*FALLTHROUGH*/
                    895:
1.1       cgd       896:        case TIOCMBIS:
1.111     christos  897:                SET(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
                    898:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
                    899:                break;
                    900:
1.1       cgd       901:        case TIOCMBIC:
1.111     christos  902:                CLR(sc->sc_mcr, tiocm_xxx2mcr(*(int *)data));
                    903:                bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
                    904:                break;
                    905:
                    906:        case TIOCMGET: {
                    907:                u_char m;
                    908:                int bits = 0;
                    909:
                    910:                m = sc->sc_mcr;
                    911:                if (ISSET(m, MCR_DTR))
                    912:                        SET(bits, TIOCM_DTR);
                    913:                if (ISSET(m, MCR_RTS))
                    914:                        SET(bits, TIOCM_RTS);
                    915:                m = sc->sc_msr;
                    916:                if (ISSET(m, MSR_DCD))
                    917:                        SET(bits, TIOCM_CD);
                    918:                if (ISSET(m, MSR_CTS))
                    919:                        SET(bits, TIOCM_CTS);
                    920:                if (ISSET(m, MSR_DSR))
                    921:                        SET(bits, TIOCM_DSR);
                    922:                if (ISSET(m, MSR_RI | MSR_TERI))
                    923:                        SET(bits, TIOCM_RI);
                    924:                if (bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_ier))
                    925:                        SET(bits, TIOCM_LE);
                    926:                *(int *)data = bits;
                    927:                break;
                    928:        }
1.99      mycroft   929:        default:
1.136     mycroft   930:                error = ENOTTY;
                    931:                break;
1.21      mycroft   932:        }
1.22      cgd       933:
1.136     mycroft   934:        splx(s);
                    935:
1.99      mycroft   936: #ifdef COM_DEBUG
1.101     mycroft   937:        if (com_debug)
1.99      mycroft   938:                comstatus(sc, "comioctl ");
                    939: #endif
                    940:
1.136     mycroft   941:        return (error);
1.99      mycroft   942: }
                    943:
1.101     mycroft   944: integrate void
                    945: com_schedrx(sc)
                    946:        struct com_softc *sc;
                    947: {
                    948:
                    949:        sc->sc_rx_ready = 1;
                    950:
                    951:        /* Wake up the poller. */
                    952: #ifdef __GENERIC_SOFT_INTERRUPTS
                    953:        softintr_schedule(sc->sc_si);
                    954: #else
1.133     cgd       955: #ifndef __NO_SOFT_SERIAL_INTERRUPT
1.101     mycroft   956:        setsoftserial();
                    957: #else
                    958:        if (!com_softintr_scheduled) {
                    959:                com_softintr_scheduled = 1;
                    960:                timeout(comsoft, NULL, 1);
                    961:        }
                    962: #endif
                    963: #endif
                    964: }
                    965:
1.99      mycroft   966: void
                    967: com_break(sc, onoff)
                    968:        struct com_softc *sc;
                    969:        int onoff;
                    970: {
                    971:
                    972:        if (onoff)
                    973:                SET(sc->sc_lcr, LCR_SBREAK);
                    974:        else
                    975:                CLR(sc->sc_lcr, LCR_SBREAK);
1.22      cgd       976:
1.99      mycroft   977:        if (!sc->sc_heldchange) {
                    978:                if (sc->sc_tx_busy) {
                    979:                        sc->sc_heldtbc = sc->sc_tbc;
                    980:                        sc->sc_tbc = 0;
                    981:                        sc->sc_heldchange = 1;
                    982:                } else
                    983:                        com_loadchannelregs(sc);
1.22      cgd       984:        }
1.99      mycroft   985: }
1.22      cgd       986:
1.99      mycroft   987: void
                    988: com_modem(sc, onoff)
                    989:        struct com_softc *sc;
                    990:        int onoff;
                    991: {
1.22      cgd       992:
1.99      mycroft   993:        if (onoff)
                    994:                SET(sc->sc_mcr, sc->sc_mcr_dtr);
                    995:        else
                    996:                CLR(sc->sc_mcr, sc->sc_mcr_dtr);
1.22      cgd       997:
1.99      mycroft   998:        if (!sc->sc_heldchange) {
                    999:                if (sc->sc_tx_busy) {
                   1000:                        sc->sc_heldtbc = sc->sc_tbc;
                   1001:                        sc->sc_tbc = 0;
                   1002:                        sc->sc_heldchange = 1;
                   1003:                } else
                   1004:                        com_loadchannelregs(sc);
1.22      cgd      1005:        }
1.1       cgd      1006: }
                   1007:
1.106     drochner 1008: static u_char
                   1009: cflag2lcr(cflag)
1.110     enami    1010:        tcflag_t cflag;
1.106     drochner 1011: {
                   1012:        u_char lcr = 0;
                   1013:
                   1014:        switch (ISSET(cflag, CSIZE)) {
1.127     mycroft  1015:        case CS5:
1.106     drochner 1016:                SET(lcr, LCR_5BITS);
                   1017:                break;
1.127     mycroft  1018:        case CS6:
1.106     drochner 1019:                SET(lcr, LCR_6BITS);
                   1020:                break;
1.127     mycroft  1021:        case CS7:
1.106     drochner 1022:                SET(lcr, LCR_7BITS);
                   1023:                break;
1.127     mycroft  1024:        case CS8:
1.106     drochner 1025:                SET(lcr, LCR_8BITS);
                   1026:                break;
                   1027:        }
                   1028:        if (ISSET(cflag, PARENB)) {
                   1029:                SET(lcr, LCR_PENAB);
                   1030:                if (!ISSET(cflag, PARODD))
                   1031:                        SET(lcr, LCR_PEVEN);
                   1032:        }
                   1033:        if (ISSET(cflag, CSTOPB))
                   1034:                SET(lcr, LCR_STOPB);
                   1035:
1.110     enami    1036:        return (lcr);
1.106     drochner 1037: }
                   1038:
1.21      mycroft  1039: int
1.1       cgd      1040: comparam(tp, t)
1.21      mycroft  1041:        struct tty *tp;
                   1042:        struct termios *t;
1.1       cgd      1043: {
1.76      thorpej  1044:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1.109     is       1045:        int ospeed = comspeed(t->c_ospeed, sc->sc_frequency);
1.62      mycroft  1046:        u_char lcr;
1.21      mycroft  1047:        int s;
                   1048:
1.127     mycroft  1049:        /* Check requested parameters. */
1.99      mycroft  1050:        if (ospeed < 0)
                   1051:                return (EINVAL);
                   1052:        if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
                   1053:                return (EINVAL);
1.21      mycroft  1054:
1.99      mycroft  1055:        /*
                   1056:         * For the console, always force CLOCAL and !HUPCL, so that the port
                   1057:         * is always active.
                   1058:         */
                   1059:        if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
                   1060:            ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
                   1061:                SET(t->c_cflag, CLOCAL);
                   1062:                CLR(t->c_cflag, HUPCL);
1.62      mycroft  1063:        }
1.129     mycroft  1064:
                   1065:        /*
                   1066:         * If there were no changes, don't do anything.  This avoids dropping
                   1067:         * input and improves performance when all we did was frob things like
                   1068:         * VMIN and VTIME.
                   1069:         */
                   1070:        if (tp->t_ospeed == t->c_ospeed &&
                   1071:            tp->t_cflag == t->c_cflag)
                   1072:                return (0);
1.126     mycroft  1073:
                   1074:        lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
                   1075:
                   1076:        s = splserial();
                   1077:
                   1078:        sc->sc_lcr = lcr;
1.36      mycroft  1079:
                   1080:        /*
1.99      mycroft  1081:         * If we're not in a mode that assumes a connection is present, then
                   1082:         * ignore carrier changes.
1.36      mycroft  1083:         */
1.99      mycroft  1084:        if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
                   1085:                sc->sc_msr_dcd = 0;
                   1086:        else
                   1087:                sc->sc_msr_dcd = MSR_DCD;
                   1088:        /*
                   1089:         * Set the flow control pins depending on the current flow control
                   1090:         * mode.
                   1091:         */
                   1092:        if (ISSET(t->c_cflag, CRTSCTS)) {
                   1093:                sc->sc_mcr_dtr = MCR_DTR;
                   1094:                sc->sc_mcr_rts = MCR_RTS;
                   1095:                sc->sc_msr_cts = MSR_CTS;
1.116     fvdl     1096:                sc->sc_efr = EFR_AUTORTS | EFR_AUTOCTS;
1.99      mycroft  1097:        } else if (ISSET(t->c_cflag, MDMBUF)) {
                   1098:                /*
                   1099:                 * For DTR/DCD flow control, make sure we don't toggle DTR for
                   1100:                 * carrier detection.
                   1101:                 */
                   1102:                sc->sc_mcr_dtr = 0;
                   1103:                sc->sc_mcr_rts = MCR_DTR;
                   1104:                sc->sc_msr_cts = MSR_DCD;
1.116     fvdl     1105:                sc->sc_efr = 0;
1.99      mycroft  1106:        } else {
                   1107:                /*
                   1108:                 * If no flow control, then always set RTS.  This will make
                   1109:                 * the other side happy if it mistakenly thinks we're doing
                   1110:                 * RTS/CTS flow control.
                   1111:                 */
                   1112:                sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
                   1113:                sc->sc_mcr_rts = 0;
                   1114:                sc->sc_msr_cts = 0;
1.116     fvdl     1115:                sc->sc_efr = 0;
1.99      mycroft  1116:                if (ISSET(sc->sc_mcr, MCR_DTR))
                   1117:                        SET(sc->sc_mcr, MCR_RTS);
                   1118:                else
                   1119:                        CLR(sc->sc_mcr, MCR_RTS);
                   1120:        }
                   1121:        sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
                   1122:
1.95      mycroft  1123: #if 0
1.99      mycroft  1124:        if (ospeed == 0)
                   1125:                CLR(sc->sc_mcr, sc->sc_mcr_dtr);
                   1126:        else
                   1127:                SET(sc->sc_mcr, sc->sc_mcr_dtr);
1.66      mycroft  1128: #endif
                   1129:
1.99      mycroft  1130:        sc->sc_dlbl = ospeed;
                   1131:        sc->sc_dlbh = ospeed >> 8;
1.66      mycroft  1132:
1.99      mycroft  1133:        /*
                   1134:         * Set the FIFO threshold based on the receive speed.
                   1135:         *
                   1136:         *  * If it's a low speed, it's probably a mouse or some other
                   1137:         *    interactive device, so set the threshold low.
                   1138:         *  * If it's a high speed, trim the trigger level down to prevent
                   1139:         *    overflows.
                   1140:         *  * Otherwise set it a bit higher.
                   1141:         */
                   1142:        if (ISSET(sc->sc_hwflags, COM_HW_HAYESP))
                   1143:                sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
                   1144:        else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
                   1145:                sc->sc_fifo = FIFO_ENABLE |
                   1146:                    (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 :
                   1147:                     t->c_ospeed <= 38400 ? FIFO_TRIGGER_8 : FIFO_TRIGGER_4);
                   1148:        else
                   1149:                sc->sc_fifo = 0;
1.21      mycroft  1150:
1.127     mycroft  1151:        /* And copy to tty. */
1.99      mycroft  1152:        tp->t_ispeed = 0;
1.57      mycroft  1153:        tp->t_ospeed = t->c_ospeed;
                   1154:        tp->t_cflag = t->c_cflag;
1.25      cgd      1155:
1.99      mycroft  1156:        if (!sc->sc_heldchange) {
                   1157:                if (sc->sc_tx_busy) {
                   1158:                        sc->sc_heldtbc = sc->sc_tbc;
                   1159:                        sc->sc_tbc = 0;
                   1160:                        sc->sc_heldchange = 1;
                   1161:                } else
                   1162:                        com_loadchannelregs(sc);
                   1163:        }
                   1164:
1.124     mycroft  1165:        if (!ISSET(t->c_cflag, CHWFLOW)) {
1.125     mycroft  1166:                /* Disable the high water mark. */
                   1167:                sc->sc_r_hiwat = 0;
                   1168:                sc->sc_r_lowat = 0;
1.124     mycroft  1169:                if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
                   1170:                        CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
                   1171:                        com_schedrx(sc);
                   1172:                }
                   1173:                if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
                   1174:                        CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
                   1175:                        com_hwiflow(sc);
                   1176:                }
1.125     mycroft  1177:        } else {
1.127     mycroft  1178:                sc->sc_r_hiwat = com_rbuf_hiwat;
                   1179:                sc->sc_r_lowat = com_rbuf_lowat;
1.124     mycroft  1180:        }
                   1181:
1.99      mycroft  1182:        splx(s);
                   1183:
1.25      cgd      1184:        /*
1.99      mycroft  1185:         * Update the tty layer's idea of the carrier bit, in case we changed
1.124     mycroft  1186:         * CLOCAL or MDMBUF.  We don't hang up here; we only do that by
                   1187:         * explicit request.
1.25      cgd      1188:         */
1.99      mycroft  1189:        (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
                   1190:
                   1191: #ifdef COM_DEBUG
1.101     mycroft  1192:        if (com_debug)
                   1193:                comstatus(sc, "comparam ");
1.99      mycroft  1194: #endif
                   1195:
                   1196:        if (!ISSET(t->c_cflag, CHWFLOW)) {
                   1197:                if (sc->sc_tx_stopped) {
                   1198:                        sc->sc_tx_stopped = 0;
                   1199:                        comstart(tp);
                   1200:                }
1.21      mycroft  1201:        }
1.1       cgd      1202:
1.99      mycroft  1203:        return (0);
                   1204: }
                   1205:
                   1206: void
                   1207: com_iflush(sc)
                   1208:        struct com_softc *sc;
                   1209: {
                   1210:        bus_space_tag_t iot = sc->sc_iot;
                   1211:        bus_space_handle_t ioh = sc->sc_ioh;
1.131     marc     1212: #ifdef DIAGNOSTIC
                   1213:        int reg;
                   1214: #endif
                   1215:        int timo;
1.99      mycroft  1216:
1.131     marc     1217: #ifdef DIAGNOSTIC
                   1218:        reg = 0xffff;
                   1219: #endif
                   1220:        timo = 50000;
1.99      mycroft  1221:        /* flush any pending I/O */
1.131     marc     1222:        while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)
                   1223:            && --timo)
                   1224: #ifdef DIAGNOSTIC
                   1225:                reg =
                   1226: #else
                   1227:                    (void)
                   1228: #endif
                   1229:                    bus_space_read_1(iot, ioh, com_data);
                   1230: #ifdef DIAGNOSTIC
                   1231:        if (!timo)
                   1232:                printf("%s: com_iflush timeout %02x\n", sc->sc_dev.dv_xname,
                   1233:                       reg);
                   1234: #endif
1.99      mycroft  1235: }
                   1236:
                   1237: void
                   1238: com_loadchannelregs(sc)
                   1239:        struct com_softc *sc;
                   1240: {
                   1241:        bus_space_tag_t iot = sc->sc_iot;
                   1242:        bus_space_handle_t ioh = sc->sc_ioh;
                   1243:
                   1244:        /* XXXXX necessary? */
                   1245:        com_iflush(sc);
                   1246:
                   1247:        bus_space_write_1(iot, ioh, com_ier, 0);
                   1248:
1.116     fvdl     1249:        if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) {
                   1250:                bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
                   1251:                bus_space_write_1(iot, ioh, com_efr, sc->sc_efr);
                   1252:        }
1.99      mycroft  1253:        bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB);
                   1254:        bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl);
                   1255:        bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh);
                   1256:        bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
                   1257:        bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr);
                   1258:        bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo);
                   1259:
                   1260:        bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
                   1261: }
                   1262:
                   1263: int
                   1264: comhwiflow(tp, block)
                   1265:        struct tty *tp;
                   1266:        int block;
                   1267: {
                   1268:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
                   1269:        int s;
                   1270:
                   1271:        if (sc->sc_mcr_rts == 0)
                   1272:                return (0);
                   1273:
                   1274:        s = splserial();
                   1275:        if (block) {
1.101     mycroft  1276:                if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
                   1277:                        SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
                   1278:                        com_hwiflow(sc);
                   1279:                }
1.99      mycroft  1280:        } else {
1.101     mycroft  1281:                if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
                   1282:                        CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
                   1283:                        com_schedrx(sc);
                   1284:                }
                   1285:                if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
                   1286:                        CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
                   1287:                        com_hwiflow(sc);
                   1288:                }
1.99      mycroft  1289:        }
1.21      mycroft  1290:        splx(s);
1.99      mycroft  1291:        return (1);
                   1292: }
                   1293:
                   1294: /*
                   1295:  * (un)block input via hw flowcontrol
                   1296:  */
                   1297: void
1.101     mycroft  1298: com_hwiflow(sc)
1.99      mycroft  1299:        struct com_softc *sc;
                   1300: {
                   1301:        bus_space_tag_t iot = sc->sc_iot;
                   1302:        bus_space_handle_t ioh = sc->sc_ioh;
                   1303:
                   1304:        if (sc->sc_mcr_rts == 0)
                   1305:                return;
                   1306:
1.101     mycroft  1307:        if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
1.99      mycroft  1308:                CLR(sc->sc_mcr, sc->sc_mcr_rts);
                   1309:                CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
                   1310:        } else {
                   1311:                SET(sc->sc_mcr, sc->sc_mcr_rts);
                   1312:                SET(sc->sc_mcr_active, sc->sc_mcr_rts);
                   1313:        }
                   1314:        bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active);
1.1       cgd      1315: }
1.21      mycroft  1316:
1.99      mycroft  1317:
1.12      deraadt  1318: void
1.1       cgd      1319: comstart(tp)
1.21      mycroft  1320:        struct tty *tp;
1.1       cgd      1321: {
1.76      thorpej  1322:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1.91      thorpej  1323:        bus_space_tag_t iot = sc->sc_iot;
                   1324:        bus_space_handle_t ioh = sc->sc_ioh;
1.21      mycroft  1325:        int s;
                   1326:
1.1       cgd      1327:        s = spltty();
1.127     mycroft  1328:        if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
1.70      mycroft  1329:                goto out;
1.99      mycroft  1330:        if (sc->sc_tx_stopped)
1.127     mycroft  1331:                goto out;
1.99      mycroft  1332:
1.61      mycroft  1333:        if (tp->t_outq.c_cc <= tp->t_lowat) {
1.62      mycroft  1334:                if (ISSET(tp->t_state, TS_ASLEEP)) {
                   1335:                        CLR(tp->t_state, TS_ASLEEP);
                   1336:                        wakeup(&tp->t_outq);
1.61      mycroft  1337:                }
1.99      mycroft  1338:                selwakeup(&tp->t_wsel);
1.61      mycroft  1339:                if (tp->t_outq.c_cc == 0)
1.127     mycroft  1340:                        goto out;
1.61      mycroft  1341:        }
1.99      mycroft  1342:
                   1343:        /* Grab the first contiguous region of buffer space. */
                   1344:        {
                   1345:                u_char *tba;
                   1346:                int tbc;
                   1347:
                   1348:                tba = tp->t_outq.c_cf;
                   1349:                tbc = ndqb(&tp->t_outq, 0);
                   1350:
                   1351:                (void)splserial();
                   1352:
                   1353:                sc->sc_tba = tba;
                   1354:                sc->sc_tbc = tbc;
                   1355:        }
                   1356:
1.62      mycroft  1357:        SET(tp->t_state, TS_BUSY);
1.99      mycroft  1358:        sc->sc_tx_busy = 1;
1.64      christos 1359:
1.99      mycroft  1360:        /* Enable transmit completion interrupts if necessary. */
1.70      mycroft  1361:        if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
                   1362:                SET(sc->sc_ier, IER_ETXRDY);
1.91      thorpej  1363:                bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1.70      mycroft  1364:        }
1.99      mycroft  1365:
                   1366:        /* Output the first chunk of the contiguous buffer. */
                   1367:        {
                   1368:                int n;
                   1369:
1.127     mycroft  1370:                n = sc->sc_tbc;
                   1371:                if (n > sc->sc_fifolen)
                   1372:                        n = sc->sc_fifolen;
1.99      mycroft  1373:                bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
                   1374:                sc->sc_tbc -= n;
                   1375:                sc->sc_tba += n;
1.64      christos 1376:        }
1.99      mycroft  1377: out:
1.1       cgd      1378:        splx(s);
1.99      mycroft  1379:        return;
1.1       cgd      1380: }
1.21      mycroft  1381:
1.1       cgd      1382: /*
                   1383:  * Stop output on a line.
                   1384:  */
1.85      mycroft  1385: void
1.1       cgd      1386: comstop(tp, flag)
1.21      mycroft  1387:        struct tty *tp;
1.80      christos 1388:        int flag;
1.1       cgd      1389: {
1.99      mycroft  1390:        struct com_softc *sc = com_cd.cd_devs[COMUNIT(tp->t_dev)];
1.21      mycroft  1391:        int s;
1.1       cgd      1392:
1.99      mycroft  1393:        s = splserial();
                   1394:        if (ISSET(tp->t_state, TS_BUSY)) {
                   1395:                /* Stop transmitting at the next chunk. */
                   1396:                sc->sc_tbc = 0;
                   1397:                sc->sc_heldtbc = 0;
1.62      mycroft  1398:                if (!ISSET(tp->t_state, TS_TTSTOP))
                   1399:                        SET(tp->t_state, TS_FLUSH);
1.99      mycroft  1400:        }
1.1       cgd      1401:        splx(s);
                   1402: }
                   1403:
1.33      mycroft  1404: void
                   1405: comdiag(arg)
                   1406:        void *arg;
                   1407: {
                   1408:        struct com_softc *sc = arg;
1.99      mycroft  1409:        int overflows, floods;
1.33      mycroft  1410:        int s;
                   1411:
1.99      mycroft  1412:        s = splserial();
1.33      mycroft  1413:        overflows = sc->sc_overflows;
                   1414:        sc->sc_overflows = 0;
1.57      mycroft  1415:        floods = sc->sc_floods;
                   1416:        sc->sc_floods = 0;
1.99      mycroft  1417:        sc->sc_errors = 0;
1.57      mycroft  1418:        splx(s);
                   1419:
1.127     mycroft  1420:        log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
1.57      mycroft  1421:            sc->sc_dev.dv_xname,
                   1422:            overflows, overflows == 1 ? "" : "s",
1.99      mycroft  1423:            floods, floods == 1 ? "" : "s");
1.57      mycroft  1424: }
                   1425:
1.99      mycroft  1426: integrate void
1.127     mycroft  1427: com_rxsoft(sc, tp)
                   1428:        struct com_softc *sc;
                   1429:        struct tty *tp;
1.99      mycroft  1430: {
1.127     mycroft  1431:        int (*rint) __P((int c, struct tty *tp)) = linesw[tp->t_line].l_rint;
                   1432:        u_char *get, *end;
                   1433:        u_int cc, scc;
                   1434:        u_char lsr;
                   1435:        int code;
                   1436:        int s;
1.57      mycroft  1437:
1.127     mycroft  1438:        end = sc->sc_ebuf;
1.99      mycroft  1439:        get = sc->sc_rbget;
1.127     mycroft  1440:        scc = cc = com_rbuf_size - sc->sc_rbavail;
1.99      mycroft  1441:
1.127     mycroft  1442:        if (cc == com_rbuf_size) {
1.99      mycroft  1443:                sc->sc_floods++;
                   1444:                if (sc->sc_errors++ == 0)
                   1445:                        timeout(comdiag, sc, 60 * hz);
                   1446:        }
                   1447:
1.101     mycroft  1448:        while (cc) {
1.128     mycroft  1449:                code = get[0];
1.127     mycroft  1450:                lsr = get[1];
1.128     mycroft  1451:                if (ISSET(lsr, LSR_OE | LSR_BI | LSR_FE | LSR_PE)) {
                   1452:                        if (ISSET(lsr, LSR_OE)) {
                   1453:                                sc->sc_overflows++;
                   1454:                                if (sc->sc_errors++ == 0)
                   1455:                                        timeout(comdiag, sc, 60 * hz);
                   1456:                        }
1.127     mycroft  1457:                        if (ISSET(lsr, LSR_BI | LSR_FE))
                   1458:                                SET(code, TTY_FE);
                   1459:                        if (ISSET(lsr, LSR_PE))
                   1460:                                SET(code, TTY_PE);
                   1461:                }
                   1462:                if ((*rint)(code, tp) == -1) {
1.101     mycroft  1463:                        /*
                   1464:                         * The line discipline's buffer is out of space.
                   1465:                         */
                   1466:                        if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
                   1467:                                /*
                   1468:                                 * We're either not using flow control, or the
                   1469:                                 * line discipline didn't tell us to block for
                   1470:                                 * some reason.  Either way, we have no way to
                   1471:                                 * know when there's more space available, so
                   1472:                                 * just drop the rest of the data.
                   1473:                                 */
1.127     mycroft  1474:                                get += cc << 1;
                   1475:                                if (get >= end)
                   1476:                                        get -= com_rbuf_size << 1;
1.101     mycroft  1477:                                cc = 0;
                   1478:                        } else {
                   1479:                                /*
                   1480:                                 * Don't schedule any more receive processing
                   1481:                                 * until the line discipline tells us there's
                   1482:                                 * space available (through comhwiflow()).
                   1483:                                 * Leave the rest of the data in the input
                   1484:                                 * buffer.
                   1485:                                 */
                   1486:                                SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
                   1487:                        }
                   1488:                        break;
                   1489:                }
1.127     mycroft  1490:                get += 2;
                   1491:                if (get >= end)
                   1492:                        get = sc->sc_rbuf;
1.101     mycroft  1493:                cc--;
1.99      mycroft  1494:        }
                   1495:
1.101     mycroft  1496:        if (cc != scc) {
                   1497:                sc->sc_rbget = get;
                   1498:                s = splserial();
                   1499:                cc = sc->sc_rbavail += scc - cc;
                   1500:                /* Buffers should be ok again, release possible block. */
                   1501:                if (cc >= sc->sc_r_lowat) {
                   1502:                        if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
                   1503:                                CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
                   1504:                                SET(sc->sc_ier, IER_ERXRDY);
                   1505:                                bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
                   1506:                        }
                   1507:                        if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
                   1508:                                CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
                   1509:                                com_hwiflow(sc);
                   1510:                        }
                   1511:                }
                   1512:                splx(s);
1.57      mycroft  1513:        }
1.99      mycroft  1514: }
                   1515:
                   1516: integrate void
1.127     mycroft  1517: com_txsoft(sc, tp)
                   1518:        struct com_softc *sc;
                   1519:        struct tty *tp;
1.99      mycroft  1520: {
1.33      mycroft  1521:
1.99      mycroft  1522:        CLR(tp->t_state, TS_BUSY);
                   1523:        if (ISSET(tp->t_state, TS_FLUSH))
                   1524:                CLR(tp->t_state, TS_FLUSH);
                   1525:        else
                   1526:                ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
                   1527:        (*linesw[tp->t_line].l_start)(tp);
                   1528: }
1.57      mycroft  1529:
1.99      mycroft  1530: integrate void
1.127     mycroft  1531: com_stsoft(sc, tp)
                   1532:        struct com_softc *sc;
                   1533:        struct tty *tp;
1.99      mycroft  1534: {
                   1535:        u_char msr, delta;
                   1536:        int s;
1.57      mycroft  1537:
1.99      mycroft  1538:        s = splserial();
                   1539:        msr = sc->sc_msr;
                   1540:        delta = sc->sc_msr_delta;
                   1541:        sc->sc_msr_delta = 0;
                   1542:        splx(s);
1.57      mycroft  1543:
1.99      mycroft  1544:        if (ISSET(delta, sc->sc_msr_dcd)) {
                   1545:                /*
                   1546:                 * Inform the tty layer that carrier detect changed.
                   1547:                 */
                   1548:                (void) (*linesw[tp->t_line].l_modem)(tp, ISSET(msr, MSR_DCD));
                   1549:        }
1.61      mycroft  1550:
1.99      mycroft  1551:        if (ISSET(delta, sc->sc_msr_cts)) {
                   1552:                /* Block or unblock output according to flow control. */
                   1553:                if (ISSET(msr, sc->sc_msr_cts)) {
                   1554:                        sc->sc_tx_stopped = 0;
                   1555:                        (*linesw[tp->t_line].l_start)(tp);
                   1556:                } else {
                   1557:                        sc->sc_tx_stopped = 1;
1.61      mycroft  1558:                }
1.99      mycroft  1559:        }
                   1560:
                   1561: #ifdef COM_DEBUG
1.101     mycroft  1562:        if (com_debug)
1.127     mycroft  1563:                comstatus(sc, "com_stsoft");
1.99      mycroft  1564: #endif
                   1565: }
                   1566:
                   1567: #ifdef __GENERIC_SOFT_INTERRUPTS
                   1568: void
                   1569: comsoft(arg)
                   1570:        void *arg;
                   1571: {
                   1572:        struct com_softc *sc = arg;
                   1573:        struct tty *tp;
                   1574:
1.131     marc     1575:        if (!sc->enabled)
                   1576:                return;
                   1577:
1.99      mycroft  1578:        {
                   1579: #else
                   1580: void
1.133     cgd      1581: #ifndef __NO_SOFT_SERIAL_INTERRUPT
1.99      mycroft  1582: comsoft()
                   1583: #else
                   1584: comsoft(arg)
                   1585:        void *arg;
                   1586: #endif
                   1587: {
                   1588:        struct com_softc        *sc;
                   1589:        struct tty      *tp;
                   1590:        int     unit;
1.133     cgd      1591: #ifdef __NO_SOFT_SERIAL_INTERRUPT
1.99      mycroft  1592:        int s;
                   1593:
                   1594:        s = splsoftserial();
                   1595:        com_softintr_scheduled = 0;
                   1596: #endif
1.57      mycroft  1597:
1.99      mycroft  1598:        for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
                   1599:                sc = com_cd.cd_devs[unit];
1.132     cgd      1600:                if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
1.99      mycroft  1601:                        continue;
1.57      mycroft  1602:
1.131     marc     1603:                if (!sc->enabled)
                   1604:                        continue;
                   1605:
1.99      mycroft  1606:                tp = sc->sc_tty;
                   1607:                if (tp == NULL || !ISSET(tp->t_state, TS_ISOPEN | TS_WOPEN))
1.57      mycroft  1608:                        continue;
1.108     is       1609: #endif
                   1610:                tp = sc->sc_tty;
1.99      mycroft  1611:
                   1612:                if (sc->sc_rx_ready) {
                   1613:                        sc->sc_rx_ready = 0;
1.127     mycroft  1614:                        com_rxsoft(sc, tp);
1.57      mycroft  1615:                }
                   1616:
1.99      mycroft  1617:                if (sc->sc_st_check) {
                   1618:                        sc->sc_st_check = 0;
1.127     mycroft  1619:                        com_stsoft(sc, tp);
1.62      mycroft  1620:                }
1.57      mycroft  1621:
1.99      mycroft  1622:                if (sc->sc_tx_done) {
                   1623:                        sc->sc_tx_done = 0;
1.127     mycroft  1624:                        com_txsoft(sc, tp);
1.57      mycroft  1625:                }
                   1626:        }
                   1627:
1.99      mycroft  1628: #ifndef __GENERIC_SOFT_INTERRUPTS
1.133     cgd      1629: #ifdef __NO_SOFT_SERIAL_INTERRUPT
1.99      mycroft  1630:        splx(s);
                   1631: #endif
                   1632: #endif
1.21      mycroft  1633: }
1.1       cgd      1634:
1.21      mycroft  1635: int
1.49      cgd      1636: comintr(arg)
1.127     mycroft  1637:        void *arg;
1.21      mycroft  1638: {
1.49      cgd      1639:        struct com_softc *sc = arg;
1.91      thorpej  1640:        bus_space_tag_t iot = sc->sc_iot;
                   1641:        bus_space_handle_t ioh = sc->sc_ioh;
1.127     mycroft  1642:        u_char *put, *end;
                   1643:        u_int cc;
                   1644:        u_char lsr, iir;
1.55      mycroft  1645:
1.131     marc     1646:        if (!sc->enabled)
                   1647:                return (0);
                   1648:
1.91      thorpej  1649:        iir = bus_space_read_1(iot, ioh, com_iir);
1.88      mycroft  1650:        if (ISSET(iir, IIR_NOPEND))
1.55      mycroft  1651:                return (0);
1.21      mycroft  1652:
1.127     mycroft  1653:        end = sc->sc_ebuf;
1.99      mycroft  1654:        put = sc->sc_rbput;
                   1655:        cc = sc->sc_rbavail;
                   1656:
                   1657:        do {
                   1658:                u_char  msr, delta;
1.21      mycroft  1659:
1.91      thorpej  1660:                lsr = bus_space_read_1(iot, ioh, com_lsr);
1.103     drochner 1661: #if defined(DDB) || defined(KGDB)
                   1662:                if (ISSET(lsr, LSR_BI)) {
                   1663: #ifdef DDB
                   1664:                        if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
                   1665:                                Debugger();
                   1666:                                continue;
                   1667:                        }
                   1668: #endif
                   1669: #ifdef KGDB
                   1670:                        if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) {
                   1671:                                kgdb_connect(1);
                   1672:                                continue;
                   1673:                        }
                   1674: #endif
1.102     thorpej  1675:                }
1.103     drochner 1676: #endif /* DDB || KGDB */
1.102     thorpej  1677:
1.101     mycroft  1678:                if (ISSET(lsr, LSR_RCV_MASK) &&
                   1679:                    !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
1.127     mycroft  1680:                        while (cc > 0) {
                   1681:                                put[0] = bus_space_read_1(iot, ioh, com_data);
                   1682:                                put[1] = lsr;
                   1683:                                put += 2;
                   1684:                                if (put >= end)
                   1685:                                        put = sc->sc_rbuf;
                   1686:                                cc--;
                   1687:
1.99      mycroft  1688:                                lsr = bus_space_read_1(iot, ioh, com_lsr);
1.127     mycroft  1689:                                if (!ISSET(lsr, LSR_RCV_MASK))
                   1690:                                        break;
1.99      mycroft  1691:                        }
1.127     mycroft  1692:
1.99      mycroft  1693:                        /*
                   1694:                         * Current string of incoming characters ended because
1.127     mycroft  1695:                         * no more data was available or we ran out of space.
                   1696:                         * Schedule a receive event if any data was received.
                   1697:                         * If we're out of space, turn off receive interrupts.
1.99      mycroft  1698:                         */
                   1699:                        sc->sc_rbput = put;
                   1700:                        sc->sc_rbavail = cc;
1.101     mycroft  1701:                        if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
                   1702:                                sc->sc_rx_ready = 1;
1.127     mycroft  1703:
1.99      mycroft  1704:                        /*
                   1705:                         * See if we are in danger of overflowing a buffer. If
                   1706:                         * so, use hardware flow control to ease the pressure.
                   1707:                         */
1.101     mycroft  1708:                        if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
1.99      mycroft  1709:                            cc < sc->sc_r_hiwat) {
1.101     mycroft  1710:                                SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
                   1711:                                com_hwiflow(sc);
1.99      mycroft  1712:                        }
1.127     mycroft  1713:
1.99      mycroft  1714:                        /*
1.101     mycroft  1715:                         * If we're out of space, disable receive interrupts
                   1716:                         * until the queue has drained a bit.
1.99      mycroft  1717:                         */
                   1718:                        if (!cc) {
1.101     mycroft  1719:                                SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
                   1720:                                CLR(sc->sc_ier, IER_ERXRDY);
                   1721:                                bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
1.99      mycroft  1722:                        }
1.88      mycroft  1723:                } else {
                   1724:                        if ((iir & IIR_IMASK) == IIR_RXRDY) {
1.91      thorpej  1725:                                bus_space_write_1(iot, ioh, com_ier, 0);
1.88      mycroft  1726:                                delay(10);
1.99      mycroft  1727:                                bus_space_write_1(iot, ioh, com_ier,sc->sc_ier);
1.88      mycroft  1728:                                iir = IIR_NOPEND;
                   1729:                                continue;
                   1730:                        }
                   1731:                }
1.55      mycroft  1732:
1.99      mycroft  1733:                msr = bus_space_read_1(iot, ioh, com_msr);
                   1734:                delta = msr ^ sc->sc_msr;
                   1735:                sc->sc_msr = msr;
                   1736:                if (ISSET(delta, sc->sc_msr_mask)) {
1.127     mycroft  1737:                        SET(sc->sc_msr_delta, delta);
1.99      mycroft  1738:
                   1739:                        /*
                   1740:                         * Stop output immediately if we lose the output
                   1741:                         * flow control signal or carrier detect.
                   1742:                         */
                   1743:                        if (ISSET(~msr, sc->sc_msr_mask)) {
                   1744:                                sc->sc_tbc = 0;
                   1745:                                sc->sc_heldtbc = 0;
1.69      mycroft  1746: #ifdef COM_DEBUG
1.101     mycroft  1747:                                if (com_debug)
                   1748:                                        comstatus(sc, "comintr  ");
1.69      mycroft  1749: #endif
1.99      mycroft  1750:                        }
1.55      mycroft  1751:
1.99      mycroft  1752:                        sc->sc_st_check = 1;
1.55      mycroft  1753:                }
1.99      mycroft  1754:        } while (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND));
1.55      mycroft  1755:
1.99      mycroft  1756:        /*
                   1757:         * Done handling any receive interrupts. See if data can be
                   1758:         * transmitted as well. Schedule tx done event if no data left
                   1759:         * and tty was marked busy.
                   1760:         */
                   1761:        if (ISSET(lsr, LSR_TXRDY)) {
                   1762:                /*
                   1763:                 * If we've delayed a parameter change, do it now, and restart
                   1764:                 * output.
                   1765:                 */
                   1766:                if (sc->sc_heldchange) {
                   1767:                        com_loadchannelregs(sc);
                   1768:                        sc->sc_heldchange = 0;
                   1769:                        sc->sc_tbc = sc->sc_heldtbc;
                   1770:                        sc->sc_heldtbc = 0;
                   1771:                }
1.127     mycroft  1772:
1.99      mycroft  1773:                /* Output the next chunk of the contiguous buffer, if any. */
                   1774:                if (sc->sc_tbc > 0) {
                   1775:                        int n;
                   1776:
1.127     mycroft  1777:                        n = sc->sc_tbc;
                   1778:                        if (n > sc->sc_fifolen)
                   1779:                                n = sc->sc_fifolen;
1.99      mycroft  1780:                        bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
                   1781:                        sc->sc_tbc -= n;
                   1782:                        sc->sc_tba += n;
1.127     mycroft  1783:                } else {
                   1784:                        /* Disable transmit completion interrupts if necessary. */
                   1785:                        if (ISSET(sc->sc_ier, IER_ETXRDY)) {
                   1786:                                CLR(sc->sc_ier, IER_ETXRDY);
                   1787:                                bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
                   1788:                        }
                   1789:                        if (sc->sc_tx_busy) {
                   1790:                                sc->sc_tx_busy = 0;
                   1791:                                sc->sc_tx_done = 1;
                   1792:                        }
1.62      mycroft  1793:                }
1.99      mycroft  1794:        }
1.62      mycroft  1795:
1.99      mycroft  1796:        /* Wake up the poller. */
                   1797: #ifdef __GENERIC_SOFT_INTERRUPTS
                   1798:        softintr_schedule(sc->sc_si);
                   1799: #else
1.133     cgd      1800: #ifndef __NO_SOFT_SERIAL_INTERRUPT
1.99      mycroft  1801:        setsoftserial();
                   1802: #else
                   1803:        if (!com_softintr_scheduled) {
                   1804:                com_softintr_scheduled = 1;
                   1805:                timeout(comsoft, NULL, 1);
1.1       cgd      1806:        }
1.99      mycroft  1807: #endif
                   1808: #endif
1.115     explorer 1809:
                   1810: #if NRND > 0 && defined(RND_COM)
                   1811:        rnd_add_uint32(&sc->rnd_source, iir | lsr);
                   1812: #endif
                   1813:
1.88      mycroft  1814:        return (1);
1.1       cgd      1815: }
                   1816:
                   1817: /*
1.102     thorpej  1818:  * The following functions are polled getc and putc routines, shared
                   1819:  * by the console and kgdb glue.
                   1820:  */
                   1821:
                   1822: int
                   1823: com_common_getc(iot, ioh)
                   1824:        bus_space_tag_t iot;
                   1825:        bus_space_handle_t ioh;
                   1826: {
                   1827:        int s = splserial();
                   1828:        u_char stat, c;
                   1829:
1.135     thorpej  1830:        /* block until a character becomes available */
                   1831:        while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
1.102     thorpej  1832:                ;
1.135     thorpej  1833:
1.102     thorpej  1834:        c = bus_space_read_1(iot, ioh, com_data);
                   1835:        stat = bus_space_read_1(iot, ioh, com_iir);
                   1836:        splx(s);
                   1837:        return (c);
                   1838: }
                   1839:
                   1840: void
                   1841: com_common_putc(iot, ioh, c)
                   1842:        bus_space_tag_t iot;
                   1843:        bus_space_handle_t ioh;
                   1844:        int c;
                   1845: {
                   1846:        int s = splserial();
                   1847:        u_char stat;
1.127     mycroft  1848:        int timo;
1.102     thorpej  1849:
                   1850:        /* wait for any pending transmission to finish */
                   1851:        timo = 50000;
                   1852:        while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
                   1853:            && --timo)
                   1854:                ;
1.135     thorpej  1855:
1.102     thorpej  1856:        bus_space_write_1(iot, ioh, com_data, c);
                   1857:        /* wait for this transmission to complete */
                   1858:        timo = 1500000;
                   1859:        while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY)
                   1860:            && --timo)
                   1861:                ;
1.135     thorpej  1862:
1.102     thorpej  1863:        /* clear any interrupts generated by this transmission */
                   1864:        stat = bus_space_read_1(iot, ioh, com_iir);
                   1865:        splx(s);
                   1866: }
                   1867:
                   1868: /*
1.99      mycroft  1869:  * Initialize UART to known state.
                   1870:  */
1.106     drochner 1871: int
1.109     is       1872: cominit(iot, iobase, rate, frequency, cflag, iohp)
1.91      thorpej  1873:        bus_space_tag_t iot;
1.106     drochner 1874:        int iobase;
1.109     is       1875:        int rate, frequency;
1.106     drochner 1876:        tcflag_t cflag;
                   1877:        bus_space_handle_t *iohp;
1.1       cgd      1878: {
1.106     drochner 1879:        bus_space_handle_t ioh;
                   1880:
                   1881:        if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
1.110     enami    1882:                return (ENOMEM); /* ??? */
1.1       cgd      1883:
1.116     fvdl     1884:        bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
                   1885:        bus_space_write_1(iot, ioh, com_efr, 0);
1.91      thorpej  1886:        bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
1.109     is       1887:        rate = comspeed(rate, frequency);
1.91      thorpej  1888:        bus_space_write_1(iot, ioh, com_dlbl, rate);
                   1889:        bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
1.106     drochner 1890:        bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
1.99      mycroft  1891:        bus_space_write_1(iot, ioh, com_mcr, 0);
1.91      thorpej  1892:        bus_space_write_1(iot, ioh, com_fifo,
1.87      mycroft  1893:            FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
1.99      mycroft  1894:        bus_space_write_1(iot, ioh, com_ier, 0);
1.106     drochner 1895:
                   1896:        *iohp = ioh;
1.110     enami    1897:        return (0);
1.99      mycroft  1898: }
                   1899:
                   1900: /*
1.106     drochner 1901:  * Following are all routines needed for COM to act as console
1.99      mycroft  1902:  */
1.106     drochner 1903:
                   1904: int
1.109     is       1905: comcnattach(iot, iobase, rate, frequency, cflag)
1.99      mycroft  1906:        bus_space_tag_t iot;
1.106     drochner 1907:        int iobase;
1.109     is       1908:        int rate, frequency;
1.106     drochner 1909:        tcflag_t cflag;
1.99      mycroft  1910: {
1.106     drochner 1911:        int res;
1.120     mycroft  1912:        static struct consdev comcons = {
                   1913:                NULL, NULL, comcngetc, comcnputc, comcnpollc, NODEV, CN_NORMAL
                   1914:        };
1.106     drochner 1915:
1.109     is       1916:        res = cominit(iot, iobase, rate, frequency, cflag, &comconsioh);
1.110     enami    1917:        if (res)
                   1918:                return (res);
1.106     drochner 1919:
                   1920:        cn_tab = &comcons;
                   1921:
                   1922:        comconstag = iot;
                   1923:        comconsaddr = iobase;
                   1924:        comconsrate = rate;
                   1925:        comconscflag = cflag;
1.99      mycroft  1926:
1.110     enami    1927:        return (0);
1.1       cgd      1928: }
                   1929:
1.80      christos 1930: int
1.1       cgd      1931: comcngetc(dev)
1.21      mycroft  1932:        dev_t dev;
1.1       cgd      1933: {
                   1934:
1.102     thorpej  1935:        return (com_common_getc(comconstag, comconsioh));
1.1       cgd      1936: }
                   1937:
                   1938: /*
                   1939:  * Console kernel output character routine.
                   1940:  */
1.48      mycroft  1941: void
1.1       cgd      1942: comcnputc(dev, c)
                   1943:        dev_t dev;
1.21      mycroft  1944:        int c;
1.1       cgd      1945: {
                   1946:
1.102     thorpej  1947:        com_common_putc(comconstag, comconsioh, c);
1.37      mycroft  1948: }
                   1949:
                   1950: void
                   1951: comcnpollc(dev, on)
                   1952:        dev_t dev;
                   1953:        int on;
                   1954: {
                   1955:
1.106     drochner 1956: }
                   1957:
                   1958: #ifdef KGDB
                   1959: int
1.109     is       1960: com_kgdb_attach(iot, iobase, rate, frequency, cflag)
1.106     drochner 1961:        bus_space_tag_t iot;
                   1962:        int iobase;
1.112     mikel    1963:        int rate, frequency;
1.106     drochner 1964:        tcflag_t cflag;
                   1965: {
                   1966:        int res;
1.107     drochner 1967:
                   1968:        if (iot == comconstag && iobase == comconsaddr)
1.110     enami    1969:                return (EBUSY); /* cannot share with console */
1.106     drochner 1970:
1.109     is       1971:        res = cominit(iot, iobase, rate, frequency, cflag, &com_kgdb_ioh);
1.110     enami    1972:        if (res)
                   1973:                return (res);
1.106     drochner 1974:
                   1975:        kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
                   1976:        kgdb_dev = 123; /* unneeded, only to satisfy some tests */
                   1977:
                   1978:        com_kgdb_iot = iot;
                   1979:        com_kgdb_addr = iobase;
                   1980:
1.110     enami    1981:        return (0);
1.106     drochner 1982: }
                   1983:
                   1984: /* ARGSUSED */
                   1985: int
                   1986: com_kgdb_getc(arg)
                   1987:        void *arg;
                   1988: {
                   1989:
                   1990:        return (com_common_getc(com_kgdb_iot, com_kgdb_ioh));
                   1991: }
                   1992:
                   1993: /* ARGSUSED */
                   1994: void
                   1995: com_kgdb_putc(arg, c)
                   1996:        void *arg;
                   1997:        int c;
                   1998: {
                   1999:
                   2000:        return (com_common_putc(com_kgdb_iot, com_kgdb_ioh, c));
                   2001: }
                   2002: #endif /* KGDB */
                   2003:
                   2004: /* helper function to identify the com ports used by
                   2005:  console or KGDB (and not yet autoconf attached) */
                   2006: int
                   2007: com_is_console(iot, iobase, ioh)
1.110     enami    2008:        bus_space_tag_t iot;
                   2009:        int iobase;
                   2010:        bus_space_handle_t *ioh;
1.106     drochner 2011: {
                   2012:        bus_space_handle_t help;
                   2013:
1.110     enami    2014:        if (!comconsattached &&
                   2015:            iot == comconstag && iobase == comconsaddr)
1.106     drochner 2016:                help = comconsioh;
                   2017: #ifdef KGDB
1.110     enami    2018:        else if (!com_kgdb_attached &&
                   2019:            iot == com_kgdb_iot && iobase == com_kgdb_addr)
1.106     drochner 2020:                help = com_kgdb_ioh;
                   2021: #endif
                   2022:        else
1.110     enami    2023:                return (0);
1.106     drochner 2024:
1.110     enami    2025:        if (ioh)
                   2026:                *ioh = help;
                   2027:        return (1);
1.2       cgd      2028: }

CVSweb <webmaster@jp.NetBSD.org>