diff options
Diffstat (limited to 'kernel/debug/gdbstub.c')
-rw-r--r-- | kernel/debug/gdbstub.c | 37 |
1 files changed, 31 insertions, 6 deletions
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 @@ | |||
30 | 30 | ||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/kgdb.h> | 32 | #include <linux/kgdb.h> |
33 | #include <linux/kdb.h> | ||
33 | #include <linux/reboot.h> | 34 | #include <linux/reboot.h> |
34 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
35 | #include <asm/cacheflush.h> | 36 | #include <asm/cacheflush.h> |
@@ -62,6 +63,30 @@ static int hex(char ch) | |||
62 | return -1; | 63 | return -1; |
63 | } | 64 | } |
64 | 65 | ||
66 | #ifdef CONFIG_KGDB_KDB | ||
67 | static int gdbstub_read_wait(void) | ||
68 | { | ||
69 | int ret = -1; | ||
70 | int i; | ||
71 | |||
72 | /* poll any additional I/O interfaces that are defined */ | ||
73 | while (ret < 0) | ||
74 | for (i = 0; kdb_poll_funcs[i] != NULL; i++) { | ||
75 | ret = kdb_poll_funcs[i](); | ||
76 | if (ret > 0) | ||
77 | break; | ||
78 | } | ||
79 | return ret; | ||
80 | } | ||
81 | #else | ||
82 | static int gdbstub_read_wait(void) | ||
83 | { | ||
84 | int ret = dbg_io_ops->read_char(); | ||
85 | while (ret == NO_POLL_CHAR) | ||
86 | ret = dbg_io_ops->read_char(); | ||
87 | return ret; | ||
88 | } | ||
89 | #endif | ||
65 | /* scan for the sequence $<data>#<checksum> */ | 90 | /* scan for the sequence $<data>#<checksum> */ |
66 | static void get_packet(char *buffer) | 91 | static void get_packet(char *buffer) |
67 | { | 92 | { |
@@ -75,7 +100,7 @@ static void get_packet(char *buffer) | |||
75 | * Spin and wait around for the start character, ignore all | 100 | * Spin and wait around for the start character, ignore all |
76 | * other characters: | 101 | * other characters: |
77 | */ | 102 | */ |
78 | while ((ch = (dbg_io_ops->read_char())) != '$') | 103 | while ((ch = (gdbstub_read_wait())) != '$') |
79 | /* nothing */; | 104 | /* nothing */; |
80 | 105 | ||
81 | kgdb_connected = 1; | 106 | kgdb_connected = 1; |
@@ -88,7 +113,7 @@ static void get_packet(char *buffer) | |||
88 | * now, read until a # or end of buffer is found: | 113 | * now, read until a # or end of buffer is found: |
89 | */ | 114 | */ |
90 | while (count < (BUFMAX - 1)) { | 115 | while (count < (BUFMAX - 1)) { |
91 | ch = dbg_io_ops->read_char(); | 116 | ch = gdbstub_read_wait(); |
92 | if (ch == '#') | 117 | if (ch == '#') |
93 | break; | 118 | break; |
94 | checksum = checksum + ch; | 119 | checksum = checksum + ch; |
@@ -98,8 +123,8 @@ static void get_packet(char *buffer) | |||
98 | buffer[count] = 0; | 123 | buffer[count] = 0; |
99 | 124 | ||
100 | if (ch == '#') { | 125 | if (ch == '#') { |
101 | xmitcsum = hex(dbg_io_ops->read_char()) << 4; | 126 | xmitcsum = hex(gdbstub_read_wait()) << 4; |
102 | xmitcsum += hex(dbg_io_ops->read_char()); | 127 | xmitcsum += hex(gdbstub_read_wait()); |
103 | 128 | ||
104 | if (checksum != xmitcsum) | 129 | if (checksum != xmitcsum) |
105 | /* failed checksum */ | 130 | /* failed checksum */ |
@@ -144,10 +169,10 @@ static void put_packet(char *buffer) | |||
144 | dbg_io_ops->flush(); | 169 | dbg_io_ops->flush(); |
145 | 170 | ||
146 | /* Now see what we get in reply. */ | 171 | /* Now see what we get in reply. */ |
147 | ch = dbg_io_ops->read_char(); | 172 | ch = gdbstub_read_wait(); |
148 | 173 | ||
149 | if (ch == 3) | 174 | if (ch == 3) |
150 | ch = dbg_io_ops->read_char(); | 175 | ch = gdbstub_read_wait(); |
151 | 176 | ||
152 | /* If we get an ACK, we are done. */ | 177 | /* If we get an ACK, we are done. */ |
153 | if (ch == '+') | 178 | if (ch == '+') |