The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/ic/com.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: com.c,v 1.232.2.1 2007/12/01 17:49:45 bouyer Exp $     */
    2 
    3 /*-
    4  * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum.
    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 the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * Copyright (c) 1991 The Regents of the University of California.
   41  * All rights reserved.
   42  *
   43  * Redistribution and use in source and binary forms, with or without
   44  * modification, are permitted provided that the following conditions
   45  * are met:
   46  * 1. Redistributions of source code must retain the above copyright
   47  *    notice, this list of conditions and the following disclaimer.
   48  * 2. Redistributions in binary form must reproduce the above copyright
   49  *    notice, this list of conditions and the following disclaimer in the
   50  *    documentation and/or other materials provided with the distribution.
   51  * 3. Neither the name of the University nor the names of its contributors
   52  *    may be used to endorse or promote products derived from this software
   53  *    without specific prior written permission.
   54  *
   55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   65  * SUCH DAMAGE.
   66  *
   67  *      @(#)com.c       7.5 (Berkeley) 5/16/91
   68  */
   69 
   70 /*
   71  * COM driver, uses National Semiconductor NS16450/NS16550AF UART
   72  * Supports automatic hardware flow control on StarTech ST16C650A UART
   73  */
   74 
   75 #include <sys/cdefs.h>
   76 __KERNEL_RCSID(0, "$NetBSD: com.c,v 1.232.2.1 2007/12/01 17:49:45 bouyer Exp $");
   77 
   78 #include "opt_com.h"
   79 #include "opt_ddb.h"
   80 #include "opt_kgdb.h"
   81 #include "opt_lockdebug.h"
   82 #include "opt_multiprocessor.h"
   83 #include "opt_ntp.h"
   84 
   85 #include "rnd.h"
   86 #if NRND > 0 && defined(RND_COM)
   87 #include <sys/rnd.h>
   88 #endif
   89 
   90 /* The COM16650 option was renamed to COM_16650. */
   91 #ifdef COM16650
   92 #error Obsolete COM16650 option; use COM_16650 instead.
   93 #endif
   94 
   95 /*
   96  * Override cnmagic(9) macro before including <sys/systm.h>.
   97  * We need to know if cn_check_magic triggered debugger, so set a flag.
   98  * Callers of cn_check_magic must declare int cn_trapped = 0;
   99  * XXX: this is *ugly*!
  100  */
  101 #define cn_trap()                               \
  102         do {                                    \
  103                 console_debugger();             \
  104                 cn_trapped = 1;                 \
  105         } while (/* CONSTCOND */ 0)
  106 
  107 #include <sys/param.h>
  108 #include <sys/systm.h>
  109 #include <sys/ioctl.h>
  110 #include <sys/select.h>
  111 #include <sys/tty.h>
  112 #include <sys/proc.h>
  113 #include <sys/user.h>
  114 #include <sys/conf.h>
  115 #include <sys/file.h>
  116 #include <sys/uio.h>
  117 #include <sys/kernel.h>
  118 #include <sys/syslog.h>
  119 #include <sys/device.h>
  120 #include <sys/malloc.h>
  121 #include <sys/timepps.h>
  122 #include <sys/vnode.h>
  123 
  124 #include <machine/intr.h>
  125 #include <machine/bus.h>
  126 
  127 #include <dev/ic/comreg.h>
  128 #include <dev/ic/comvar.h>
  129 #include <dev/ic/ns16550reg.h>
  130 #include <dev/ic/st16650reg.h>
  131 #ifdef COM_HAYESP
  132 #include <dev/ic/hayespreg.h>
  133 #endif
  134 #define com_lcr com_cfcr
  135 #include <dev/cons.h>
  136 
  137 #ifdef COM_HAYESP
  138 int comprobeHAYESP(bus_space_handle_t hayespioh, struct com_softc *sc);
  139 #endif
  140 
  141 static void com_enable_debugport(struct com_softc *);
  142 
  143 void    com_config(struct com_softc *);
  144 void    com_shutdown(struct com_softc *);
  145 int     comspeed(long, long, int);
  146 static  u_char  cflag2lcr(tcflag_t);
  147 int     comparam(struct tty *, struct termios *);
  148 void    comstart(struct tty *);
  149 int     comhwiflow(struct tty *, int);
  150 
  151 void    com_loadchannelregs(struct com_softc *);
  152 void    com_hwiflow(struct com_softc *);
  153 void    com_break(struct com_softc *, int);
  154 void    com_modem(struct com_softc *, int);
  155 void    tiocm_to_com(struct com_softc *, u_long, int);
  156 int     com_to_tiocm(struct com_softc *);
  157 void    com_iflush(struct com_softc *);
  158 
  159 int     com_common_getc(dev_t, bus_space_tag_t, bus_space_handle_t);
  160 void    com_common_putc(dev_t, bus_space_tag_t, bus_space_handle_t, int);
  161 
  162 int     cominit(bus_space_tag_t, bus_addr_t, int, int, int, tcflag_t,
  163             bus_space_handle_t *);
  164 
  165 int     comcngetc(dev_t);
  166 void    comcnputc(dev_t, int);
  167 void    comcnpollc(dev_t, int);
  168 
  169 #define integrate       static inline
  170 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  171 void    comsoft(void *);
  172 #else
  173 #ifndef __NO_SOFT_SERIAL_INTERRUPT
  174 void    comsoft(void);
  175 #else
  176 void    comsoft(void *);
  177 static struct callout comsoft_callout = CALLOUT_INITIALIZER;
  178 #endif
  179 #endif
  180 integrate void com_rxsoft(struct com_softc *, struct tty *);
  181 integrate void com_txsoft(struct com_softc *, struct tty *);
  182 integrate void com_stsoft(struct com_softc *, struct tty *);
  183 integrate void com_schedrx(struct com_softc *);
  184 void    comdiag(void *);
  185 
  186 extern struct cfdriver com_cd;
  187 
  188 dev_type_open(comopen);
  189 dev_type_close(comclose);
  190 dev_type_read(comread);
  191 dev_type_write(comwrite);
  192 dev_type_ioctl(comioctl);
  193 dev_type_stop(comstop);
  194 dev_type_tty(comtty);
  195 dev_type_poll(compoll);
  196 
  197 const struct cdevsw com_cdevsw = {
  198         comopen, comclose, comread, comwrite, comioctl,
  199         comstop, comtty, compoll, nommap, ttykqfilter, D_TTY
  200 };
  201 
  202 /*
  203  * Make this an option variable one can patch.
  204  * But be warned:  this must be a power of 2!
  205  */
  206 u_int com_rbuf_size = COM_RING_SIZE;
  207 
  208 /* Stop input when 3/4 of the ring is full; restart when only 1/4 is full. */
  209 u_int com_rbuf_hiwat = (COM_RING_SIZE * 1) / 4;
  210 u_int com_rbuf_lowat = (COM_RING_SIZE * 3) / 4;
  211 
  212 static bus_addr_t       comconsaddr;
  213 static bus_space_tag_t comconstag;
  214 static bus_space_handle_t comconsioh;
  215 static int      comconsattached;
  216 static int comconsrate;
  217 static tcflag_t comconscflag;
  218 static struct cnm_state com_cnm_state;
  219 
  220 static int ppscap =
  221         PPS_TSFMT_TSPEC |
  222         PPS_CAPTUREASSERT |
  223         PPS_CAPTURECLEAR |
  224         PPS_OFFSETASSERT | PPS_OFFSETCLEAR;
  225 
  226 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
  227 #ifdef __NO_SOFT_SERIAL_INTERRUPT
  228 volatile int    com_softintr_scheduled;
  229 #endif
  230 #endif
  231 
  232 #ifdef KGDB
  233 #include <sys/kgdb.h>
  234 
  235 static bus_addr_t com_kgdb_addr;
  236 static bus_space_tag_t com_kgdb_iot;
  237 static bus_space_handle_t com_kgdb_ioh;
  238 static int com_kgdb_attached;
  239 
  240 int     com_kgdb_getc(void *);
  241 void    com_kgdb_putc(void *, int);
  242 #endif /* KGDB */
  243 
  244 #define COMUNIT_MASK    0x7ffff
  245 #define COMDIALOUT_MASK 0x80000
  246 
  247 #define COMUNIT(x)      (minor(x) & COMUNIT_MASK)
  248 #define COMDIALOUT(x)   (minor(x) & COMDIALOUT_MASK)
  249 
  250 #define COM_ISALIVE(sc) ((sc)->enabled != 0 && \
  251                          ISSET((sc)->sc_dev.dv_flags, DVF_ACTIVE))
  252 
  253 #define BR      BUS_SPACE_BARRIER_READ
  254 #define BW      BUS_SPACE_BARRIER_WRITE
  255 #define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f))
  256 
  257 #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
  258 
  259 #define COM_LOCK(sc) simple_lock(&(sc)->sc_lock)
  260 #define COM_UNLOCK(sc) simple_unlock(&(sc)->sc_lock)
  261 
  262 #else
  263 
  264 #define COM_LOCK(sc)
  265 #define COM_UNLOCK(sc)
  266 
  267 #endif
  268 
  269 /*ARGSUSED*/
  270 int
  271 comspeed(long speed, long frequency, int type)
  272 {
  273 #define divrnd(n, q)    (((n)*2/(q)+1)/2)       /* divide and round off */
  274 
  275         int x, err;
  276 
  277 #if 0
  278         if (speed == 0)
  279                 return (0);
  280 #endif
  281         if (speed <= 0)
  282                 return (-1);
  283         x = divrnd(frequency / 16, speed);
  284         if (x <= 0)
  285                 return (-1);
  286         err = divrnd(((quad_t)frequency) * 1000 / 16, speed * x) - 1000;
  287         if (err < 0)
  288                 err = -err;
  289         if (err > COM_TOLERANCE)
  290                 return (-1);
  291         return (x);
  292 
  293 #undef  divrnd
  294 }
  295 
  296 #ifdef COM_DEBUG
  297 int     com_debug = 0;
  298 
  299 void comstatus(struct com_softc *, char *);
  300 void
  301 comstatus(struct com_softc *sc, char *str)
  302 {
  303         struct tty *tp = sc->sc_tty;
  304 
  305         printf("%s: %s %cclocal  %cdcd %cts_carr_on %cdtr %ctx_stopped\n",
  306             sc->sc_dev.dv_xname, str,
  307             ISSET(tp->t_cflag, CLOCAL) ? '+' : '-',
  308             ISSET(sc->sc_msr, MSR_DCD) ? '+' : '-',
  309             ISSET(tp->t_state, TS_CARR_ON) ? '+' : '-',
  310             ISSET(sc->sc_mcr, MCR_DTR) ? '+' : '-',
  311             sc->sc_tx_stopped ? '+' : '-');
  312 
  313         printf("%s: %s %ccrtscts %ccts %cts_ttstop  %crts rx_flags=0x%x\n",
  314             sc->sc_dev.dv_xname, str,
  315             ISSET(tp->t_cflag, CRTSCTS) ? '+' : '-',
  316             ISSET(sc->sc_msr, MSR_CTS) ? '+' : '-',
  317             ISSET(tp->t_state, TS_TTSTOP) ? '+' : '-',
  318             ISSET(sc->sc_mcr, MCR_RTS) ? '+' : '-',
  319             sc->sc_rx_flags);
  320 }
  321 #endif
  322 
  323 int
  324 comprobe1(bus_space_tag_t iot, bus_space_handle_t ioh)
  325 {
  326 
  327         /* force access to id reg */
  328         bus_space_write_1(iot, ioh, com_lcr, LCR_8BITS);
  329         bus_space_write_1(iot, ioh, com_iir, 0);
  330         if ((bus_space_read_1(iot, ioh, com_lcr) != LCR_8BITS) ||
  331             (bus_space_read_1(iot, ioh, com_iir) & 0x38))
  332                 return (0);
  333 
  334         return (1);
  335 }
  336 
  337 #ifdef COM_HAYESP
  338 int
  339 comprobeHAYESP(bus_space_handle_t hayespioh, struct com_softc *sc)
  340 {
  341         char    val, dips;
  342         int     combaselist[] = { 0x3f8, 0x2f8, 0x3e8, 0x2e8 };
  343         bus_space_tag_t iot = sc->sc_iot;
  344 
  345         /*
  346          * Hayes ESP cards have two iobases.  One is for compatibility with
  347          * 16550 serial chips, and at the same ISA PC base addresses.  The
  348          * other is for ESP-specific enhanced features, and lies at a
  349          * different addressing range entirely (0x140, 0x180, 0x280, or 0x300).
  350          */
  351 
  352         /* Test for ESP signature */
  353         if ((bus_space_read_1(iot, hayespioh, 0) & 0xf3) == 0)
  354                 return (0);
  355 
  356         /*
  357          * ESP is present at ESP enhanced base address; unknown com port
  358          */
  359 
  360         /* Get the dip-switch configurations */
  361         bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETDIPS);
  362         dips = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1);
  363 
  364         /* Determine which com port this ESP card services: bits 0,1 of  */
  365         /*  dips is the port # (0-3); combaselist[val] is the com_iobase */
  366         if (sc->sc_iobase != combaselist[dips & 0x03])
  367                 return (0);
  368 
  369         printf(": ESP");
  370 
  371         /* Check ESP Self Test bits. */
  372         /* Check for ESP version 2.0: bits 4,5,6 == 010 */
  373         bus_space_write_1(iot, hayespioh, HAYESP_CMD1, HAYESP_GETTEST);
  374         val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS1); /* Clear reg1 */
  375         val = bus_space_read_1(iot, hayespioh, HAYESP_STATUS2);
  376         if ((val & 0x70) < 0x20) {
  377                 printf("-old (%o)", val & 0x70);
  378                 /* we do not support the necessary features */
  379                 return (0);
  380         }
  381 
  382         /* Check for ability to emulate 16550: bit 8 == 1 */
  383         if ((dips & 0x80) == 0) {
  384                 printf(" slave");
  385                 /* XXX Does slave really mean no 16550 support?? */
  386                 return (0);
  387         }
  388 
  389         /*
  390          * If we made it this far, we are a full-featured ESP v2.0 (or
  391          * better), at the correct com port address.
  392          */
  393 
  394         sc->sc_type = COM_TYPE_HAYESP;
  395         printf(", 1024 byte fifo\n");
  396         return (1);
  397 }
  398 #endif
  399 
  400 static void
  401 com_enable_debugport(struct com_softc *sc)
  402 {
  403         int s;
  404 
  405         /* Turn on line break interrupt, set carrier. */
  406         s = splserial();
  407         COM_LOCK(sc);
  408         sc->sc_ier = IER_ERXRDY;
  409 #ifdef COM_PXA2X0
  410         if (sc->sc_type == COM_TYPE_PXA2x0)
  411                 sc->sc_ier |= IER_EUART | IER_ERXTOUT;
  412 #endif
  413         bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
  414         SET(sc->sc_mcr, MCR_DTR | MCR_RTS);
  415         bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_mcr, sc->sc_mcr);
  416         COM_UNLOCK(sc);
  417         splx(s);
  418 }
  419 
  420 void
  421 com_attach_subr(struct com_softc *sc)
  422 {
  423         bus_addr_t iobase = sc->sc_iobase;
  424         bus_space_tag_t iot = sc->sc_iot;
  425         bus_space_handle_t ioh = sc->sc_ioh;
  426         struct tty *tp;
  427 #ifdef COM_16650
  428         u_int8_t lcr;
  429 #endif
  430 #ifdef COM_HAYESP
  431         int     hayesp_ports[] = { 0x140, 0x180, 0x280, 0x300, 0 };
  432         int     *hayespp;
  433 #endif
  434         const char *fifo_msg = NULL;
  435 
  436         callout_init(&sc->sc_diag_callout);
  437 #if (defined(MULTIPROCESSOR) || defined(LOCKDEBUG)) && defined(COM_MPLOCK)
  438         simple_lock_init(&sc->sc_lock);
  439 #endif
  440 
  441         /* Disable interrupts before configuring the device. */
  442 #ifdef COM_PXA2X0
  443         if (sc->sc_type == COM_TYPE_PXA2x0)
  444                 sc->sc_ier = IER_EUART;
  445         else
  446 #endif
  447                 sc->sc_ier = 0;
  448         bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
  449 
  450         if (iot == comconstag && iobase == comconsaddr) {
  451                 comconsattached = 1;
  452 
  453                 /* Make sure the console is always "hardwired". */
  454                 delay(10000);                   /* wait for output to finish */
  455                 SET(sc->sc_hwflags, COM_HW_CONSOLE);
  456                 SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
  457         }
  458 
  459 #ifdef COM_HAYESP
  460         sc->sc_prescaler = 0;                   /* set prescaler to x1. */
  461 
  462         /* Look for a Hayes ESP board. */
  463         for (hayespp = hayesp_ports; *hayespp != 0; hayespp++) {
  464                 bus_space_handle_t hayespioh;
  465 
  466 #define HAYESP_NPORTS   8                       /* XXX XXX XXX ??? ??? ??? */
  467                 if (bus_space_map(iot, *hayespp, HAYESP_NPORTS, 0, &hayespioh))
  468                         continue;
  469                 if (comprobeHAYESP(hayespioh, sc)) {
  470                         sc->sc_hayespioh = hayespioh;
  471                         sc->sc_fifolen = 1024;
  472 
  473                         break;
  474                 }
  475                 bus_space_unmap(iot, hayespioh, HAYESP_NPORTS);
  476         }
  477         /* No ESP; look for other things. */
  478         if (sc->sc_type != COM_TYPE_HAYESP) {
  479 #endif
  480         sc->sc_fifolen = 1;
  481         /* look for a NS 16550AF UART with FIFOs */
  482         bus_space_write_1(iot, ioh, com_fifo,
  483             FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_14);
  484         delay(100);
  485         if (ISSET(bus_space_read_1(iot, ioh, com_iir), IIR_FIFO_MASK)
  486             == IIR_FIFO_MASK)
  487                 if (ISSET(bus_space_read_1(iot, ioh, com_fifo), FIFO_TRIGGER_14)
  488                     == FIFO_TRIGGER_14) {
  489                         SET(sc->sc_hwflags, COM_HW_FIFO);
  490 
  491 #ifdef COM_16650
  492                         /*
  493                          * IIR changes into the EFR if LCR is set to LCR_EERS
  494                          * on 16650s. We also know IIR != 0 at this point.
  495                          * Write 0 into the EFR, and read it. If the result
  496                          * is 0, we have a 16650.
  497                          *
  498                          * Older 16650s were broken; the test to detect them
  499                          * is taken from the Linux driver. Apparently
  500                          * setting DLAB enable gives access to the EFR on
  501                          * these chips.
  502                          */
  503                         lcr = bus_space_read_1(iot, ioh, com_lcr);
  504                         bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
  505                         bus_space_write_1(iot, ioh, com_efr, 0);
  506                         if (bus_space_read_1(iot, ioh, com_efr) == 0) {
  507                                 bus_space_write_1(iot, ioh, com_lcr,
  508                                     lcr | LCR_DLAB);
  509                                 if (bus_space_read_1(iot, ioh, com_efr) == 0) {
  510                                         CLR(sc->sc_hwflags, COM_HW_FIFO);
  511                                         sc->sc_fifolen = 0;
  512                                 } else {
  513                                         SET(sc->sc_hwflags, COM_HW_FLOW);
  514                                         sc->sc_fifolen = 32;
  515                                 }
  516                         } else
  517 #endif
  518                                 sc->sc_fifolen = 16;
  519 
  520 #ifdef COM_16650
  521                         bus_space_write_1(iot, ioh, com_lcr, lcr);
  522                         if (sc->sc_fifolen == 0)
  523                                 fifo_msg = "st16650, broken fifo";
  524                         else if (sc->sc_fifolen == 32)
  525                                 fifo_msg = "st16650a, working fifo";
  526                         else
  527 #endif
  528                                 fifo_msg = "ns16550a, working fifo";
  529                 } else
  530                         fifo_msg = "ns16550, broken fifo";
  531         else
  532                 fifo_msg = "ns8250 or ns16450, no fifo";
  533         bus_space_write_1(iot, ioh, com_fifo, 0);
  534         /*
  535          * Some chips will clear down both Tx and Rx FIFOs when zero is
  536          * written to com_fifo. If this chip is the console, writing zero
  537          * results in some of the chip/FIFO description being lost, so delay
  538          * printing it until now.
  539          */
  540         delay(10);
  541         aprint_normal(": %s\n", fifo_msg);
  542         if (ISSET(sc->sc_hwflags, COM_HW_TXFIFO_DISABLE)) {
  543                 sc->sc_fifolen = 1;
  544                 aprint_normal("%s: txfifo disabled\n", sc->sc_dev.dv_xname);
  545         }
  546 #ifdef COM_HAYESP
  547         }
  548 #endif
  549 
  550         tp = ttymalloc();
  551         tp->t_oproc = comstart;
  552         tp->t_param = comparam;
  553         tp->t_hwiflow = comhwiflow;
  554 
  555         sc->sc_tty = tp;
  556         sc->sc_rbuf = malloc(com_rbuf_size << 1, M_DEVBUF, M_NOWAIT);
  557         sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
  558         sc->sc_rbavail = com_rbuf_size;
  559         if (sc->sc_rbuf == NULL) {
  560                 aprint_error("%s: unable to allocate ring buffer\n",
  561                     sc->sc_dev.dv_xname);
  562                 return;
  563         }
  564         sc->sc_ebuf = sc->sc_rbuf + (com_rbuf_size << 1);
  565 
  566         tty_attach(tp);
  567 
  568         if (!ISSET(sc->sc_hwflags, COM_HW_NOIEN))
  569                 SET(sc->sc_mcr, MCR_IENABLE);
  570 
  571         if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
  572                 int maj;
  573 
  574                 /* locate the major number */
  575                 maj = cdevsw_lookup_major(&com_cdevsw);
  576 
  577                 tp->t_dev = cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
  578 
  579                 aprint_normal("%s: console\n", sc->sc_dev.dv_xname);
  580         }
  581 
  582 #ifdef KGDB
  583         /*
  584          * Allow kgdb to "take over" this port.  If this is
  585          * not the console and is the kgdb device, it has
  586          * exclusive use.  If it's the console _and_ the
  587          * kgdb device, it doesn't.
  588          */
  589         if (iot == com_kgdb_iot && iobase == com_kgdb_addr) {
  590                 if (!ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
  591                         com_kgdb_attached = 1;
  592 
  593                         SET(sc->sc_hwflags, COM_HW_KGDB);
  594                 }
  595                 aprint_normal("%s: kgdb\n", sc->sc_dev.dv_xname);
  596         }
  597 #endif
  598 
  599 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  600         sc->sc_si = softintr_establish(IPL_SOFTSERIAL, comsoft, sc);
  601 #endif
  602 
  603 #if NRND > 0 && defined(RND_COM)
  604         rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
  605                           RND_TYPE_TTY, 0);
  606 #endif
  607 
  608         /* if there are no enable/disable functions, assume the device
  609            is always enabled */
  610         if (!sc->enable)
  611                 sc->enabled = 1;
  612 
  613         com_config(sc);
  614 
  615         SET(sc->sc_hwflags, COM_HW_DEV_OK);
  616 }
  617 
  618 void
  619 com_config(struct com_softc *sc)
  620 {
  621         bus_space_tag_t iot = sc->sc_iot;
  622         bus_space_handle_t ioh = sc->sc_ioh;
  623 
  624         /* Disable interrupts before configuring the device. */
  625 #ifdef COM_PXA2X0
  626         if (sc->sc_type == COM_TYPE_PXA2x0)
  627                 sc->sc_ier = IER_EUART;
  628         else
  629 #endif
  630                 sc->sc_ier = 0;
  631         bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
  632         (void) bus_space_read_1(iot, ioh, com_iir);
  633 
  634 #ifdef COM_HAYESP
  635         /* Look for a Hayes ESP board. */
  636         if (sc->sc_type == COM_TYPE_HAYESP) {
  637                 sc->sc_fifolen = 1024;
  638 
  639                 /* Set 16550 compatibility mode */
  640                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
  641                                   HAYESP_SETMODE);
  642                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  643                                   HAYESP_MODE_FIFO|HAYESP_MODE_RTS|
  644                                   HAYESP_MODE_SCALE);
  645 
  646                 /* Set RTS/CTS flow control */
  647                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
  648                                   HAYESP_SETFLOWTYPE);
  649                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  650                                   HAYESP_FLOW_RTS);
  651                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  652                                   HAYESP_FLOW_CTS);
  653 
  654                 /* Set flow control levels */
  655                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
  656                                   HAYESP_SETRXFLOW);
  657                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  658                                   HAYESP_HIBYTE(HAYESP_RXHIWMARK));
  659                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  660                                   HAYESP_LOBYTE(HAYESP_RXHIWMARK));
  661                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  662                                   HAYESP_HIBYTE(HAYESP_RXLOWMARK));
  663                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
  664                                   HAYESP_LOBYTE(HAYESP_RXLOWMARK));
  665         }
  666 #endif
  667 
  668         if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE|COM_HW_KGDB))
  669                 com_enable_debugport(sc);
  670 }
  671 
  672 int
  673 com_detach(struct device *self, int flags)
  674 {
  675         struct com_softc *sc = (struct com_softc *)self;
  676         int maj, mn;
  677 
  678         /* locate the major number */
  679         maj = cdevsw_lookup_major(&com_cdevsw);
  680 
  681         /* Nuke the vnodes for any open instances. */
  682         mn = self->dv_unit;
  683         vdevgone(maj, mn, mn, VCHR);
  684 
  685         mn |= COMDIALOUT_MASK;
  686         vdevgone(maj, mn, mn, VCHR);
  687 
  688         if (sc->sc_rbuf == NULL) {
  689                 /*
  690                  * Ring buffer allocation failed in the com_attach_subr,
  691                  * only the tty is allocated, and nothing else.
  692                  */
  693                 ttyfree(sc->sc_tty);
  694                 return 0;
  695         }
  696 
  697         /* Free the receive buffer. */
  698         free(sc->sc_rbuf, M_DEVBUF);
  699 
  700         /* Detach and free the tty. */
  701         tty_detach(sc->sc_tty);
  702         ttyfree(sc->sc_tty);
  703 
  704 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
  705         /* Unhook the soft interrupt handler. */
  706         softintr_disestablish(sc->sc_si);
  707 #endif
  708 
  709 #if NRND > 0 && defined(RND_COM)
  710         /* Unhook the entropy source. */
  711         rnd_detach_source(&sc->rnd_source);
  712 #endif
  713 
  714         return (0);
  715 }
  716 
  717 int
  718 com_activate(struct device *self, enum devact act)
  719 {
  720         struct com_softc *sc = (struct com_softc *)self;
  721         int s, rv = 0;
  722 
  723         s = splserial();
  724         COM_LOCK(sc);
  725         switch (act) {
  726         case DVACT_ACTIVATE:
  727                 rv = EOPNOTSUPP;
  728                 break;
  729 
  730         case DVACT_DEACTIVATE:
  731                 if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB)) {
  732                         rv = EBUSY;
  733                         break;
  734                 }
  735 
  736                 if (sc->disable != NULL && sc->enabled != 0) {
  737                         (*sc->disable)(sc);
  738                         sc->enabled = 0;
  739                 }
  740                 break;
  741         }
  742 
  743         COM_UNLOCK(sc);
  744         splx(s);
  745         return (rv);
  746 }
  747 
  748 void
  749 com_shutdown(struct com_softc *sc)
  750 {
  751         struct tty *tp = sc->sc_tty;
  752         int s;
  753 
  754         s = splserial();
  755         COM_LOCK(sc);
  756 
  757         /* If we were asserting flow control, then deassert it. */
  758         SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
  759         com_hwiflow(sc);
  760 
  761         /* Clear any break condition set with TIOCSBRK. */
  762         com_break(sc, 0);
  763 
  764         /* Turn off PPS capture on last close. */
  765         sc->sc_ppsmask = 0;
  766         sc->ppsparam.mode = 0;
  767 
  768         /*
  769          * Hang up if necessary.  Wait a bit, so the other side has time to
  770          * notice even if we immediately open the port again.
  771          * Avoid tsleeping above splhigh().
  772          */
  773         if (ISSET(tp->t_cflag, HUPCL)) {
  774                 com_modem(sc, 0);
  775                 COM_UNLOCK(sc);
  776                 splx(s);
  777                 /* XXX tsleep will only timeout */
  778                 (void) tsleep(sc, TTIPRI, ttclos, hz);
  779                 s = splserial();
  780                 COM_LOCK(sc);
  781         }
  782 
  783         /* Turn off interrupts. */
  784         if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
  785                 sc->sc_ier = IER_ERXRDY; /* interrupt on break */
  786 #ifdef COM_PXA2X0
  787                 if (sc->sc_type == COM_TYPE_PXA2x0)
  788                         sc->sc_ier |= IER_ERXTOUT;
  789 #endif
  790         } else
  791                 sc->sc_ier = 0;
  792 
  793 #ifdef COM_PXA2X0
  794         if (sc->sc_type == COM_TYPE_PXA2x0)
  795                 sc->sc_ier |= IER_EUART;
  796 #endif
  797 
  798         bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
  799 
  800         if (sc->disable) {
  801 #ifdef DIAGNOSTIC
  802                 if (!sc->enabled)
  803                         panic("com_shutdown: not enabled?");
  804 #endif
  805                 (*sc->disable)(sc);
  806                 sc->enabled = 0;
  807         }
  808         COM_UNLOCK(sc);
  809         splx(s);
  810 }
  811 
  812 int
  813 comopen(dev_t dev, int flag, int mode, struct proc *p)
  814 {
  815         struct com_softc *sc;
  816         struct tty *tp;
  817         int s, s2;
  818         int error;
  819 
  820         sc = device_lookup(&com_cd, COMUNIT(dev));
  821         if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK) ||
  822                 sc->sc_rbuf == NULL)
  823                 return (ENXIO);
  824 
  825         if (ISSET(sc->sc_dev.dv_flags, DVF_ACTIVE) == 0)
  826                 return (ENXIO);
  827 
  828 #ifdef KGDB
  829         /*
  830          * If this is the kgdb port, no other use is permitted.
  831          */
  832         if (ISSET(sc->sc_hwflags, COM_HW_KGDB))
  833                 return (EBUSY);
  834 #endif
  835 
  836         tp = sc->sc_tty;
  837 
  838         if (ISSET(tp->t_state, TS_ISOPEN) &&
  839             ISSET(tp->t_state, TS_XCLUDE) &&
  840                 p->p_ucred->cr_uid != 0)
  841                 return (EBUSY);
  842 
  843         s = spltty();
  844 
  845         /*
  846          * Do the following iff this is a first open.
  847          */
  848         if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
  849                 struct termios t;
  850 
  851                 tp->t_dev = dev;
  852 
  853                 s2 = splserial();
  854                 COM_LOCK(sc);
  855 
  856                 if (sc->enable) {
  857                         if ((*sc->enable)(sc)) {
  858                                 COM_UNLOCK(sc);
  859                                 splx(s2);
  860                                 splx(s);
  861                                 printf("%s: device enable failed\n",
  862                                        sc->sc_dev.dv_xname);
  863                                 return (EIO);
  864                         }
  865                         sc->enabled = 1;
  866                         com_config(sc);
  867                 }
  868 
  869                 /* Turn on interrupts. */
  870                 sc->sc_ier = IER_ERXRDY | IER_ERLS | IER_EMSC;
  871 #ifdef COM_PXA2X0
  872                 if (sc->sc_type == COM_TYPE_PXA2x0)
  873                         sc->sc_ier |= IER_EUART | IER_ERXTOUT;
  874 #endif
  875                 bus_space_write_1(sc->sc_iot, sc->sc_ioh, com_ier, sc->sc_ier);
  876 
  877                 /* Fetch the current modem control status, needed later. */
  878                 sc->sc_msr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, com_msr);
  879 
  880                 /* Clear PPS capture state on first open. */
  881                 sc->sc_ppsmask = 0;
  882                 sc->ppsparam.mode = 0;
  883 
  884                 COM_UNLOCK(sc);
  885                 splx(s2);
  886 
  887                 /*
  888                  * Initialize the termios status to the defaults.  Add in the
  889                  * sticky bits from TIOCSFLAGS.
  890                  */
  891                 t.c_ispeed = 0;
  892                 if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
  893                         t.c_ospeed = comconsrate;
  894                         t.c_cflag = comconscflag;
  895                 } else {
  896                         t.c_ospeed = TTYDEF_SPEED;
  897                         t.c_cflag = TTYDEF_CFLAG;
  898                 }
  899                 if (ISSET(sc->sc_swflags, TIOCFLAG_CLOCAL))
  900                         SET(t.c_cflag, CLOCAL);
  901                 if (ISSET(sc->sc_swflags, TIOCFLAG_CRTSCTS))
  902                         SET(t.c_cflag, CRTSCTS);
  903                 if (ISSET(sc->sc_swflags, TIOCFLAG_MDMBUF))
  904                         SET(t.c_cflag, MDMBUF);
  905                 /* Make sure comparam() will do something. */
  906                 tp->t_ospeed = 0;
  907                 (void) comparam(tp, &t);
  908                 tp->t_iflag = TTYDEF_IFLAG;
  909                 tp->t_oflag = TTYDEF_OFLAG;
  910                 tp->t_lflag = TTYDEF_LFLAG;
  911                 ttychars(tp);
  912                 ttsetwater(tp);
  913 
  914                 s2 = splserial();
  915                 COM_LOCK(sc);
  916 
  917                 /*
  918                  * Turn on DTR.  We must always do this, even if carrier is not
  919                  * present, because otherwise we'd have to use TIOCSDTR
  920                  * immediately after setting CLOCAL, which applications do not
  921                  * expect.  We always assert DTR while the device is open
  922                  * unless explicitly requested to deassert it.
  923                  */
  924                 com_modem(sc, 1);
  925 
  926                 /* Clear the input ring, and unblock. */
  927                 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
  928                 sc->sc_rbavail = com_rbuf_size;
  929                 com_iflush(sc);
  930                 CLR(sc->sc_rx_flags, RX_ANY_BLOCK);
  931                 com_hwiflow(sc);
  932 
  933 #ifdef COM_DEBUG
  934                 if (com_debug)
  935                         comstatus(sc, "comopen  ");
  936 #endif
  937 
  938                 COM_UNLOCK(sc);
  939                 splx(s2);
  940         }
  941 
  942         splx(s);
  943 
  944         error = ttyopen(tp, COMDIALOUT(dev), ISSET(flag, O_NONBLOCK));
  945         if (error)
  946                 goto bad;
  947 
  948         error = (*tp->t_linesw->l_open)(dev, tp);
  949         if (error)
  950                 goto bad;
  951 
  952         return (0);
  953 
  954 bad:
  955         if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
  956                 /*
  957                  * We failed to open the device, and nobody else had it opened.
  958                  * Clean up the state as appropriate.
  959                  */
  960                 com_shutdown(sc);
  961         }
  962 
  963         return (error);
  964 }
  965 
  966 int
  967 comclose(dev_t dev, int flag, int mode, struct proc *p)
  968 {
  969         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
  970         struct tty *tp = sc->sc_tty;
  971 
  972         /* XXX This is for cons.c. */
  973         if (!ISSET(tp->t_state, TS_ISOPEN))
  974                 return (0);
  975 
  976         (*tp->t_linesw->l_close)(tp, flag);
  977         ttyclose(tp);
  978 
  979         if (COM_ISALIVE(sc) == 0)
  980                 return (0);
  981 
  982         if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) {
  983                 /*
  984                  * Although we got a last close, the device may still be in
  985                  * use; e.g. if this was the dialout node, and there are still
  986                  * processes waiting for carrier on the non-dialout node.
  987                  */
  988                 com_shutdown(sc);
  989         }
  990 
  991         return (0);
  992 }
  993 
  994 int
  995 comread(dev_t dev, struct uio *uio, int flag)
  996 {
  997         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
  998         struct tty *tp = sc->sc_tty;
  999 
 1000         if (COM_ISALIVE(sc) == 0)
 1001                 return (EIO);
 1002 
 1003         return ((*tp->t_linesw->l_read)(tp, uio, flag));
 1004 }
 1005 
 1006 int
 1007 comwrite(dev_t dev, struct uio *uio, int flag)
 1008 {
 1009         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
 1010         struct tty *tp = sc->sc_tty;
 1011 
 1012         if (COM_ISALIVE(sc) == 0)
 1013                 return (EIO);
 1014 
 1015         return ((*tp->t_linesw->l_write)(tp, uio, flag));
 1016 }
 1017 
 1018 int
 1019 compoll(dev_t dev, int events, struct proc *p)
 1020 {
 1021         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
 1022         struct tty *tp = sc->sc_tty;
 1023 
 1024         if (COM_ISALIVE(sc) == 0)
 1025                 return (EIO);
 1026 
 1027         return ((*tp->t_linesw->l_poll)(tp, events, p));
 1028 }
 1029 
 1030 struct tty *
 1031 comtty(dev_t dev)
 1032 {
 1033         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
 1034         struct tty *tp = sc->sc_tty;
 1035 
 1036         return (tp);
 1037 }
 1038 
 1039 int
 1040 comioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
 1041 {
 1042         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(dev));
 1043         struct tty *tp = sc->sc_tty;
 1044         int error;
 1045         int s;
 1046 
 1047         if (COM_ISALIVE(sc) == 0)
 1048                 return (EIO);
 1049 
 1050         error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, p);
 1051         if (error != EPASSTHROUGH)
 1052                 return (error);
 1053 
 1054         error = ttioctl(tp, cmd, data, flag, p);
 1055         if (error != EPASSTHROUGH)
 1056                 return (error);
 1057 
 1058         error = 0;
 1059 
 1060         s = splserial();
 1061         COM_LOCK(sc);
 1062 
 1063         switch (cmd) {
 1064         case TIOCSBRK:
 1065                 com_break(sc, 1);
 1066                 break;
 1067 
 1068         case TIOCCBRK:
 1069                 com_break(sc, 0);
 1070                 break;
 1071 
 1072         case TIOCSDTR:
 1073                 com_modem(sc, 1);
 1074                 break;
 1075 
 1076         case TIOCCDTR:
 1077                 com_modem(sc, 0);
 1078                 break;
 1079 
 1080         case TIOCGFLAGS:
 1081                 *(int *)data = sc->sc_swflags;
 1082                 break;
 1083 
 1084         case TIOCSFLAGS:
 1085                 error = suser(p->p_ucred, &p->p_acflag);
 1086                 if (error)
 1087                         break;
 1088                 sc->sc_swflags = *(int *)data;
 1089                 break;
 1090 
 1091         case TIOCMSET:
 1092         case TIOCMBIS:
 1093         case TIOCMBIC:
 1094                 tiocm_to_com(sc, cmd, *(int *)data);
 1095                 break;
 1096 
 1097         case TIOCMGET:
 1098                 *(int *)data = com_to_tiocm(sc);
 1099                 break;
 1100 
 1101         case PPS_IOC_CREATE:
 1102                 break;
 1103 
 1104         case PPS_IOC_DESTROY:
 1105                 break;
 1106 
 1107         case PPS_IOC_GETPARAMS: {
 1108                 pps_params_t *pp;
 1109                 pp = (pps_params_t *)data;
 1110                 *pp = sc->ppsparam;
 1111                 break;
 1112         }
 1113 
 1114         case PPS_IOC_SETPARAMS: {
 1115                 pps_params_t *pp;
 1116                 int mode;
 1117                 pp = (pps_params_t *)data;
 1118                 if (pp->mode & ~ppscap) {
 1119                         error = EINVAL;
 1120                         break;
 1121                 }
 1122                 sc->ppsparam = *pp;
 1123                 /*
 1124                  * Compute msr masks from user-specified timestamp state.
 1125                  */
 1126                 mode = sc->ppsparam.mode;
 1127                 switch (mode & PPS_CAPTUREBOTH) {
 1128                 case 0:
 1129                         sc->sc_ppsmask = 0;
 1130                         break;
 1131 
 1132                 case PPS_CAPTUREASSERT:
 1133                         sc->sc_ppsmask = MSR_DCD;
 1134                         sc->sc_ppsassert = MSR_DCD;
 1135                         sc->sc_ppsclear = -1;
 1136                         break;
 1137 
 1138                 case PPS_CAPTURECLEAR:
 1139                         sc->sc_ppsmask = MSR_DCD;
 1140                         sc->sc_ppsassert = -1;
 1141                         sc->sc_ppsclear = 0;
 1142                         break;
 1143 
 1144                 case PPS_CAPTUREBOTH:
 1145                         sc->sc_ppsmask = MSR_DCD;
 1146                         sc->sc_ppsassert = MSR_DCD;
 1147                         sc->sc_ppsclear = 0;
 1148                         break;
 1149 
 1150                 default:
 1151                         error = EINVAL;
 1152                         break;
 1153                 }
 1154                 break;
 1155         }
 1156 
 1157         case PPS_IOC_GETCAP:
 1158                 *(int*)data = ppscap;
 1159                 break;
 1160 
 1161         case PPS_IOC_FETCH: {
 1162                 pps_info_t *pi;
 1163                 pi = (pps_info_t *)data;
 1164                 *pi = sc->ppsinfo;
 1165                 break;
 1166         }
 1167 
 1168 #ifdef PPS_SYNC
 1169         case PPS_IOC_KCBIND: {
 1170                 int edge = (*(int *)data) & PPS_CAPTUREBOTH;
 1171 
 1172                 if (edge == 0) {
 1173                         /*
 1174                          * remove binding for this source; ignore
 1175                          * the request if this is not the current
 1176                          * hardpps source
 1177                          */
 1178                         if (pps_kc_hardpps_source == sc) {
 1179                                 pps_kc_hardpps_source = NULL;
 1180                                 pps_kc_hardpps_mode = 0;
 1181                         }
 1182                 } else {
 1183                         /*
 1184                          * bind hardpps to this source, replacing any
 1185                          * previously specified source or edges
 1186                          */
 1187                         pps_kc_hardpps_source = sc;
 1188                         pps_kc_hardpps_mode = edge;
 1189                 }
 1190                 break;
 1191         }
 1192 #endif /* PPS_SYNC */
 1193 
 1194         case TIOCDCDTIMESTAMP:  /* XXX old, overloaded  API used by xntpd v3 */
 1195                 /*
 1196                  * Some GPS clocks models use the falling rather than
 1197                  * rising edge as the on-the-second signal.
 1198                  * The old API has no way to specify PPS polarity.
 1199                  */
 1200                 sc->sc_ppsmask = MSR_DCD;
 1201 #ifndef PPS_TRAILING_EDGE
 1202                 sc->sc_ppsassert = MSR_DCD;
 1203                 sc->sc_ppsclear = -1;
 1204                 TIMESPEC_TO_TIMEVAL((struct timeval *)data,
 1205                     &sc->ppsinfo.assert_timestamp);
 1206 #else
 1207                 sc->sc_ppsassert = -1;
 1208                 sc->sc_ppsclear = 0;
 1209                 TIMESPEC_TO_TIMEVAL((struct timeval *)data,
 1210                     &sc->ppsinfo.clear_timestamp);
 1211 #endif
 1212                 break;
 1213 
 1214         default:
 1215                 error = EPASSTHROUGH;
 1216                 break;
 1217         }
 1218 
 1219         COM_UNLOCK(sc);
 1220         splx(s);
 1221 
 1222 #ifdef COM_DEBUG
 1223         if (com_debug)
 1224                 comstatus(sc, "comioctl ");
 1225 #endif
 1226 
 1227         return (error);
 1228 }
 1229 
 1230 integrate void
 1231 com_schedrx(struct com_softc *sc)
 1232 {
 1233 
 1234         sc->sc_rx_ready = 1;
 1235 
 1236         /* Wake up the poller. */
 1237 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
 1238         softintr_schedule(sc->sc_si);
 1239 #else
 1240 #ifndef __NO_SOFT_SERIAL_INTERRUPT
 1241         setsoftserial();
 1242 #else
 1243         if (!com_softintr_scheduled) {
 1244                 com_softintr_scheduled = 1;
 1245                 callout_reset(&comsoft_callout, 1, comsoft, NULL);
 1246         }
 1247 #endif
 1248 #endif
 1249 }
 1250 
 1251 void
 1252 com_break(struct com_softc *sc, int onoff)
 1253 {
 1254 
 1255         if (onoff)
 1256                 SET(sc->sc_lcr, LCR_SBREAK);
 1257         else
 1258                 CLR(sc->sc_lcr, LCR_SBREAK);
 1259 
 1260         if (!sc->sc_heldchange) {
 1261                 if (sc->sc_tx_busy) {
 1262                         sc->sc_heldtbc = sc->sc_tbc;
 1263                         sc->sc_tbc = 0;
 1264                         sc->sc_heldchange = 1;
 1265                 } else
 1266                         com_loadchannelregs(sc);
 1267         }
 1268 }
 1269 
 1270 void
 1271 com_modem(struct com_softc *sc, int onoff)
 1272 {
 1273 
 1274         if (sc->sc_mcr_dtr == 0)
 1275                 return;
 1276 
 1277         if (onoff)
 1278                 SET(sc->sc_mcr, sc->sc_mcr_dtr);
 1279         else
 1280                 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
 1281 
 1282         if (!sc->sc_heldchange) {
 1283                 if (sc->sc_tx_busy) {
 1284                         sc->sc_heldtbc = sc->sc_tbc;
 1285                         sc->sc_tbc = 0;
 1286                         sc->sc_heldchange = 1;
 1287                 } else
 1288                         com_loadchannelregs(sc);
 1289         }
 1290 }
 1291 
 1292 void
 1293 tiocm_to_com(struct com_softc *sc, u_long how, int ttybits)
 1294 {
 1295         u_char combits;
 1296 
 1297         combits = 0;
 1298         if (ISSET(ttybits, TIOCM_DTR))
 1299                 SET(combits, MCR_DTR);
 1300         if (ISSET(ttybits, TIOCM_RTS))
 1301                 SET(combits, MCR_RTS);
 1302 
 1303         switch (how) {
 1304         case TIOCMBIC:
 1305                 CLR(sc->sc_mcr, combits);
 1306                 break;
 1307 
 1308         case TIOCMBIS:
 1309                 SET(sc->sc_mcr, combits);
 1310                 break;
 1311 
 1312         case TIOCMSET:
 1313                 CLR(sc->sc_mcr, MCR_DTR | MCR_RTS);
 1314                 SET(sc->sc_mcr, combits);
 1315                 break;
 1316         }
 1317 
 1318         if (!sc->sc_heldchange) {
 1319                 if (sc->sc_tx_busy) {
 1320                         sc->sc_heldtbc = sc->sc_tbc;
 1321                         sc->sc_tbc = 0;
 1322                         sc->sc_heldchange = 1;
 1323                 } else
 1324                         com_loadchannelregs(sc);
 1325         }
 1326 }
 1327 
 1328 int
 1329 com_to_tiocm(struct com_softc *sc)
 1330 {
 1331         u_char combits;
 1332         int ttybits = 0;
 1333 
 1334         combits = sc->sc_mcr;
 1335         if (ISSET(combits, MCR_DTR))
 1336                 SET(ttybits, TIOCM_DTR);
 1337         if (ISSET(combits, MCR_RTS))
 1338                 SET(ttybits, TIOCM_RTS);
 1339 
 1340         combits = sc->sc_msr;
 1341         if (ISSET(combits, MSR_DCD))
 1342                 SET(ttybits, TIOCM_CD);
 1343         if (ISSET(combits, MSR_CTS))
 1344                 SET(ttybits, TIOCM_CTS);
 1345         if (ISSET(combits, MSR_DSR))
 1346                 SET(ttybits, TIOCM_DSR);
 1347         if (ISSET(combits, MSR_RI | MSR_TERI))
 1348                 SET(ttybits, TIOCM_RI);
 1349 
 1350         if (ISSET(sc->sc_ier, IER_ERXRDY | IER_ETXRDY | IER_ERLS | IER_EMSC))
 1351                 SET(ttybits, TIOCM_LE);
 1352 
 1353         return (ttybits);
 1354 }
 1355 
 1356 static u_char
 1357 cflag2lcr(tcflag_t cflag)
 1358 {
 1359         u_char lcr = 0;
 1360 
 1361         switch (ISSET(cflag, CSIZE)) {
 1362         case CS5:
 1363                 SET(lcr, LCR_5BITS);
 1364                 break;
 1365         case CS6:
 1366                 SET(lcr, LCR_6BITS);
 1367                 break;
 1368         case CS7:
 1369                 SET(lcr, LCR_7BITS);
 1370                 break;
 1371         case CS8:
 1372                 SET(lcr, LCR_8BITS);
 1373                 break;
 1374         }
 1375         if (ISSET(cflag, PARENB)) {
 1376                 SET(lcr, LCR_PENAB);
 1377                 if (!ISSET(cflag, PARODD))
 1378                         SET(lcr, LCR_PEVEN);
 1379         }
 1380         if (ISSET(cflag, CSTOPB))
 1381                 SET(lcr, LCR_STOPB);
 1382 
 1383         return (lcr);
 1384 }
 1385 
 1386 int
 1387 comparam(struct tty *tp, struct termios *t)
 1388 {
 1389         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
 1390         int ospeed;
 1391         u_char lcr;
 1392         int s;
 1393 
 1394         if (COM_ISALIVE(sc) == 0)
 1395                 return (EIO);
 1396 
 1397 #ifdef COM_HAYESP
 1398         if (sc->sc_type == COM_TYPE_HAYESP) {
 1399                 int prescaler, speed;
 1400 
 1401                 /*
 1402                  * Calculate UART clock prescaler.  It should be in
 1403                  * range of 0 .. 3.
 1404                  */
 1405                 for (prescaler = 0, speed = t->c_ospeed; prescaler < 4;
 1406                     prescaler++, speed /= 2)
 1407                         if ((ospeed = comspeed(speed, sc->sc_frequency,
 1408                                                sc->sc_type)) > 0)
 1409                                 break;
 1410 
 1411                 if (prescaler == 4)
 1412                         return (EINVAL);
 1413                 sc->sc_prescaler = prescaler;
 1414         } else
 1415 #endif
 1416         ospeed = comspeed(t->c_ospeed, sc->sc_frequency, sc->sc_type);
 1417 
 1418         /* Check requested parameters. */
 1419         if (ospeed < 0)
 1420                 return (EINVAL);
 1421         if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
 1422                 return (EINVAL);
 1423 
 1424         /*
 1425          * For the console, always force CLOCAL and !HUPCL, so that the port
 1426          * is always active.
 1427          */
 1428         if (ISSET(sc->sc_swflags, TIOCFLAG_SOFTCAR) ||
 1429             ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
 1430                 SET(t->c_cflag, CLOCAL);
 1431                 CLR(t->c_cflag, HUPCL);
 1432         }
 1433 
 1434         /*
 1435          * If there were no changes, don't do anything.  This avoids dropping
 1436          * input and improves performance when all we did was frob things like
 1437          * VMIN and VTIME.
 1438          */
 1439         if (tp->t_ospeed == t->c_ospeed &&
 1440             tp->t_cflag == t->c_cflag)
 1441                 return (0);
 1442 
 1443         lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag);
 1444 
 1445         s = splserial();
 1446         COM_LOCK(sc);
 1447 
 1448         sc->sc_lcr = lcr;
 1449 
 1450         /*
 1451          * If we're not in a mode that assumes a connection is present, then
 1452          * ignore carrier changes.
 1453          */
 1454         if (ISSET(t->c_cflag, CLOCAL | MDMBUF))
 1455                 sc->sc_msr_dcd = 0;
 1456         else
 1457                 sc->sc_msr_dcd = MSR_DCD;
 1458         /*
 1459          * Set the flow control pins depending on the current flow control
 1460          * mode.
 1461          */
 1462         if (ISSET(t->c_cflag, CRTSCTS)) {
 1463                 sc->sc_mcr_dtr = MCR_DTR;
 1464                 sc->sc_mcr_rts = MCR_RTS;
 1465                 sc->sc_msr_cts = MSR_CTS;
 1466                 sc->sc_efr = EFR_AUTORTS | EFR_AUTOCTS;
 1467         } else if (ISSET(t->c_cflag, MDMBUF)) {
 1468                 /*
 1469                  * For DTR/DCD flow control, make sure we don't toggle DTR for
 1470                  * carrier detection.
 1471                  */
 1472                 sc->sc_mcr_dtr = 0;
 1473                 sc->sc_mcr_rts = MCR_DTR;
 1474                 sc->sc_msr_cts = MSR_DCD;
 1475                 sc->sc_efr = 0;
 1476         } else {
 1477                 /*
 1478                  * If no flow control, then always set RTS.  This will make
 1479                  * the other side happy if it mistakenly thinks we're doing
 1480                  * RTS/CTS flow control.
 1481                  */
 1482                 sc->sc_mcr_dtr = MCR_DTR | MCR_RTS;
 1483                 sc->sc_mcr_rts = 0;
 1484                 sc->sc_msr_cts = 0;
 1485                 sc->sc_efr = 0;
 1486                 if (ISSET(sc->sc_mcr, MCR_DTR))
 1487                         SET(sc->sc_mcr, MCR_RTS);
 1488                 else
 1489                         CLR(sc->sc_mcr, MCR_RTS);
 1490         }
 1491         sc->sc_msr_mask = sc->sc_msr_cts | sc->sc_msr_dcd;
 1492 
 1493 #if 0
 1494         if (ospeed == 0)
 1495                 CLR(sc->sc_mcr, sc->sc_mcr_dtr);
 1496         else
 1497                 SET(sc->sc_mcr, sc->sc_mcr_dtr);
 1498 #endif
 1499 
 1500         sc->sc_dlbl = ospeed;
 1501         sc->sc_dlbh = ospeed >> 8;
 1502 
 1503         /*
 1504          * Set the FIFO threshold based on the receive speed.
 1505          *
 1506          *  * If it's a low speed, it's probably a mouse or some other
 1507          *    interactive device, so set the threshold low.
 1508          *  * If it's a high speed, trim the trigger level down to prevent
 1509          *    overflows.
 1510          *  * Otherwise set it a bit higher.
 1511          */
 1512         if (sc->sc_type == COM_TYPE_HAYESP)
 1513                 sc->sc_fifo = FIFO_DMA_MODE | FIFO_ENABLE | FIFO_TRIGGER_8;
 1514         else if (ISSET(sc->sc_hwflags, COM_HW_FIFO))
 1515                 sc->sc_fifo = FIFO_ENABLE |
 1516                     (t->c_ospeed <= 1200 ? FIFO_TRIGGER_1 : FIFO_TRIGGER_8);
 1517         else
 1518                 sc->sc_fifo = 0;
 1519 
 1520         /* And copy to tty. */
 1521         tp->t_ispeed = 0;
 1522         tp->t_ospeed = t->c_ospeed;
 1523         tp->t_cflag = t->c_cflag;
 1524 
 1525         if (!sc->sc_heldchange) {
 1526                 if (sc->sc_tx_busy) {
 1527                         sc->sc_heldtbc = sc->sc_tbc;
 1528                         sc->sc_tbc = 0;
 1529                         sc->sc_heldchange = 1;
 1530                 } else
 1531                         com_loadchannelregs(sc);
 1532         }
 1533 
 1534         if (!ISSET(t->c_cflag, CHWFLOW)) {
 1535                 /* Disable the high water mark. */
 1536                 sc->sc_r_hiwat = 0;
 1537                 sc->sc_r_lowat = 0;
 1538                 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
 1539                         CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
 1540                         com_schedrx(sc);
 1541                 }
 1542                 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED)) {
 1543                         CLR(sc->sc_rx_flags, RX_TTY_BLOCKED|RX_IBUF_BLOCKED);
 1544                         com_hwiflow(sc);
 1545                 }
 1546         } else {
 1547                 sc->sc_r_hiwat = com_rbuf_hiwat;
 1548                 sc->sc_r_lowat = com_rbuf_lowat;
 1549         }
 1550 
 1551         COM_UNLOCK(sc);
 1552         splx(s);
 1553 
 1554         /*
 1555          * Update the tty layer's idea of the carrier bit, in case we changed
 1556          * CLOCAL or MDMBUF.  We don't hang up here; we only do that by
 1557          * explicit request.
 1558          */
 1559         (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, MSR_DCD));
 1560 
 1561 #ifdef COM_DEBUG
 1562         if (com_debug)
 1563                 comstatus(sc, "comparam ");
 1564 #endif
 1565 
 1566         if (!ISSET(t->c_cflag, CHWFLOW)) {
 1567                 if (sc->sc_tx_stopped) {
 1568                         sc->sc_tx_stopped = 0;
 1569                         comstart(tp);
 1570                 }
 1571         }
 1572 
 1573         return (0);
 1574 }
 1575 
 1576 void
 1577 com_iflush(struct com_softc *sc)
 1578 {
 1579         bus_space_tag_t iot = sc->sc_iot;
 1580         bus_space_handle_t ioh = sc->sc_ioh;
 1581 #ifdef DIAGNOSTIC
 1582         int reg;
 1583 #endif
 1584         int timo;
 1585 
 1586 #ifdef DIAGNOSTIC
 1587         reg = 0xffff;
 1588 #endif
 1589         timo = 50000;
 1590         /* flush any pending I/O */
 1591         while (ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)
 1592             && --timo)
 1593 #ifdef DIAGNOSTIC
 1594                 reg =
 1595 #else
 1596                     (void)
 1597 #endif
 1598                     bus_space_read_1(iot, ioh, com_data);
 1599 #ifdef DIAGNOSTIC
 1600         if (!timo)
 1601                 printf("%s: com_iflush timeout %02x\n", sc->sc_dev.dv_xname,
 1602                        reg);
 1603 #endif
 1604 }
 1605 
 1606 void
 1607 com_loadchannelregs(struct com_softc *sc)
 1608 {
 1609         bus_space_tag_t iot = sc->sc_iot;
 1610         bus_space_handle_t ioh = sc->sc_ioh;
 1611 
 1612         /* XXXXX necessary? */
 1613         com_iflush(sc);
 1614 
 1615 #ifdef COM_PXA2X0
 1616         if (sc->sc_type == COM_TYPE_PXA2x0)
 1617                 bus_space_write_1(iot, ioh, com_ier, IER_EUART);
 1618         else
 1619 #endif
 1620                 bus_space_write_1(iot, ioh, com_ier, 0);
 1621 
 1622         if (ISSET(sc->sc_hwflags, COM_HW_FLOW)) {
 1623                 bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
 1624                 bus_space_write_1(iot, ioh, com_efr, sc->sc_efr);
 1625         }
 1626         bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr | LCR_DLAB);
 1627         bus_space_write_1(iot, ioh, com_dlbl, sc->sc_dlbl);
 1628         bus_space_write_1(iot, ioh, com_dlbh, sc->sc_dlbh);
 1629         bus_space_write_1(iot, ioh, com_lcr, sc->sc_lcr);
 1630         bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active = sc->sc_mcr);
 1631         bus_space_write_1(iot, ioh, com_fifo, sc->sc_fifo);
 1632 #ifdef COM_HAYESP
 1633         if (sc->sc_type == COM_TYPE_HAYESP) {
 1634                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD1,
 1635                     HAYESP_SETPRESCALER);
 1636                 bus_space_write_1(iot, sc->sc_hayespioh, HAYESP_CMD2,
 1637                     sc->sc_prescaler);
 1638         }
 1639 #endif
 1640 
 1641         bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
 1642 }
 1643 
 1644 int
 1645 comhwiflow(struct tty *tp, int block)
 1646 {
 1647         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
 1648         int s;
 1649 
 1650         if (COM_ISALIVE(sc) == 0)
 1651                 return (0);
 1652 
 1653         if (sc->sc_mcr_rts == 0)
 1654                 return (0);
 1655 
 1656         s = splserial();
 1657         COM_LOCK(sc);
 1658 
 1659         if (block) {
 1660                 if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
 1661                         SET(sc->sc_rx_flags, RX_TTY_BLOCKED);
 1662                         com_hwiflow(sc);
 1663                 }
 1664         } else {
 1665                 if (ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED)) {
 1666                         CLR(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
 1667                         com_schedrx(sc);
 1668                 }
 1669                 if (ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
 1670                         CLR(sc->sc_rx_flags, RX_TTY_BLOCKED);
 1671                         com_hwiflow(sc);
 1672                 }
 1673         }
 1674 
 1675         COM_UNLOCK(sc);
 1676         splx(s);
 1677         return (1);
 1678 }
 1679 
 1680 /*
 1681  * (un)block input via hw flowcontrol
 1682  */
 1683 void
 1684 com_hwiflow(struct com_softc *sc)
 1685 {
 1686         bus_space_tag_t iot = sc->sc_iot;
 1687         bus_space_handle_t ioh = sc->sc_ioh;
 1688 
 1689         if (sc->sc_mcr_rts == 0)
 1690                 return;
 1691 
 1692         if (ISSET(sc->sc_rx_flags, RX_ANY_BLOCK)) {
 1693                 CLR(sc->sc_mcr, sc->sc_mcr_rts);
 1694                 CLR(sc->sc_mcr_active, sc->sc_mcr_rts);
 1695         } else {
 1696                 SET(sc->sc_mcr, sc->sc_mcr_rts);
 1697                 SET(sc->sc_mcr_active, sc->sc_mcr_rts);
 1698         }
 1699         bus_space_write_1(iot, ioh, com_mcr, sc->sc_mcr_active);
 1700 }
 1701 
 1702 
 1703 void
 1704 comstart(struct tty *tp)
 1705 {
 1706         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
 1707         bus_space_tag_t iot = sc->sc_iot;
 1708         bus_space_handle_t ioh = sc->sc_ioh;
 1709         int s;
 1710 
 1711         if (COM_ISALIVE(sc) == 0)
 1712                 return;
 1713 
 1714         s = spltty();
 1715         if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
 1716                 goto out;
 1717         if (sc->sc_tx_stopped)
 1718                 goto out;
 1719 
 1720         if (tp->t_outq.c_cc <= tp->t_lowat) {
 1721                 if (ISSET(tp->t_state, TS_ASLEEP)) {
 1722                         CLR(tp->t_state, TS_ASLEEP);
 1723                         wakeup(&tp->t_outq);
 1724                 }
 1725                 selwakeup(&tp->t_wsel);
 1726                 if (tp->t_outq.c_cc == 0)
 1727                         goto out;
 1728         }
 1729 
 1730         /* Grab the first contiguous region of buffer space. */
 1731         {
 1732                 u_char *tba;
 1733                 int tbc;
 1734 
 1735                 tba = tp->t_outq.c_cf;
 1736                 tbc = ndqb(&tp->t_outq, 0);
 1737 
 1738                 (void)splserial();
 1739                 COM_LOCK(sc);
 1740 
 1741                 sc->sc_tba = tba;
 1742                 sc->sc_tbc = tbc;
 1743         }
 1744 
 1745         SET(tp->t_state, TS_BUSY);
 1746         sc->sc_tx_busy = 1;
 1747 
 1748         /* Enable transmit completion interrupts if necessary. */
 1749         if (!ISSET(sc->sc_ier, IER_ETXRDY)) {
 1750                 SET(sc->sc_ier, IER_ETXRDY);
 1751                 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
 1752         }
 1753 
 1754         /* Output the first chunk of the contiguous buffer. */
 1755         if (!ISSET(sc->sc_hwflags, COM_HW_NO_TXPRELOAD)) {
 1756                 u_int n;
 1757 
 1758                 n = sc->sc_tbc;
 1759                 if (n > sc->sc_fifolen)
 1760                         n = sc->sc_fifolen;
 1761                 bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
 1762                 sc->sc_tbc -= n;
 1763                 sc->sc_tba += n;
 1764         }
 1765 
 1766         COM_UNLOCK(sc);
 1767 out:
 1768         splx(s);
 1769         return;
 1770 }
 1771 
 1772 /*
 1773  * Stop output on a line.
 1774  */
 1775 void
 1776 comstop(struct tty *tp, int flag)
 1777 {
 1778         struct com_softc *sc = device_lookup(&com_cd, COMUNIT(tp->t_dev));
 1779         int s;
 1780 
 1781         s = splserial();
 1782         COM_LOCK(sc);
 1783         if (ISSET(tp->t_state, TS_BUSY)) {
 1784                 /* Stop transmitting at the next chunk. */
 1785                 sc->sc_tbc = 0;
 1786                 sc->sc_heldtbc = 0;
 1787                 if (!ISSET(tp->t_state, TS_TTSTOP))
 1788                         SET(tp->t_state, TS_FLUSH);
 1789         }
 1790         COM_UNLOCK(sc);
 1791         splx(s);
 1792 }
 1793 
 1794 void
 1795 comdiag(void *arg)
 1796 {
 1797         struct com_softc *sc = arg;
 1798         int overflows, floods;
 1799         int s;
 1800 
 1801         s = splserial();
 1802         COM_LOCK(sc);
 1803         overflows = sc->sc_overflows;
 1804         sc->sc_overflows = 0;
 1805         floods = sc->sc_floods;
 1806         sc->sc_floods = 0;
 1807         sc->sc_errors = 0;
 1808         COM_UNLOCK(sc);
 1809         splx(s);
 1810 
 1811         log(LOG_WARNING, "%s: %d silo overflow%s, %d ibuf flood%s\n",
 1812             sc->sc_dev.dv_xname,
 1813             overflows, overflows == 1 ? "" : "s",
 1814             floods, floods == 1 ? "" : "s");
 1815 }
 1816 
 1817 integrate void
 1818 com_rxsoft(struct com_softc *sc, struct tty *tp)
 1819 {
 1820         int (*rint)(int, struct tty *) = tp->t_linesw->l_rint;
 1821         u_char *get, *end;
 1822         u_int cc, scc;
 1823         u_char lsr;
 1824         int code;
 1825         int s;
 1826 
 1827         end = sc->sc_ebuf;
 1828         get = sc->sc_rbget;
 1829         scc = cc = com_rbuf_size - sc->sc_rbavail;
 1830 
 1831         if (cc == com_rbuf_size) {
 1832                 sc->sc_floods++;
 1833                 if (sc->sc_errors++ == 0)
 1834                         callout_reset(&sc->sc_diag_callout, 60 * hz,
 1835                             comdiag, sc);
 1836         }
 1837 
 1838         /* If not yet open, drop the entire buffer content here */
 1839         if (!ISSET(tp->t_state, TS_ISOPEN)) {
 1840                 get += cc << 1;
 1841                 if (get >= end)
 1842                         get -= com_rbuf_size << 1;
 1843                 cc = 0;
 1844         }
 1845         while (cc) {
 1846                 code = get[0];
 1847                 lsr = get[1];
 1848                 if (ISSET(lsr, LSR_OE | LSR_BI | LSR_FE | LSR_PE)) {
 1849                         if (ISSET(lsr, LSR_OE)) {
 1850                                 sc->sc_overflows++;
 1851                                 if (sc->sc_errors++ == 0)
 1852                                         callout_reset(&sc->sc_diag_callout,
 1853                                             60 * hz, comdiag, sc);
 1854                         }
 1855                         if (ISSET(lsr, LSR_BI | LSR_FE))
 1856                                 SET(code, TTY_FE);
 1857                         if (ISSET(lsr, LSR_PE))
 1858                                 SET(code, TTY_PE);
 1859                 }
 1860                 if ((*rint)(code, tp) == -1) {
 1861                         /*
 1862                          * The line discipline's buffer is out of space.
 1863                          */
 1864                         if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
 1865                                 /*
 1866                                  * We're either not using flow control, or the
 1867                                  * line discipline didn't tell us to block for
 1868                                  * some reason.  Either way, we have no way to
 1869                                  * know when there's more space available, so
 1870                                  * just drop the rest of the data.
 1871                                  */
 1872                                 get += cc << 1;
 1873                                 if (get >= end)
 1874                                         get -= com_rbuf_size << 1;
 1875                                 cc = 0;
 1876                         } else {
 1877                                 /*
 1878                                  * Don't schedule any more receive processing
 1879                                  * until the line discipline tells us there's
 1880                                  * space available (through comhwiflow()).
 1881                                  * Leave the rest of the data in the input
 1882                                  * buffer.
 1883                                  */
 1884                                 SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
 1885                         }
 1886                         break;
 1887                 }
 1888                 get += 2;
 1889                 if (get >= end)
 1890                         get = sc->sc_rbuf;
 1891                 cc--;
 1892         }
 1893 
 1894         if (cc != scc) {
 1895                 sc->sc_rbget = get;
 1896                 s = splserial();
 1897                 COM_LOCK(sc);
 1898 
 1899                 cc = sc->sc_rbavail += scc - cc;
 1900                 /* Buffers should be ok again, release possible block. */
 1901                 if (cc >= sc->sc_r_lowat) {
 1902                         if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
 1903                                 CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
 1904                                 SET(sc->sc_ier, IER_ERXRDY);
 1905 #ifdef COM_PXA2X0
 1906                                 if (sc->sc_type == COM_TYPE_PXA2x0)
 1907                                         SET(sc->sc_ier, IER_ERXTOUT);
 1908 #endif
 1909                                 bus_space_write_1(sc->sc_iot, sc->sc_ioh,
 1910                                     com_ier, sc->sc_ier);
 1911                         }
 1912                         if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
 1913                                 CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
 1914                                 com_hwiflow(sc);
 1915                         }
 1916                 }
 1917                 COM_UNLOCK(sc);
 1918                 splx(s);
 1919         }
 1920 }
 1921 
 1922 integrate void
 1923 com_txsoft(struct com_softc *sc, struct tty *tp)
 1924 {
 1925 
 1926         CLR(tp->t_state, TS_BUSY);
 1927         if (ISSET(tp->t_state, TS_FLUSH))
 1928                 CLR(tp->t_state, TS_FLUSH);
 1929         else
 1930                 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
 1931         (*tp->t_linesw->l_start)(tp);
 1932 }
 1933 
 1934 integrate void
 1935 com_stsoft(struct com_softc *sc, struct tty *tp)
 1936 {
 1937         u_char msr, delta;
 1938         int s;
 1939 
 1940         s = splserial();
 1941         COM_LOCK(sc);
 1942         msr = sc->sc_msr;
 1943         delta = sc->sc_msr_delta;
 1944         sc->sc_msr_delta = 0;
 1945         COM_UNLOCK(sc);
 1946         splx(s);
 1947 
 1948         if (ISSET(delta, sc->sc_msr_dcd)) {
 1949                 /*
 1950                  * Inform the tty layer that carrier detect changed.
 1951                  */
 1952                 (void) (*tp->t_linesw->l_modem)(tp, ISSET(msr, MSR_DCD));
 1953         }
 1954 
 1955         if (ISSET(delta, sc->sc_msr_cts)) {
 1956                 /* Block or unblock output according to flow control. */
 1957                 if (ISSET(msr, sc->sc_msr_cts)) {
 1958                         sc->sc_tx_stopped = 0;
 1959                         (*tp->t_linesw->l_start)(tp);
 1960                 } else {
 1961                         sc->sc_tx_stopped = 1;
 1962                 }
 1963         }
 1964 
 1965 #ifdef COM_DEBUG
 1966         if (com_debug)
 1967                 comstatus(sc, "com_stsoft");
 1968 #endif
 1969 }
 1970 
 1971 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
 1972 void
 1973 comsoft(void *arg)
 1974 {
 1975         struct com_softc *sc = arg;
 1976         struct tty *tp;
 1977 
 1978         if (COM_ISALIVE(sc) == 0)
 1979                 return;
 1980 
 1981         {
 1982 #else
 1983 void
 1984 #ifndef __NO_SOFT_SERIAL_INTERRUPT
 1985 comsoft(void)
 1986 #else
 1987 comsoft(void *arg)
 1988 #endif
 1989 {
 1990         struct com_softc        *sc;
 1991         struct tty      *tp;
 1992         int     unit;
 1993 #ifdef __NO_SOFT_SERIAL_INTERRUPT
 1994         int s;
 1995 
 1996         s = splsoftserial();
 1997         com_softintr_scheduled = 0;
 1998 #endif
 1999 
 2000         for (unit = 0; unit < com_cd.cd_ndevs; unit++) {
 2001                 sc = device_lookup(&com_cd, unit);
 2002                 if (sc == NULL || !ISSET(sc->sc_hwflags, COM_HW_DEV_OK))
 2003                         continue;
 2004 
 2005                 if (COM_ISALIVE(sc) == 0)
 2006                         continue;
 2007 
 2008                 tp = sc->sc_tty;
 2009                 if (tp == NULL)
 2010                         continue;
 2011                 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0)
 2012                         continue;
 2013 #endif
 2014                 tp = sc->sc_tty;
 2015 
 2016                 if (sc->sc_rx_ready) {
 2017                         sc->sc_rx_ready = 0;
 2018                         com_rxsoft(sc, tp);
 2019                 }
 2020 
 2021                 if (sc->sc_st_check) {
 2022                         sc->sc_st_check = 0;
 2023                         com_stsoft(sc, tp);
 2024                 }
 2025 
 2026                 if (sc->sc_tx_done) {
 2027                         sc->sc_tx_done = 0;
 2028                         com_txsoft(sc, tp);
 2029                 }
 2030         }
 2031 
 2032 #ifndef __HAVE_GENERIC_SOFT_INTERRUPTS
 2033 #ifdef __NO_SOFT_SERIAL_INTERRUPT
 2034         splx(s);
 2035 #endif
 2036 #endif
 2037 }
 2038 
 2039 #ifdef __ALIGN_BRACKET_LEVEL_FOR_CTAGS
 2040         /* there has got to be a better way to do comsoft() */
 2041 }}
 2042 #endif
 2043 
 2044 int
 2045 comintr(void *arg)
 2046 {
 2047         struct com_softc *sc = arg;
 2048         bus_space_tag_t iot = sc->sc_iot;
 2049         bus_space_handle_t ioh = sc->sc_ioh;
 2050         u_char *put, *end;
 2051         u_int cc;
 2052         u_char lsr, iir;
 2053 
 2054         if (COM_ISALIVE(sc) == 0)
 2055                 return (0);
 2056 
 2057         COM_LOCK(sc);
 2058         iir = bus_space_read_1(iot, ioh, com_iir);
 2059         if (ISSET(iir, IIR_NOPEND)) {
 2060                 COM_UNLOCK(sc);
 2061                 return (0);
 2062         }
 2063 
 2064         end = sc->sc_ebuf;
 2065         put = sc->sc_rbput;
 2066         cc = sc->sc_rbavail;
 2067 
 2068 again:  do {
 2069                 u_char  msr, delta;
 2070 
 2071                 lsr = bus_space_read_1(iot, ioh, com_lsr);
 2072                 if (ISSET(lsr, LSR_BI)) {
 2073                         int cn_trapped = 0;
 2074 
 2075                         cn_check_magic(sc->sc_tty->t_dev,
 2076                                        CNC_BREAK, com_cnm_state);
 2077                         if (cn_trapped)
 2078                                 continue;
 2079 #if defined(KGDB) && !defined(DDB)
 2080                         if (ISSET(sc->sc_hwflags, COM_HW_KGDB)) {
 2081                                 kgdb_connect(1);
 2082                                 continue;
 2083                         }
 2084 #endif
 2085                 }
 2086 
 2087                 if (ISSET(lsr, LSR_RCV_MASK) &&
 2088                     !ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
 2089                         while (cc > 0) {
 2090                                 int cn_trapped = 0;
 2091                                 put[0] = bus_space_read_1(iot, ioh, com_data);
 2092                                 put[1] = lsr;
 2093                                 cn_check_magic(sc->sc_tty->t_dev,
 2094                                                put[0], com_cnm_state);
 2095                                 if (cn_trapped)
 2096                                         goto next;
 2097                                 put += 2;
 2098                                 if (put >= end)
 2099                                         put = sc->sc_rbuf;
 2100                                 cc--;
 2101                         next:
 2102                                 lsr = bus_space_read_1(iot, ioh, com_lsr);
 2103                                 if (!ISSET(lsr, LSR_RCV_MASK))
 2104                                         break;
 2105                         }
 2106 
 2107                         /*
 2108                          * Current string of incoming characters ended because
 2109                          * no more data was available or we ran out of space.
 2110                          * Schedule a receive event if any data was received.
 2111                          * If we're out of space, turn off receive interrupts.
 2112                          */
 2113                         sc->sc_rbput = put;
 2114                         sc->sc_rbavail = cc;
 2115                         if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
 2116                                 sc->sc_rx_ready = 1;
 2117 
 2118                         /*
 2119                          * See if we are in danger of overflowing a buffer. If
 2120                          * so, use hardware flow control to ease the pressure.
 2121                          */
 2122                         if (!ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED) &&
 2123                             cc < sc->sc_r_hiwat) {
 2124                                 SET(sc->sc_rx_flags, RX_IBUF_BLOCKED);
 2125                                 com_hwiflow(sc);
 2126                         }
 2127 
 2128                         /*
 2129                          * If we're out of space, disable receive interrupts
 2130                          * until the queue has drained a bit.
 2131                          */
 2132                         if (!cc) {
 2133                                 SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
 2134 #ifdef COM_PXA2X0
 2135                                 if (sc->sc_type == COM_TYPE_PXA2x0)
 2136                                         CLR(sc->sc_ier, IER_ERXRDY|IER_ERXTOUT);
 2137                                 else
 2138 #endif
 2139                                         CLR(sc->sc_ier, IER_ERXRDY);
 2140                                 bus_space_write_1(iot, ioh, com_ier,
 2141                                     sc->sc_ier);
 2142                         }
 2143                 } else {
 2144                         if ((iir & (IIR_RXRDY|IIR_TXRDY)) == IIR_RXRDY) {
 2145                                 (void) bus_space_read_1(iot, ioh, com_data);
 2146                                 continue;
 2147                         }
 2148                 }
 2149 
 2150                 msr = bus_space_read_1(iot, ioh, com_msr);
 2151                 delta = msr ^ sc->sc_msr;
 2152                 sc->sc_msr = msr;
 2153                 /*
 2154                  * Pulse-per-second (PSS) signals on edge of DCD?
 2155                  * Process these even if line discipline is ignoring DCD.
 2156                  */
 2157                 if (delta & sc->sc_ppsmask) {
 2158                         struct timeval tv;
 2159                         if ((msr & sc->sc_ppsmask) == sc->sc_ppsassert) {
 2160                                 /* XXX nanotime() */
 2161                                 microtime(&tv);
 2162                                 TIMEVAL_TO_TIMESPEC(&tv,
 2163                                     &sc->ppsinfo.assert_timestamp);
 2164                                 if (sc->ppsparam.mode & PPS_OFFSETASSERT) {
 2165                                         timespecadd(&sc->ppsinfo.assert_timestamp,
 2166                                             &sc->ppsparam.assert_offset,
 2167                                                     &sc->ppsinfo.assert_timestamp);
 2168                                 }
 2169 
 2170 #ifdef PPS_SYNC
 2171                                 if (pps_kc_hardpps_source == sc &&
 2172                                     pps_kc_hardpps_mode & PPS_CAPTUREASSERT) {
 2173                                         hardpps(&tv, tv.tv_usec);
 2174                                 }
 2175 #endif
 2176                                 sc->ppsinfo.assert_sequence++;
 2177                                 sc->ppsinfo.current_mode = sc->ppsparam.mode;
 2178 
 2179                         } else if ((msr & sc->sc_ppsmask) == sc->sc_ppsclear) {
 2180                                 /* XXX nanotime() */
 2181                                 microtime(&tv);
 2182                                 TIMEVAL_TO_TIMESPEC(&tv,
 2183                                     &sc->ppsinfo.clear_timestamp);
 2184                                 if (sc->ppsparam.mode & PPS_OFFSETCLEAR) {
 2185                                         timespecadd(&sc->ppsinfo.clear_timestamp,
 2186                                             &sc->ppsparam.clear_offset,
 2187                                             &sc->ppsinfo.clear_timestamp);
 2188                                 }
 2189 
 2190 #ifdef PPS_SYNC
 2191                                 if (pps_kc_hardpps_source == sc &&
 2192                                     pps_kc_hardpps_mode & PPS_CAPTURECLEAR) {
 2193                                         hardpps(&tv, tv.tv_usec);
 2194                                 }
 2195 #endif
 2196                                 sc->ppsinfo.clear_sequence++;
 2197                                 sc->ppsinfo.current_mode = sc->ppsparam.mode;
 2198                         }
 2199                 }
 2200 
 2201                 /*
 2202                  * Process normal status changes
 2203                  */
 2204                 if (ISSET(delta, sc->sc_msr_mask)) {
 2205                         SET(sc->sc_msr_delta, delta);
 2206 
 2207                         /*
 2208                          * Stop output immediately if we lose the output
 2209                          * flow control signal or carrier detect.
 2210                          */
 2211                         if (ISSET(~msr, sc->sc_msr_mask)) {
 2212                                 sc->sc_tbc = 0;
 2213                                 sc->sc_heldtbc = 0;
 2214 #ifdef COM_DEBUG
 2215                                 if (com_debug)
 2216                                         comstatus(sc, "comintr  ");
 2217 #endif
 2218                         }
 2219 
 2220                         sc->sc_st_check = 1;
 2221                 }
 2222         } while (!ISSET((iir =
 2223             bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND) &&
 2224             /*
 2225              * Since some device (e.g., ST16C1550) doesn't clear IIR_TXRDY
 2226              * by IIR read, so we can't do this way: `process all interrupts,
 2227              * then do TX if possble'.
 2228              */
 2229             (iir & IIR_IMASK) != IIR_TXRDY);
 2230 
 2231         /*
 2232          * Read LSR again, since there may be an interrupt between
 2233          * the last LSR read and IIR read above.
 2234          */
 2235         lsr = bus_space_read_1(iot, ioh, com_lsr);
 2236 
 2237         /*
 2238          * See if data can be transmitted as well.
 2239          * Schedule tx done event if no data left
 2240          * and tty was marked busy.
 2241          */
 2242         if (ISSET(lsr, LSR_TXRDY)) {
 2243                 /*
 2244                  * If we've delayed a parameter change, do it now, and restart
 2245                  * output.
 2246                  */
 2247                 if (sc->sc_heldchange) {
 2248                         com_loadchannelregs(sc);
 2249                         sc->sc_heldchange = 0;
 2250                         sc->sc_tbc = sc->sc_heldtbc;
 2251                         sc->sc_heldtbc = 0;
 2252                 }
 2253 
 2254                 /* Output the next chunk of the contiguous buffer, if any. */
 2255                 if (sc->sc_tbc > 0) {
 2256                         u_int n;
 2257 
 2258                         n = sc->sc_tbc;
 2259                         if (n > sc->sc_fifolen)
 2260                                 n = sc->sc_fifolen;
 2261                         bus_space_write_multi_1(iot, ioh, com_data, sc->sc_tba, n);
 2262                         sc->sc_tbc -= n;
 2263                         sc->sc_tba += n;
 2264                 } else {
 2265                         /* Disable transmit completion interrupts if necessary. */
 2266                         if (ISSET(sc->sc_ier, IER_ETXRDY)) {
 2267                                 CLR(sc->sc_ier, IER_ETXRDY);
 2268                                 bus_space_write_1(iot, ioh, com_ier, sc->sc_ier);
 2269                         }
 2270                         if (sc->sc_tx_busy) {
 2271                                 sc->sc_tx_busy = 0;
 2272                                 sc->sc_tx_done = 1;
 2273                         }
 2274                 }
 2275         }
 2276 
 2277         if (!ISSET((iir = bus_space_read_1(iot, ioh, com_iir)), IIR_NOPEND))
 2278                 goto again;
 2279 
 2280         COM_UNLOCK(sc);
 2281 
 2282         /* Wake up the poller. */
 2283 #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
 2284         softintr_schedule(sc->sc_si);
 2285 #else
 2286 #ifndef __NO_SOFT_SERIAL_INTERRUPT
 2287         setsoftserial();
 2288 #else
 2289         if (!com_softintr_scheduled) {
 2290                 com_softintr_scheduled = 1;
 2291                 callout_reset(&comsoft_callout, 1, comsoft, NULL);
 2292         }
 2293 #endif
 2294 #endif
 2295 
 2296 #if NRND > 0 && defined(RND_COM)
 2297         rnd_add_uint32(&sc->rnd_source, iir | lsr);
 2298 #endif
 2299 
 2300         return (1);
 2301 }
 2302 
 2303 /*
 2304  * The following functions are polled getc and putc routines, shared
 2305  * by the console and kgdb glue.
 2306  *
 2307  * The read-ahead code is so that you can detect pending in-band
 2308  * cn_magic in polled mode while doing output rather than having to
 2309  * wait until the kernel decides it needs input.
 2310  */
 2311 
 2312 #define MAX_READAHEAD   20
 2313 static int com_readahead[MAX_READAHEAD];
 2314 static int com_readaheadcount = 0;
 2315 
 2316 int
 2317 com_common_getc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh)
 2318 {
 2319         int s = splserial();
 2320         u_char stat, c;
 2321 
 2322         /* got a character from reading things earlier */
 2323         if (com_readaheadcount > 0) {
 2324                 int i;
 2325 
 2326                 c = com_readahead[0];
 2327                 for (i = 1; i < com_readaheadcount; i++) {
 2328                         com_readahead[i-1] = com_readahead[i];
 2329                 }
 2330                 com_readaheadcount--;
 2331                 splx(s);
 2332                 return (c);
 2333         }
 2334 
 2335         /* block until a character becomes available */
 2336         while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
 2337                 ;
 2338 
 2339         c = bus_space_read_1(iot, ioh, com_data);
 2340         stat = bus_space_read_1(iot, ioh, com_iir);
 2341         {
 2342                 int cn_trapped = 0; /* unused */
 2343 #ifdef DDB
 2344                 extern int db_active;
 2345                 if (!db_active)
 2346 #endif
 2347                         cn_check_magic(dev, c, com_cnm_state);
 2348         }
 2349         splx(s);
 2350         return (c);
 2351 }
 2352 
 2353 void
 2354 com_common_putc(dev_t dev, bus_space_tag_t iot, bus_space_handle_t ioh, int c)
 2355 {
 2356         int s = splserial();
 2357         int cin, stat, timo;
 2358 
 2359         if (com_readaheadcount < MAX_READAHEAD
 2360              && ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY)) {
 2361                 int cn_trapped = 0;
 2362                 cin = bus_space_read_1(iot, ioh, com_data);
 2363                 stat = bus_space_read_1(iot, ioh, com_iir);
 2364                 cn_check_magic(dev, cin, com_cnm_state);
 2365                 com_readahead[com_readaheadcount++] = cin;
 2366         }
 2367 
 2368         /* wait for any pending transmission to finish */
 2369         timo = 150000;
 2370         while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
 2371                 continue;
 2372 
 2373         bus_space_write_1(iot, ioh, com_data, c);
 2374         COM_BARRIER(iot, ioh, BR | BW);
 2375 
 2376         splx(s);
 2377 }
 2378 
 2379 /*
 2380  * Initialize UART for use as console or KGDB line.
 2381  */
 2382 int
 2383 cominit(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
 2384     int type, tcflag_t cflag, bus_space_handle_t *iohp)
 2385 {
 2386         bus_space_handle_t ioh;
 2387 
 2388         if (bus_space_map(iot, iobase, COM_NPORTS, 0, &ioh))
 2389                 return (ENOMEM); /* ??? */
 2390 
 2391         bus_space_write_1(iot, ioh, com_lcr, LCR_EERS);
 2392         bus_space_write_1(iot, ioh, com_efr, 0);
 2393         bus_space_write_1(iot, ioh, com_lcr, LCR_DLAB);
 2394         rate = comspeed(rate, frequency, type);
 2395         bus_space_write_1(iot, ioh, com_dlbl, rate);
 2396         bus_space_write_1(iot, ioh, com_dlbh, rate >> 8);
 2397         bus_space_write_1(iot, ioh, com_lcr, cflag2lcr(cflag));
 2398         bus_space_write_1(iot, ioh, com_mcr, MCR_DTR | MCR_RTS);
 2399         bus_space_write_1(iot, ioh, com_fifo,
 2400             FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
 2401 #ifdef COM_PXA2X0
 2402         if (type == COM_TYPE_PXA2x0)
 2403                 bus_space_write_1(iot, ioh, com_ier, IER_EUART);
 2404         else
 2405 #endif
 2406                 bus_space_write_1(iot, ioh, com_ier, 0);
 2407 
 2408         *iohp = ioh;
 2409         return (0);
 2410 }
 2411 
 2412 /*
 2413  * Following are all routines needed for COM to act as console
 2414  */
 2415 struct consdev comcons = {
 2416         NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL, NULL, NULL,
 2417         NODEV, CN_NORMAL
 2418 };
 2419 
 2420 
 2421 int
 2422 comcnattach(bus_space_tag_t iot, bus_addr_t iobase, int rate, int frequency,
 2423     int type, tcflag_t cflag)
 2424 {
 2425         int res;
 2426 
 2427         res = cominit(iot, iobase, rate, frequency, type, cflag, &comconsioh);
 2428         if (res)
 2429                 return (res);
 2430 
 2431         cn_tab = &comcons;
 2432         cn_init_magic(&com_cnm_state);
 2433         cn_set_magic("\047\001"); /* default magic is BREAK */
 2434 
 2435         comconstag = iot;
 2436         comconsaddr = iobase;
 2437         comconsrate = rate;
 2438         comconscflag = cflag;
 2439 
 2440         return (0);
 2441 }
 2442 
 2443 int
 2444 comcngetc(dev_t dev)
 2445 {
 2446 
 2447         return (com_common_getc(dev, comconstag, comconsioh));
 2448 }
 2449 
 2450 /*
 2451  * Console kernel output character routine.
 2452  */
 2453 void
 2454 comcnputc(dev_t dev, int c)
 2455 {
 2456 
 2457         com_common_putc(dev, comconstag, comconsioh, c);
 2458 }
 2459 
 2460 void
 2461 comcnpollc(dev_t dev, int on)
 2462 {
 2463 
 2464 }
 2465 
 2466 #ifdef KGDB
 2467 int
 2468 com_kgdb_attach(bus_space_tag_t iot, bus_addr_t iobase, int rate,
 2469     int frequency, int type, tcflag_t cflag)
 2470 {
 2471         int res;
 2472 
 2473         if (iot == comconstag && iobase == comconsaddr) {
 2474 #if !defined(DDB)
 2475                 return (EBUSY); /* cannot share with console */
 2476 #else
 2477                 com_kgdb_ioh = comconsioh;
 2478 #endif
 2479         } else {
 2480                 res = cominit(iot, iobase, rate, frequency, type, cflag,
 2481                               &com_kgdb_ioh);
 2482                 if (res)
 2483                         return (res);
 2484 
 2485                 /*
 2486                  * XXXfvdl this shouldn't be needed, but the cn_magic goo
 2487                  * expects this to be initialized
 2488                  */
 2489                 cn_init_magic(&com_cnm_state);
 2490                 cn_set_magic("\047\001");
 2491         }
 2492 
 2493         kgdb_attach(com_kgdb_getc, com_kgdb_putc, NULL);
 2494         kgdb_dev = 123; /* unneeded, only to satisfy some tests */
 2495 
 2496         com_kgdb_iot = iot;
 2497         com_kgdb_addr = iobase;
 2498 
 2499         return (0);
 2500 }
 2501 
 2502 /* ARGSUSED */
 2503 int
 2504 com_kgdb_getc(void *arg)
 2505 {
 2506 
 2507         return (com_common_getc(NODEV, com_kgdb_iot, com_kgdb_ioh));
 2508 }
 2509 
 2510 /* ARGSUSED */
 2511 void
 2512 com_kgdb_putc(void *arg, int c)
 2513 {
 2514 
 2515         com_common_putc(NODEV, com_kgdb_iot, com_kgdb_ioh, c);
 2516 }
 2517 #endif /* KGDB */
 2518 
 2519 /* helper function to identify the com ports used by
 2520  console or KGDB (and not yet autoconf attached) */
 2521 int
 2522 com_is_console(bus_space_tag_t iot, bus_addr_t iobase, bus_space_handle_t *ioh)
 2523 {
 2524         bus_space_handle_t help;
 2525 
 2526         if (!comconsattached &&
 2527             iot == comconstag && iobase == comconsaddr)
 2528                 help = comconsioh;
 2529 #ifdef KGDB
 2530         else if (!com_kgdb_attached &&
 2531             iot == com_kgdb_iot && iobase == com_kgdb_addr)
 2532                 help = com_kgdb_ioh;
 2533 #endif
 2534         else
 2535                 return (0);
 2536 
 2537         if (ioh)
 2538                 *ioh = help;
 2539         return (1);
 2540 }

Cache object: 0bcbb98606c4c8c3ac3d9f3884fb89e2


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.