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/uart/uart_dev_ns8250.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 /*-
    2  * Copyright (c) 2003 Marcel Moolenaar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD$");
   29 
   30 #include <sys/param.h>
   31 #include <sys/systm.h>
   32 #include <sys/bus.h>
   33 #include <sys/conf.h>
   34 #include <machine/bus.h>
   35 
   36 #include <dev/uart/uart.h>
   37 #include <dev/uart/uart_cpu.h>
   38 #include <dev/uart/uart_bus.h>
   39 #include <dev/uart/uart_dev_ns8250.h>
   40 
   41 #include "uart_if.h"
   42 
   43 #define DEFAULT_RCLK    1843200
   44 
   45 /*
   46  * Clear pending interrupts. THRE is cleared by reading IIR. Data
   47  * that may have been received gets lost here.
   48  */
   49 static void
   50 ns8250_clrint(struct uart_bas *bas)
   51 {
   52         uint8_t iir;
   53 
   54         iir = uart_getreg(bas, REG_IIR);
   55         while ((iir & IIR_NOPEND) == 0) {
   56                 iir &= IIR_IMASK;
   57                 if (iir == IIR_RLS)
   58                         (void)uart_getreg(bas, REG_LSR);
   59                 else if (iir == IIR_RXRDY || iir == IIR_RXTOUT)
   60                         (void)uart_getreg(bas, REG_DATA);
   61                 else if (iir == IIR_MLSC)
   62                         (void)uart_getreg(bas, REG_MSR);
   63                 uart_barrier(bas);
   64                 iir = uart_getreg(bas, REG_IIR);
   65         }
   66 }
   67 
   68 static int
   69 ns8250_delay(struct uart_bas *bas)
   70 {
   71         int divisor;
   72         u_char lcr;
   73 
   74         lcr = uart_getreg(bas, REG_LCR);
   75         uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
   76         uart_barrier(bas);
   77         divisor = uart_getdreg(bas, REG_DL);
   78         uart_barrier(bas);
   79         uart_setreg(bas, REG_LCR, lcr);
   80         uart_barrier(bas);
   81 
   82         /* 1/10th the time to transmit 1 character (estimate). */
   83         return (16000000 * divisor / bas->rclk);
   84 }
   85 
   86 static int
   87 ns8250_divisor(int rclk, int baudrate)
   88 {
   89         int actual_baud, divisor;
   90         int error;
   91 
   92         if (baudrate == 0)
   93                 return (0);
   94 
   95         divisor = (rclk / (baudrate << 3) + 1) >> 1;
   96         if (divisor == 0 || divisor >= 65536)
   97                 return (0);
   98         actual_baud = rclk / (divisor << 4);
   99 
  100         /* 10 times error in percent: */
  101         error = ((actual_baud - baudrate) * 2000 / baudrate + 1) >> 1;
  102 
  103         /* 3.0% maximum error tolerance: */
  104         if (error < -30 || error > 30)
  105                 return (0);
  106 
  107         return (divisor);
  108 }
  109 
  110 static int
  111 ns8250_drain(struct uart_bas *bas, int what)
  112 {
  113         int delay, limit;
  114 
  115         delay = ns8250_delay(bas);
  116 
  117         if (what & UART_DRAIN_TRANSMITTER) {
  118                 /*
  119                  * Pick an arbitrary high limit to avoid getting stuck in
  120                  * an infinite loop when the hardware is broken. Make the
  121                  * limit high enough to handle large FIFOs.
  122                  */
  123                 limit = 10*1024;
  124                 while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
  125                         DELAY(delay);
  126                 if (limit == 0) {
  127                         /* printf("ns8250: transmitter appears stuck... "); */
  128                         return (EIO);
  129                 }
  130         }
  131 
  132         if (what & UART_DRAIN_RECEIVER) {
  133                 /*
  134                  * Pick an arbitrary high limit to avoid getting stuck in
  135                  * an infinite loop when the hardware is broken. Make the
  136                  * limit high enough to handle large FIFOs and integrated
  137                  * UARTs. The HP rx2600 for example has 3 UARTs on the
  138                  * management board that tend to get a lot of data send
  139                  * to it when the UART is first activated.
  140                  */
  141                 limit=10*4096;
  142                 while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) && --limit) {
  143                         (void)uart_getreg(bas, REG_DATA);
  144                         uart_barrier(bas);
  145                         DELAY(delay << 2);
  146                 }
  147                 if (limit == 0) {
  148                         /* printf("ns8250: receiver appears broken... "); */
  149                         return (EIO);
  150                 }
  151         }
  152 
  153         return (0);
  154 }
  155 
  156 /*
  157  * We can only flush UARTs with FIFOs. UARTs without FIFOs should be
  158  * drained. WARNING: this function clobbers the FIFO setting!
  159  */
  160 static void
  161 ns8250_flush(struct uart_bas *bas, int what)
  162 {
  163         uint8_t fcr;
  164 
  165         fcr = FCR_ENABLE;
  166         if (what & UART_FLUSH_TRANSMITTER)
  167                 fcr |= FCR_XMT_RST;
  168         if (what & UART_FLUSH_RECEIVER)
  169                 fcr |= FCR_RCV_RST;
  170         uart_setreg(bas, REG_FCR, fcr);
  171         uart_barrier(bas);
  172 }
  173 
  174 static int
  175 ns8250_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  176     int parity)
  177 {
  178         int divisor;
  179         uint8_t lcr;
  180 
  181         lcr = 0;
  182         if (databits >= 8)
  183                 lcr |= LCR_8BITS;
  184         else if (databits == 7)
  185                 lcr |= LCR_7BITS;
  186         else if (databits == 6)
  187                 lcr |= LCR_6BITS;
  188         else
  189                 lcr |= LCR_5BITS;
  190         if (stopbits > 1)
  191                 lcr |= LCR_STOPB;
  192         lcr |= parity << 3;
  193 
  194         /* Set baudrate. */
  195         if (baudrate > 0) {
  196                 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
  197                 uart_barrier(bas);
  198                 divisor = ns8250_divisor(bas->rclk, baudrate);
  199                 if (divisor == 0)
  200                         return (EINVAL);
  201                 uart_setdreg(bas, REG_DL, divisor);
  202                 uart_barrier(bas);
  203         }
  204 
  205         /* Set LCR and clear DLAB. */
  206         uart_setreg(bas, REG_LCR, lcr);
  207         uart_barrier(bas);
  208         return (0);
  209 }
  210 
  211 /*
  212  * Low-level UART interface.
  213  */
  214 static int ns8250_probe(struct uart_bas *bas);
  215 static void ns8250_init(struct uart_bas *bas, int, int, int, int);
  216 static void ns8250_term(struct uart_bas *bas);
  217 static void ns8250_putc(struct uart_bas *bas, int);
  218 static int ns8250_poll(struct uart_bas *bas);
  219 static int ns8250_getc(struct uart_bas *bas);
  220 
  221 struct uart_ops uart_ns8250_ops = {
  222         .probe = ns8250_probe,
  223         .init = ns8250_init,
  224         .term = ns8250_term,
  225         .putc = ns8250_putc,
  226         .poll = ns8250_poll,
  227         .getc = ns8250_getc,
  228 };
  229 
  230 static int
  231 ns8250_probe(struct uart_bas *bas)
  232 {
  233         u_char lcr, val;
  234 
  235         /* Check known 0 bits that don't depend on DLAB. */
  236         val = uart_getreg(bas, REG_IIR);
  237         if (val & 0x30)
  238                 return (ENXIO);
  239         val = uart_getreg(bas, REG_MCR);
  240         if (val & 0xe0)
  241                 return (ENXIO);
  242 
  243         lcr = uart_getreg(bas, REG_LCR);
  244         uart_setreg(bas, REG_LCR, lcr & ~LCR_DLAB);
  245         uart_barrier(bas);
  246 
  247         /* Check known 0 bits that depend on !DLAB. */
  248         val = uart_getreg(bas, REG_IER);
  249         if (val & 0xf0)
  250                 goto fail;
  251 
  252         uart_setreg(bas, REG_LCR, lcr);
  253         uart_barrier(bas);
  254         return (0);
  255 
  256  fail:
  257         uart_setreg(bas, REG_LCR, lcr);
  258         uart_barrier(bas);
  259         return (ENXIO);
  260 }
  261 
  262 static void
  263 ns8250_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  264     int parity)
  265 {
  266 
  267         if (bas->rclk == 0)
  268                 bas->rclk = DEFAULT_RCLK;
  269         ns8250_param(bas, baudrate, databits, stopbits, parity);
  270 
  271         /* Disable all interrupt sources. */
  272         uart_setreg(bas, REG_IER, 0);
  273         uart_barrier(bas);
  274 
  275         /* Disable the FIFO (if present). */
  276         uart_setreg(bas, REG_FCR, 0);
  277         uart_barrier(bas);
  278 
  279         /* Set RTS & DTR. */
  280         uart_setreg(bas, REG_MCR, MCR_IE | MCR_RTS | MCR_DTR);
  281         uart_barrier(bas);
  282 
  283         ns8250_clrint(bas);
  284 }
  285 
  286 static void
  287 ns8250_term(struct uart_bas *bas)
  288 {
  289 
  290         /* Clear RTS & DTR. */
  291         uart_setreg(bas, REG_MCR, MCR_IE);
  292         uart_barrier(bas);
  293 }
  294 
  295 static void
  296 ns8250_putc(struct uart_bas *bas, int c)
  297 {
  298         int delay, limit;
  299 
  300         /* 1/10th the time to transmit 1 character (estimate). */
  301         delay = ns8250_delay(bas);
  302 
  303         limit = 20;
  304         while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0 && --limit)
  305                 DELAY(delay);
  306         uart_setreg(bas, REG_DATA, c);
  307         uart_barrier(bas);
  308         limit = 40;
  309         while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
  310                 DELAY(delay);
  311 }
  312 
  313 static int
  314 ns8250_poll(struct uart_bas *bas)
  315 {
  316 
  317         if (uart_getreg(bas, REG_LSR) & LSR_RXRDY)
  318                 return (uart_getreg(bas, REG_DATA));
  319         return (-1);
  320 }
  321 
  322 static int
  323 ns8250_getc(struct uart_bas *bas)
  324 {
  325         int delay;
  326 
  327         /* 1/10th the time to transmit 1 character (estimate). */
  328         delay = ns8250_delay(bas);
  329 
  330         while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0)
  331                 DELAY(delay);
  332         return (uart_getreg(bas, REG_DATA));
  333 }
  334 
  335 /*
  336  * High-level UART interface.
  337  */
  338 struct ns8250_softc {
  339         struct uart_softc base;
  340         uint8_t         fcr;
  341         uint8_t         ier;
  342         uint8_t         mcr;
  343 };
  344 
  345 static int ns8250_bus_attach(struct uart_softc *);
  346 static int ns8250_bus_detach(struct uart_softc *);
  347 static int ns8250_bus_flush(struct uart_softc *, int);
  348 static int ns8250_bus_getsig(struct uart_softc *);
  349 static int ns8250_bus_ioctl(struct uart_softc *, int, intptr_t);
  350 static int ns8250_bus_ipend(struct uart_softc *);
  351 static int ns8250_bus_param(struct uart_softc *, int, int, int, int);
  352 static int ns8250_bus_probe(struct uart_softc *);
  353 static int ns8250_bus_receive(struct uart_softc *);
  354 static int ns8250_bus_setsig(struct uart_softc *, int);
  355 static int ns8250_bus_transmit(struct uart_softc *);
  356 
  357 static kobj_method_t ns8250_methods[] = {
  358         KOBJMETHOD(uart_attach,         ns8250_bus_attach),
  359         KOBJMETHOD(uart_detach,         ns8250_bus_detach),
  360         KOBJMETHOD(uart_flush,          ns8250_bus_flush),
  361         KOBJMETHOD(uart_getsig,         ns8250_bus_getsig),
  362         KOBJMETHOD(uart_ioctl,          ns8250_bus_ioctl),
  363         KOBJMETHOD(uart_ipend,          ns8250_bus_ipend),
  364         KOBJMETHOD(uart_param,          ns8250_bus_param),
  365         KOBJMETHOD(uart_probe,          ns8250_bus_probe),
  366         KOBJMETHOD(uart_receive,        ns8250_bus_receive),
  367         KOBJMETHOD(uart_setsig,         ns8250_bus_setsig),
  368         KOBJMETHOD(uart_transmit,       ns8250_bus_transmit),
  369         { 0, 0 }
  370 };
  371 
  372 struct uart_class uart_ns8250_class = {
  373         "ns8250 class",
  374         ns8250_methods,
  375         sizeof(struct ns8250_softc),
  376         .uc_range = 8,
  377         .uc_rclk = DEFAULT_RCLK
  378 };
  379 
  380 #define SIGCHG(c, i, s, d)                              \
  381         if (c) {                                        \
  382                 i |= (i & s) ? s : s | d;               \
  383         } else {                                        \
  384                 i = (i & s) ? (i & ~s) | d : i;         \
  385         }
  386 
  387 static int
  388 ns8250_bus_attach(struct uart_softc *sc)
  389 {
  390         struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
  391         struct uart_bas *bas;
  392 
  393         bas = &sc->sc_bas;
  394 
  395         ns8250->mcr = uart_getreg(bas, REG_MCR);
  396         ns8250->fcr = FCR_ENABLE | FCR_RX_MEDH;
  397         uart_setreg(bas, REG_FCR, ns8250->fcr);
  398         uart_barrier(bas);
  399         ns8250_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
  400 
  401         if (ns8250->mcr & MCR_DTR)
  402                 sc->sc_hwsig |= SER_DTR;
  403         if (ns8250->mcr & MCR_RTS)
  404                 sc->sc_hwsig |= SER_RTS;
  405         ns8250_bus_getsig(sc);
  406 
  407         ns8250_clrint(bas);
  408         ns8250->ier = IER_EMSC | IER_ERLS | IER_ERXRDY;
  409         uart_setreg(bas, REG_IER, ns8250->ier);
  410         uart_barrier(bas);
  411         return (0);
  412 }
  413 
  414 static int
  415 ns8250_bus_detach(struct uart_softc *sc)
  416 {
  417         struct uart_bas *bas;
  418 
  419         bas = &sc->sc_bas;
  420         uart_setreg(bas, REG_IER, 0);
  421         uart_barrier(bas);
  422         ns8250_clrint(bas);
  423         return (0);
  424 }
  425 
  426 static int
  427 ns8250_bus_flush(struct uart_softc *sc, int what)
  428 {
  429         struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
  430         struct uart_bas *bas;
  431         int error;
  432 
  433         bas = &sc->sc_bas;
  434         mtx_lock_spin(&sc->sc_hwmtx);
  435         if (sc->sc_hasfifo) {
  436                 ns8250_flush(bas, what);
  437                 uart_setreg(bas, REG_FCR, ns8250->fcr);
  438                 uart_barrier(bas);
  439                 error = 0;
  440         } else
  441                 error = ns8250_drain(bas, what);
  442         mtx_unlock_spin(&sc->sc_hwmtx);
  443         return (error);
  444 }
  445 
  446 static int
  447 ns8250_bus_getsig(struct uart_softc *sc)
  448 {
  449         uint32_t new, old, sig;
  450         uint8_t msr;
  451 
  452         do {
  453                 old = sc->sc_hwsig;
  454                 sig = old;
  455                 mtx_lock_spin(&sc->sc_hwmtx);
  456                 msr = uart_getreg(&sc->sc_bas, REG_MSR);
  457                 mtx_unlock_spin(&sc->sc_hwmtx);
  458                 SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
  459                 SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
  460                 SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
  461                 SIGCHG(msr & MSR_RI,  sig, SER_RI,  SER_DRI);
  462                 new = sig & ~UART_SIGMASK_DELTA;
  463         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  464         return (sig);
  465 }
  466 
  467 static int
  468 ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
  469 {
  470         struct uart_bas *bas;
  471         int baudrate, divisor, error;
  472         uint8_t efr, lcr;
  473 
  474         bas = &sc->sc_bas;
  475         error = 0;
  476         mtx_lock_spin(&sc->sc_hwmtx);
  477         switch (request) {
  478         case UART_IOCTL_BREAK:
  479                 lcr = uart_getreg(bas, REG_LCR);
  480                 if (data)
  481                         lcr |= LCR_SBREAK;
  482                 else
  483                         lcr &= ~LCR_SBREAK;
  484                 uart_setreg(bas, REG_LCR, lcr);
  485                 uart_barrier(bas);
  486                 break;
  487         case UART_IOCTL_IFLOW:
  488                 lcr = uart_getreg(bas, REG_LCR);
  489                 uart_barrier(bas);
  490                 uart_setreg(bas, REG_LCR, 0xbf);
  491                 uart_barrier(bas);
  492                 efr = uart_getreg(bas, REG_EFR);
  493                 if (data)
  494                         efr |= EFR_RTS;
  495                 else
  496                         efr &= ~EFR_RTS;
  497                 uart_setreg(bas, REG_EFR, efr);
  498                 uart_barrier(bas);
  499                 uart_setreg(bas, REG_LCR, lcr);
  500                 uart_barrier(bas);
  501                 break;
  502         case UART_IOCTL_OFLOW:
  503                 lcr = uart_getreg(bas, REG_LCR);
  504                 uart_barrier(bas);
  505                 uart_setreg(bas, REG_LCR, 0xbf);
  506                 uart_barrier(bas);
  507                 efr = uart_getreg(bas, REG_EFR);
  508                 if (data)
  509                         efr |= EFR_CTS;
  510                 else
  511                         efr &= ~EFR_CTS;
  512                 uart_setreg(bas, REG_EFR, efr);
  513                 uart_barrier(bas);
  514                 uart_setreg(bas, REG_LCR, lcr);
  515                 uart_barrier(bas);
  516                 break;
  517         case UART_IOCTL_BAUD:
  518                 lcr = uart_getreg(bas, REG_LCR);
  519                 uart_setreg(bas, REG_LCR, lcr | LCR_DLAB);
  520                 uart_barrier(bas);
  521                 divisor = uart_getdreg(bas, REG_DL);
  522                 uart_barrier(bas);
  523                 uart_setreg(bas, REG_LCR, lcr);
  524                 uart_barrier(bas);
  525                 baudrate = (divisor > 0) ? bas->rclk / divisor / 16 : 0;
  526                 if (baudrate > 0)
  527                         *(int*)data = baudrate;
  528                 else
  529                         error = ENXIO;
  530                 break;
  531         default:
  532                 error = EINVAL;
  533                 break;
  534         }
  535         mtx_unlock_spin(&sc->sc_hwmtx);
  536         return (error);
  537 }
  538 
  539 static int
  540 ns8250_bus_ipend(struct uart_softc *sc)
  541 {
  542         struct uart_bas *bas;
  543         int ipend;
  544         uint8_t iir, lsr;
  545 
  546         bas = &sc->sc_bas;
  547         mtx_lock_spin(&sc->sc_hwmtx);
  548         iir = uart_getreg(bas, REG_IIR);
  549         if (iir & IIR_NOPEND) {
  550                 mtx_unlock_spin(&sc->sc_hwmtx);
  551                 return (0);
  552         }
  553         ipend = 0;
  554         if (iir & IIR_RXRDY) {
  555                 lsr = uart_getreg(bas, REG_LSR);
  556                 mtx_unlock_spin(&sc->sc_hwmtx);
  557                 if (lsr & LSR_OE)
  558                         ipend |= UART_IPEND_OVERRUN;
  559                 if (lsr & LSR_BI)
  560                         ipend |= UART_IPEND_BREAK;
  561                 if (lsr & LSR_RXRDY)
  562                         ipend |= UART_IPEND_RXREADY;
  563         } else {
  564                 mtx_unlock_spin(&sc->sc_hwmtx);
  565                 if (iir & IIR_TXRDY)
  566                         ipend |= UART_IPEND_TXIDLE;
  567                 else
  568                         ipend |= UART_IPEND_SIGCHG;
  569         }
  570         return ((sc->sc_leaving) ? 0 : ipend);
  571 }
  572 
  573 static int
  574 ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits,
  575     int stopbits, int parity)
  576 {
  577         struct uart_bas *bas;
  578         int error;
  579 
  580         bas = &sc->sc_bas;
  581         mtx_lock_spin(&sc->sc_hwmtx);
  582         error = ns8250_param(bas, baudrate, databits, stopbits, parity);
  583         mtx_unlock_spin(&sc->sc_hwmtx);
  584         return (error);
  585 }
  586 
  587 static int
  588 ns8250_bus_probe(struct uart_softc *sc)
  589 {
  590         struct uart_bas *bas;
  591         int count, delay, error, limit;
  592         uint8_t lsr, mcr;
  593 
  594         bas = &sc->sc_bas;
  595 
  596         error = ns8250_probe(bas);
  597         if (error)
  598                 return (error);
  599 
  600         mcr = MCR_IE;
  601         if (sc->sc_sysdev == NULL) {
  602                 /* By using ns8250_init() we also set DTR and RTS. */
  603                 ns8250_init(bas, 9600, 8, 1, UART_PARITY_NONE);
  604         } else
  605                 mcr |= MCR_DTR | MCR_RTS;
  606 
  607         error = ns8250_drain(bas, UART_DRAIN_TRANSMITTER);
  608         if (error)
  609                 return (error);
  610 
  611         /*
  612          * Set loopback mode. This avoids having garbage on the wire and
  613          * also allows us send and receive data. We set DTR and RTS to
  614          * avoid the possibility that automatic flow-control prevents
  615          * any data from being sent.
  616          */
  617         uart_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_IE | MCR_DTR | MCR_RTS);
  618         uart_barrier(bas);
  619 
  620         /*
  621          * Enable FIFOs. And check that the UART has them. If not, we're
  622          * done. Since this is the first time we enable the FIFOs, we reset
  623          * them.
  624          */
  625         uart_setreg(bas, REG_FCR, FCR_ENABLE);
  626         uart_barrier(bas);
  627         sc->sc_hasfifo = (uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK) ? 1 : 0;
  628         if (!sc->sc_hasfifo) {
  629                 /*
  630                  * NS16450 or INS8250. We don't bother to differentiate
  631                  * between them. They're too old to be interesting.
  632                  */
  633                 uart_setreg(bas, REG_MCR, mcr);
  634                 uart_barrier(bas);
  635                 device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
  636                 return (0);
  637         }
  638 
  639         uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_XMT_RST | FCR_RCV_RST);
  640         uart_barrier(bas);
  641 
  642         count = 0;
  643         delay = ns8250_delay(bas);
  644 
  645         /* We have FIFOs. Drain the transmitter and receiver. */
  646         error = ns8250_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER);
  647         if (error) {
  648                 uart_setreg(bas, REG_MCR, mcr);
  649                 uart_setreg(bas, REG_FCR, 0);
  650                 uart_barrier(bas);
  651                 goto describe;
  652         }
  653 
  654         /*
  655          * We should have a sufficiently clean "pipe" to determine the
  656          * size of the FIFOs. We send as much characters as is reasonable
  657          * and wait for the the overflow bit in the LSR register to be
  658          * asserted, counting the characters as we send them. Based on
  659          * that count we know the FIFO size.
  660          */
  661         do {
  662                 uart_setreg(bas, REG_DATA, 0);
  663                 uart_barrier(bas);
  664                 count++;
  665 
  666                 limit = 30;
  667                 lsr = 0;
  668                 /*
  669                  * LSR bits are cleared upon read, so we must accumulate
  670                  * them to be able to test LSR_OE below.
  671                  */
  672                 while (((lsr |= uart_getreg(bas, REG_LSR)) & LSR_TEMT) == 0 &&
  673                     --limit)
  674                         DELAY(delay);
  675                 if (limit == 0) {
  676                         uart_setreg(bas, REG_IER, 0);
  677                         uart_setreg(bas, REG_MCR, mcr);
  678                         uart_setreg(bas, REG_FCR, 0);
  679                         uart_barrier(bas);
  680                         count = 0;
  681                         goto describe;
  682                 }
  683         } while ((lsr & LSR_OE) == 0 && count < 130);
  684         count--;
  685 
  686         uart_setreg(bas, REG_MCR, mcr);
  687 
  688         /* Reset FIFOs. */
  689         ns8250_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
  690 
  691  describe:
  692         if (count >= 14 && count <= 16) {
  693                 sc->sc_rxfifosz = 16;
  694                 device_set_desc(sc->sc_dev, "16550 or compatible");
  695         } else if (count >= 28 && count <= 32) {
  696                 sc->sc_rxfifosz = 32;
  697                 device_set_desc(sc->sc_dev, "16650 or compatible");
  698         } else if (count >= 56 && count <= 64) {
  699                 sc->sc_rxfifosz = 64;
  700                 device_set_desc(sc->sc_dev, "16750 or compatible");
  701         } else if (count >= 112 && count <= 128) {
  702                 sc->sc_rxfifosz = 128;
  703                 device_set_desc(sc->sc_dev, "16950 or compatible");
  704         } else {
  705                 sc->sc_rxfifosz = 16;
  706                 device_set_desc(sc->sc_dev,
  707                     "Non-standard ns8250 class UART with FIFOs");
  708         }
  709 
  710         /*
  711          * Force the Tx FIFO size to 16 bytes for now. We don't program the
  712          * Tx trigger. Also, we assume that all data has been sent when the
  713          * interrupt happens.
  714          */
  715         sc->sc_txfifosz = 16;
  716 
  717 #if 0
  718         /*
  719          * XXX there are some issues related to hardware flow control and
  720          * it's likely that uart(4) is the cause. This basicly needs more
  721          * investigation, but we avoid using for hardware flow control
  722          * until then.
  723          */
  724         /* 16650s or higher have automatic flow control. */
  725         if (sc->sc_rxfifosz > 16) {
  726                 sc->sc_hwiflow = 1;
  727                 sc->sc_hwoflow = 1;
  728         }
  729 #endif
  730 
  731         return (0);
  732 }
  733 
  734 static int
  735 ns8250_bus_receive(struct uart_softc *sc)
  736 {
  737         struct uart_bas *bas;
  738         int xc;
  739         uint8_t lsr;
  740 
  741         bas = &sc->sc_bas;
  742         mtx_lock_spin(&sc->sc_hwmtx);
  743         lsr = uart_getreg(bas, REG_LSR);
  744         while (lsr & LSR_RXRDY) {
  745                 if (uart_rx_full(sc)) {
  746                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
  747                         break;
  748                 }
  749                 xc = uart_getreg(bas, REG_DATA);
  750                 if (lsr & LSR_FE)
  751                         xc |= UART_STAT_FRAMERR;
  752                 if (lsr & LSR_PE)
  753                         xc |= UART_STAT_PARERR;
  754                 uart_rx_put(sc, xc);
  755                 lsr = uart_getreg(bas, REG_LSR);
  756         }
  757         /* Discard everything left in the Rx FIFO. */
  758         while (lsr & LSR_RXRDY) {
  759                 (void)uart_getreg(bas, REG_DATA);
  760                 uart_barrier(bas);
  761                 lsr = uart_getreg(bas, REG_LSR);
  762         }
  763         mtx_unlock_spin(&sc->sc_hwmtx);
  764         return (0);
  765 }
  766 
  767 static int
  768 ns8250_bus_setsig(struct uart_softc *sc, int sig)
  769 {
  770         struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
  771         struct uart_bas *bas;
  772         uint32_t new, old;
  773 
  774         bas = &sc->sc_bas;
  775         do {
  776                 old = sc->sc_hwsig;
  777                 new = old;
  778                 if (sig & SER_DDTR) {
  779                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  780                             SER_DDTR);
  781                 }
  782                 if (sig & SER_DRTS) {
  783                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  784                             SER_DRTS);
  785                 }
  786         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  787         mtx_lock_spin(&sc->sc_hwmtx);
  788         ns8250->mcr &= ~(MCR_DTR|MCR_RTS);
  789         if (new & SER_DTR)
  790                 ns8250->mcr |= MCR_DTR;
  791         if (new & SER_RTS)
  792                 ns8250->mcr |= MCR_RTS;
  793         uart_setreg(bas, REG_MCR, ns8250->mcr);
  794         uart_barrier(bas);
  795         mtx_unlock_spin(&sc->sc_hwmtx);
  796         return (0);
  797 }
  798 
  799 static int
  800 ns8250_bus_transmit(struct uart_softc *sc)
  801 {
  802         struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc;
  803         struct uart_bas *bas;
  804         int i;
  805 
  806         bas = &sc->sc_bas;
  807         mtx_lock_spin(&sc->sc_hwmtx);
  808         while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
  809                 ;
  810         uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY);
  811         uart_barrier(bas);
  812         for (i = 0; i < sc->sc_txdatasz; i++) {
  813                 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]);
  814                 uart_barrier(bas);
  815         }
  816         sc->sc_txbusy = 1;
  817         mtx_unlock_spin(&sc->sc_hwmtx);
  818         return (0);
  819 }

Cache object: 8eac17dd6f56d93cfcbcdd087406b536


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