uart_core.c revision 285619
1116518Sphk/*- 2116518Sphk * Copyright (c) 2003 Marcel Moolenaar 3116518Sphk * All rights reserved. 4116518Sphk * 5116518Sphk * Redistribution and use in source and binary forms, with or without 6116518Sphk * modification, are permitted provided that the following conditions 7116518Sphk * are met: 8116518Sphk * 9116518Sphk * 1. Redistributions of source code must retain the above copyright 10116518Sphk * notice, this list of conditions and the following disclaimer. 11116518Sphk * 2. Redistributions in binary form must reproduce the above copyright 12116518Sphk * notice, this list of conditions and the following disclaimer in the 13116518Sphk * documentation and/or other materials provided with the distribution. 14116518Sphk * 15116518Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16116518Sphk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17116518Sphk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18116518Sphk * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19116518Sphk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20116518Sphk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21116518Sphk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22116518Sphk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23116518Sphk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24116518Sphk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25116518Sphk */ 26116518Sphk 27116518Sphk#include <sys/cdefs.h> 28116518Sphk__FBSDID("$FreeBSD: head/sys/dev/uart/uart_core.c 285619 2015-07-16 04:15:22Z neel $"); 29116518Sphk 30116518Sphk#include <sys/param.h> 31116518Sphk#include <sys/systm.h> 32116518Sphk#include <sys/bus.h> 33116518Sphk#include <sys/conf.h> 34116518Sphk#include <sys/cons.h> 35116518Sphk#include <sys/fcntl.h> 36116518Sphk#include <sys/interrupt.h> 37116518Sphk#include <sys/kdb.h> 38116518Sphk#include <sys/kernel.h> 39116518Sphk#include <sys/malloc.h> 40116518Sphk#include <sys/queue.h> 41116518Sphk#include <sys/reboot.h> 42116518Sphk#include <sys/sysctl.h> 43116518Sphk#include <machine/bus.h> 44116518Sphk#include <sys/rman.h> 45116518Sphk#include <machine/resource.h> 46116518Sphk#include <machine/stdarg.h> 47116518Sphk 48116518Sphk#include <dev/uart/uart.h> 49116518Sphk#include <dev/uart/uart_bus.h> 50116518Sphk#include <dev/uart/uart_cpu.h> 51116518Sphk 52116518Sphk#include "uart_if.h" 53116518Sphk 54116518Sphkdevclass_t uart_devclass; 55116518Sphkchar uart_driver_name[] = "uart"; 56116518Sphk 57116518SphkSLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs = 58116518Sphk SLIST_HEAD_INITIALIZER(uart_sysdevs); 59116518Sphk 60116518Sphkstatic MALLOC_DEFINE(M_UART, "UART", "UART driver"); 61116518Sphk 62116518Sphk#ifndef UART_POLL_FREQ 63116518Sphk#define UART_POLL_FREQ 50 64116518Sphk#endif 65116518Sphkstatic int uart_poll_freq = UART_POLL_FREQ; 66116518SphkSYSCTL_INT(_debug, OID_AUTO, uart_poll_freq, CTLFLAG_RDTUN, &uart_poll_freq, 67116518Sphk 0, "UART poll frequency"); 68116518Sphk 69116518Sphkstatic int uart_force_poll; 70116518SphkSYSCTL_INT(_debug, OID_AUTO, uart_force_poll, CTLFLAG_RDTUN, &uart_force_poll, 71116518Sphk 0, "Force UART polling"); 72116518Sphk 73116518Sphkvoid 74116518Sphkuart_add_sysdev(struct uart_devinfo *di) 75116518Sphk{ 76116518Sphk SLIST_INSERT_HEAD(&uart_sysdevs, di, next); 77116518Sphk} 78116518Sphk 79116518Sphkconst char * 80116518Sphkuart_getname(struct uart_class *uc) 81116518Sphk{ 82116518Sphk return ((uc != NULL) ? uc->name : NULL); 83116518Sphk} 84116518Sphk 85116518Sphkstruct uart_ops * 86116518Sphkuart_getops(struct uart_class *uc) 87116518Sphk{ 88116518Sphk return ((uc != NULL) ? uc->uc_ops : NULL); 89116518Sphk} 90116518Sphk 91116518Sphkint 92116518Sphkuart_getrange(struct uart_class *uc) 93125755Sphk{ 94116518Sphk return ((uc != NULL) ? uc->uc_range : 0); 95116518Sphk} 96116518Sphk 97116518Sphku_int 98116518Sphkuart_getregshift(struct uart_class *uc) 99125755Sphk{ 100116518Sphk return ((uc != NULL) ? uc->uc_rshift : 0); 101116518Sphk} 102116518Sphk 103116518Sphk/* 104116518Sphk * Schedule a soft interrupt. We do this on the 0 to !0 transition 105116518Sphk * of the TTY pending interrupt status. 106116518Sphk */ 107116518Sphkvoid 108116518Sphkuart_sched_softih(struct uart_softc *sc, uint32_t ipend) 109116518Sphk{ 110116518Sphk uint32_t new, old; 111116518Sphk 112116518Sphk do { 113116518Sphk old = sc->sc_ttypend; 114116518Sphk new = old | ipend; 115116518Sphk } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); 116116518Sphk 117116518Sphk if ((old & SER_INT_MASK) == 0) 118116518Sphk swi_sched(sc->sc_softih, 0); 119116518Sphk} 120116518Sphk 121116518Sphk/* 122116518Sphk * A break condition has been detected. We treat the break condition as 123116518Sphk * a special case that should not happen during normal operation. When 124116518Sphk * the break condition is to be passed to higher levels in the form of 125116518Sphk * a NUL character, we really want the break to be in the right place in 126116518Sphk * the input stream. The overhead to achieve that is not in relation to 127116518Sphk * the exceptional nature of the break condition, so we permit ourselves 128116518Sphk * to be sloppy. 129116518Sphk */ 130116518Sphkstatic __inline int 131116518Sphkuart_intr_break(void *arg) 132116518Sphk{ 133125755Sphk struct uart_softc *sc = arg; 134116518Sphk 135116518Sphk#if defined(KDB) 136116518Sphk if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 137116518Sphk if (kdb_break()) 138116518Sphk return (0); 139116518Sphk } 140116518Sphk#endif 141116518Sphk if (sc->sc_opened) 142116518Sphk uart_sched_softih(sc, SER_INT_BREAK); 143116518Sphk return (0); 144116518Sphk} 145116518Sphk 146116518Sphk/* 147116518Sphk * Handle a receiver overrun situation. We lost at least 1 byte in the 148116518Sphk * input stream and it's our job to contain the situation. We grab as 149116518Sphk * much of the data we can, but otherwise flush the receiver FIFO to 150116518Sphk * create some breathing room. The net effect is that we avoid the 151116518Sphk * overrun condition to happen for the next X characters, where X is 152116518Sphk * related to the FIFO size at the cost of losing data right away. 153116518Sphk * So, instead of having multiple overrun interrupts in close proximity 154116518Sphk * to each other and possibly pessimizing UART interrupt latency for 155116518Sphk * other UARTs in a multiport configuration, we create a longer segment 156116518Sphk * of missing characters by freeing up the FIFO. 157116518Sphk * Each overrun condition is marked in the input buffer by a token. The 158116518Sphk * token represents the loss of at least one, but possible more bytes in 159116518Sphk * the input stream. 160116518Sphk */ 161116518Sphkstatic __inline int 162116518Sphkuart_intr_overrun(void *arg) 163116518Sphk{ 164116518Sphk struct uart_softc *sc = arg; 165116518Sphk 166116518Sphk if (sc->sc_opened) { 167116518Sphk UART_RECEIVE(sc); 168116518Sphk if (uart_rx_put(sc, UART_STAT_OVERRUN)) 169116518Sphk sc->sc_rxbuf[sc->sc_rxput] = UART_STAT_OVERRUN; 170116518Sphk uart_sched_softih(sc, SER_INT_RXREADY); 171116518Sphk } 172116518Sphk UART_FLUSH(sc, UART_FLUSH_RECEIVER); 173116518Sphk return (0); 174116518Sphk} 175116518Sphk 176116518Sphk/* 177116518Sphk * Received data ready. 178116518Sphk */ 179116518Sphkstatic __inline int 180116518Sphkuart_intr_rxready(void *arg) 181116518Sphk{ 182125755Sphk struct uart_softc *sc = arg; 183116518Sphk int rxp; 184116518Sphk 185116518Sphk rxp = sc->sc_rxput; 186116518Sphk UART_RECEIVE(sc); 187116518Sphk#if defined(KDB) 188116518Sphk if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) { 189116518Sphk while (rxp != sc->sc_rxput) { 190116518Sphk kdb_alt_break(sc->sc_rxbuf[rxp++], &sc->sc_altbrk); 191116518Sphk if (rxp == sc->sc_rxbufsz) 192116518Sphk rxp = 0; 193121366Sphk } 194116518Sphk } 195116518Sphk#endif 196116518Sphk if (sc->sc_opened) 197116518Sphk uart_sched_softih(sc, SER_INT_RXREADY); 198116518Sphk else 199116518Sphk sc->sc_rxput = sc->sc_rxget; /* Ignore received data. */ 200116518Sphk return (1); 201116518Sphk} 202116518Sphk 203116518Sphk/* 204116518Sphk * Line or modem status change (OOB signalling). 205116518Sphk * We pass the signals to the software interrupt handler for further 206116518Sphk * processing. Note that we merge the delta bits, but set the state 207116518Sphk * bits. This is to avoid losing state transitions due to having more 208116518Sphk * than 1 hardware interrupt between software interrupts. 209116518Sphk */ 210116518Sphkstatic __inline int 211116518Sphkuart_intr_sigchg(void *arg) 212116518Sphk{ 213116518Sphk struct uart_softc *sc = arg; 214116518Sphk int new, old, sig; 215116518Sphk 216116518Sphk sig = UART_GETSIG(sc); 217116518Sphk 218116518Sphk if (sc->sc_pps.ppsparam.mode & PPS_CAPTUREBOTH) { 219116518Sphk if (sig & UART_SIG_DPPS) { 220116518Sphk pps_capture(&sc->sc_pps); 221116518Sphk pps_event(&sc->sc_pps, (sig & UART_SIG_PPS) ? 222116518Sphk PPS_CAPTUREASSERT : PPS_CAPTURECLEAR); 223116518Sphk } 224116518Sphk } 225116518Sphk 226116518Sphk /* 227116518Sphk * Keep track of signal changes, even when the device is not 228116518Sphk * opened. This allows us to inform upper layers about a 229116518Sphk * possible loss of DCD and thus the existence of a (possibly) 230116518Sphk * different connection when we have DCD back, during the time 231116518Sphk * that the device was closed. 232116518Sphk */ 233116518Sphk do { 234116518Sphk old = sc->sc_ttypend; 235116518Sphk new = old & ~SER_MASK_STATE; 236116518Sphk new |= sig & SER_INT_SIGMASK; 237116518Sphk } while (!atomic_cmpset_32(&sc->sc_ttypend, old, new)); 238116518Sphk 239116518Sphk if (sc->sc_opened) 240116518Sphk uart_sched_softih(sc, SER_INT_SIGCHG); 241116518Sphk return (1); 242116518Sphk} 243116518Sphk 244116518Sphk/* 245116518Sphk * The transmitter can accept more data. 246116518Sphk */ 247116518Sphkstatic __inline int 248116518Sphkuart_intr_txidle(void *arg) 249116518Sphk{ 250116518Sphk struct uart_softc *sc = arg; 251116518Sphk 252116518Sphk if (sc->sc_txbusy) { 253116518Sphk sc->sc_txbusy = 0; 254116518Sphk uart_sched_softih(sc, SER_INT_TXIDLE); 255116518Sphk } 256116518Sphk return (0); 257116518Sphk} 258116518Sphk 259116518Sphkstatic int 260116518Sphkuart_intr(void *arg) 261116518Sphk{ 262116518Sphk struct uart_softc *sc = arg; 263116518Sphk int cnt, ipend; 264116518Sphk 265116518Sphk if (sc->sc_leaving) 266116518Sphk return (FILTER_STRAY); 267116518Sphk 268116518Sphk cnt = 0; 269116518Sphk while (cnt < 20 && (ipend = UART_IPEND(sc)) != 0) { 270116518Sphk cnt++; 271116518Sphk if (ipend & SER_INT_OVERRUN) 272116518Sphk uart_intr_overrun(sc); 273116518Sphk if (ipend & SER_INT_BREAK) 274116518Sphk uart_intr_break(sc); 275116518Sphk if (ipend & SER_INT_RXREADY) 276116518Sphk uart_intr_rxready(sc); 277116518Sphk if (ipend & SER_INT_SIGCHG) 278116518Sphk uart_intr_sigchg(sc); 279116518Sphk if (ipend & SER_INT_TXIDLE) 280116518Sphk uart_intr_txidle(sc); 281116518Sphk } 282116518Sphk 283116518Sphk if (sc->sc_polled) { 284116518Sphk callout_reset(&sc->sc_timer, hz / uart_poll_freq, 285116518Sphk (timeout_t *)uart_intr, sc); 286116518Sphk } 287116518Sphk 288116518Sphk return ((cnt == 0) ? FILTER_STRAY : 289116518Sphk ((cnt == 20) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED)); 290116518Sphk} 291116518Sphk 292116518Sphkserdev_intr_t * 293116518Sphkuart_bus_ihand(device_t dev, int ipend) 294116518Sphk{ 295116518Sphk 296116518Sphk switch (ipend) { 297116518Sphk case SER_INT_BREAK: 298116518Sphk return (uart_intr_break); 299116518Sphk case SER_INT_OVERRUN: 300116518Sphk return (uart_intr_overrun); 301116518Sphk case SER_INT_RXREADY: 302125755Sphk return (uart_intr_rxready); 303116518Sphk case SER_INT_SIGCHG: 304116518Sphk return (uart_intr_sigchg); 305116518Sphk case SER_INT_TXIDLE: 306116518Sphk return (uart_intr_txidle); 307116518Sphk } 308116518Sphk return (NULL); 309116518Sphk} 310116518Sphk 311116518Sphkint 312125755Sphkuart_bus_ipend(device_t dev) 313116518Sphk{ 314116518Sphk struct uart_softc *sc; 315116518Sphk 316116518Sphk sc = device_get_softc(dev); 317116518Sphk return (UART_IPEND(sc)); 318116518Sphk} 319116518Sphk 320116518Sphkint 321116518Sphkuart_bus_sysdev(device_t dev) 322125755Sphk{ 323116518Sphk struct uart_softc *sc; 324116518Sphk 325116518Sphk sc = device_get_softc(dev); 326116518Sphk return ((sc->sc_sysdev != NULL) ? 1 : 0); 327116518Sphk} 328116518Sphk 329116518Sphkint 330116518Sphkuart_bus_probe(device_t dev, int regshft, int rclk, int rid, int chan) 331116518Sphk{ 332125755Sphk struct uart_softc *sc; 333116518Sphk struct uart_devinfo *sysdev; 334116518Sphk int error; 335116518Sphk 336116518Sphk sc = device_get_softc(dev); 337116518Sphk 338116518Sphk /* 339116518Sphk * All uart_class references are weak. Check that the needed 340116518Sphk * class has been compiled-in. Fail if not. 341116518Sphk */ 342116518Sphk if (sc->sc_class == NULL) 343116518Sphk return (ENXIO); 344116518Sphk 345116518Sphk /* 346116518Sphk * Initialize the instance. Note that the instance (=softc) does 347116518Sphk * not necessarily match the hardware specific softc. We can't do 348116518Sphk * anything about it now, because we may not attach to the device. 349116518Sphk * Hardware drivers cannot use any of the class specific fields 350116518Sphk * while probing. 351116518Sphk */ 352116518Sphk kobj_init((kobj_t)sc, (kobj_class_t)sc->sc_class); 353116518Sphk sc->sc_dev = dev; 354116518Sphk if (device_get_desc(dev) == NULL) 355116518Sphk device_set_desc(dev, uart_getname(sc->sc_class)); 356116518Sphk 357116518Sphk /* 358116518Sphk * Allocate the register resource. We assume that all UARTs have 359116518Sphk * a single register window in either I/O port space or memory 360116518Sphk * mapped I/O space. Any UART that needs multiple windows will 361116518Sphk * consequently not be supported by this driver as-is. We try I/O 362116518Sphk * port space first because that's the common case. 363125755Sphk */ 364116518Sphk sc->sc_rrid = rid; 365116518Sphk sc->sc_rtype = SYS_RES_IOPORT; 366116518Sphk sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 367116518Sphk 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE); 368116518Sphk if (sc->sc_rres == NULL) { 369116518Sphk sc->sc_rrid = rid; 370116518Sphk sc->sc_rtype = SYS_RES_MEMORY; 371116518Sphk sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, 372116518Sphk &sc->sc_rrid, 0, ~0, uart_getrange(sc->sc_class), 373116518Sphk RF_ACTIVE); 374116518Sphk if (sc->sc_rres == NULL) 375116518Sphk return (ENXIO); 376116518Sphk } 377116518Sphk 378116518Sphk /* 379116518Sphk * Fill in the bus access structure and compare this device with 380116518Sphk * a possible console device and/or a debug port. We set the flags 381116518Sphk * in the softc so that the hardware dependent probe can adjust 382116518Sphk * accordingly. In general, you don't want to permanently disrupt 383116518Sphk * console I/O. 384116518Sphk */ 385116518Sphk sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 386121475Sphk sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 387116518Sphk sc->sc_bas.chan = chan; 388116518Sphk sc->sc_bas.regshft = regshft; 389116518Sphk sc->sc_bas.rclk = (rclk == 0) ? sc->sc_class->uc_rclk : rclk; 390116518Sphk 391116518Sphk SLIST_FOREACH(sysdev, &uart_sysdevs, next) { 392116518Sphk if (chan == sysdev->bas.chan && 393116518Sphk uart_cpu_eqres(&sc->sc_bas, &sysdev->bas)) { 394116518Sphk /* XXX check if ops matches class. */ 395116518Sphk sc->sc_sysdev = sysdev; 396116518Sphk sysdev->bas.rclk = sc->sc_bas.rclk; 397116518Sphk } 398116518Sphk } 399116518Sphk 400116518Sphk error = UART_PROBE(sc); 401116518Sphk bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 402116518Sphk return ((error) ? error : BUS_PROBE_DEFAULT); 403116518Sphk} 404125755Sphk 405116518Sphkint 406116518Sphkuart_bus_attach(device_t dev) 407116518Sphk{ 408116518Sphk struct uart_softc *sc, *sc0; 409116518Sphk const char *sep; 410116518Sphk int error, filt; 411116518Sphk 412121475Sphk /* 413116518Sphk * The sc_class field defines the type of UART we're going to work 414116518Sphk * with and thus the size of the softc. Replace the generic softc 415116518Sphk * with one that matches the UART now that we're certain we handle 416116518Sphk * the device. 417116518Sphk */ 418116518Sphk sc0 = device_get_softc(dev); 419116518Sphk if (sc0->sc_class->size > sizeof(*sc)) { 420116518Sphk sc = malloc(sc0->sc_class->size, M_UART, M_WAITOK|M_ZERO); 421116518Sphk bcopy(sc0, sc, sizeof(*sc)); 422116518Sphk device_set_softc(dev, sc); 423116518Sphk } else 424116518Sphk sc = sc0; 425116518Sphk 426116518Sphk /* 427116518Sphk * Now that we know the softc for this device, connect the back 428116518Sphk * pointer from the sysdev for this device, if any 429116518Sphk */ 430116518Sphk if (sc->sc_sysdev != NULL) 431116518Sphk sc->sc_sysdev->sc = sc; 432116518Sphk 433116518Sphk /* 434116518Sphk * Protect ourselves against interrupts while we're not completely 435116518Sphk * finished attaching and initializing. We don't expect interrupts 436125755Sphk * until after UART_ATTACH() though. 437116518Sphk */ 438116518Sphk sc->sc_leaving = 1; 439116518Sphk 440116518Sphk mtx_init(&sc->sc_hwmtx_s, "uart_hwmtx", NULL, MTX_SPIN); 441116518Sphk if (sc->sc_hwmtx == NULL) 442116518Sphk sc->sc_hwmtx = &sc->sc_hwmtx_s; 443116518Sphk 444116518Sphk /* 445116518Sphk * Re-allocate. We expect that the softc contains the information 446116518Sphk * collected by uart_bus_probe() intact. 447116518Sphk */ 448116518Sphk sc->sc_rres = bus_alloc_resource(dev, sc->sc_rtype, &sc->sc_rrid, 449116518Sphk 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE); 450116518Sphk if (sc->sc_rres == NULL) { 451116518Sphk mtx_destroy(&sc->sc_hwmtx_s); 452116518Sphk return (ENXIO); 453116518Sphk } 454116518Sphk sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 455116518Sphk sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 456116518Sphk 457125538Sle /* 458116518Sphk * Ensure there is room for at least three full FIFOs of data in the 459116518Sphk * receive buffer (handles the case of low-level drivers with huge 460116518Sphk * FIFOs), and also ensure that there is no less than the historical 461116518Sphk * size of 384 bytes (handles the typical small-FIFO case). 462116518Sphk */ 463116518Sphk sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3); 464116518Sphk sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), 465116518Sphk M_UART, M_WAITOK); 466116518Sphk sc->sc_txbuf = malloc(sc->sc_txfifosz * sizeof(*sc->sc_txbuf), 467116518Sphk M_UART, M_WAITOK); 468116518Sphk 469 error = UART_ATTACH(sc); 470 if (error) 471 goto fail; 472 473 if (sc->sc_hwiflow || sc->sc_hwoflow) { 474 sep = ""; 475 device_print_prettyname(dev); 476 if (sc->sc_hwiflow) { 477 printf("%sRTS iflow", sep); 478 sep = ", "; 479 } 480 if (sc->sc_hwoflow) { 481 printf("%sCTS oflow", sep); 482 sep = ", "; 483 } 484 printf("\n"); 485 } 486 487 if (sc->sc_sysdev != NULL) { 488 if (sc->sc_sysdev->baudrate == 0) { 489 if (UART_IOCTL(sc, UART_IOCTL_BAUD, 490 (intptr_t)&sc->sc_sysdev->baudrate) != 0) 491 sc->sc_sysdev->baudrate = -1; 492 } 493 switch (sc->sc_sysdev->type) { 494 case UART_DEV_CONSOLE: 495 device_printf(dev, "console"); 496 break; 497 case UART_DEV_DBGPORT: 498 device_printf(dev, "debug port"); 499 break; 500 case UART_DEV_KEYBOARD: 501 device_printf(dev, "keyboard"); 502 break; 503 default: 504 device_printf(dev, "unknown system device"); 505 break; 506 } 507 printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate, 508 "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits, 509 sc->sc_sysdev->stopbits); 510 } 511 512 sc->sc_pps.ppscap = PPS_CAPTUREBOTH; 513 pps_init(&sc->sc_pps); 514 515 sc->sc_leaving = 0; 516 filt = uart_intr(sc); 517 518 /* 519 * Don't use interrupts if we couldn't clear any pending interrupt 520 * conditions. We may have broken H/W and polling is probably the 521 * safest thing to do. 522 */ 523 if (filt != FILTER_SCHEDULE_THREAD && !uart_force_poll) { 524 sc->sc_irid = 0; 525 sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, 526 &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); 527 } 528 if (sc->sc_ires != NULL) { 529 error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY, 530 uart_intr, NULL, sc, &sc->sc_icookie); 531 sc->sc_fastintr = (error == 0) ? 1 : 0; 532 533 if (!sc->sc_fastintr) 534 error = bus_setup_intr(dev, sc->sc_ires, 535 INTR_TYPE_TTY | INTR_MPSAFE, NULL, 536 (driver_intr_t *)uart_intr, sc, &sc->sc_icookie); 537 538 if (error) { 539 device_printf(dev, "could not activate interrupt\n"); 540 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 541 sc->sc_ires); 542 sc->sc_ires = NULL; 543 } 544 } 545 if (sc->sc_ires == NULL) { 546 /* No interrupt resource. Force polled mode. */ 547 sc->sc_polled = 1; 548 callout_init(&sc->sc_timer, 1); 549 callout_reset(&sc->sc_timer, hz / uart_poll_freq, 550 (timeout_t *)uart_intr, sc); 551 } 552 553 if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { 554 sep = ""; 555 device_print_prettyname(dev); 556 if (sc->sc_fastintr) { 557 printf("%sfast interrupt", sep); 558 sep = ", "; 559 } 560 if (sc->sc_polled) { 561 printf("%spolled mode (%dHz)", sep, uart_poll_freq); 562 sep = ", "; 563 } 564 printf("\n"); 565 } 566 567 error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) 568 ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc); 569 if (error) 570 goto fail; 571 572 if (sc->sc_sysdev != NULL) 573 sc->sc_sysdev->hwmtx = sc->sc_hwmtx; 574 575 return (0); 576 577 fail: 578 free(sc->sc_txbuf, M_UART); 579 free(sc->sc_rxbuf, M_UART); 580 581 if (sc->sc_ires != NULL) { 582 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); 583 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 584 sc->sc_ires); 585 } 586 bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 587 588 mtx_destroy(&sc->sc_hwmtx_s); 589 590 return (error); 591} 592 593int 594uart_bus_detach(device_t dev) 595{ 596 struct uart_softc *sc; 597 598 sc = device_get_softc(dev); 599 600 sc->sc_leaving = 1; 601 602 if (sc->sc_sysdev != NULL) 603 sc->sc_sysdev->hwmtx = NULL; 604 605 UART_DETACH(sc); 606 607 if (sc->sc_sysdev != NULL && sc->sc_sysdev->detach != NULL) 608 (*sc->sc_sysdev->detach)(sc); 609 else 610 uart_tty_detach(sc); 611 612 free(sc->sc_txbuf, M_UART); 613 free(sc->sc_rxbuf, M_UART); 614 615 if (sc->sc_ires != NULL) { 616 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); 617 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 618 sc->sc_ires); 619 } 620 bus_release_resource(dev, sc->sc_rtype, sc->sc_rrid, sc->sc_rres); 621 622 mtx_destroy(&sc->sc_hwmtx_s); 623 624 if (sc->sc_class->size > sizeof(*sc)) { 625 device_set_softc(dev, NULL); 626 free(sc, M_UART); 627 } else 628 device_set_softc(dev, NULL); 629 630 return (0); 631} 632 633int 634uart_bus_resume(device_t dev) 635{ 636 struct uart_softc *sc; 637 638 sc = device_get_softc(dev); 639 return (UART_ATTACH(sc)); 640} 641 642void 643uart_grab(struct uart_devinfo *di) 644{ 645 646 if (di->sc) 647 UART_GRAB(di->sc); 648} 649 650void 651uart_ungrab(struct uart_devinfo *di) 652{ 653 654 if (di->sc) 655 UART_UNGRAB(di->sc); 656} 657