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/altera/jtag_uart/altera_jtag_uart_tty.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2011-2012, 2016 Robert N. M. Watson
    5  * All rights reserved.
    6  *
    7  * This software was developed by SRI International and the University of
    8  * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
    9  * ("CTSRD"), as part of the DARPA CRASH research programme.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   30  * SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD$");
   35 
   36 #include <sys/param.h>
   37 #include <sys/bus.h>
   38 #include <sys/cons.h>
   39 #include <sys/endian.h>
   40 #include <sys/kdb.h>
   41 #include <sys/rman.h>
   42 #include <sys/systm.h>
   43 #include <sys/kernel.h>
   44 #include <sys/reboot.h>
   45 #include <sys/sysctl.h>
   46 #include <sys/tty.h>
   47 
   48 #include <ddb/ddb.h>
   49 
   50 #include <machine/atomic.h>
   51 #include <machine/bus.h>
   52 
   53 #include <dev/altera/jtag_uart/altera_jtag_uart.h>
   54 
   55 /*
   56  * If one of the Altera JTAG UARTs is currently the system console, register
   57  * it here.
   58  */
   59 static struct altera_jtag_uart_softc    *aju_cons_sc;
   60 
   61 static tsw_outwakeup_t  aju_outwakeup;
   62 static void             aju_ac_callout(void *);
   63 static void             aju_io_callout(void *);
   64 
   65 static struct ttydevsw aju_ttydevsw = {
   66         .tsw_flags      = TF_NOPREFIX,
   67         .tsw_outwakeup  = aju_outwakeup,
   68 };
   69 
   70 /*
   71  * When polling for the AC bit, the number of times we have to not see it
   72  * before assuming JTAG has disappeared on us.  By default, four seconds.
   73  */
   74 #define AJU_JTAG_MAXMISS                20
   75 
   76 /*
   77  * Polling intervals for input/output and JTAG connection events.
   78  */
   79 #define AJU_IO_POLLINTERVAL             (hz/100)
   80 #define AJU_AC_POLLINTERVAL             (hz/5)
   81 
   82 /*
   83  * Statistics on JTAG removal events when sending, for debugging purposes
   84  * only.
   85  */
   86 static u_int aju_jtag_vanished;
   87 SYSCTL_UINT(_debug, OID_AUTO, aju_jtag_vanished, CTLFLAG_RW,
   88     &aju_jtag_vanished, 0, "Number of times JTAG has vanished");
   89 
   90 static u_int aju_jtag_appeared;
   91 SYSCTL_UINT(_debug, OID_AUTO, aju_jtag_appeared, CTLFLAG_RW,
   92     &aju_jtag_appeared, 0, "Number of times JTAG has appeared");
   93 
   94 SYSCTL_INT(_debug, OID_AUTO, aju_cons_jtag_present, CTLFLAG_RW,
   95     &aju_cons_jtag_present, 0, "JTAG console present flag");
   96 
   97 SYSCTL_UINT(_debug, OID_AUTO, aju_cons_jtag_missed, CTLFLAG_RW,
   98     &aju_cons_jtag_missed, 0, "JTAG console missed counter");
   99 
  100 /*
  101  * Interrupt-related statistics.
  102  */
  103 static u_int aju_intr_readable_enabled;
  104 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_readable_enabled, CTLFLAG_RW,
  105     &aju_intr_readable_enabled, 0, "Number of times read interrupt enabled");
  106 
  107 static u_int aju_intr_writable_disabled;
  108 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_writable_disabled, CTLFLAG_RW,
  109     &aju_intr_writable_disabled, 0,
  110     "Number of times write interrupt disabled");
  111 
  112 static u_int aju_intr_writable_enabled;
  113 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_writable_enabled, CTLFLAG_RW,
  114     &aju_intr_writable_enabled, 0,
  115     "Number of times write interrupt enabled");
  116 
  117 static u_int aju_intr_disabled;
  118 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_disabled, CTLFLAG_RW,
  119     &aju_intr_disabled, 0, "Number of times write interrupt disabled");
  120 
  121 static u_int aju_intr_read_count;
  122 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_read_count, CTLFLAG_RW,
  123     &aju_intr_read_count, 0, "Number of times read interrupt fired");
  124 
  125 static u_int aju_intr_write_count;
  126 SYSCTL_UINT(_debug, OID_AUTO, aju_intr_write_count, CTLFLAG_RW,
  127     &aju_intr_write_count, 0, "Number of times write interrupt fired");
  128 
  129 /*
  130  * Low-level read and write register routines; the Altera UART is little
  131  * endian, so we byte swap 32-bit reads and writes.
  132  */
  133 static inline uint32_t
  134 aju_data_read(struct altera_jtag_uart_softc *sc)
  135 {
  136 
  137         return (le32toh(bus_read_4(sc->ajus_mem_res,
  138             ALTERA_JTAG_UART_DATA_OFF)));
  139 }
  140 
  141 static inline void
  142 aju_data_write(struct altera_jtag_uart_softc *sc, uint32_t v)
  143 {
  144 
  145         bus_write_4(sc->ajus_mem_res, ALTERA_JTAG_UART_DATA_OFF, htole32(v));
  146 }
  147 
  148 static inline uint32_t
  149 aju_control_read(struct altera_jtag_uart_softc *sc)
  150 {
  151 
  152         return (le32toh(bus_read_4(sc->ajus_mem_res,
  153             ALTERA_JTAG_UART_CONTROL_OFF)));
  154 }
  155 
  156 static inline void
  157 aju_control_write(struct altera_jtag_uart_softc *sc, uint32_t v)
  158 {
  159 
  160         bus_write_4(sc->ajus_mem_res, ALTERA_JTAG_UART_CONTROL_OFF,
  161             htole32(v));
  162 }
  163 
  164 /*
  165  * Slightly higher-level routines aware of buffering and flow control.
  166  */
  167 static inline int
  168 aju_writable(struct altera_jtag_uart_softc *sc)
  169 {
  170 
  171         return ((aju_control_read(sc) &
  172             ALTERA_JTAG_UART_CONTROL_WSPACE) != 0);
  173 }
  174 
  175 static inline int
  176 aju_readable(struct altera_jtag_uart_softc *sc)
  177 {
  178         uint32_t v;
  179 
  180         AJU_LOCK_ASSERT(sc);
  181 
  182         if (*sc->ajus_buffer_validp)
  183                 return (1);
  184         v = aju_data_read(sc);
  185         if ((v & ALTERA_JTAG_UART_DATA_RVALID) != 0) {
  186                 *sc->ajus_buffer_validp = 1;
  187                 *sc->ajus_buffer_datap = (v & ALTERA_JTAG_UART_DATA_DATA);
  188                 return (1);
  189         }
  190         return (0);
  191 }
  192 
  193 static char
  194 aju_read(struct altera_jtag_uart_softc *sc)
  195 {
  196 
  197         AJU_LOCK_ASSERT(sc);
  198 
  199         while (!aju_readable(sc));
  200         *sc->ajus_buffer_validp = 0;
  201         return (*sc->ajus_buffer_datap);
  202 }
  203 
  204 /*
  205  * Routines for enabling and disabling interrupts for read and write.
  206  */
  207 static void
  208 aju_intr_readable_enable(struct altera_jtag_uart_softc *sc)
  209 {
  210         uint32_t v;
  211 
  212         AJU_LOCK_ASSERT(sc);
  213 
  214         atomic_add_int(&aju_intr_readable_enabled, 1);
  215         v = aju_control_read(sc);
  216         v |= ALTERA_JTAG_UART_CONTROL_RE;
  217         aju_control_write(sc, v);
  218 }
  219 
  220 static void
  221 aju_intr_writable_enable(struct altera_jtag_uart_softc *sc)
  222 {
  223         uint32_t v;
  224 
  225         AJU_LOCK_ASSERT(sc);
  226 
  227         atomic_add_int(&aju_intr_writable_enabled, 1);
  228         v = aju_control_read(sc);
  229         v |= ALTERA_JTAG_UART_CONTROL_WE;
  230         aju_control_write(sc, v);
  231 }
  232 
  233 static void
  234 aju_intr_writable_disable(struct altera_jtag_uart_softc *sc)
  235 {
  236         uint32_t v;
  237 
  238         AJU_LOCK_ASSERT(sc);
  239 
  240         atomic_add_int(&aju_intr_writable_disabled, 1);
  241         v = aju_control_read(sc);
  242         v &= ~ALTERA_JTAG_UART_CONTROL_WE;
  243         aju_control_write(sc, v);
  244 }
  245 
  246 static void
  247 aju_intr_disable(struct altera_jtag_uart_softc *sc)
  248 {
  249         uint32_t v;
  250 
  251         AJU_LOCK_ASSERT(sc);
  252 
  253         atomic_add_int(&aju_intr_disabled, 1);
  254         v = aju_control_read(sc);
  255         v &= ~(ALTERA_JTAG_UART_CONTROL_RE | ALTERA_JTAG_UART_CONTROL_WE);
  256         aju_control_write(sc, v);
  257 }
  258 
  259 /*
  260  * The actual work of checking for, and handling, available reads.  This is
  261  * used in both polled and interrupt-driven modes, as JTAG UARTs may be hooked
  262  * up with, or without, IRQs allocated.
  263  */
  264 static void
  265 aju_handle_input(struct altera_jtag_uart_softc *sc, struct tty *tp)
  266 {
  267         int c;
  268 
  269         tty_assert_locked(tp);
  270         AJU_LOCK_ASSERT(sc);
  271 
  272         while (aju_readable(sc)) {
  273                 c = aju_read(sc);
  274                 AJU_UNLOCK(sc);
  275 #ifdef KDB
  276                 if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE)
  277                         kdb_alt_break(c, &sc->ajus_alt_break_state);
  278 #endif
  279                 ttydisc_rint(tp, c, 0);
  280                 AJU_LOCK(sc);
  281         }
  282         AJU_UNLOCK(sc);
  283         ttydisc_rint_done(tp);
  284         AJU_LOCK(sc);
  285 }
  286 
  287 /*
  288  * Send output to the UART until either there's none left to send, or we run
  289  * out of room and need to await an interrupt so that we can start sending
  290  * again.
  291  *
  292  * XXXRW: It would be nice to query WSPACE at the beginning and write to the
  293  * FIFO in bugger chunks.
  294  */
  295 static void
  296 aju_handle_output(struct altera_jtag_uart_softc *sc, struct tty *tp)
  297 {
  298         uint32_t v;
  299         uint8_t ch;
  300 
  301         tty_assert_locked(tp);
  302         AJU_LOCK_ASSERT(sc);
  303 
  304         AJU_UNLOCK(sc);
  305         while (ttydisc_getc_poll(tp) != 0) {
  306                 AJU_LOCK(sc);
  307                 if (*sc->ajus_jtag_presentp == 0) {
  308                         /*
  309                          * If JTAG is not present, then we will drop this
  310                          * character instead of perhaps scheduling an
  311                          * interrupt to let us know when there is buffer
  312                          * space.  Otherwise we might get a write interrupt
  313                          * later even though we aren't interested in sending
  314                          * anymore.  Loop to drain TTY-layer buffer.
  315                          */
  316                         AJU_UNLOCK(sc);
  317                         if (ttydisc_getc(tp, &ch, sizeof(ch)) !=
  318                             sizeof(ch))
  319                                 panic("%s: ttydisc_getc", __func__);
  320                         continue;
  321                 }
  322                 v = aju_control_read(sc);
  323                 if ((v & ALTERA_JTAG_UART_CONTROL_WSPACE) == 0) {
  324                         if (sc->ajus_irq_res != NULL &&
  325                             (v & ALTERA_JTAG_UART_CONTROL_WE) == 0)
  326                                 aju_intr_writable_enable(sc);
  327                         return;
  328                 }
  329                 AJU_UNLOCK(sc);
  330                 if (ttydisc_getc(tp, &ch, sizeof(ch)) != sizeof(ch))
  331                         panic("%s: ttydisc_getc 2", __func__);
  332                 AJU_LOCK(sc);
  333 
  334                 /*
  335                  * XXXRW: There is a slight race here in which we test for
  336                  * writability, drop the lock, get the character from the tty
  337                  * layer, re-acquire the lock, and then write.  It's possible
  338                  * for other code -- specifically, the low-level console -- to
  339                  * have* written in the mean time, which might mean that there
  340                  * is no longer space.  The BERI memory bus will cause this
  341                  * write to block, wedging the processor until space is
  342                  * available -- which could be a while if JTAG is not
  343                  * attached!
  344                  *
  345                  * The 'easy' fix is to drop the character if WSPACE has
  346                  * become unset.  Not sure what the 'hard' fix is.
  347                  */
  348                 aju_data_write(sc, ch);
  349                 AJU_UNLOCK(sc);
  350         }
  351         AJU_LOCK(sc);
  352 
  353         /*
  354          * If interrupts are configured, and there's no data to write, but we
  355          * had previously enabled write interrupts, disable them now.
  356          */
  357         v = aju_control_read(sc);
  358         if (sc->ajus_irq_res != NULL && (v & ALTERA_JTAG_UART_CONTROL_WE) != 0)
  359                 aju_intr_writable_disable(sc);
  360 }
  361 
  362 static void
  363 aju_outwakeup(struct tty *tp)
  364 {
  365         struct altera_jtag_uart_softc *sc = tty_softc(tp);
  366 
  367         tty_assert_locked(tp);
  368 
  369         AJU_LOCK(sc);
  370         aju_handle_output(sc, tp);
  371         AJU_UNLOCK(sc);
  372 }
  373 
  374 static void
  375 aju_io_callout(void *arg)
  376 {
  377         struct altera_jtag_uart_softc *sc = arg;
  378         struct tty *tp = sc->ajus_ttyp;
  379 
  380         tty_lock(tp);
  381         AJU_LOCK(sc);
  382 
  383         /*
  384          * It would be convenient if we could share code with aju_intr() here
  385          * by testing the control register for ALTERA_JTAG_UART_CONTROL_RI and
  386          * ALTERA_JTAG_UART_CONTROL_WI.  Unfortunately, it's not clear that
  387          * this is supported, so do all the work to poll for both input and
  388          * output.
  389          */
  390         aju_handle_input(sc, tp);
  391         aju_handle_output(sc, tp);
  392 
  393         /*
  394          * Reschedule next poll attempt.  There's some argument that we should
  395          * do adaptive polling based on the expectation of I/O: is something
  396          * pending in the output buffer, or have we recently had input, but we
  397          * don't.
  398          */
  399         callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL,
  400             aju_io_callout, sc);
  401         AJU_UNLOCK(sc);
  402         tty_unlock(tp);
  403 }
  404 
  405 static void
  406 aju_ac_callout(void *arg)
  407 {
  408         struct altera_jtag_uart_softc *sc = arg;
  409         struct tty *tp = sc->ajus_ttyp;
  410         uint32_t v;
  411 
  412         tty_lock(tp);
  413         AJU_LOCK(sc);
  414         v = aju_control_read(sc);
  415         if (v & ALTERA_JTAG_UART_CONTROL_AC) {
  416                 v &= ~ALTERA_JTAG_UART_CONTROL_AC;
  417                 aju_control_write(sc, v);
  418                 if (*sc->ajus_jtag_presentp == 0) {
  419                         *sc->ajus_jtag_presentp = 1;
  420                         atomic_add_int(&aju_jtag_appeared, 1);
  421                         aju_handle_output(sc, tp);
  422                 }
  423 
  424                 /* Any hit eliminates all recent misses. */
  425                 *sc->ajus_jtag_missedp = 0;
  426         } else if (*sc->ajus_jtag_presentp != 0) {
  427                 /*
  428                  * If we've exceeded our tolerance for misses, mark JTAG as
  429                  * disconnected and drain output.  Otherwise, bump the miss
  430                  * counter.
  431                  */
  432                 if (*sc->ajus_jtag_missedp > AJU_JTAG_MAXMISS) {
  433                         *sc->ajus_jtag_presentp = 0;
  434                         atomic_add_int(&aju_jtag_vanished, 1);
  435                         aju_handle_output(sc, tp);
  436                 } else
  437                         (*sc->ajus_jtag_missedp)++;
  438         }
  439         callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL,
  440             aju_ac_callout, sc);
  441         AJU_UNLOCK(sc);
  442         tty_unlock(tp);
  443 }
  444 
  445 static void
  446 aju_intr(void *arg)
  447 {
  448         struct altera_jtag_uart_softc *sc = arg;
  449         struct tty *tp = sc->ajus_ttyp;
  450         uint32_t v;
  451 
  452         tty_lock(tp);
  453         AJU_LOCK(sc);
  454         v = aju_control_read(sc);
  455         if (v & ALTERA_JTAG_UART_CONTROL_RI) {
  456                 atomic_add_int(&aju_intr_read_count, 1);
  457                 aju_handle_input(sc, tp);
  458         }
  459         if (v & ALTERA_JTAG_UART_CONTROL_WI) {
  460                 atomic_add_int(&aju_intr_write_count, 1);
  461                 aju_handle_output(sc, tp);
  462         }
  463         AJU_UNLOCK(sc);
  464         tty_unlock(tp);
  465 }
  466 
  467 int
  468 altera_jtag_uart_attach(struct altera_jtag_uart_softc *sc)
  469 {
  470         struct tty *tp;
  471         int error;
  472 
  473         AJU_LOCK_INIT(sc);
  474 
  475         /*
  476          * XXXRW: Currently, we detect the console solely based on it using a
  477          * reserved address, and borrow console-level locks and buffer if so.
  478          * Is there a better way?
  479          */
  480         if (rman_get_start(sc->ajus_mem_res) == BERI_UART_BASE) {
  481                 sc->ajus_lockp = &aju_cons_lock;
  482                 sc->ajus_buffer_validp = &aju_cons_buffer_valid;
  483                 sc->ajus_buffer_datap = &aju_cons_buffer_data;
  484                 sc->ajus_jtag_presentp = &aju_cons_jtag_present;
  485                 sc->ajus_jtag_missedp = &aju_cons_jtag_missed;
  486                 sc->ajus_flags |= ALTERA_JTAG_UART_FLAG_CONSOLE;
  487         } else {
  488                 sc->ajus_lockp = &sc->ajus_lock;
  489                 sc->ajus_buffer_validp = &sc->ajus_buffer_valid;
  490                 sc->ajus_buffer_datap = &sc->ajus_buffer_data;
  491                 sc->ajus_jtag_presentp = &sc->ajus_jtag_present;
  492                 sc->ajus_jtag_missedp = &sc->ajus_jtag_missed;
  493         }
  494 
  495         /*
  496          * Disable interrupts regardless of whether or not we plan to use
  497          * them.  We will register an interrupt handler now if they will be
  498          * used, but not re-enable intil later once the remainder of the tty
  499          * layer is properly initialised, as we're not ready for input yet.
  500          */
  501         AJU_LOCK(sc);
  502         aju_intr_disable(sc);
  503         AJU_UNLOCK(sc);
  504         if (sc->ajus_irq_res != NULL) {
  505                 error = bus_setup_intr(sc->ajus_dev, sc->ajus_irq_res,
  506                     INTR_ENTROPY | INTR_TYPE_TTY | INTR_MPSAFE, NULL,
  507                     aju_intr, sc, &sc->ajus_irq_cookie);
  508                 if (error) {
  509                         device_printf(sc->ajus_dev,
  510                             "could not activate interrupt\n");
  511                         AJU_LOCK_DESTROY(sc);
  512                         return (error);
  513                 }
  514         }
  515         tp = sc->ajus_ttyp = tty_alloc(&aju_ttydevsw, sc);
  516         if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE) {
  517                 aju_cons_sc = sc;
  518                 tty_init_console(tp, 0);
  519         }
  520         tty_makedev(tp, NULL, "%s%d", AJU_TTYNAME, sc->ajus_unit);
  521 
  522         /*
  523          * If we will be using interrupts, enable them now; otherwise, start
  524          * polling.  From this point onwards, input can arrive.
  525          */
  526         if (sc->ajus_irq_res != NULL) {
  527                 AJU_LOCK(sc);
  528                 aju_intr_readable_enable(sc);
  529                 AJU_UNLOCK(sc);
  530         } else {
  531                 callout_init(&sc->ajus_io_callout, 1);
  532                 callout_reset(&sc->ajus_io_callout, AJU_IO_POLLINTERVAL,
  533                     aju_io_callout, sc);
  534         }
  535         callout_init(&sc->ajus_ac_callout, 1);
  536         callout_reset(&sc->ajus_ac_callout, AJU_AC_POLLINTERVAL,
  537             aju_ac_callout, sc);
  538         return (0);
  539 }
  540 
  541 void
  542 altera_jtag_uart_detach(struct altera_jtag_uart_softc *sc)
  543 {
  544         struct tty *tp = sc->ajus_ttyp;
  545 
  546         /*
  547          * If we're using interrupts, disable and release the interrupt
  548          * handler now.  Otherwise drain the polling timeout.
  549          */
  550         if (sc->ajus_irq_res != NULL) {
  551                 AJU_LOCK(sc);
  552                 aju_intr_disable(sc);
  553                 AJU_UNLOCK(sc);
  554                 bus_teardown_intr(sc->ajus_dev, sc->ajus_irq_res,
  555                     sc->ajus_irq_cookie);
  556         } else
  557                 callout_drain(&sc->ajus_io_callout);
  558         callout_drain(&sc->ajus_ac_callout);
  559         if (sc->ajus_flags & ALTERA_JTAG_UART_FLAG_CONSOLE)
  560                 aju_cons_sc = NULL;
  561         tty_lock(tp);
  562         tty_rel_gone(tp);
  563         AJU_LOCK_DESTROY(sc);
  564 }

Cache object: 7749983dde5c633843ade26900a1c3ef


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