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

Cache object: 18c36bcce8630ffa42b8f2fc619334e2


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