diff options
author | Vic Yang <victoryang@chromium.org> | 2013-04-23 17:29:55 +0800 |
---|---|---|
committer | ChromeBot <chrome-bot@google.com> | 2013-04-23 10:39:09 -0700 |
commit | 2dd01e59eac4a25164bc4c3a76280a57a7fca6c7 (patch) | |
tree | 8c3c2c3be0d455fd3629dc3d23c0a4c0d4d3faf3 | |
parent | 4d0c4b1a53be54eb9b82d02878e09e0671fafb07 (diff) | |
download | chrome-ec-2dd01e59eac4a25164bc4c3a76280a57a7fca6c7.tar.gz |
Software flow control in console
This adds software flow control handling (a.k.a X-on/X-off). When Ctrl-Q
is received, UART transmitting is paused until Ctrl-S is received. If
the FIFO or buffer fill up during this period, console output is lost.
BUG=chrome-os-partner:18680
TEST=Press Ctrl-Q and see console stopped. Press Ctrl-S and see buffered
messages.
BRANCH=spring
Change-Id: I9ce1198a1119dadc558bb522c48037bb83bba415
Signed-off-by: Vic Yang <victoryang@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/48887
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | common/uart_buffering.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/common/uart_buffering.c b/common/uart_buffering.c index 5251507b38..277ae90a16 100644 --- a/common/uart_buffering.c +++ b/common/uart_buffering.c @@ -59,6 +59,7 @@ static volatile int rx_cur_buf_ptr; static int last_rx_was_cr; static int tx_snapshot_head; static int tx_snapshot_tail; +static int uart_suspended; static enum { ESC_OUTSIDE, /* Not in escape code */ @@ -463,6 +464,13 @@ static void handle_console_char(int c) history_next(); } else if (c == CTRL('P')) { history_prev(); + } else if (c == CTRL('Q')) { + uart_suspended = 1; + uart_tx_stop(); + } else if (c == CTRL('S')) { + uart_suspended = 0; + if (uart_tx_stopped()) + uart_tx_start(); } else if (c == '\n') { /* Newline */ uart_write_char('\r'); uart_write_char('\n'); @@ -500,6 +508,9 @@ void uart_process(void) while (uart_rx_available()) handle_console_char(uart_read_char()); + if (uart_suspended) + return; + /* Copy output from buffer until TX fifo full or output buffer empty */ fill_tx_fifo(); @@ -516,7 +527,7 @@ int uart_puts(const char *outstr) break; } - if (uart_tx_stopped()) + if (!uart_suspended && uart_tx_stopped()) uart_tx_start(); /* Successful if we consumed all output */ @@ -527,7 +538,7 @@ int uart_vprintf(const char *format, va_list args) { int rv = vfnprintf(__tx_char, NULL, format, args); - if (uart_tx_stopped()) + if (!uart_suspended && uart_tx_stopped()) uart_tx_start(); return rv; @@ -546,6 +557,10 @@ int uart_printf(const char *format, ...) void uart_flush_output(void) { + /* If UART is suspended, ignore flush request. */ + if (uart_suspended) + return; + /* * If we're in interrupt context, copy output explicitly, since the * UART interrupt may not be able to preempt this one. |