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_z8530.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_z8530.h>
   40 
   41 #include "uart_if.h"
   42 
   43 #define DEFAULT_RCLK    307200
   44 
   45 /* Multiplexed I/O. */
   46 static __inline void
   47 uart_setmreg(struct uart_bas *bas, int reg, int val)
   48 {
   49 
   50         uart_setreg(bas, REG_CTRL, reg);
   51         uart_barrier(bas);
   52         uart_setreg(bas, REG_CTRL, val);
   53 }
   54 
   55 static __inline uint8_t
   56 uart_getmreg(struct uart_bas *bas, int reg)
   57 {
   58 
   59         uart_setreg(bas, REG_CTRL, reg);
   60         uart_barrier(bas);
   61         return (uart_getreg(bas, REG_CTRL));
   62 }
   63 
   64 static int
   65 z8530_divisor(int rclk, int baudrate)
   66 {
   67         int act_baud, divisor, error;
   68 
   69         if (baudrate == 0)
   70                 return (0);
   71 
   72         divisor = (rclk + baudrate) / (baudrate << 1) - 2;
   73         if (divisor >= 65536)
   74                 return (0);
   75         act_baud = rclk / 2 / (divisor + 2);
   76 
   77         /* 10 times error in percent: */
   78         error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1;
   79 
   80         /* 3.0% maximum error tolerance: */
   81         if (error < -30 || error > 30)
   82                 return (0);
   83 
   84         return (divisor);
   85 }
   86 
   87 static int
   88 z8530_param(struct uart_bas *bas, int baudrate, int databits, int stopbits,
   89     int parity, uint8_t *tpcp)
   90 {
   91         int divisor;
   92         uint8_t mpm, rpc, tpc;
   93 
   94         rpc = RPC_RXE;
   95         mpm = MPM_CM16;
   96         tpc = TPC_TXE | (*tpcp & (TPC_DTR | TPC_RTS));
   97 
   98         if (databits >= 8) {
   99                 rpc |= RPC_RB8;
  100                 tpc |= TPC_TB8;
  101         } else if (databits == 7) {
  102                 rpc |= RPC_RB7;
  103                 tpc |= TPC_TB7;
  104         } else if (databits == 6) {
  105                 rpc |= RPC_RB6;
  106                 tpc |= TPC_TB6;
  107         } else {
  108                 rpc |= RPC_RB5;
  109                 tpc |= TPC_TB5;
  110         }
  111         mpm |= (stopbits > 1) ? MPM_SB2 : MPM_SB1;
  112         switch (parity) {
  113         case UART_PARITY_EVEN:  mpm |= MPM_PE | MPM_EVEN; break;
  114         case UART_PARITY_NONE:  break;
  115         case UART_PARITY_ODD:   mpm |= MPM_PE; break;
  116         default:                return (EINVAL);
  117         }
  118 
  119         /* Set baudrate. */
  120         if (baudrate > 0) {
  121                 divisor = z8530_divisor(bas->rclk, baudrate);
  122                 if (divisor == 0)
  123                         return (EINVAL);
  124                 uart_setmreg(bas, WR_TCL, divisor & 0xff);
  125                 uart_barrier(bas);
  126                 uart_setmreg(bas, WR_TCH, (divisor >> 8) & 0xff);
  127                 uart_barrier(bas);
  128         }
  129 
  130         uart_setmreg(bas, WR_RPC, rpc);
  131         uart_barrier(bas);
  132         uart_setmreg(bas, WR_MPM, mpm);
  133         uart_barrier(bas);
  134         uart_setmreg(bas, WR_TPC, tpc);
  135         uart_barrier(bas);
  136         *tpcp = tpc;
  137         return (0);
  138 }
  139 
  140 static int
  141 z8530_setup(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  142     int parity)
  143 {
  144         uint8_t tpc;
  145 
  146         if (bas->rclk == 0)
  147                 bas->rclk = DEFAULT_RCLK;
  148 
  149         /* Assume we don't need to perform a full hardware reset. */
  150         switch (bas->chan) {
  151         case 1:
  152                 uart_setmreg(bas, WR_MIC, MIC_NV | MIC_CRA);
  153                 break;
  154         case 2:
  155                 uart_setmreg(bas, WR_MIC, MIC_NV | MIC_CRB);
  156                 break;
  157         }
  158         uart_barrier(bas);
  159         /* Set clock sources and enable BRG. */
  160         uart_setmreg(bas, WR_CMC, CMC_RC_BRG | CMC_TC_BRG);
  161         uart_setmreg(bas, WR_MCB2, MCB2_PCLK | MCB2_BRGE);
  162         uart_barrier(bas);
  163         /* Set data encoding. */
  164         uart_setmreg(bas, WR_MCB1, MCB1_NRZ);
  165         uart_barrier(bas);
  166 
  167         tpc = TPC_DTR | TPC_RTS;
  168         z8530_param(bas, baudrate, databits, stopbits, parity, &tpc);
  169         return (int)tpc;
  170 }
  171 
  172 /*
  173  * Low-level UART interface.
  174  */
  175 static int z8530_probe(struct uart_bas *bas);
  176 static void z8530_init(struct uart_bas *bas, int, int, int, int);
  177 static void z8530_term(struct uart_bas *bas);
  178 static void z8530_putc(struct uart_bas *bas, int);
  179 static int z8530_poll(struct uart_bas *bas);
  180 static int z8530_getc(struct uart_bas *bas);
  181 
  182 struct uart_ops uart_z8530_ops = {
  183         .probe = z8530_probe,
  184         .init = z8530_init,
  185         .term = z8530_term,
  186         .putc = z8530_putc,
  187         .poll = z8530_poll,
  188         .getc = z8530_getc,
  189 };
  190 
  191 static int
  192 z8530_probe(struct uart_bas *bas)
  193 {
  194 
  195         return (0);
  196 }
  197 
  198 static void
  199 z8530_init(struct uart_bas *bas, int baudrate, int databits, int stopbits,
  200     int parity)
  201 {
  202 
  203         z8530_setup(bas, baudrate, databits, stopbits, parity);
  204 }
  205 
  206 static void
  207 z8530_term(struct uart_bas *bas)
  208 {
  209 }
  210 
  211 static void
  212 z8530_putc(struct uart_bas *bas, int c)
  213 {
  214 
  215         while (!(uart_getreg(bas, REG_CTRL) & BES_TXE))
  216                 ;
  217         uart_setreg(bas, REG_DATA, c);
  218         uart_barrier(bas);
  219 }
  220 
  221 static int
  222 z8530_poll(struct uart_bas *bas)
  223 {
  224 
  225         if (!(uart_getreg(bas, REG_CTRL) & BES_RXA))
  226                 return (-1);
  227         return (uart_getreg(bas, REG_DATA));
  228 }
  229 
  230 static int
  231 z8530_getc(struct uart_bas *bas)
  232 {
  233 
  234         while (!(uart_getreg(bas, REG_CTRL) & BES_RXA))
  235                 ;
  236         return (uart_getreg(bas, REG_DATA));
  237 }
  238 
  239 /*
  240  * High-level UART interface.
  241  */
  242 struct z8530_softc {
  243         struct uart_softc base;
  244         uint8_t tpc;
  245         uint8_t txidle;
  246 };
  247 
  248 static int z8530_bus_attach(struct uart_softc *);
  249 static int z8530_bus_detach(struct uart_softc *);
  250 static int z8530_bus_flush(struct uart_softc *, int);
  251 static int z8530_bus_getsig(struct uart_softc *);
  252 static int z8530_bus_ioctl(struct uart_softc *, int, intptr_t);
  253 static int z8530_bus_ipend(struct uart_softc *);
  254 static int z8530_bus_param(struct uart_softc *, int, int, int, int);
  255 static int z8530_bus_probe(struct uart_softc *);
  256 static int z8530_bus_receive(struct uart_softc *);
  257 static int z8530_bus_setsig(struct uart_softc *, int);
  258 static int z8530_bus_transmit(struct uart_softc *);
  259 
  260 static kobj_method_t z8530_methods[] = {
  261         KOBJMETHOD(uart_attach,         z8530_bus_attach),
  262         KOBJMETHOD(uart_detach,         z8530_bus_detach),
  263         KOBJMETHOD(uart_flush,          z8530_bus_flush),
  264         KOBJMETHOD(uart_getsig,         z8530_bus_getsig),
  265         KOBJMETHOD(uart_ioctl,          z8530_bus_ioctl),
  266         KOBJMETHOD(uart_ipend,          z8530_bus_ipend),
  267         KOBJMETHOD(uart_param,          z8530_bus_param),
  268         KOBJMETHOD(uart_probe,          z8530_bus_probe),
  269         KOBJMETHOD(uart_receive,        z8530_bus_receive),
  270         KOBJMETHOD(uart_setsig,         z8530_bus_setsig),
  271         KOBJMETHOD(uart_transmit,       z8530_bus_transmit),
  272         { 0, 0 }
  273 };
  274 
  275 struct uart_class uart_z8530_class = {
  276         "z8530 class",
  277         z8530_methods,
  278         sizeof(struct z8530_softc),
  279         .uc_range = 2,
  280         .uc_rclk = DEFAULT_RCLK
  281 };
  282 
  283 #define SIGCHG(c, i, s, d)                              \
  284         if (c) {                                        \
  285                 i |= (i & s) ? s : s | d;               \
  286         } else {                                        \
  287                 i = (i & s) ? (i & ~s) | d : i;         \
  288         }
  289 
  290 static int
  291 z8530_bus_attach(struct uart_softc *sc)
  292 {
  293         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  294         struct uart_bas *bas;
  295         struct uart_devinfo *di;
  296 
  297         bas = &sc->sc_bas;
  298         if (sc->sc_sysdev != NULL) {
  299                 di = sc->sc_sysdev;
  300                 z8530->tpc = TPC_DTR|TPC_RTS;
  301                 z8530_param(bas, di->baudrate, di->databits, di->stopbits,
  302                     di->parity, &z8530->tpc);
  303         } else {
  304                 z8530->tpc = z8530_setup(bas, 9600, 8, 1, UART_PARITY_NONE);
  305                 z8530->tpc &= ~(TPC_DTR|TPC_RTS);
  306         }
  307         z8530->txidle = 1;      /* Report UART_IPEND_TXIDLE. */
  308 
  309         sc->sc_rxfifosz = 3;
  310         sc->sc_txfifosz = 1;
  311 
  312         (void)z8530_bus_getsig(sc);
  313 
  314         uart_setmreg(bas, WR_IC, IC_BRK | IC_CTS | IC_DCD);
  315         uart_barrier(bas);
  316         uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA);
  317         uart_barrier(bas);
  318         uart_setmreg(bas, WR_IV, 0);
  319         uart_barrier(bas);
  320         uart_setmreg(bas, WR_TPC, z8530->tpc);
  321         uart_barrier(bas);
  322         uart_setmreg(bas, WR_MIC, MIC_NV | MIC_MIE);
  323         uart_barrier(bas);
  324         return (0);
  325 }
  326 
  327 static int
  328 z8530_bus_detach(struct uart_softc *sc)
  329 {
  330 
  331         return (0);
  332 }
  333 
  334 static int
  335 z8530_bus_flush(struct uart_softc *sc, int what)
  336 {
  337 
  338         return (0);
  339 }
  340 
  341 static int
  342 z8530_bus_getsig(struct uart_softc *sc)
  343 {
  344         uint32_t new, old, sig;
  345         uint8_t bes;
  346 
  347         do {
  348                 old = sc->sc_hwsig;
  349                 sig = old;
  350                 mtx_lock_spin(&sc->sc_hwmtx);
  351                 bes = uart_getmreg(&sc->sc_bas, RR_BES);
  352                 mtx_unlock_spin(&sc->sc_hwmtx);
  353                 SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
  354                 SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
  355                 SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
  356                 new = sig & ~UART_SIGMASK_DELTA;
  357         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  358         return (sig);
  359 }
  360 
  361 static int
  362 z8530_bus_ioctl(struct uart_softc *sc, int request, intptr_t data)
  363 {
  364         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  365         struct uart_bas *bas;
  366         int error;
  367 
  368         bas = &sc->sc_bas;
  369         error = 0;
  370         mtx_lock_spin(&sc->sc_hwmtx);
  371         switch (request) {
  372         case UART_IOCTL_BREAK:
  373                 if (data)
  374                         z8530->tpc |= TPC_BRK;
  375                 else
  376                         z8530->tpc &= ~TPC_BRK;
  377                 uart_setmreg(bas, WR_TPC, z8530->tpc);
  378                 uart_barrier(bas);
  379                 break;
  380         default:
  381                 error = EINVAL;
  382                 break;
  383         }
  384         mtx_unlock_spin(&sc->sc_hwmtx);
  385         return (error);
  386 }
  387 
  388 static int
  389 z8530_bus_ipend(struct uart_softc *sc)
  390 {
  391         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  392         struct uart_bas *bas;
  393         int ipend;
  394         uint32_t sig;
  395         uint8_t bes, ip, iv, src;
  396 
  397         bas = &sc->sc_bas;
  398         ipend = 0;
  399 
  400         mtx_lock_spin(&sc->sc_hwmtx);
  401         switch (bas->chan) {
  402         case 1:
  403                 ip = uart_getmreg(bas, RR_IP);
  404                 break;
  405         case 2: /* XXX hack!!! */
  406                 iv = uart_getmreg(bas, RR_IV) & 0x0E;
  407                 switch (iv) {
  408                 case IV_TEB:    ip = IP_TIA; break;
  409                 case IV_XSB:    ip = IP_SIA; break;
  410                 case IV_RAB:    ip = IP_RIA; break;
  411                 default:        ip = 0; break;
  412                 }
  413                 break;
  414         default:
  415                 ip = 0;
  416                 break;
  417         }
  418 
  419         if (ip & IP_RIA)
  420                 ipend |= UART_IPEND_RXREADY;
  421 
  422         if (ip & IP_TIA) {
  423                 uart_setreg(bas, REG_CTRL, CR_RSTTXI);
  424                 uart_barrier(bas);
  425                 if (z8530->txidle) {
  426                         ipend |= UART_IPEND_TXIDLE;
  427                         z8530->txidle = 0;      /* Mask UART_IPEND_TXIDLE. */
  428                 }
  429         }
  430 
  431         if (ip & IP_SIA) {
  432                 uart_setreg(bas, REG_CTRL, CR_RSTXSI);
  433                 uart_barrier(bas);
  434                 bes = uart_getmreg(bas, RR_BES);
  435                 if (bes & BES_BRK)
  436                         ipend |= UART_IPEND_BREAK;
  437                 sig = sc->sc_hwsig;
  438                 SIGCHG(bes & BES_CTS, sig, SER_CTS, SER_DCTS);
  439                 SIGCHG(bes & BES_DCD, sig, SER_DCD, SER_DDCD);
  440                 SIGCHG(bes & BES_SYNC, sig, SER_DSR, SER_DDSR);
  441                 if (sig & UART_SIGMASK_DELTA)
  442                         ipend |= UART_IPEND_SIGCHG;
  443                 src = uart_getmreg(bas, RR_SRC);
  444                 if (src & SRC_OVR) {
  445                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  446                         uart_barrier(bas);
  447                         ipend |= UART_IPEND_OVERRUN;
  448                 }
  449         }
  450 
  451         if (ipend) {
  452                 uart_setreg(bas, REG_CTRL, CR_RSTIUS);
  453                 uart_barrier(bas);
  454         }
  455 
  456         mtx_unlock_spin(&sc->sc_hwmtx);
  457 
  458         return (ipend);
  459 }
  460 
  461 static int
  462 z8530_bus_param(struct uart_softc *sc, int baudrate, int databits,
  463     int stopbits, int parity)
  464 {
  465         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  466         int error;
  467 
  468         mtx_lock_spin(&sc->sc_hwmtx);
  469         error = z8530_param(&sc->sc_bas, baudrate, databits, stopbits, parity,
  470             &z8530->tpc);
  471         mtx_unlock_spin(&sc->sc_hwmtx);
  472         return (error);
  473 }
  474 
  475 static int
  476 z8530_bus_probe(struct uart_softc *sc)
  477 {
  478         char buf[80];
  479         int error;
  480         char ch;
  481 
  482         error = z8530_probe(&sc->sc_bas);
  483         if (error)
  484                 return (error);
  485 
  486         ch = sc->sc_bas.chan - 1 + 'A';
  487 
  488         snprintf(buf, sizeof(buf), "z8530, channel %c", ch);
  489         device_set_desc_copy(sc->sc_dev, buf);
  490         return (0);
  491 }
  492 
  493 static int
  494 z8530_bus_receive(struct uart_softc *sc)
  495 {
  496         struct uart_bas *bas;
  497         int xc;
  498         uint8_t bes, src;
  499 
  500         bas = &sc->sc_bas;
  501         mtx_lock_spin(&sc->sc_hwmtx);
  502         bes = uart_getmreg(bas, RR_BES);
  503         while (bes & BES_RXA) {
  504                 if (uart_rx_full(sc)) {
  505                         sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN;
  506                         break;
  507                 }
  508                 xc = uart_getreg(bas, REG_DATA);
  509                 uart_barrier(bas);
  510                 src = uart_getmreg(bas, RR_SRC);
  511                 if (src & SRC_FE)
  512                         xc |= UART_STAT_FRAMERR;
  513                 if (src & SRC_PE)
  514                         xc |= UART_STAT_PARERR;
  515                 if (src & SRC_OVR)
  516                         xc |= UART_STAT_OVERRUN;
  517                 uart_rx_put(sc, xc);
  518                 if (src & (SRC_FE | SRC_PE | SRC_OVR)) {
  519                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  520                         uart_barrier(bas);
  521                 }
  522                 bes = uart_getmreg(bas, RR_BES);
  523         }
  524         /* Discard everything left in the Rx FIFO. */
  525         while (bes & BES_RXA) {
  526                 (void)uart_getreg(bas, REG_DATA);
  527                 uart_barrier(bas);
  528                 src = uart_getmreg(bas, RR_SRC);
  529                 if (src & (SRC_FE | SRC_PE | SRC_OVR)) {
  530                         uart_setreg(bas, REG_CTRL, CR_RSTERR);
  531                         uart_barrier(bas);
  532                 }
  533                 bes = uart_getmreg(bas, RR_BES);
  534         }
  535         mtx_unlock_spin(&sc->sc_hwmtx);
  536         return (0);
  537 }
  538 
  539 static int
  540 z8530_bus_setsig(struct uart_softc *sc, int sig)
  541 {
  542         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  543         struct uart_bas *bas;
  544         uint32_t new, old;
  545 
  546         bas = &sc->sc_bas;
  547         do {
  548                 old = sc->sc_hwsig;
  549                 new = old;
  550                 if (sig & SER_DDTR) {
  551                         SIGCHG(sig & SER_DTR, new, SER_DTR,
  552                             SER_DDTR);
  553                 }
  554                 if (sig & SER_DRTS) {
  555                         SIGCHG(sig & SER_RTS, new, SER_RTS,
  556                             SER_DRTS);
  557                 }
  558         } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new));
  559 
  560         mtx_lock_spin(&sc->sc_hwmtx);
  561         if (new & SER_DTR)
  562                 z8530->tpc |= TPC_DTR;
  563         else
  564                 z8530->tpc &= ~TPC_DTR;
  565         if (new & SER_RTS)
  566                 z8530->tpc |= TPC_RTS;
  567         else
  568                 z8530->tpc &= ~TPC_RTS;
  569         uart_setmreg(bas, WR_TPC, z8530->tpc);
  570         uart_barrier(bas);
  571         mtx_unlock_spin(&sc->sc_hwmtx);
  572         return (0);
  573 }
  574 
  575 static int
  576 z8530_bus_transmit(struct uart_softc *sc)
  577 {
  578         struct z8530_softc *z8530 = (struct z8530_softc*)sc;
  579         struct uart_bas *bas;
  580 
  581         bas = &sc->sc_bas;
  582         mtx_lock_spin(&sc->sc_hwmtx);
  583         while (!(uart_getmreg(bas, RR_BES) & BES_TXE))
  584                 ;
  585         uart_setreg(bas, REG_DATA, sc->sc_txbuf[0]);
  586         uart_barrier(bas);
  587         sc->sc_txbusy = 1;
  588         z8530->txidle = 1;      /* Report UART_IPEND_TXIDLE again. */
  589         mtx_unlock_spin(&sc->sc_hwmtx);
  590         return (0);
  591 }

Cache object: 6a087ffcfa1e53f09e92a6d3f5f0cca4


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