uart_core.c (250576) | uart_core.c (253161) |
---|---|
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> | 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 250576 2013-05-12 16:43:26Z eadler $"); | 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; | 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 flag = 0, ipend; | 251 int cnt, ipend; |
252 | 252 |
253 while (!sc->sc_leaving && (ipend = UART_IPEND(sc)) != 0) { 254 flag = 1; | 253 if (sc->sc_leaving) 254 return (FILTER_STRAY); 255 256 cnt = 0; 257 while (cnt < 20 && (ipend = UART_IPEND(sc)) != 0) { 258 cnt++; |
255 if (ipend & SER_INT_OVERRUN) 256 uart_intr_overrun(sc); 257 if (ipend & SER_INT_BREAK) 258 uart_intr_break(sc); 259 if (ipend & SER_INT_RXREADY) 260 uart_intr_rxready(sc); 261 if (ipend & SER_INT_SIGCHG) 262 uart_intr_sigchg(sc); 263 if (ipend & SER_INT_TXIDLE) 264 uart_intr_txidle(sc); 265 } 266 267 if (sc->sc_polled) { 268 callout_reset(&sc->sc_timer, hz / uart_poll_freq, 269 (timeout_t *)uart_intr, sc); 270 } 271 | 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 |
272 return((flag)?FILTER_HANDLED:FILTER_STRAY); | 276 return ((cnt == 0) ? FILTER_STRAY : 277 ((cnt == 20) ? FILTER_SCHEDULE_THREAD : FILTER_HANDLED)); |
273} 274 275serdev_intr_t * 276uart_bus_ihand(device_t dev, int ipend) 277{ 278 279 switch (ipend) { 280 case SER_INT_BREAK: --- 104 unchanged lines hidden (view full) --- 385 return ((error) ? error : BUS_PROBE_DEFAULT); 386} 387 388int 389uart_bus_attach(device_t dev) 390{ 391 struct uart_softc *sc, *sc0; 392 const char *sep; | 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; |
393 int error; | 398 int error, filt; |
394 395 /* 396 * The sc_class field defines the type of UART we're going to work 397 * with and thus the size of the softc. Replace the generic softc 398 * with one that matches the UART now that we're certain we handle 399 * the device. 400 */ 401 sc0 = device_get_softc(dev); --- 23 unchanged lines hidden (view full) --- 425 0, ~0, uart_getrange(sc->sc_class), RF_ACTIVE); 426 if (sc->sc_rres == NULL) { 427 mtx_destroy(&sc->sc_hwmtx_s); 428 return (ENXIO); 429 } 430 sc->sc_bas.bsh = rman_get_bushandle(sc->sc_rres); 431 sc->sc_bas.bst = rman_get_bustag(sc->sc_rres); 432 | 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 |
433 sc->sc_irid = 0; 434 sc->sc_ires = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->sc_irid, 435 RF_ACTIVE | RF_SHAREABLE); 436 if (sc->sc_ires != NULL) { 437 error = bus_setup_intr(dev, 438 sc->sc_ires, INTR_TYPE_TTY, 439 uart_intr, NULL, sc, &sc->sc_icookie); 440 if (error) 441 error = bus_setup_intr(dev, 442 sc->sc_ires, INTR_TYPE_TTY | INTR_MPSAFE, 443 NULL, (driver_intr_t *)uart_intr, sc, &sc->sc_icookie); 444 else 445 sc->sc_fastintr = 1; 446 447 if (error) { 448 device_printf(dev, "could not activate interrupt\n"); 449 bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irid, 450 sc->sc_ires); 451 sc->sc_ires = NULL; 452 } 453 } 454 if (sc->sc_ires == NULL) { 455 /* No interrupt resource. Force polled mode. */ 456 sc->sc_polled = 1; 457 callout_init(&sc->sc_timer, 1); 458 } 459 | |
460 /* 461 * Ensure there is room for at least three full FIFOs of data in the 462 * receive buffer (handles the case of low-level drivers with huge 463 * FIFOs), and also ensure that there is no less than the historical 464 * size of 384 bytes (handles the typical small-FIFO case). 465 */ 466 sc->sc_rxbufsz = MAX(384, sc->sc_rxfifosz * 3); 467 sc->sc_rxbuf = malloc(sc->sc_rxbufsz * sizeof(*sc->sc_rxbuf), --- 14 unchanged lines hidden (view full) --- 482 } 483 if (sc->sc_hwoflow) { 484 printf("%sCTS oflow", sep); 485 sep = ", "; 486 } 487 printf("\n"); 488 } 489 | 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 |
490 if (bootverbose && (sc->sc_fastintr || sc->sc_polled)) { 491 sep = ""; 492 device_print_prettyname(dev); 493 if (sc->sc_fastintr) { 494 printf("%sfast interrupt", sep); 495 sep = ", "; 496 } 497 if (sc->sc_polled) { 498 printf("%spolled mode", sep); 499 sep = ", "; 500 } 501 printf("\n"); 502 } 503 | |
504 if (sc->sc_sysdev != NULL) { 505 if (sc->sc_sysdev->baudrate == 0) { 506 if (UART_IOCTL(sc, UART_IOCTL_BAUD, 507 (intptr_t)&sc->sc_sysdev->baudrate) != 0) 508 sc->sc_sysdev->baudrate = -1; 509 } 510 switch (sc->sc_sysdev->type) { 511 case UART_DEV_CONSOLE: --- 12 unchanged lines hidden (view full) --- 524 printf(" (%d,%c,%d,%d)\n", sc->sc_sysdev->baudrate, 525 "noems"[sc->sc_sysdev->parity], sc->sc_sysdev->databits, 526 sc->sc_sysdev->stopbits); 527 } 528 529 sc->sc_pps.ppscap = PPS_CAPTUREBOTH; 530 pps_init(&sc->sc_pps); 531 | 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 |
|
532 error = (sc->sc_sysdev != NULL && sc->sc_sysdev->attach != NULL) 533 ? (*sc->sc_sysdev->attach)(sc) : uart_tty_attach(sc); 534 if (error) 535 goto fail; 536 537 if (sc->sc_sysdev != NULL) 538 sc->sc_sysdev->hwmtx = sc->sc_hwmtx; 539 | 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 |
540 sc->sc_leaving = 0; 541 uart_intr(sc); | |
542 return (0); 543 544 fail: 545 free(sc->sc_txbuf, M_UART); 546 free(sc->sc_rxbuf, M_UART); 547 548 if (sc->sc_ires != NULL) { 549 bus_teardown_intr(dev, sc->sc_ires, sc->sc_icookie); --- 58 unchanged lines hidden --- | 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 --- |