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_i8251.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_i8251.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 i8251_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 i8251_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 i8251_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 i8251_drain(struct uart_bas *bas, int what)
  112 {
  113         int delay, limit;
  114 
  115         delay = i8251_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("i8251: 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("i8251: 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 i8251_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 i8251_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 = i8251_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 i8251_probe(struct uart_bas *bas);
  215 static void i8251_init(struct uart_bas *bas, int, int, int, int);
  216 static void i8251_term(struct uart_bas *bas);
  217 static void i8251_putc(struct uart_bas *bas, int);
  218 static int i8251_poll(struct uart_bas *bas);
  219 static int i8251_getc(struct uart_bas *bas);
  220 
  221 struct uart_ops uart_i8251_ops = {
  222         .probe = i8251_probe,
  223         .init = i8251_init,
  224         .term = i8251_term,
  225         .putc = i8251_putc,
  226         .poll = i8251_poll,
  227         .getc = i8251_getc,
  228 };
  229 
  230 static int
  231 i8251_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 i8251_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         i8251_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         i8251_clrint(bas);
  284 }
  285 
  286 static void
  287 i8251_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 i8251_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 = i8251_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         limit = 40;
  308         while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
  309                 DELAY(delay);
  310 }
  311 
  312 static int
  313 i8251_poll(struct uart_bas *bas)
  314 {
  315 
  316         if (uart_getreg(bas, REG_LSR) & LSR_RXRDY)
  317                 return (uart_getreg(bas, REG_DATA));
  318         return (-1);
  319 }
  320 
  321 static int
  322 i8251_getc(struct uart_bas *bas)
  323 {
  324         int delay;
  325 
  326         /* 1/10th the time to transmit 1 character (estimate). */
  327         delay = i8251_delay(bas);
  328 
  329         while ((uart_getreg(bas, REG_LSR) & LSR_RXRDY) == 0)
  330                 DELAY(delay);
  331         return (uart_getreg(bas, REG_DATA));
  332 }
  333 
  334 /*
  335  * High-level UART interface.
  336  */
  337 struct i8251_softc {
  338         struct uart_softc base;
  339         uint8_t         fcr;
  340         uint8_t         ier;
  341         uint8_t         mcr;
  342 };
  343 
  344 static int i8251_bus_attach(struct uart_softc *);
  345 static int i8251_bus_detach(struct uart_softc *);
  346 static int i8251_bus_flush(struct uart_softc *, int);
  347 static int i8251_bus_getsig(struct uart_softc *);
  348 static int i8251_bus_ioctl(struct uart_softc *, int, intptr_t);
  349 static int i8251_bus_ipend(struct uart_softc *);
  350 static int i8251_bus_param(struct uart_softc *, int, int, int, int);
  351 static int i8251_bus_probe(struct uart_softc *);
  352 static int i8251_bus_receive(struct uart_softc *);
  353 static int i8251_bus_setsig(struct uart_softc *, int);
  354 static int i8251_bus_transmit(struct uart_softc *);
  355 
  356 static kobj_method_t i8251_methods[] = {
  357         KOBJMETHOD(uart_attach,         i8251_bus_attach),
  358         KOBJMETHOD(uart_detach,         i8251_bus_detach),
  359         KOBJMETHOD(uart_flush,          i8251_bus_flush),
  360         KOBJMETHOD(uart_getsig,         i8251_bus_getsig),
  361         KOBJMETHOD(uart_ioctl,          i8251_bus_ioctl),
  362         KOBJMETHOD(uart_ipend,          i8251_bus_ipend),
  363         KOBJMETHOD(uart_param,          i8251_bus_param),
  364         KOBJMETHOD(uart_probe,          i8251_bus_probe),
  365         KOBJMETHOD(uart_receive,        i8251_bus_receive),
  366         KOBJMETHOD(uart_setsig,         i8251_bus_setsig),
  367         KOBJMETHOD(uart_transmit,       i8251_bus_transmit),
  368         { 0, 0 }
  369 };
  370 
  371 struct uart_class uart_i8251_class = {
  372         "i8251 class",
  373         i8251_methods,
  374         sizeof(struct i8251_softc),
  375         .uc_range = 8,
  376         .uc_rclk = DEFAULT_RCLK
  377 };
  378 
  379 #define SIGCHG(c, i, s, d)                              \
  380         if (c) {                                        \
  381                 i |= (i & s) ? s : s | d;               \
  382         } else {                                        \
  383                 i = (i & s) ? (i & ~s) | d : i;         \
  384         }
  385 
  386 static int
  387 i8251_bus_attach(struct uart_softc *sc)
  388 {
  389         struct i8251_softc *i8251 = (struct i8251_softc*)sc;
  390         struct uart_bas *bas;
  391 
  392         bas = &sc->sc_bas;
  393 
  394         i8251->mcr = uart_getreg(bas, REG_MCR);
  395         i8251->fcr = FCR_ENABLE | FCR_RX_MEDH;
  396         uart_setreg(bas, REG_FCR, i8251->fcr);
  397         uart_barrier(bas);
  398         i8251_bus_flush(sc, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
  399 
  400         if (i8251->mcr & MCR_DTR)
  401                 sc->sc_hwsig |= SER_DTR;
  402         if (i8251->mcr & MCR_RTS)
  403                 sc->sc_hwsig |= SER_RTS;
  404         i8251_bus_getsig(sc);
  405 
  406         i8251_clrint(bas);
  407         i8251->ier = IER_EMSC | IER_ERLS | IER_ERXRDY;
  408         uart_setreg(bas, REG_IER, i8251->ier);
  409         uart_barrier(bas);
  410         return (0);
  411 }
  412 
  413 static int
  414 i8251_bus_detach(struct uart_softc *sc)
  415 {
  416         struct uart_bas *bas;
  417 
  418         bas = &sc->sc_bas;
  419         uart_setreg(bas, REG_IER, 0);
  420         uart_barrier(bas);
  421         i8251_clrint(bas);
  422         return (0);
  423 }
  424 
  425 static int
  426 i8251_bus_flush(struct uart_softc *sc, int what)
  427 {
  428         struct i8251_softc *i8251 = (struct i8251_softc*)sc;
  429         struct uart_bas *bas;
  430         int error;
  431 
  432         bas = &sc->sc_bas;
  433         mtx_lock_spin(&sc->sc_hwmtx);
  434         if (sc->sc_hasfifo) {
  435                 i8251_flush(bas, what);
  436                 uart_setreg(bas, REG_FCR, i8251->fcr);
  437                 uart_barrier(bas);
  438                 error = 0;
  439         } else
  440                 error = i8251_drain(bas, what);
  441         mtx_unlock_spin(&sc->sc_hwmtx);
  442         return (error);
  443 }
  444 
  445 static int
  446 i8251_bus_getsig(struct uart_softc *sc)
  447 {
  448         uint32_t new, old, sig;
  449         uint8_t msr;
  450 
  451         do {
  452                 old = sc->sc_hwsig;
  453                 sig = old;
  454                 mtx_lock_spin(&sc->sc_hwmtx);
  455                 msr = uart_getreg(&sc->sc_bas, REG_MSR);
  456                 mtx_unlock_spin(&sc->sc_hwmtx);
  457                 SIGCHG(msr & MSR_DSR, sig, SER_DSR, SER_DDSR);
  458                 SIGCHG(msr & MSR_CTS, sig, SER_CTS, SER_DCTS);
  459                 SIGCHG(msr & MSR_DCD, sig, SER_DCD, SER_DDCD);
  460                 SIGCHG(msr & MSR_RI,  sig, SER_RI,  SER_DRI);
  461                 new = sig & ~UART_SIGMASK_DELTA;
  462         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  463         return (sig);
  464 }
  465 
  466 static int
  467 i8251_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
  468 {
  469         struct uart_bas *bas;
  470         int error;
  471         uint8_t lcr;
  472 
  473         bas = &sc->sc_bas;
  474         error = 0;
  475         mtx_lock_spin(&sc->sc_hwmtx);
  476         switch (request) {
  477         case UART_IOCTL_BREAK:
  478                 lcr = uart_getreg(bas, REG_LCR);
  479                 if (data)
  480                         lcr |= LCR_SBREAK;
  481                 else
  482                         lcr &= ~LCR_SBREAK;
  483                 uart_setreg(bas, REG_LCR, lcr);
  484                 uart_barrier(bas);
  485                 break;
  486         default:
  487                 error = EINVAL;
  488                 break;
  489         }
  490         mtx_unlock_spin(&sc->sc_hwmtx);
  491         return (error);
  492 }
  493 
  494 static int
  495 i8251_bus_ipend(struct uart_softc *sc)
  496 {
  497         struct uart_bas *bas;
  498         int ipend;
  499         uint8_t iir, lsr;
  500 
  501         bas = &sc->sc_bas;
  502         mtx_lock_spin(&sc->sc_hwmtx);
  503         iir = uart_getreg(bas, REG_IIR);
  504         if (iir & IIR_NOPEND) {
  505                 mtx_unlock_spin(&sc->sc_hwmtx);
  506                 return (0);
  507         }
  508         ipend = 0;
  509         if (iir & IIR_RXRDY) {
  510                 lsr = uart_getreg(bas, REG_LSR);
  511                 mtx_unlock_spin(&sc->sc_hwmtx);
  512                 if (lsr & LSR_OE)
  513                         ipend |= UART_IPEND_OVERRUN;
  514                 if (lsr & LSR_BI)
  515                         ipend |= UART_IPEND_BREAK;
  516                 if (lsr & LSR_RXRDY)
  517                         ipend |= UART_IPEND_RXREADY;
  518         } else {
  519                 mtx_unlock_spin(&sc->sc_hwmtx);
  520                 if (iir & IIR_TXRDY)
  521                         ipend |= UART_IPEND_TXIDLE;
  522                 else
  523                         ipend |= UART_IPEND_SIGCHG;
  524         }
  525         return ((sc->sc_leaving) ? 0 : ipend);
  526 }
  527 
  528 static int
  529 i8251_bus_param(struct uart_softc *sc, int baudrate, int databits,
  530     int stopbits, int parity)
  531 {
  532         struct uart_bas *bas;
  533         int error;
  534 
  535         bas = &sc->sc_bas;
  536         mtx_lock_spin(&sc->sc_hwmtx);
  537         error = i8251_param(bas, baudrate, databits, stopbits, parity);
  538         mtx_unlock_spin(&sc->sc_hwmtx);
  539         return (error);
  540 }
  541 
  542 static int
  543 i8251_bus_probe(struct uart_softc *sc)
  544 {
  545         struct uart_bas *bas;
  546         int count, delay, error, limit;
  547         uint8_t mcr;
  548 
  549         bas = &sc->sc_bas;
  550 
  551         error = i8251_probe(bas);
  552         if (error)
  553                 return (error);
  554 
  555         mcr = MCR_IE;
  556         if (sc->sc_sysdev == NULL) {
  557                 /* By using i8251_init() we also set DTR and RTS. */
  558                 i8251_init(bas, 9600, 8, 1, UART_PARITY_NONE);
  559         } else
  560                 mcr |= MCR_DTR | MCR_RTS;
  561 
  562         error = i8251_drain(bas, UART_DRAIN_TRANSMITTER);
  563         if (error)
  564                 return (error);
  565 
  566         /*
  567          * Set loopback mode. This avoids having garbage on the wire and
  568          * also allows us send and receive data. We set DTR and RTS to
  569          * avoid the possibility that automatic flow-control prevents
  570          * any data from being sent. We clear IE to avoid raising interrupts.
  571          */
  572         uart_setreg(bas, REG_MCR, MCR_LOOPBACK | MCR_DTR | MCR_RTS);
  573         uart_barrier(bas);
  574 
  575         /*
  576          * Enable FIFOs. And check that the UART has them. If not, we're
  577          * done. Otherwise we set DMA mode with the highest trigger level
  578          * so that we can determine the FIFO size. Since this is the first
  579          * time we enable the FIFOs, we reset them.
  580          */
  581         uart_setreg(bas, REG_FCR, FCR_ENABLE);
  582         uart_barrier(bas);
  583         sc->sc_hasfifo = (uart_getreg(bas, REG_IIR) & IIR_FIFO_MASK) ? 1 : 0;
  584         if (!sc->sc_hasfifo) {
  585                 /*
  586                  * NS16450 or II8251. We don't bother to differentiate
  587                  * between them. They're too old to be interesting.
  588                  */
  589                 uart_setreg(bas, REG_MCR, mcr);
  590                 uart_barrier(bas);
  591                 device_set_desc(sc->sc_dev, "8250 or 16450 or compatible");
  592                 return (0);
  593         }
  594 
  595         uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_DMA | FCR_RX_HIGH |
  596             FCR_XMT_RST | FCR_RCV_RST);
  597         uart_barrier(bas);
  598 
  599         count = 0;
  600         delay = i8251_delay(bas);
  601 
  602         /* We have FIFOs. Drain the transmitter and receiver. */
  603         error = i8251_drain(bas, UART_DRAIN_RECEIVER|UART_DRAIN_TRANSMITTER);
  604         if (error) {
  605                 uart_setreg(bas, REG_MCR, mcr);
  606                 uart_setreg(bas, REG_FCR, 0);
  607                 uart_barrier(bas);
  608                 goto describe;
  609         }
  610 
  611         uart_setreg(bas, REG_IER, IER_ERXRDY);
  612         uart_barrier(bas);
  613 
  614         /*
  615          * We should have a sufficiently clean "pipe" to determine the
  616          * size of the FIFOs. We send as much characters as is reasonable
  617          * and wait for the the RX interrupt to be asserted, counting the
  618          * characters as we send them. Based on that count we know the
  619          * FIFO size.
  620          */
  621         while ((uart_getreg(bas, REG_IIR) & IIR_RXRDY) == 0 && count < 1030) {
  622                 uart_setreg(bas, REG_DATA, 0);
  623                 uart_barrier(bas);
  624                 count++;
  625 
  626                 limit = 30;
  627                 while ((uart_getreg(bas, REG_LSR) & LSR_TEMT) == 0 && --limit)
  628                         DELAY(delay);
  629                 if (limit == 0) {
  630                         uart_setreg(bas, REG_IER, 0);
  631                         uart_setreg(bas, REG_MCR, mcr);
  632                         uart_setreg(bas, REG_FCR, 0);
  633                         uart_barrier(bas);
  634                         count = 0;
  635                         goto describe;
  636                 }
  637         }
  638 
  639         uart_setreg(bas, REG_IER, 0);
  640         uart_setreg(bas, REG_MCR, mcr);
  641 
  642         /* Reset FIFOs. */
  643         i8251_flush(bas, UART_FLUSH_RECEIVER|UART_FLUSH_TRANSMITTER);
  644 
  645  describe:
  646         if (count >= 14 && count < 16) {
  647                 sc->sc_rxfifosz = 16;
  648                 device_set_desc(sc->sc_dev, "16550 or compatible");
  649         } else if (count >= 28 && count < 32) {
  650                 sc->sc_rxfifosz = 32;
  651                 device_set_desc(sc->sc_dev, "16650 or compatible");
  652         } else if (count >= 56 && count < 64) {
  653                 sc->sc_rxfifosz = 64;
  654                 device_set_desc(sc->sc_dev, "16750 or compatible");
  655         } else if (count >= 112 && count < 128) {
  656                 sc->sc_rxfifosz = 128;
  657                 device_set_desc(sc->sc_dev, "16950 or compatible");
  658         } else {
  659                 sc->sc_rxfifosz = 1;
  660                 device_set_desc(sc->sc_dev,
  661                     "Non-standard i8251 class UART with FIFOs");
  662         }
  663 
  664         /*
  665          * Force the Tx FIFO size to 16 bytes for now. We don't program the
  666          * Tx trigger. Also, we assume that all data has been sent when the
  667          * interrupt happens.
  668          */
  669         sc->sc_txfifosz = 16;
  670 
  671         return (0);
  672 }
  673 
  674 static int
  675 i8251_bus_receive(struct uart_softc *sc)
  676 {
  677         struct uart_bas *bas;
  678         int xc;
  679         uint8_t lsr;
  680 
  681         bas = &sc->sc_bas;
  682         mtx_lock_spin(&sc->sc_hwmtx);
  683         lsr = uart_getreg(bas, REG_LSR);
  684         while (lsr & LSR_RXRDY) {
  685                 if (uart_rx_full(sc)) {
  686                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
  687                         break;
  688                 }
  689                 xc = uart_getreg(bas, REG_DATA);
  690                 if (lsr & LSR_FE)
  691                         xc |= UART_STAT_FRAMERR;
  692                 if (lsr & LSR_PE)
  693                         xc |= UART_STAT_PARERR;
  694                 uart_rx_put(sc, xc);
  695                 lsr = uart_getreg(bas, REG_LSR);
  696         }
  697         /* Discard everything left in the Rx FIFO. */
  698         while (lsr & LSR_RXRDY) {
  699                 (void)uart_getreg(bas, REG_DATA);
  700                 uart_barrier(bas);
  701                 lsr = uart_getreg(bas, REG_LSR);
  702         }
  703         mtx_unlock_spin(&sc->sc_hwmtx);
  704         return (0);
  705 }
  706 
  707 static int
  708 i8251_bus_setsig(struct uart_softc *sc, int sig)
  709 {
  710         struct i8251_softc *i8251 = (struct i8251_softc*)sc;
  711         struct uart_bas *bas;
  712         uint32_t new, old;
  713 
  714         bas = &sc->sc_bas;
  715         do {
  716                 old = sc->sc_hwsig;
  717                 new = old;
  718                 if (sig & SER_DDTR) {
  719                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  720                             SER_DDTR);
  721                 }
  722                 if (sig & SER_DRTS) {
  723                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  724                             SER_DRTS);
  725                 }
  726         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  727         mtx_lock_spin(&sc->sc_hwmtx);
  728         i8251->mcr &= ~(MCR_DTR|MCR_RTS);
  729         if (new & SER_DTR)
  730                 i8251->mcr |= MCR_DTR;
  731         if (new & SER_RTS)
  732                 i8251->mcr |= MCR_RTS;
  733         uart_setreg(bas, REG_MCR, i8251->mcr);
  734         uart_barrier(bas);
  735         mtx_unlock_spin(&sc->sc_hwmtx);
  736         return (0);
  737 }
  738 
  739 static int
  740 i8251_bus_transmit(struct uart_softc *sc)
  741 {
  742         struct i8251_softc *i8251 = (struct i8251_softc*)sc;
  743         struct uart_bas *bas;
  744         int i;
  745 
  746         bas = &sc->sc_bas;
  747         mtx_lock_spin(&sc->sc_hwmtx);
  748         while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0)
  749                 ;
  750         uart_setreg(bas, REG_IER, i8251->ier | IER_ETXRDY);
  751         uart_barrier(bas);
  752         for (i = 0; i < sc->sc_txdatasz; i++) {
  753                 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]);
  754                 uart_barrier(bas);
  755         }
  756         sc->sc_txbusy = 1;
  757         mtx_unlock_spin(&sc->sc_hwmtx);
  758         return (0);
  759 }

Cache object: dc543272516a503220ba2cba87f6faca


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