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 * --- 11 unchanged lines hidden (view full) --- 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: head/sys/dev/uart/uart_core.c 253161 2013-07-10 17:42:20Z marcel $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/conf.h> 34#include <sys/cons.h> 35#include <sys/fcntl.h> 36#include <sys/interrupt.h> --- 206 unchanged lines hidden (view full) --- 243 } 244 return (0); 245} 246 247static int 248uart_intr(void *arg) 249{ 250 struct uart_softc *sc = arg; |
251 int cnt, ipend; |
252 |
253 if (sc->sc_leaving) 254 return (FILTER_STRAY); 255 256 cnt = 0; 257 while (cnt < 20 && (ipend = UART_IPEND(sc)) != 0) { 258 cnt++; |
259 if (ipend & SER_INT_OVERRUN) 260 uart_intr_overrun(sc); 261 if (ipend & SER_INT_BREAK) 262 uart_intr_break(sc); 263 if (ipend & SER_INT_RXREADY) 264 uart_intr_rxready(sc); 265 if (ipend & SER_INT_SIGCHG) 266 uart_intr_sigchg(sc); 267 if (ipend & SER_INT_TXIDLE) 268 uart_intr_txidle(sc); 269 } 270 271 if (sc->sc_polled) { 272 callout_reset(&sc->sc_timer, hz / uart_poll_freq, 273 (timeout_t *)uart_intr, sc); 274 } 275 |
276 return ((cnt == 0) ? FILTER_STRAY : 277 ((cnt == 20) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED)); |
278} 279 280serdev_intr_t * 281uart_bus_ihand(device_t dev, int ipend) 282{ 283 284 switch (ipend) { 285 case SER_INT_BREAK: --- 104 unchanged lines hidden (view full) --- 390 return ((error) ? error : BUS_PROBE_DEFAULT); 391} 392 393int 394uart_bus_attach(device_t dev) 395{ 396 struct uart_softc *sc, *sc0; 397 const char *sep; |
398 int error, filt; |
399 400 /* 401 * The sc_class field defines the type of UART we're going to work 402 * with and thus the size of the softc. Replace the generic softc 403 * with one that matches the UART now that we're certain we handle 404 * the device. 405 */ 406 sc0 = device_get_softc(dev); --- 23 unchanged lines hidden (view full) --- 430 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE); 431 if (sc->sc_rres == NULL) { 432 mtx_destroy(&sc->sc_hwmtx_s); 433 return (ENXIO); 434 } 435 sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 436 sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 437 |
438 /* 439 * Ensure there is room for at least three full FIFOs of data in the 440 * receive buffer (handles the case of low-level drivers with huge 441 * FIFOs), and also ensure that there is no less than the historical 442 * size of 384 bytes (handles the typical small-FIFO case). 443 */ 444 sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3); 445 sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), --- 14 unchanged lines hidden (view full) --- 460 } 461 if (sc->sc_hwoflow) { 462 printf("%sCTS oflow", sep); 463 sep = ", "; 464 } 465 printf("\n"); 466 } 467 |
468 if (sc->sc_sysdev != NULL) { 469 if (sc->sc_sysdev->baudrate == 0) { 470 if (UART_IOCTL(sc, UART_IOCTL_BAUD, 471 (intptr_t)&sc->sc_sysdev->baudrate) != 0) 472 sc->sc_sysdev->baudrate = -1; 473 } 474 switch (sc->sc_sysdev->type) { 475 case UART_DEV_CONSOLE: --- 12 unchanged lines hidden (view full) --- 488 printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate, 489 "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits, 490 sc->sc_sysdev->stopbits); 491 } 492 493 sc->sc_pps.ppscap = PPS_CAPTUREBOTH; 494 pps_init(&sc->sc_pps); 495 |
496 sc->sc_leaving = 0; 497 filt = uart_intr(sc); 498 499 /* 500 * Don't use interrupts if we couldn't clear any pending interrupt 501 * conditions. We may have broken H/W and polling is probably the 502 * safest thing to do. 503 */ 504 if (filt != FILTER_SCHEDULE_THREAD) { 505 sc->sc_irid = 0; 506 sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, 507 &sc->sc_irid, RF_ACTIVE | RF_SHAREABLE); 508 } 509 if (sc->sc_ires != NULL) { 510 error = bus_setup_intr(dev, sc->sc_ires, INTR_TYPE_TTY, 511 uart_intr, NULL, sc, &sc->sc_icookie); 512 sc->sc_fastintr = (error == 0) ? 1 : 0; 513 514 if (!sc->sc_fastintr) 515 error = bus_setup_intr(dev, sc->sc_ires, 516 INTR_TYPE_TTY | INTR_MPSAFE, NULL, 517 (driver_intr_t *)uart_intr, sc, &sc->sc_icookie); 518 519 if (error) { 520 device_printf(dev, "could not activate interrupt\n"); 521 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 522 sc->sc_ires); 523 sc->sc_ires = NULL; 524 } 525 } 526 if (sc->sc_ires == NULL) { 527 /* No interrupt resource. Force polled mode. */ 528 sc->sc_polled = 1; 529 callout_init(&sc->sc_timer, 1); 530 } 531 532 if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { 533 sep = ""; 534 device_print_prettyname(dev); 535 if (sc->sc_fastintr) { 536 printf("%sfast interrupt", sep); 537 sep = ", "; 538 } 539 if (sc->sc_polled) { 540 printf("%spolled mode", sep); 541 sep = ", "; 542 } 543 printf("\n"); 544 } 545 |
546 error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) 547 ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc); 548 if (error) 549 goto fail; 550 551 if (sc->sc_sysdev != NULL) 552 sc->sc_sysdev->hwmtx = sc->sc_hwmtx; 553 |
554 return (0); 555 556 fail: 557 free(sc->sc_txbuf, M_UART); 558 free(sc->sc_rxbuf, M_UART); 559 560 if (sc->sc_ires != NULL) { 561 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); --- 58 unchanged lines hidden --- |