From 9151ec67634b493c67ee8ceda2ed9f16c35f8ad0 Mon Sep 17 00:00:00 2001 From: Thomas Doerfler Date: Tue, 18 Nov 2008 09:20:18 +0000 Subject: libchip/serial/ns16550.c: Transmit the character in the polled write function within a critical section for printk() compatibility. --- c/src/ChangeLog | 5 ++++ c/src/libchip/serial/ns16550.c | 63 +++++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 34 deletions(-) (limited to 'c/src') diff --git a/c/src/ChangeLog b/c/src/ChangeLog index a5c6150a4b..1efc23890d 100644 --- a/c/src/ChangeLog +++ b/c/src/ChangeLog @@ -1,3 +1,8 @@ +2008-11-13 Sebastian Huber + + * libchip/serial/ns16550.c: Transmit the character in the polled write + function within a critical section for printk() compatibility. + 2008-10-02 Sebastian Huber * libchip/i2c/spi-sd-card.c: Update for status-checks.h changes. diff --git a/c/src/libchip/serial/ns16550.c b/c/src/libchip/serial/ns16550.c index 62f680076e..b7c2c887b9 100644 --- a/c/src/libchip/serial/ns16550.c +++ b/c/src/libchip/serial/ns16550.c @@ -196,44 +196,39 @@ NS16550_STATIC int ns16550_close( return(RTEMS_SUCCESSFUL); } -/* - * ns16550_write_polled +/** + * @brief Polled write for NS16550. */ - -NS16550_STATIC void ns16550_write_polled( - int minor, - char cChar -) +NS16550_STATIC void ns16550_write_polled( int minor, char c) { - uint32_t pNS16550; - unsigned char ucLineStatus; - getRegister_f getReg; - setRegister_f setReg; - - pNS16550 = Console_Port_Tbl[minor].ulCtrlPort1; - getReg = Console_Port_Tbl[minor].getRegister; - setReg = Console_Port_Tbl[minor].setRegister; + uint32_t port = Console_Port_Tbl [minor].ulCtrlPort1; + getRegister_f get = Console_Port_Tbl [minor].getRegister; + setRegister_f set = Console_Port_Tbl [minor].setRegister; + uint32_t status; + rtems_interrupt_level level; + + while (1) { + /* Try to transmit the character in a critical section */ + rtems_interrupt_disable( level); + + /* Read the transmitter holding register and check it */ + status = get( port, NS16550_LINE_STATUS); + if ((status & SP_LSR_THOLD) != 0) { + /* Transmit character */ + set( port, NS16550_TRANSMIT_BUFFER, c); + + /* Finished */ + rtems_interrupt_enable( level); + break; + } else { + rtems_interrupt_enable( level); + } - /* - * wait for transmitter holding register to be empty - */ - ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); - while ((ucLineStatus & SP_LSR_THOLD) == 0) { - /* - * Yield while we wait - */ -#if 0 - if(_System_state_Is_up(_System_state_Get())) { - rtems_task_wake_after(RTEMS_YIELD_PROCESSOR); - } -#endif - ucLineStatus = (*getReg)(pNS16550, NS16550_LINE_STATUS); + /* Wait for transmitter holding register to be empty */ + do { + status = get( port, NS16550_LINE_STATUS); + } while ((status & SP_LSR_THOLD) == 0); } - - /* - * transmit character - */ - (*setReg)(pNS16550, NS16550_TRANSMIT_BUFFER, cChar); } /* -- cgit v1.2.3