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

Cache object: 07cd91df4210a33f1d6c0f9f5877fb8a


[ 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.