aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/early/ehci-dbgp.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/early/ehci-dbgp.c')
-rw-r--r--drivers/usb/early/ehci-dbgp.c120
1 files changed, 111 insertions, 9 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c
index 6e98a3697844..94ecdbc758ce 100644
--- a/drivers/usb/early/ehci-dbgp.c
+++ b/drivers/usb/early/ehci-dbgp.c
@@ -19,6 +19,9 @@
19#include <linux/usb/ch9.h> 19#include <linux/usb/ch9.h>
20#include <linux/usb/ehci_def.h> 20#include <linux/usb/ehci_def.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/serial_core.h>
23#include <linux/kgdb.h>
24#include <linux/kthread.h>
22#include <asm/io.h> 25#include <asm/io.h>
23#include <asm/pci-direct.h> 26#include <asm/pci-direct.h>
24#include <asm/fixmap.h> 27#include <asm/fixmap.h>
@@ -55,6 +58,7 @@ static struct ehci_regs __iomem *ehci_regs;
55static struct ehci_dbg_port __iomem *ehci_debug; 58static struct ehci_dbg_port __iomem *ehci_debug;
56static int dbgp_not_safe; /* Cannot use debug device during ehci reset */ 59static int dbgp_not_safe; /* Cannot use debug device during ehci reset */
57static unsigned int dbgp_endpoint_out; 60static unsigned int dbgp_endpoint_out;
61static unsigned int dbgp_endpoint_in;
58 62
59struct ehci_dev { 63struct ehci_dev {
60 u32 bus; 64 u32 bus;
@@ -91,6 +95,13 @@ static inline u32 dbgp_len_update(u32 x, u32 len)
91 return (x & ~0x0f) | (len & 0x0f); 95 return (x & ~0x0f) | (len & 0x0f);
92} 96}
93 97
98#ifdef CONFIG_KGDB
99static struct kgdb_io kgdbdbgp_io_ops;
100#define dbgp_kgdb_mode (dbg_io_ops == &kgdbdbgp_io_ops)
101#else
102#define dbgp_kgdb_mode (0)
103#endif
104
94/* 105/*
95 * USB Packet IDs (PIDs) 106 * USB Packet IDs (PIDs)
96 */ 107 */
@@ -182,11 +193,10 @@ static void dbgp_breath(void)
182 /* Sleep to give the debug port a chance to breathe */ 193 /* Sleep to give the debug port a chance to breathe */
183} 194}
184 195
185static int dbgp_wait_until_done(unsigned ctrl) 196static int dbgp_wait_until_done(unsigned ctrl, int loop)
186{ 197{
187 u32 pids, lpid; 198 u32 pids, lpid;
188 int ret; 199 int ret;
189 int loop = DBGP_LOOPS;
190 200
191retry: 201retry:
192 writel(ctrl | DBGP_GO, &ehci_debug->control); 202 writel(ctrl | DBGP_GO, &ehci_debug->control);
@@ -276,13 +286,13 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint,
276 dbgp_set_data(bytes, size); 286 dbgp_set_data(bytes, size);
277 writel(addr, &ehci_debug->address); 287 writel(addr, &ehci_debug->address);
278 writel(pids, &ehci_debug->pids); 288 writel(pids, &ehci_debug->pids);
279 ret = dbgp_wait_until_done(ctrl); 289 ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);
280 290
281 return ret; 291 return ret;
282} 292}
283 293
284static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, 294static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
285 int size) 295 int size, int loops)
286{ 296{
287 u32 pids, addr, ctrl; 297 u32 pids, addr, ctrl;
288 int ret; 298 int ret;
@@ -302,7 +312,7 @@ static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data,
302 312
303 writel(addr, &ehci_debug->address); 313 writel(addr, &ehci_debug->address);
304 writel(pids, &ehci_debug->pids); 314 writel(pids, &ehci_debug->pids);
305 ret = dbgp_wait_until_done(ctrl); 315 ret = dbgp_wait_until_done(ctrl, loops);
306 if (ret < 0) 316 if (ret < 0)
307 return ret; 317 return ret;
308 318
@@ -343,12 +353,12 @@ static int dbgp_control_msg(unsigned devnum, int requesttype,
343 dbgp_set_data(&req, sizeof(req)); 353 dbgp_set_data(&req, sizeof(req));
344 writel(addr, &ehci_debug->address); 354 writel(addr, &ehci_debug->address);
345 writel(pids, &ehci_debug->pids); 355 writel(pids, &ehci_debug->pids);
346 ret = dbgp_wait_until_done(ctrl); 356 ret = dbgp_wait_until_done(ctrl, DBGP_LOOPS);
347 if (ret < 0) 357 if (ret < 0)
348 return ret; 358 return ret;
349 359
350 /* Read the result */ 360 /* Read the result */
351 return dbgp_bulk_read(devnum, 0, data, size); 361 return dbgp_bulk_read(devnum, 0, data, size, DBGP_LOOPS);
352} 362}
353 363
354/* Find a PCI capability */ 364/* Find a PCI capability */
@@ -559,6 +569,7 @@ try_again:
559 goto err; 569 goto err;
560 } 570 }
561 dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint; 571 dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint;
572 dbgp_endpoint_in = dbgp_desc.bDebugInEndpoint;
562 573
563 /* Move the device to 127 if it isn't already there */ 574 /* Move the device to 127 if it isn't already there */
564 if (devnum != USB_DEBUG_DEVNUM) { 575 if (devnum != USB_DEBUG_DEVNUM) {
@@ -968,8 +979,9 @@ int dbgp_reset_prep(void)
968 if (!ehci_debug) 979 if (!ehci_debug)
969 return 0; 980 return 0;
970 981
971 if (early_dbgp_console.index != -1 && 982 if ((early_dbgp_console.index != -1 &&
972 !(early_dbgp_console.flags & CON_BOOT)) 983 !(early_dbgp_console.flags & CON_BOOT)) ||
984 dbgp_kgdb_mode)
973 return 1; 985 return 1;
974 /* This means the console is not initialized, or should get 986 /* This means the console is not initialized, or should get
975 * shutdown so as to allow for reuse of the usb device, which 987 * shutdown so as to allow for reuse of the usb device, which
@@ -982,3 +994,93 @@ int dbgp_reset_prep(void)
982 return 0; 994 return 0;
983} 995}
984EXPORT_SYMBOL_GPL(dbgp_reset_prep); 996EXPORT_SYMBOL_GPL(dbgp_reset_prep);
997
998#ifdef CONFIG_KGDB
999
1000static char kgdbdbgp_buf[DBGP_MAX_PACKET];
1001static int kgdbdbgp_buf_sz;
1002static int kgdbdbgp_buf_idx;
1003static int kgdbdbgp_loop_cnt = DBGP_LOOPS;
1004
1005static int kgdbdbgp_read_char(void)
1006{
1007 int ret;
1008
1009 if (kgdbdbgp_buf_idx < kgdbdbgp_buf_sz) {
1010 char ch = kgdbdbgp_buf[kgdbdbgp_buf_idx++];
1011 return ch;
1012 }
1013
1014 ret = dbgp_bulk_read(USB_DEBUG_DEVNUM, dbgp_endpoint_in,
1015 &kgdbdbgp_buf, DBGP_MAX_PACKET,
1016 kgdbdbgp_loop_cnt);
1017 if (ret <= 0)
1018 return NO_POLL_CHAR;
1019 kgdbdbgp_buf_sz = ret;
1020 kgdbdbgp_buf_idx = 1;
1021 return kgdbdbgp_buf[0];
1022}
1023
1024static void kgdbdbgp_write_char(u8 chr)
1025{
1026 early_dbgp_write(NULL, &chr, 1);
1027}
1028
1029static struct kgdb_io kgdbdbgp_io_ops = {
1030 .name = "kgdbdbgp",
1031 .read_char = kgdbdbgp_read_char,
1032 .write_char = kgdbdbgp_write_char,
1033};
1034
1035static int kgdbdbgp_wait_time;
1036
1037static int __init kgdbdbgp_parse_config(char *str)
1038{
1039 char *ptr;
1040
1041 if (!ehci_debug) {
1042 if (early_dbgp_init(str))
1043 return -1;
1044 }
1045 ptr = strchr(str, ',');
1046 if (ptr) {
1047 ptr++;
1048 kgdbdbgp_wait_time = simple_strtoul(ptr, &ptr, 10);
1049 }
1050 kgdb_register_io_module(&kgdbdbgp_io_ops);
1051 kgdbdbgp_io_ops.is_console = early_dbgp_console.index != -1;
1052
1053 return 0;
1054}
1055early_param("kgdbdbgp", kgdbdbgp_parse_config);
1056
1057static int kgdbdbgp_reader_thread(void *ptr)
1058{
1059 int ret;
1060
1061 while (readl(&ehci_debug->control) & DBGP_ENABLED) {
1062 kgdbdbgp_loop_cnt = 1;
1063 ret = kgdbdbgp_read_char();
1064 kgdbdbgp_loop_cnt = DBGP_LOOPS;
1065 if (ret != NO_POLL_CHAR) {
1066 if (ret == 0x3 || ret == '$') {
1067 if (ret == '$')
1068 kgdbdbgp_buf_idx--;
1069 kgdb_breakpoint();
1070 }
1071 continue;
1072 }
1073 schedule_timeout_interruptible(kgdbdbgp_wait_time * HZ);
1074 }
1075 return 0;
1076}
1077
1078static int __init kgdbdbgp_start_thread(void)
1079{
1080 if (dbgp_kgdb_mode && kgdbdbgp_wait_time)
1081 kthread_run(kgdbdbgp_reader_thread, NULL, "%s", "dbgp");
1082
1083 return 0;
1084}
1085module_init(kgdbdbgp_start_thread);
1086#endif /* CONFIG_KGDB */