uart_dev_ns8250.c (120022) | uart_dev_ns8250.c (120143) |
---|---|
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_dev_ns8250.c 120022 2003-09-13 06:25:04Z marcel $"); | 28__FBSDID("$FreeBSD: head/sys/dev/uart/uart_dev_ns8250.c 120143 2003-09-17 01:41:21Z marcel $"); |
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> --- 385 unchanged lines hidden (view full) --- 422 return (0); 423} 424 425static int 426ns8250_bus_flush(struct uart_softc *sc, int what) 427{ 428 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 429 struct uart_bas *bas; | 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> --- 385 unchanged lines hidden (view full) --- 422 return (0); 423} 424 425static int 426ns8250_bus_flush(struct uart_softc *sc, int what) 427{ 428 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 429 struct uart_bas *bas; |
430 int error; |
|
430 431 bas = &sc->sc_bas; | 431 432 bas = &sc->sc_bas; |
433 mtx_lock_spin(&sc->sc_hwmtx); |
|
432 if (sc->sc_hasfifo) { 433 ns8250_flush(bas, what); 434 uart_setreg(bas, REG_FCR, ns8250->fcr); 435 uart_barrier(bas); | 434 if (sc->sc_hasfifo) { 435 ns8250_flush(bas, what); 436 uart_setreg(bas, REG_FCR, ns8250->fcr); 437 uart_barrier(bas); |
436 return (0); 437 } 438 return (ns8250_drain(bas, what)); | 438 error = 0; 439 } else 440 error = ns8250_drain(bas, what); 441 mtx_unlock_spin(&sc->sc_hwmtx); 442 return (error); |
439} 440 441static int 442ns8250_bus_getsig(struct uart_softc *sc) 443{ 444 uint32_t new, old, sig; 445 uint8_t msr; 446 447 do { 448 old = sc->sc_hwsig; 449 sig = old; | 443} 444 445static int 446ns8250_bus_getsig(struct uart_softc *sc) 447{ 448 uint32_t new, old, sig; 449 uint8_t msr; 450 451 do { 452 old = sc->sc_hwsig; 453 sig = old; |
454 mtx_lock_spin(&sc->sc_hwmtx); |
|
450 msr = uart_getreg(&sc->sc_bas, REG_MSR); | 455 msr = uart_getreg(&sc->sc_bas, REG_MSR); |
456 mtx_unlock_spin(&sc->sc_hwmtx); |
|
451 SIGCHG(msr & MSR_DSR, sig, UART_SIG_DSR, UART_SIG_DDSR); 452 SIGCHG(msr & MSR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS); 453 SIGCHG(msr & MSR_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD); 454 SIGCHG(msr & MSR_RI, sig, UART_SIG_RI, UART_SIG_DRI); 455 new = sig & ~UART_SIGMASK_DELTA; 456 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 457 return (sig); 458} 459 460static int 461ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 462{ 463 struct uart_bas *bas; | 457 SIGCHG(msr & MSR_DSR, sig, UART_SIG_DSR, UART_SIG_DDSR); 458 SIGCHG(msr & MSR_CTS, sig, UART_SIG_CTS, UART_SIG_DCTS); 459 SIGCHG(msr & MSR_DCD, sig, UART_SIG_DCD, UART_SIG_DDCD); 460 SIGCHG(msr & MSR_RI, sig, UART_SIG_RI, UART_SIG_DRI); 461 new = sig & ~UART_SIGMASK_DELTA; 462 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); 463 return (sig); 464} 465 466static int 467ns8250_bus_ioctl(struct uart_softc *sc, int request, intptr_t data) 468{ 469 struct uart_bas *bas; |
470 int error; |
|
464 uint8_t efr, lcr; 465 466 bas = &sc->sc_bas; | 471 uint8_t efr, lcr; 472 473 bas = &sc->sc_bas; |
474 error = 0; 475 mtx_lock_spin(&sc->sc_hwmtx); |
|
467 switch (request) { 468 case UART_IOCTL_BREAK: 469 lcr = uart_getreg(bas, REG_LCR); 470 if (data) 471 lcr |= LCR_SBREAK; 472 else 473 lcr &= ~LCR_SBREAK; 474 uart_setreg(bas, REG_LCR, lcr); --- 25 unchanged lines hidden (view full) --- 500 else 501 efr &= ~EFR_CTS; 502 uart_setreg(bas, REG_EFR, efr); 503 uart_barrier(bas); 504 uart_setreg(bas, REG_LCR, lcr); 505 uart_barrier(bas); 506 break; 507 default: | 476 switch (request) { 477 case UART_IOCTL_BREAK: 478 lcr = uart_getreg(bas, REG_LCR); 479 if (data) 480 lcr |= LCR_SBREAK; 481 else 482 lcr &= ~LCR_SBREAK; 483 uart_setreg(bas, REG_LCR, lcr); --- 25 unchanged lines hidden (view full) --- 509 else 510 efr &= ~EFR_CTS; 511 uart_setreg(bas, REG_EFR, efr); 512 uart_barrier(bas); 513 uart_setreg(bas, REG_LCR, lcr); 514 uart_barrier(bas); 515 break; 516 default: |
508 return (EINVAL); | 517 error = EINVAL; 518 break; |
509 } | 519 } |
510 return (0); | 520 mtx_unlock_spin(&sc->sc_hwmtx); 521 return (error); |
511} 512 513static int 514ns8250_bus_ipend(struct uart_softc *sc) 515{ 516 struct uart_bas *bas; 517 int ipend; 518 uint8_t iir, lsr; 519 520 bas = &sc->sc_bas; | 522} 523 524static int 525ns8250_bus_ipend(struct uart_softc *sc) 526{ 527 struct uart_bas *bas; 528 int ipend; 529 uint8_t iir, lsr; 530 531 bas = &sc->sc_bas; |
532 mtx_lock_spin(&sc->sc_hwmtx); |
|
521 iir = uart_getreg(bas, REG_IIR); | 533 iir = uart_getreg(bas, REG_IIR); |
522 if (iir & IIR_NOPEND) | 534 if (iir & IIR_NOPEND) { 535 mtx_unlock_spin(&sc->sc_hwmtx); |
523 return (0); | 536 return (0); |
524 | 537 } |
525 ipend = 0; 526 if (iir & IIR_RXRDY) { 527 lsr = uart_getreg(bas, REG_LSR); | 538 ipend = 0; 539 if (iir & IIR_RXRDY) { 540 lsr = uart_getreg(bas, REG_LSR); |
541 mtx_unlock_spin(&sc->sc_hwmtx); |
|
528 if (lsr & LSR_OE) 529 ipend |= UART_IPEND_OVERRUN; 530 if (lsr & LSR_BI) 531 ipend |= UART_IPEND_BREAK; 532 if (lsr & LSR_RXRDY) 533 ipend |= UART_IPEND_RXREADY; 534 } else { | 542 if (lsr & LSR_OE) 543 ipend |= UART_IPEND_OVERRUN; 544 if (lsr & LSR_BI) 545 ipend |= UART_IPEND_BREAK; 546 if (lsr & LSR_RXRDY) 547 ipend |= UART_IPEND_RXREADY; 548 } else { |
549 mtx_unlock_spin(&sc->sc_hwmtx); |
|
535 if (iir & IIR_TXRDY) 536 ipend |= UART_IPEND_TXIDLE; 537 else 538 ipend |= UART_IPEND_SIGCHG; 539 } | 550 if (iir & IIR_TXRDY) 551 ipend |= UART_IPEND_TXIDLE; 552 else 553 ipend |= UART_IPEND_SIGCHG; 554 } |
540 | |
541 return ((sc->sc_leaving) ? 0 : ipend); 542} 543 544static int 545ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits, 546 int stopbits, int parity) 547{ 548 struct uart_bas *bas; | 555 return ((sc->sc_leaving) ? 0 : ipend); 556} 557 558static int 559ns8250_bus_param(struct uart_softc *sc, int baudrate, int databits, 560 int stopbits, int parity) 561{ 562 struct uart_bas *bas; |
563 int error; |
|
549 550 bas = &sc->sc_bas; | 564 565 bas = &sc->sc_bas; |
551 return (ns8250_param(bas, baudrate, databits, stopbits, parity)); | 566 mtx_lock_spin(&sc->sc_hwmtx); 567 error = ns8250_param(bas, baudrate, databits, stopbits, parity); 568 mtx_unlock_spin(&sc->sc_hwmtx); 569 return (error); |
552} 553 554static int 555ns8250_bus_probe(struct uart_softc *sc) 556{ 557 struct uart_bas *bas; 558 int count, delay, error, limit; 559 uint8_t mcr; --- 132 unchanged lines hidden (view full) --- 692static int 693ns8250_bus_receive(struct uart_softc *sc) 694{ 695 struct uart_bas *bas; 696 int xc; 697 uint8_t lsr; 698 699 bas = &sc->sc_bas; | 570} 571 572static int 573ns8250_bus_probe(struct uart_softc *sc) 574{ 575 struct uart_bas *bas; 576 int count, delay, error, limit; 577 uint8_t mcr; --- 132 unchanged lines hidden (view full) --- 710static int 711ns8250_bus_receive(struct uart_softc *sc) 712{ 713 struct uart_bas *bas; 714 int xc; 715 uint8_t lsr; 716 717 bas = &sc->sc_bas; |
718 mtx_lock_spin(&sc->sc_hwmtx); |
|
700 while (!uart_rx_full(sc)) { 701 lsr = uart_getreg(bas, REG_LSR); 702 if ((lsr & LSR_RXRDY) == 0) 703 break; 704 xc = uart_getreg(bas, REG_DATA); 705 if (lsr & LSR_FE) 706 xc |= UART_STAT_FRAMERR; 707 if (lsr & LSR_PE) 708 xc |= UART_STAT_PARERR; 709 uart_rx_put(sc, xc); 710 } | 719 while (!uart_rx_full(sc)) { 720 lsr = uart_getreg(bas, REG_LSR); 721 if ((lsr & LSR_RXRDY) == 0) 722 break; 723 xc = uart_getreg(bas, REG_DATA); 724 if (lsr & LSR_FE) 725 xc |= UART_STAT_FRAMERR; 726 if (lsr & LSR_PE) 727 xc |= UART_STAT_PARERR; 728 uart_rx_put(sc, xc); 729 } |
730 mtx_unlock_spin(&sc->sc_hwmtx); |
|
711 return (0); 712} 713 714static int 715ns8250_bus_setsig(struct uart_softc *sc, int sig) 716{ 717 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 718 struct uart_bas *bas; --- 7 unchanged lines hidden (view full) --- 726 SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR, 727 UART_SIG_DDTR); 728 } 729 if (sig & UART_SIG_DRTS) { 730 SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS, 731 UART_SIG_DRTS); 732 } 733 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); | 731 return (0); 732} 733 734static int 735ns8250_bus_setsig(struct uart_softc *sc, int sig) 736{ 737 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 738 struct uart_bas *bas; --- 7 unchanged lines hidden (view full) --- 746 SIGCHG(sig & UART_SIG_DTR, new, UART_SIG_DTR, 747 UART_SIG_DDTR); 748 } 749 if (sig & UART_SIG_DRTS) { 750 SIGCHG(sig & UART_SIG_RTS, new, UART_SIG_RTS, 751 UART_SIG_DRTS); 752 } 753 } while (!atomic_cmpset_32(&sc->sc_hwsig, old, new)); |
754 mtx_lock_spin(&sc->sc_hwmtx); |
|
734 ns8250->mcr &= ~(MCR_DTR|MCR_RTS); 735 if (new & UART_SIG_DTR) 736 ns8250->mcr |= MCR_DTR; 737 if (new & UART_SIG_RTS) 738 ns8250->mcr |= MCR_RTS; 739 uart_setreg(bas, REG_MCR, ns8250->mcr); 740 uart_barrier(bas); | 755 ns8250->mcr &= ~(MCR_DTR|MCR_RTS); 756 if (new & UART_SIG_DTR) 757 ns8250->mcr |= MCR_DTR; 758 if (new & UART_SIG_RTS) 759 ns8250->mcr |= MCR_RTS; 760 uart_setreg(bas, REG_MCR, ns8250->mcr); 761 uart_barrier(bas); |
762 mtx_unlock_spin(&sc->sc_hwmtx); |
|
741 return (0); 742} 743 744static int 745ns8250_bus_transmit(struct uart_softc *sc) 746{ 747 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 748 struct uart_bas *bas; 749 int i; 750 751 bas = &sc->sc_bas; | 763 return (0); 764} 765 766static int 767ns8250_bus_transmit(struct uart_softc *sc) 768{ 769 struct ns8250_softc *ns8250 = (struct ns8250_softc*)sc; 770 struct uart_bas *bas; 771 int i; 772 773 bas = &sc->sc_bas; |
774 mtx_lock_spin(&sc->sc_hwmtx); |
|
752 while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) 753 ; 754 uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); 755 uart_barrier(bas); 756 for (i = 0; i < sc->sc_txdatasz; i++) { 757 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); 758 uart_barrier(bas); 759 } 760 sc->sc_txbusy = 1; | 775 while ((uart_getreg(bas, REG_LSR) & LSR_THRE) == 0) 776 ; 777 uart_setreg(bas, REG_IER, ns8250->ier | IER_ETXRDY); 778 uart_barrier(bas); 779 for (i = 0; i < sc->sc_txdatasz; i++) { 780 uart_setreg(bas, REG_DATA, sc->sc_txbuf[i]); 781 uart_barrier(bas); 782 } 783 sc->sc_txbusy = 1; |
784 mtx_unlock_spin(&sc->sc_hwmtx); |
|
761 return (0); 762} | 785 return (0); 786} |