Index: sys/arm/s3c2xx0/uart_dev_s3c2410.c =================================================================== --- sys/arm/s3c2xx0/uart_dev_s3c2410.c (revision 260005) +++ sys/arm/s3c2xx0/uart_dev_s3c2410.c (working copy) @@ -70,6 +70,8 @@ static void s3c2410_putc(struct uart_bas *bas, int); static int s3c2410_rxready(struct uart_bas *bas); static int s3c2410_getc(struct uart_bas *bas, struct mtx *mtx); +static void s3c2410_grab(struct uart_bas *bas); +static void s3c2410_ungrab(struct uart_bas *bas); extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; @@ -143,6 +145,8 @@ .putc = s3c2410_putc, .rxready = s3c2410_rxready, .getc = s3c2410_getc, + .grab = s3c2410_grab, + .ungrab = s3c2410_ungrab, }; static int @@ -204,6 +208,20 @@ return sscom_getc(bas->bst, bas->bsh); } +static void +s3c2410_grab(struct uart_bas *bas) +{ + + arm_mask_irq(get_sub_irq(irq, RX_OFF)); +} + +static void +s3c2410_ungrab(struct uart_bas *bas) +{ + + arm_unmask_irq(get_sub_irq(irq, RX_OFF)); +} + static int s3c2410_bus_probe(struct uart_softc *sc); static int s3c2410_bus_attach(struct uart_softc *sc); static int s3c2410_bus_flush(struct uart_softc *, int); Index: sys/arm/sa11x0/uart_dev_sa1110.c =================================================================== --- sys/arm/sa11x0/uart_dev_sa1110.c (revision 260005) +++ sys/arm/sa11x0/uart_dev_sa1110.c (working copy) @@ -54,6 +54,8 @@ static void sa1110_putc(struct uart_bas *bas, int); static int sa1110_rxready(struct uart_bas *bas); static int sa1110_getc(struct uart_bas *bas, struct mtx *mtx); +static void sa1110_grab(struct uart_bas *bas); +static void sa1110_ungrab(struct uart_bas *bas); extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; @@ -64,6 +66,8 @@ .putc = sa1110_putc, .rxready = sa1110_rxready, .getc = sa1110_getc, + .grab = sa1110_grab, + .ungrab = sa1110_ungrab, }; static int @@ -127,6 +131,22 @@ return (c); } +static void +sa1110_grab(struct uart_bas *bas) +{ + + /* Turn off Rx interrupts */ + uart_setreg(bas, SACOM_CR3, CR3_TXE | CR3_TIE); +} + +static void +sa1110_ungrab(struct uart_bas *bas) +{ + + /* Turn on Rx interrupts */ + uart_setreg(bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE); +} + static int sa1110_bus_probe(struct uart_softc *sc); static int sa1110_bus_attach(struct uart_softc *sc); static int sa1110_bus_flush(struct uart_softc *, int); @@ -164,10 +184,10 @@ static int sa1110_bus_attach(struct uart_softc *sc) { - bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); - sc->sc_hwiflow = 0; - uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE); + sc->sc_hwiflow = 0; + uart_setreg(&sc->sc_bas, SACOM_CR3, CR3_RXE | CR3_TXE | CR3_RIE | CR3_TIE); return (0); } static int Index: sys/arm/xilinx/uart_dev_cdnc.c =================================================================== --- sys/arm/xilinx/uart_dev_cdnc.c (revision 260005) +++ sys/arm/xilinx/uart_dev_cdnc.c (working copy) @@ -155,6 +155,8 @@ static void cdnc_uart_putc(struct uart_bas *bas, int); static int cdnc_uart_rxready(struct uart_bas *bas); static int cdnc_uart_getc(struct uart_bas *bas, struct mtx *mtx); +static void cdnc_uart_grab(struct uart_bas *bas); +static void cdnc_uart_ungrab(struct uart_bas *bas); extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; @@ -165,6 +167,8 @@ .putc = cdnc_uart_putc, .rxready = cdnc_uart_rxready, .getc = cdnc_uart_getc, + .grab = cdnc_uart_grab, + .ungrab = cdnc_uart_ungrab, }; #define SIGCHG(c, i, s, d) \ @@ -383,6 +387,27 @@ return (c); } +static void +cdnc_uart_grab(struct uart_bas *bas) +{ + + /* Enable interrupts. */ + WR4(bas, CDNC_UART_IEN_REG, + CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR | + CDNC_UART_INT_DMSI); +} + +static void +cdnc_uart_ungrab(struct uart_bas *bas) +{ + + /* Enable interrupts. */ + WR4(bas, CDNC_UART_IEN_REG, + CDNC_UART_INT_RXTRIG | CDNC_UART_INT_RXTMOUT | + CDNC_UART_INT_TXOVR | CDNC_UART_INT_RXOVR | + CDNC_UART_INT_DMSI); +} + /*****************************************************************************/ /* * High-level UART interface. Index: sys/dev/uart/uart_dev_imx.c =================================================================== --- sys/dev/uart/uart_dev_imx.c (revision 260005) +++ sys/dev/uart/uart_dev_imx.c (working copy) @@ -56,6 +56,8 @@ static void imx_uart_putc(struct uart_bas *bas, int); static int imx_uart_rxready(struct uart_bas *bas); static int imx_uart_getc(struct uart_bas *bas, struct mtx *); +static void imx_uart_grab(struct uart_bas *bas); +static void imx_uart_ungrab(struct uart_bas *bas); static struct uart_ops uart_imx_uart_ops = { .probe = imx_uart_probe, @@ -64,6 +66,8 @@ .putc = imx_uart_putc, .rxready = imx_uart_rxready, .getc = imx_uart_getc, + .grab = imx_uart_grab, + .ungrab = imx_uart_ungrab, }; static int @@ -122,6 +126,18 @@ return (c & 0xff); } +static void +imx_uart_grab(struct uart_bas *bas) +{ + DIS(bas, UCR4, DREN); +} + +static void +imx_uart_ungrab(struct uart_bas *bas) +{ + ENA(bas, UCR4, DREN); +} + /* * High-level UART interface. */ @@ -189,12 +205,7 @@ (void)imx_uart_bus_getsig(sc); - /* XXX workaround to have working console on mount prompt */ - if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE){ - DIS(bas, UCR4, DREN); - } else { - ENA(bas, UCR4, DREN); - } + ENA(bas, UCR4, DREN); DIS(bas, UCR1, RRDYEN); DIS(bas, UCR1, IDEN); DIS(bas, UCR3, RXDSEN); @@ -402,13 +413,6 @@ imx_uart_bus_setsig(struct uart_softc *sc, int sig) { - /* TODO: implement (?) */ - - /* XXX workaround to have working console on mount prompt */ - /* Enable RX interrupt */ - if (sc->sc_sysdev != NULL && sc->sc_sysdev->type == UART_DEV_CONSOLE) - if (!IS(&sc->sc_bas, UCR4, DREN)) - ENA(&sc->sc_bas, UCR4, DREN); return (0); } Index: sys/dev/uart/uart_dev_lpc.c =================================================================== --- sys/dev/uart/uart_dev_lpc.c (revision 260005) +++ sys/dev/uart/uart_dev_lpc.c (working copy) @@ -252,6 +252,8 @@ static void lpc_ns8250_putc(struct uart_bas *bas, int); static int lpc_ns8250_rxready(struct uart_bas *bas); static int lpc_ns8250_getc(struct uart_bas *bas, struct mtx *); +static void lpc_ns8250_grab(struct uart_bas *bas); +static void lpc_ns8250_ungrab(struct uart_bas *bas); static struct uart_ops uart_lpc_ns8250_ops = { .probe = lpc_ns8250_probe, @@ -260,6 +262,8 @@ .putc = lpc_ns8250_putc, .rxready = lpc_ns8250_rxready, .getc = lpc_ns8250_getc, + .grab = lpc_ns8250_grab, + .ungrab = lpc_ns8250_ungrab, }; static int @@ -376,6 +380,27 @@ return (c); } +static void +lpc_ns8250_grab(struct uart_bas *bas) +{ + /* Should be using ns8250->fcr here, but can't access it via bas */ + uint8_t fcr = FCR_ENABLE; + + /* Switch to RX polling while grabbed */ + uart_setreg(bas, REG_FCR, fcr); +} + +static void +lpc_ns8250_ungrab(struct uart_bas *bas) +{ + /* Should be using ns8250->fcr here, but can't access it via bas */ + uint8_t fcr = FCR_ENABLE | FCR_RX_MEDH; + + /* Switch to RX interrupts while not grabbed */ + uart_setreg(bas, REG_FCR, fcr); +} + + /* * High-level UART interface. */ Index: sys/dev/uart/uart_dev_ns8250.c =================================================================== --- sys/dev/uart/uart_dev_ns8250.c (revision 260005) +++ sys/dev/uart/uart_dev_ns8250.c (working copy) @@ -239,6 +239,8 @@ static void ns8250_putc(struct uart_bas *bas, int); static int ns8250_rxready(struct uart_bas *bas); static int ns8250_getc(struct uart_bas *bas, struct mtx *); +static void ns8250_grab(struct uart_bas *bas); +static void ns8250_ungrab(struct uart_bas *bas); struct uart_ops uart_ns8250_ops = { .probe = ns8250_probe, @@ -247,6 +249,8 @@ .putc = ns8250_putc, .rxready = ns8250_rxready, .getc = ns8250_getc, + .grab = ns8250_grab, + .ungrab = ns8250_ungrab, }; static int @@ -353,6 +357,26 @@ return (c); } +static void +ns8250_grab(struct uart_bas *bas) +{ + /* Should be using ns8250->fcr here, but can't access it via bas */ + uint8_t fcr = FCR_ENABLE; + + /* Switch to RX polling while grabbed */ + uart_setreg(bas, REG_FCR, fcr); +} + +static void +ns8250_ungrab(struct uart_bas *bas) +{ + /* Should be using ns8250->fcr here, but can't access it via bas */ + uint8_t fcr = FCR_ENABLE | FCR_RX_MEDH; + + /* Switch to RX interrupts while not grabbed */ + uart_setreg(bas, REG_FCR, fcr); +} + static kobj_method_t ns8250_methods[] = { KOBJMETHOD(uart_attach, ns8250_bus_attach), KOBJMETHOD(uart_detach, ns8250_bus_detach), Index: sys/dev/uart/uart_dev_pl011.c =================================================================== --- sys/dev/uart/uart_dev_pl011.c (revision 260005) +++ sys/dev/uart/uart_dev_pl011.c (working copy) @@ -102,6 +102,8 @@ static void uart_pl011_putc(struct uart_bas *bas, int); static int uart_pl011_rxready(struct uart_bas *bas); static int uart_pl011_getc(struct uart_bas *bas, struct mtx *); +static void uart_pl011_grab(struct uart_bas *bas); +static void uart_pl011_ungrab(struct uart_bas *bas); static struct uart_ops uart_pl011_ops = { .probe = uart_pl011_probe, @@ -110,6 +112,8 @@ .putc = uart_pl011_putc, .rxready = uart_pl011_rxready, .getc = uart_pl011_getc, + .grab = uart_pl011_grab, + .ungrab = uart_pl011_ungrab, }; static int @@ -218,6 +222,24 @@ return (c); } +static void +uart_pl011_grab(struct uart_bas *bas) +{ + + /* Switch to RX polling while grabbed */ + __uart_setreg(bas, UART_IMSC, + ~UART_RXREADY & __uart_getreg(bas, UART_IMSC)); +} + +static void +uart_pl011_ungrab(struct uart_bas *bas) +{ + + /* Switch to RX interrupts while not grabbed */ + __uart_setreg(bas, UART_IMSC, + UART_RXREADY | __uart_getreg(bas, UART_IMSC)); +} + /* * High-level UART interface. */ Index: sys/dev/uart/uart_dev_quicc.c =================================================================== --- sys/dev/uart/uart_dev_quicc.c (revision 260005) +++ sys/dev/uart/uart_dev_quicc.c (working copy) @@ -148,6 +148,8 @@ static void quicc_putc(struct uart_bas *bas, int); static int quicc_rxready(struct uart_bas *bas); static int quicc_getc(struct uart_bas *bas, struct mtx *); +static void quicc_grab(struct uart_bas *bas); +static void quicc_ungrab(struct uart_bas *bas); static struct uart_ops uart_quicc_ops = { .probe = quicc_probe, @@ -156,6 +158,8 @@ .putc = quicc_putc, .rxready = quicc_rxready, .getc = quicc_getc, + .grab = quicc_grab, + .ungrab = quicc_ungrab, }; static int @@ -227,6 +231,28 @@ return (c); } +static void +quicc_grab(struct uart_bas *bas) +{ + uint16_t st, rb; + + /* Disable interrupts on the receive buffer. */ + rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); + st = quicc_read2(bas, rb); + quicc_write2(bas, rb, st & ~0x9000); +} + +static void +quicc_ungrab(struct uart_bas *bas) +{ + uint16_t st, rb; + + /* Enable interrupts on the receive buffer. */ + rb = quicc_read2(bas, QUICC_PRAM_SCC_RBASE(bas->chan - 1)); + st = quicc_read2(bas, rb); + quicc_write2(bas, rb, st | 0x9000); +} + /* * High-level UART interface. */ Index: sys/dev/uart/uart_dev_sab82532.c =================================================================== --- sys/dev/uart/uart_dev_sab82532.c (revision 260005) +++ sys/dev/uart/uart_dev_sab82532.c (working copy) @@ -175,6 +175,8 @@ static void sab82532_putc(struct uart_bas *bas, int); static int sab82532_rxready(struct uart_bas *bas); static int sab82532_getc(struct uart_bas *bas, struct mtx *); +static void sab82532_grab(struct uart_bas *bas); +static void sab82532_ungrab(struct uart_bas *bas); static struct uart_ops uart_sab82532_ops = { .probe = sab82532_probe, @@ -183,6 +185,8 @@ .putc = sab82532_putc, .rxready = sab82532_rxready, .getc = sab82532_getc, + .grab = sab82532_grab, + .ungrab = sab82532_ungrab, }; static int @@ -347,6 +351,27 @@ return (c); } +static void +sab82532_grab(struct uart_bas *bas) +{ + uint8_t imr0; + + imr0 = SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO; /* No TCD or RPF */ + uart_setreg(bas, SAB_IMR0, 0xff & ~imr0); + uart_barrier(bas); +} + +static void +sab82532_ungrab(struct uart_bas *bas) +{ + uint8_t imr0; + + imr0 = SAB_IMR0_TCD|SAB_IMR0_TIME|SAB_IMR0_CDSC|SAB_IMR0_RFO| + SAB_IMR0_RPF; + uart_setreg(bas, SAB_IMR0, 0xff & ~imr0); + uart_barrier(bas); +} + /* * High-level UART interface. */ Index: sys/dev/uart/uart_dev_z8530.c =================================================================== --- sys/dev/uart/uart_dev_z8530.c (revision 260005) +++ sys/dev/uart/uart_dev_z8530.c (working copy) @@ -194,6 +194,8 @@ static void z8530_putc(struct uart_bas *bas, int); static int z8530_rxready(struct uart_bas *bas); static int z8530_getc(struct uart_bas *bas, struct mtx *); +static void z8530_grab(struct uart_bas *bas); +static void z8530_ungrab(struct uart_bas *bas); static struct uart_ops uart_z8530_ops = { .probe = z8530_probe, @@ -202,6 +204,8 @@ .putc = z8530_putc, .rxready = z8530_rxready, .getc = z8530_getc, + .grab = z8530_grab, + .ungrab = z8530_ungrab, }; static int @@ -261,6 +265,20 @@ return (c); } +static void +z8530_grab(struct uart_bas *bas) +{ + uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE); + uart_barrier(bas); +} + +static void +z8530_ungrab(struct uart_bas *bas) +{ + uart_setmreg(bas, WR_IDT, IDT_XIE | IDT_TIE | IDT_RIA); + uart_barrier(bas); +} + /* * High-level UART interface. */ Index: sys/mips/adm5120/uart_dev_adm5120.c =================================================================== --- sys/mips/adm5120/uart_dev_adm5120.c (revision 260005) +++ sys/mips/adm5120/uart_dev_adm5120.c (working copy) @@ -58,6 +58,8 @@ static void adm5120_uart_putc(struct uart_bas *bas, int); static int adm5120_uart_rxready(struct uart_bas *bas); static int adm5120_uart_getc(struct uart_bas *bas, struct mtx *); +static void adm5120_uart_grab(struct uart_bas *bas); +static void adm5120_uart_ungrab(struct uart_bas *bas); static struct uart_ops uart_adm5120_uart_ops = { .probe = adm5120_uart_probe, @@ -66,6 +68,8 @@ .putc = adm5120_uart_putc, .rxready = adm5120_uart_rxready, .getc = adm5120_uart_getc, + .grab = adm5120_uart_grab, + .ungrab = adm5120_uart_ungrab, }; static int @@ -131,6 +135,25 @@ return (c); } +static void +adm5120_uart_grab(struct uart_bas *bas) +{ + + /* Enable interrupts - no RX_INT or RX_TIMEOUT */ + uart_setreg(bas, UART_CR_REG, + UART_CR_PORT_EN | UART_CR_MODEM_STATUS_INT_EN); +} + +static void +adm5120_uart_ungrab(struct uart_bas *bas) +{ + + /* Enable interrupts */ + uart_setreg(bas, UART_CR_REG, + UART_CR_PORT_EN|UART_CR_RX_INT_EN|UART_CR_RX_TIMEOUT_INT_EN| + UART_CR_MODEM_STATUS_INT_EN); +} + /* * High-level UART interface. */ Index: sys/mips/atheros/uart_dev_ar933x.c =================================================================== --- sys/mips/atheros/uart_dev_ar933x.c (revision 260005) +++ sys/mips/atheros/uart_dev_ar933x.c (working copy) @@ -201,6 +201,8 @@ static void ar933x_putc(struct uart_bas *bas, int); static int ar933x_rxready(struct uart_bas *bas); static int ar933x_getc(struct uart_bas *bas, struct mtx *); +static void ar933x_grab(struct uart_bas *bas); +static void ar933x_ungrab(struct uart_bas *bas); static struct uart_ops uart_ar933x_ops = { .probe = ar933x_probe, @@ -209,6 +211,8 @@ .putc = ar933x_putc, .rxready = ar933x_rxready, .getc = ar933x_getc, + .grab = ar933x_grab, + .ungrab = ar933x_ungrab, }; static int @@ -305,6 +309,26 @@ return (c); } +static void +ar933x_grab(struct uart_bas *bas) +{ + + /* Disable the host interrupt now */ + reg = ar933x_getreg(bas, AR933X_UART_CS_REG); + reg &= ~AR933X_UART_CS_HOST_INT_EN; + ar933x_setreg(bas, AR933X_UART_CS_REG, reg); +} + +static void +ar933x_ungrab(struct uart_bas *bas) +{ + + /* Enable the host interrupt now */ + reg = ar933x_getreg(bas, AR933X_UART_CS_REG); + reg |= AR933X_UART_CS_HOST_INT_EN; + ar933x_setreg(bas, AR933X_UART_CS_REG, reg); +} + /* * High-level UART interface. */ Index: sys/mips/cavium/uart_dev_oct16550.c =================================================================== --- sys/mips/cavium/uart_dev_oct16550.c (revision 260005) +++ sys/mips/cavium/uart_dev_oct16550.c (working copy) @@ -266,6 +266,8 @@ static void oct16550_putc(struct uart_bas *bas, int); static int oct16550_rxready(struct uart_bas *bas); static int oct16550_getc(struct uart_bas *bas, struct mtx *); +static void oct16550_grab(struct uart_bas *bas); +static void oct16550_ungrab(struct uart_bas *bas); struct uart_ops uart_oct16550_ops = { .probe = oct16550_probe, @@ -274,6 +276,8 @@ .putc = oct16550_putc, .rxready = oct16550_rxready, .getc = oct16550_getc, + .grab = oct16550_grab, + .ungrab = oct16550_ungrab, }; static int @@ -377,6 +381,25 @@ return (c); } +static void +oct16550_grab(struct uart_bas *bas) +{ + + /* Should use oct16550->fcr here, but can't access it from here */ + uart_setreg(bas, REG_FCR, FCR_ENABLE); + uart_barrier(bas); +} + +static void +oct16550_ungrab(struct uart_bas *bas) +{ + + /* Should use oct16550->fcr here, but can't access it from here */ + uart_setreg(bas, REG_FCR, FCR_ENABLE | FCR_RX_HIGH); + uart_barrier(bas); +} + + /* * High-level UART interface. */ Index: sys/mips/rt305x/uart_dev_rt305x.c =================================================================== --- sys/mips/rt305x/uart_dev_rt305x.c (revision 260005) +++ sys/mips/rt305x/uart_dev_rt305x.c (working copy) @@ -62,6 +62,8 @@ static void rt305x_uart_putc(struct uart_bas *bas, int); static int rt305x_uart_rxready(struct uart_bas *bas); static int rt305x_uart_getc(struct uart_bas *bas, struct mtx *); +static void rt305x_uart_grab(struct uart_bas *bas); +static void rt305x_uart_ungrab(struct uart_bas *bas); static struct uart_ops uart_rt305x_uart_ops = { .probe = rt305x_uart_probe, @@ -70,6 +72,8 @@ .putc = rt305x_uart_putc, .rxready = rt305x_uart_rxready, .getc = rt305x_uart_getc, + .grab = rt305x_uart_grab, + .ungrab = rt305x_uart_ungrab, }; static int uart_output = 1; @@ -177,6 +181,25 @@ return (c); } +static void +rt305x_uart_grab(struct uart_bas *bas) +{ + + /* disable interrupts -- XXX not sure which one is RX, so kill them all */ + uart_setreg(bas, UART_IER_REG, 0); + uart_barrier(bas); +} + +static void +rt305x_uart_ungrab(struct uart_bas *bas) +{ + + /* Enable interrupts */ + uart_setreg(bas, UART_IER_REG, + UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI); + uart_barrier(bas); +} + /* * High-level UART interface. */ @@ -278,7 +301,7 @@ uart_setreg(bas, UART_FCR_REG, uart_getreg(bas, UART_FCR_REG) | UART_FCR_FIFOEN | UART_FCR_TXTGR_1 | UART_FCR_RXTGR_1); - uart_barrier(bas); + uart_barrier(bas); /* Enable interrupts */ uart_setreg(bas, UART_IER_REG, UART_IER_EDSSI | UART_IER_ELSI | UART_IER_ERBFI);