From f5316b4aea024da9266d740322a5481657f6ce59 Mon Sep 17 00:00:00 2001 From: Jason Wessel Date: Thu, 20 May 2010 21:04:22 -0500 Subject: kgdb,8250,pl011: Return immediately from console poll The design of the kdb shell requires that every device that can provide input to kdb have a polling routine that exits immediately if there is no character available. This is required in order to get the page scrolling mechanism working. Changing the kernel debugger I/O API to require all polling character routines to exit immediately if there is no data allows the kernel debugger to process multiple input channels. NO_POLL_CHAR will be the return code to the polling routine when ever there is no character available. CC: linux-serial@vger.kernel.org Signed-off-by: Jason Wessel --- kernel/debug/gdbstub.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'kernel/debug/gdbstub.c') diff --git a/kernel/debug/gdbstub.c b/kernel/debug/gdbstub.c index 188203a19657..3c000490a7dd 100644 --- a/kernel/debug/gdbstub.c +++ b/kernel/debug/gdbstub.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,30 @@ static int hex(char ch) return -1; } +#ifdef CONFIG_KGDB_KDB +static int gdbstub_read_wait(void) +{ + int ret = -1; + int i; + + /* poll any additional I/O interfaces that are defined */ + while (ret < 0) + for (i = 0; kdb_poll_funcs[i] != NULL; i++) { + ret = kdb_poll_funcs[i](); + if (ret > 0) + break; + } + return ret; +} +#else +static int gdbstub_read_wait(void) +{ + int ret = dbg_io_ops->read_char(); + while (ret == NO_POLL_CHAR) + ret = dbg_io_ops->read_char(); + return ret; +} +#endif /* scan for the sequence $# */ static void get_packet(char *buffer) { @@ -75,7 +100,7 @@ static void get_packet(char *buffer) * Spin and wait around for the start character, ignore all * other characters: */ - while ((ch = (dbg_io_ops->read_char())) != '$') + while ((ch = (gdbstub_read_wait())) != '$') /* nothing */; kgdb_connected = 1; @@ -88,7 +113,7 @@ static void get_packet(char *buffer) * now, read until a # or end of buffer is found: */ while (count < (BUFMAX - 1)) { - ch = dbg_io_ops->read_char(); + ch = gdbstub_read_wait(); if (ch == '#') break; checksum = checksum + ch; @@ -98,8 +123,8 @@ static void get_packet(char *buffer) buffer[count] = 0; if (ch == '#') { - xmitcsum = hex(dbg_io_ops->read_char()) << 4; - xmitcsum += hex(dbg_io_ops->read_char()); + xmitcsum = hex(gdbstub_read_wait()) << 4; + xmitcsum += hex(gdbstub_read_wait()); if (checksum != xmitcsum) /* failed checksum */ @@ -144,10 +169,10 @@ static void put_packet(char *buffer) dbg_io_ops->flush(); /* Now see what we get in reply. */ - ch = dbg_io_ops->read_char(); + ch = gdbstub_read_wait(); if (ch == 3) - ch = dbg_io_ops->read_char(); + ch = gdbstub_read_wait(); /* If we get an ACK, we are done. */ if (ch == '+') -- cgit v1.2.3