diff options
Diffstat (limited to 'drivers/usb/early')
-rw-r--r-- | drivers/usb/early/ehci-dbgp.c | 442 |
1 files changed, 294 insertions, 148 deletions
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index 6198ebded3a4..06e05ea17871 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -1,5 +1,19 @@ | |||
1 | /* | ||
2 | * Standalone EHCI usb debug driver | ||
3 | * | ||
4 | * Originally written by: | ||
5 | * Eric W. Biederman" <ebiederm@xmission.com> and | ||
6 | * Yinghai Lu <yhlu.kernel@gmail.com> | ||
7 | * | ||
8 | * Changes for early/late printk and HW errata: | ||
9 | * Jason Wessel <jason.wessel@windriver.com> | ||
10 | * Copyright (C) 2009 Wind River Systems, Inc. | ||
11 | * | ||
12 | */ | ||
13 | |||
1 | #include <linux/console.h> | 14 | #include <linux/console.h> |
2 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/module.h> | ||
3 | #include <linux/pci_regs.h> | 17 | #include <linux/pci_regs.h> |
4 | #include <linux/pci_ids.h> | 18 | #include <linux/pci_ids.h> |
5 | #include <linux/usb/ch9.h> | 19 | #include <linux/usb/ch9.h> |
@@ -9,15 +23,37 @@ | |||
9 | #include <asm/pci-direct.h> | 23 | #include <asm/pci-direct.h> |
10 | #include <asm/fixmap.h> | 24 | #include <asm/fixmap.h> |
11 | 25 | ||
12 | #ifdef DBGP_DEBUG | 26 | /* The code here is intended to talk directly to the EHCI debug port |
13 | # define dbgp_printk printk | 27 | * and does not require that you have any kind of USB host controller |
14 | #else | 28 | * drivers or USB device drivers compiled into the kernel. |
15 | static inline void dbgp_printk(const char *fmt, ...) { } | 29 | * |
16 | #endif | 30 | * If you make a change to anything in here, the following test cases |
31 | * need to pass where a USB debug device works in the following | ||
32 | * configurations. | ||
33 | * | ||
34 | * 1. boot args: earlyprintk=dbgp | ||
35 | * o kernel compiled with # CONFIG_USB_EHCI_HCD is not set | ||
36 | * o kernel compiled with CONFIG_USB_EHCI_HCD=y | ||
37 | * 2. boot args: earlyprintk=dbgp,keep | ||
38 | * o kernel compiled with # CONFIG_USB_EHCI_HCD is not set | ||
39 | * o kernel compiled with CONFIG_USB_EHCI_HCD=y | ||
40 | * 3. boot args: earlyprintk=dbgp console=ttyUSB0 | ||
41 | * o kernel has CONFIG_USB_EHCI_HCD=y and | ||
42 | * CONFIG_USB_SERIAL_DEBUG=y | ||
43 | * 4. boot args: earlyprintk=vga,dbgp | ||
44 | * o kernel compiled with # CONFIG_USB_EHCI_HCD is not set | ||
45 | * o kernel compiled with CONFIG_USB_EHCI_HCD=y | ||
46 | * | ||
47 | * For the 4th configuration you can turn on or off the DBGP_DEBUG | ||
48 | * such that you can debug the dbgp device's driver code. | ||
49 | */ | ||
50 | |||
51 | static int dbgp_phys_port = 1; | ||
17 | 52 | ||
18 | static struct ehci_caps __iomem *ehci_caps; | 53 | static struct ehci_caps __iomem *ehci_caps; |
19 | static struct ehci_regs __iomem *ehci_regs; | 54 | static struct ehci_regs __iomem *ehci_regs; |
20 | static struct ehci_dbg_port __iomem *ehci_debug; | 55 | static struct ehci_dbg_port __iomem *ehci_debug; |
56 | static int dbgp_not_safe; /* Cannot use debug device during ehci reset */ | ||
21 | static unsigned int dbgp_endpoint_out; | 57 | static unsigned int dbgp_endpoint_out; |
22 | 58 | ||
23 | struct ehci_dev { | 59 | struct ehci_dev { |
@@ -32,6 +68,26 @@ static struct ehci_dev ehci_dev; | |||
32 | 68 | ||
33 | #define DBGP_DATA_TOGGLE 0x8800 | 69 | #define DBGP_DATA_TOGGLE 0x8800 |
34 | 70 | ||
71 | #ifdef DBGP_DEBUG | ||
72 | #define dbgp_printk printk | ||
73 | static void dbgp_ehci_status(char *str) | ||
74 | { | ||
75 | if (!ehci_debug) | ||
76 | return; | ||
77 | dbgp_printk("dbgp: %s\n", str); | ||
78 | dbgp_printk(" Debug control: %08x", readl(&ehci_debug->control)); | ||
79 | dbgp_printk(" ehci cmd : %08x", readl(&ehci_regs->command)); | ||
80 | dbgp_printk(" ehci conf flg: %08x\n", | ||
81 | readl(&ehci_regs->configured_flag)); | ||
82 | dbgp_printk(" ehci status : %08x", readl(&ehci_regs->status)); | ||
83 | dbgp_printk(" ehci portsc : %08x\n", | ||
84 | readl(&ehci_regs->port_status[dbgp_phys_port - 1])); | ||
85 | } | ||
86 | #else | ||
87 | static inline void dbgp_ehci_status(char *str) { } | ||
88 | static inline void dbgp_printk(const char *fmt, ...) { } | ||
89 | #endif | ||
90 | |||
35 | static inline u32 dbgp_pid_update(u32 x, u32 tok) | 91 | static inline u32 dbgp_pid_update(u32 x, u32 tok) |
36 | { | 92 | { |
37 | return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff); | 93 | return ((x ^ DBGP_DATA_TOGGLE) & 0xffff00) | (tok & 0xff); |
@@ -79,21 +135,23 @@ static inline u32 dbgp_len_update(u32 x, u32 len) | |||
79 | #define HUB_RESET_TIMEOUT 500 | 135 | #define HUB_RESET_TIMEOUT 500 |
80 | 136 | ||
81 | #define DBGP_MAX_PACKET 8 | 137 | #define DBGP_MAX_PACKET 8 |
138 | #define DBGP_TIMEOUT (250 * 1000) | ||
82 | 139 | ||
83 | static int dbgp_wait_until_complete(void) | 140 | static int dbgp_wait_until_complete(void) |
84 | { | 141 | { |
85 | u32 ctrl; | 142 | u32 ctrl; |
86 | int loop = 0x100000; | 143 | int loop = DBGP_TIMEOUT; |
87 | 144 | ||
88 | do { | 145 | do { |
89 | ctrl = readl(&ehci_debug->control); | 146 | ctrl = readl(&ehci_debug->control); |
90 | /* Stop when the transaction is finished */ | 147 | /* Stop when the transaction is finished */ |
91 | if (ctrl & DBGP_DONE) | 148 | if (ctrl & DBGP_DONE) |
92 | break; | 149 | break; |
150 | udelay(1); | ||
93 | } while (--loop > 0); | 151 | } while (--loop > 0); |
94 | 152 | ||
95 | if (!loop) | 153 | if (!loop) |
96 | return -1; | 154 | return -DBGP_TIMEOUT; |
97 | 155 | ||
98 | /* | 156 | /* |
99 | * Now that we have observed the completed transaction, | 157 | * Now that we have observed the completed transaction, |
@@ -103,7 +161,7 @@ static int dbgp_wait_until_complete(void) | |||
103 | return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl); | 161 | return (ctrl & DBGP_ERROR) ? -DBGP_ERRCODE(ctrl) : DBGP_LEN(ctrl); |
104 | } | 162 | } |
105 | 163 | ||
106 | static void __init dbgp_mdelay(int ms) | 164 | static inline void dbgp_mdelay(int ms) |
107 | { | 165 | { |
108 | int i; | 166 | int i; |
109 | 167 | ||
@@ -130,8 +188,17 @@ retry: | |||
130 | pids = readl(&ehci_debug->pids); | 188 | pids = readl(&ehci_debug->pids); |
131 | lpid = DBGP_PID_GET(pids); | 189 | lpid = DBGP_PID_GET(pids); |
132 | 190 | ||
133 | if (ret < 0) | 191 | if (ret < 0) { |
192 | /* A -DBGP_TIMEOUT failure here means the device has | ||
193 | * failed, perhaps because it was unplugged, in which | ||
194 | * case we do not want to hang the system so the dbgp | ||
195 | * will be marked as unsafe to use. EHCI reset is the | ||
196 | * only way to recover if you unplug the dbgp device. | ||
197 | */ | ||
198 | if (ret == -DBGP_TIMEOUT && !dbgp_not_safe) | ||
199 | dbgp_not_safe = 1; | ||
134 | return ret; | 200 | return ret; |
201 | } | ||
135 | 202 | ||
136 | /* | 203 | /* |
137 | * If the port is getting full or it has dropped data | 204 | * If the port is getting full or it has dropped data |
@@ -149,7 +216,7 @@ retry: | |||
149 | return ret; | 216 | return ret; |
150 | } | 217 | } |
151 | 218 | ||
152 | static void dbgp_set_data(const void *buf, int size) | 219 | static inline void dbgp_set_data(const void *buf, int size) |
153 | { | 220 | { |
154 | const unsigned char *bytes = buf; | 221 | const unsigned char *bytes = buf; |
155 | u32 lo, hi; | 222 | u32 lo, hi; |
@@ -164,7 +231,7 @@ static void dbgp_set_data(const void *buf, int size) | |||
164 | writel(hi, &ehci_debug->data47); | 231 | writel(hi, &ehci_debug->data47); |
165 | } | 232 | } |
166 | 233 | ||
167 | static void __init dbgp_get_data(void *buf, int size) | 234 | static inline void dbgp_get_data(void *buf, int size) |
168 | { | 235 | { |
169 | unsigned char *bytes = buf; | 236 | unsigned char *bytes = buf; |
170 | u32 lo, hi; | 237 | u32 lo, hi; |
@@ -208,7 +275,7 @@ static int dbgp_bulk_write(unsigned devnum, unsigned endpoint, | |||
208 | return ret; | 275 | return ret; |
209 | } | 276 | } |
210 | 277 | ||
211 | static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, | 278 | static int dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, |
212 | int size) | 279 | int size) |
213 | { | 280 | { |
214 | u32 pids, addr, ctrl; | 281 | u32 pids, addr, ctrl; |
@@ -239,7 +306,7 @@ static int __init dbgp_bulk_read(unsigned devnum, unsigned endpoint, void *data, | |||
239 | return ret; | 306 | return ret; |
240 | } | 307 | } |
241 | 308 | ||
242 | static int __init dbgp_control_msg(unsigned devnum, int requesttype, | 309 | static int dbgp_control_msg(unsigned devnum, int requesttype, |
243 | int request, int value, int index, void *data, int size) | 310 | int request, int value, int index, void *data, int size) |
244 | { | 311 | { |
245 | u32 pids, addr, ctrl; | 312 | u32 pids, addr, ctrl; |
@@ -342,13 +409,179 @@ static u32 __init find_dbgp(int ehci_num, u32 *rbus, u32 *rslot, u32 *rfunc) | |||
342 | return 0; | 409 | return 0; |
343 | } | 410 | } |
344 | 411 | ||
412 | static int dbgp_ehci_startup(void) | ||
413 | { | ||
414 | u32 ctrl, cmd, status; | ||
415 | int loop; | ||
416 | |||
417 | /* Claim ownership, but do not enable yet */ | ||
418 | ctrl = readl(&ehci_debug->control); | ||
419 | ctrl |= DBGP_OWNER; | ||
420 | ctrl &= ~(DBGP_ENABLED | DBGP_INUSE); | ||
421 | writel(ctrl, &ehci_debug->control); | ||
422 | udelay(1); | ||
423 | |||
424 | dbgp_ehci_status("EHCI startup"); | ||
425 | /* Start the ehci running */ | ||
426 | cmd = readl(&ehci_regs->command); | ||
427 | cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET); | ||
428 | cmd |= CMD_RUN; | ||
429 | writel(cmd, &ehci_regs->command); | ||
430 | |||
431 | /* Ensure everything is routed to the EHCI */ | ||
432 | writel(FLAG_CF, &ehci_regs->configured_flag); | ||
433 | |||
434 | /* Wait until the controller is no longer halted */ | ||
435 | loop = 10; | ||
436 | do { | ||
437 | status = readl(&ehci_regs->status); | ||
438 | if (!(status & STS_HALT)) | ||
439 | break; | ||
440 | udelay(1); | ||
441 | } while (--loop > 0); | ||
442 | |||
443 | if (!loop) { | ||
444 | dbgp_printk("ehci can not be started\n"); | ||
445 | return -ENODEV; | ||
446 | } | ||
447 | dbgp_printk("ehci started\n"); | ||
448 | return 0; | ||
449 | } | ||
450 | |||
451 | static int dbgp_ehci_controller_reset(void) | ||
452 | { | ||
453 | int loop = 250 * 1000; | ||
454 | u32 cmd; | ||
455 | |||
456 | /* Reset the EHCI controller */ | ||
457 | cmd = readl(&ehci_regs->command); | ||
458 | cmd |= CMD_RESET; | ||
459 | writel(cmd, &ehci_regs->command); | ||
460 | do { | ||
461 | cmd = readl(&ehci_regs->command); | ||
462 | } while ((cmd & CMD_RESET) && (--loop > 0)); | ||
463 | |||
464 | if (!loop) { | ||
465 | dbgp_printk("can not reset ehci\n"); | ||
466 | return -1; | ||
467 | } | ||
468 | dbgp_ehci_status("ehci reset done"); | ||
469 | return 0; | ||
470 | } | ||
471 | static int ehci_wait_for_port(int port); | ||
472 | /* Return 0 on success | ||
473 | * Return -ENODEV for any general failure | ||
474 | * Return -EIO if wait for port fails | ||
475 | */ | ||
476 | int dbgp_external_startup(void) | ||
477 | { | ||
478 | int devnum; | ||
479 | struct usb_debug_descriptor dbgp_desc; | ||
480 | int ret; | ||
481 | u32 ctrl, portsc; | ||
482 | int dbg_port = dbgp_phys_port; | ||
483 | int tries = 3; | ||
484 | |||
485 | ret = dbgp_ehci_startup(); | ||
486 | if (ret) | ||
487 | return ret; | ||
488 | |||
489 | /* Wait for a device to show up in the debug port */ | ||
490 | ret = ehci_wait_for_port(dbg_port); | ||
491 | if (ret < 0) { | ||
492 | portsc = readl(&ehci_regs->port_status[dbg_port - 1]); | ||
493 | dbgp_printk("No device found in debug port\n"); | ||
494 | return -EIO; | ||
495 | } | ||
496 | dbgp_ehci_status("wait for port done"); | ||
497 | |||
498 | /* Enable the debug port */ | ||
499 | ctrl = readl(&ehci_debug->control); | ||
500 | ctrl |= DBGP_CLAIM; | ||
501 | writel(ctrl, &ehci_debug->control); | ||
502 | ctrl = readl(&ehci_debug->control); | ||
503 | if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) { | ||
504 | dbgp_printk("No device in debug port\n"); | ||
505 | writel(ctrl & ~DBGP_CLAIM, &ehci_debug->control); | ||
506 | return -ENODEV; | ||
507 | } | ||
508 | dbgp_ehci_status("debug ported enabled"); | ||
509 | |||
510 | /* Completely transfer the debug device to the debug controller */ | ||
511 | portsc = readl(&ehci_regs->port_status[dbg_port - 1]); | ||
512 | portsc &= ~PORT_PE; | ||
513 | writel(portsc, &ehci_regs->port_status[dbg_port - 1]); | ||
514 | |||
515 | dbgp_mdelay(100); | ||
516 | |||
517 | try_again: | ||
518 | /* Find the debug device and make it device number 127 */ | ||
519 | for (devnum = 0; devnum <= 127; devnum++) { | ||
520 | ret = dbgp_control_msg(devnum, | ||
521 | USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
522 | USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0, | ||
523 | &dbgp_desc, sizeof(dbgp_desc)); | ||
524 | if (ret > 0) | ||
525 | break; | ||
526 | } | ||
527 | if (devnum > 127) { | ||
528 | dbgp_printk("Could not find attached debug device\n"); | ||
529 | goto err; | ||
530 | } | ||
531 | if (ret < 0) { | ||
532 | dbgp_printk("Attached device is not a debug device\n"); | ||
533 | goto err; | ||
534 | } | ||
535 | dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint; | ||
536 | |||
537 | /* Move the device to 127 if it isn't already there */ | ||
538 | if (devnum != USB_DEBUG_DEVNUM) { | ||
539 | ret = dbgp_control_msg(devnum, | ||
540 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
541 | USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0); | ||
542 | if (ret < 0) { | ||
543 | dbgp_printk("Could not move attached device to %d\n", | ||
544 | USB_DEBUG_DEVNUM); | ||
545 | goto err; | ||
546 | } | ||
547 | devnum = USB_DEBUG_DEVNUM; | ||
548 | dbgp_printk("debug device renamed to 127\n"); | ||
549 | } | ||
550 | |||
551 | /* Enable the debug interface */ | ||
552 | ret = dbgp_control_msg(USB_DEBUG_DEVNUM, | ||
553 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
554 | USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0); | ||
555 | if (ret < 0) { | ||
556 | dbgp_printk(" Could not enable the debug device\n"); | ||
557 | goto err; | ||
558 | } | ||
559 | dbgp_printk("debug interface enabled\n"); | ||
560 | /* Perform a small write to get the even/odd data state in sync | ||
561 | */ | ||
562 | ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, dbgp_endpoint_out, " ", 1); | ||
563 | if (ret < 0) { | ||
564 | dbgp_printk("dbgp_bulk_write failed: %d\n", ret); | ||
565 | goto err; | ||
566 | } | ||
567 | dbgp_printk("small write doned\n"); | ||
568 | dbgp_not_safe = 0; | ||
569 | |||
570 | return 0; | ||
571 | err: | ||
572 | if (tries--) | ||
573 | goto try_again; | ||
574 | return -ENODEV; | ||
575 | } | ||
576 | EXPORT_SYMBOL_GPL(dbgp_external_startup); | ||
577 | |||
345 | static int __init ehci_reset_port(int port) | 578 | static int __init ehci_reset_port(int port) |
346 | { | 579 | { |
347 | u32 portsc; | 580 | u32 portsc; |
348 | u32 delay_time, delay; | 581 | u32 delay_time, delay; |
349 | int loop; | 582 | int loop; |
350 | 583 | ||
351 | dbgp_printk("ehci_reset_port %i\n", port); | 584 | dbgp_ehci_status("reset port"); |
352 | /* Reset the usb debug port */ | 585 | /* Reset the usb debug port */ |
353 | portsc = readl(&ehci_regs->port_status[port - 1]); | 586 | portsc = readl(&ehci_regs->port_status[port - 1]); |
354 | portsc &= ~PORT_PE; | 587 | portsc &= ~PORT_PE; |
@@ -388,7 +621,7 @@ static int __init ehci_reset_port(int port) | |||
388 | return -EBUSY; | 621 | return -EBUSY; |
389 | } | 622 | } |
390 | 623 | ||
391 | static int __init ehci_wait_for_port(int port) | 624 | static int ehci_wait_for_port(int port) |
392 | { | 625 | { |
393 | u32 status; | 626 | u32 status; |
394 | int ret, reps; | 627 | int ret, reps; |
@@ -487,12 +720,9 @@ static void __init early_ehci_bios_handoff(void) | |||
487 | 720 | ||
488 | static int __init ehci_setup(void) | 721 | static int __init ehci_setup(void) |
489 | { | 722 | { |
490 | struct usb_debug_descriptor dbgp_desc; | 723 | u32 ctrl, portsc, hcs_params; |
491 | u32 cmd, ctrl, status, portsc, hcs_params; | ||
492 | u32 debug_port, new_debug_port = 0, n_ports; | 724 | u32 debug_port, new_debug_port = 0, n_ports; |
493 | u32 devnum; | ||
494 | int ret, i; | 725 | int ret, i; |
495 | int loop; | ||
496 | int port_map_tried; | 726 | int port_map_tried; |
497 | int playtimes = 3; | 727 | int playtimes = 3; |
498 | 728 | ||
@@ -505,10 +735,12 @@ try_next_port: | |||
505 | 735 | ||
506 | hcs_params = readl(&ehci_caps->hcs_params); | 736 | hcs_params = readl(&ehci_caps->hcs_params); |
507 | debug_port = HCS_DEBUG_PORT(hcs_params); | 737 | debug_port = HCS_DEBUG_PORT(hcs_params); |
738 | dbgp_phys_port = debug_port; | ||
508 | n_ports = HCS_N_PORTS(hcs_params); | 739 | n_ports = HCS_N_PORTS(hcs_params); |
509 | 740 | ||
510 | dbgp_printk("debug_port: %d\n", debug_port); | 741 | dbgp_printk("debug_port: %d\n", debug_port); |
511 | dbgp_printk("n_ports: %d\n", n_ports); | 742 | dbgp_printk("n_ports: %d\n", n_ports); |
743 | dbgp_ehci_status(""); | ||
512 | 744 | ||
513 | for (i = 1; i <= n_ports; i++) { | 745 | for (i = 1; i <= n_ports; i++) { |
514 | portsc = readl(&ehci_regs->port_status[i-1]); | 746 | portsc = readl(&ehci_regs->port_status[i-1]); |
@@ -523,138 +755,27 @@ try_next_port: | |||
523 | return -1; | 755 | return -1; |
524 | } | 756 | } |
525 | 757 | ||
526 | loop = 250 * 1000; | 758 | /* Only reset the controller if it is not already in the |
527 | /* Reset the EHCI controller */ | 759 | * configured state */ |
528 | cmd = readl(&ehci_regs->command); | 760 | if (!(readl(&ehci_regs->configured_flag) & FLAG_CF)) { |
529 | cmd |= CMD_RESET; | 761 | if (dbgp_ehci_controller_reset() != 0) |
530 | writel(cmd, &ehci_regs->command); | 762 | return -1; |
531 | do { | 763 | } else { |
532 | cmd = readl(&ehci_regs->command); | 764 | dbgp_ehci_status("ehci skip - already configured"); |
533 | } while ((cmd & CMD_RESET) && (--loop > 0)); | ||
534 | |||
535 | if (!loop) { | ||
536 | dbgp_printk("can not reset ehci\n"); | ||
537 | return -1; | ||
538 | } | ||
539 | dbgp_printk("ehci reset done\n"); | ||
540 | |||
541 | /* Claim ownership, but do not enable yet */ | ||
542 | ctrl = readl(&ehci_debug->control); | ||
543 | ctrl |= DBGP_OWNER; | ||
544 | ctrl &= ~(DBGP_ENABLED | DBGP_INUSE); | ||
545 | writel(ctrl, &ehci_debug->control); | ||
546 | udelay(1); | ||
547 | |||
548 | /* Start the ehci running */ | ||
549 | cmd = readl(&ehci_regs->command); | ||
550 | cmd &= ~(CMD_LRESET | CMD_IAAD | CMD_PSE | CMD_ASE | CMD_RESET); | ||
551 | cmd |= CMD_RUN; | ||
552 | writel(cmd, &ehci_regs->command); | ||
553 | |||
554 | /* Ensure everything is routed to the EHCI */ | ||
555 | writel(FLAG_CF, &ehci_regs->configured_flag); | ||
556 | |||
557 | /* Wait until the controller is no longer halted */ | ||
558 | loop = 10; | ||
559 | do { | ||
560 | status = readl(&ehci_regs->status); | ||
561 | if (!(status & STS_HALT)) | ||
562 | break; | ||
563 | udelay(1); | ||
564 | } while (--loop > 0); | ||
565 | |||
566 | if (!loop) { | ||
567 | dbgp_printk("ehci can not be started\n"); | ||
568 | return -1; | ||
569 | } | 765 | } |
570 | dbgp_printk("ehci started\n"); | ||
571 | 766 | ||
572 | /* Wait for a device to show up in the debug port */ | 767 | ret = dbgp_external_startup(); |
573 | ret = ehci_wait_for_port(debug_port); | 768 | if (ret == -EIO) |
574 | if (ret < 0) { | ||
575 | dbgp_printk("No device found in debug port\n"); | ||
576 | goto next_debug_port; | 769 | goto next_debug_port; |
577 | } | ||
578 | dbgp_printk("ehci wait for port done\n"); | ||
579 | |||
580 | /* Enable the debug port */ | ||
581 | ctrl = readl(&ehci_debug->control); | ||
582 | ctrl |= DBGP_CLAIM; | ||
583 | writel(ctrl, &ehci_debug->control); | ||
584 | ctrl = readl(&ehci_debug->control); | ||
585 | if ((ctrl & DBGP_CLAIM) != DBGP_CLAIM) { | ||
586 | dbgp_printk("No device in debug port\n"); | ||
587 | writel(ctrl & ~DBGP_CLAIM, &ehci_debug->control); | ||
588 | goto err; | ||
589 | } | ||
590 | dbgp_printk("debug ported enabled\n"); | ||
591 | 770 | ||
592 | /* Completely transfer the debug device to the debug controller */ | ||
593 | portsc = readl(&ehci_regs->port_status[debug_port - 1]); | ||
594 | portsc &= ~PORT_PE; | ||
595 | writel(portsc, &ehci_regs->port_status[debug_port - 1]); | ||
596 | |||
597 | dbgp_mdelay(100); | ||
598 | |||
599 | /* Find the debug device and make it device number 127 */ | ||
600 | for (devnum = 0; devnum <= 127; devnum++) { | ||
601 | ret = dbgp_control_msg(devnum, | ||
602 | USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
603 | USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0, | ||
604 | &dbgp_desc, sizeof(dbgp_desc)); | ||
605 | if (ret > 0) | ||
606 | break; | ||
607 | } | ||
608 | if (devnum > 127) { | ||
609 | dbgp_printk("Could not find attached debug device\n"); | ||
610 | goto err; | ||
611 | } | ||
612 | if (ret < 0) { | 771 | if (ret < 0) { |
613 | dbgp_printk("Attached device is not a debug device\n"); | 772 | /* Things didn't work so remove my claim */ |
614 | goto err; | 773 | ctrl = readl(&ehci_debug->control); |
615 | } | 774 | ctrl &= ~(DBGP_CLAIM | DBGP_OUT); |
616 | dbgp_endpoint_out = dbgp_desc.bDebugOutEndpoint; | 775 | writel(ctrl, &ehci_debug->control); |
617 | 776 | return -1; | |
618 | /* Move the device to 127 if it isn't already there */ | ||
619 | if (devnum != USB_DEBUG_DEVNUM) { | ||
620 | ret = dbgp_control_msg(devnum, | ||
621 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
622 | USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0); | ||
623 | if (ret < 0) { | ||
624 | dbgp_printk("Could not move attached device to %d\n", | ||
625 | USB_DEBUG_DEVNUM); | ||
626 | goto err; | ||
627 | } | ||
628 | devnum = USB_DEBUG_DEVNUM; | ||
629 | dbgp_printk("debug device renamed to 127\n"); | ||
630 | } | ||
631 | |||
632 | /* Enable the debug interface */ | ||
633 | ret = dbgp_control_msg(USB_DEBUG_DEVNUM, | ||
634 | USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
635 | USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0); | ||
636 | if (ret < 0) { | ||
637 | dbgp_printk(" Could not enable the debug device\n"); | ||
638 | goto err; | ||
639 | } | ||
640 | dbgp_printk("debug interface enabled\n"); | ||
641 | |||
642 | /* Perform a small write to get the even/odd data state in sync | ||
643 | */ | ||
644 | ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, dbgp_endpoint_out, " ", 1); | ||
645 | if (ret < 0) { | ||
646 | dbgp_printk("dbgp_bulk_write failed: %d\n", ret); | ||
647 | goto err; | ||
648 | } | 777 | } |
649 | dbgp_printk("small write doned\n"); | ||
650 | |||
651 | return 0; | 778 | return 0; |
652 | err: | ||
653 | /* Things didn't work so remove my claim */ | ||
654 | ctrl = readl(&ehci_debug->control); | ||
655 | ctrl &= ~(DBGP_CLAIM | DBGP_OUT); | ||
656 | writel(ctrl, &ehci_debug->control); | ||
657 | return -1; | ||
658 | 779 | ||
659 | next_debug_port: | 780 | next_debug_port: |
660 | port_map_tried |= (1<<(debug_port - 1)); | 781 | port_map_tried |= (1<<(debug_port - 1)); |
@@ -749,6 +870,7 @@ int __init early_dbgp_init(char *s) | |||
749 | 870 | ||
750 | return -1; | 871 | return -1; |
751 | } | 872 | } |
873 | dbgp_ehci_status("early_init_complete"); | ||
752 | 874 | ||
753 | return 0; | 875 | return 0; |
754 | } | 876 | } |
@@ -758,9 +880,27 @@ static void early_dbgp_write(struct console *con, const char *str, u32 n) | |||
758 | int chunk, ret; | 880 | int chunk, ret; |
759 | char buf[DBGP_MAX_PACKET]; | 881 | char buf[DBGP_MAX_PACKET]; |
760 | int use_cr = 0; | 882 | int use_cr = 0; |
883 | u32 cmd, ctrl; | ||
884 | int reset_run = 0; | ||
761 | 885 | ||
762 | if (!ehci_debug) | 886 | if (!ehci_debug || dbgp_not_safe) |
763 | return; | 887 | return; |
888 | |||
889 | cmd = readl(&ehci_regs->command); | ||
890 | if (unlikely(!(cmd & CMD_RUN))) { | ||
891 | /* If the ehci controller is not in the run state do extended | ||
892 | * checks to see if the acpi or some other initialization also | ||
893 | * reset the ehci debug port */ | ||
894 | ctrl = readl(&ehci_debug->control); | ||
895 | if (!(ctrl & DBGP_ENABLED)) { | ||
896 | dbgp_not_safe = 1; | ||
897 | dbgp_external_startup(); | ||
898 | } else { | ||
899 | cmd |= CMD_RUN; | ||
900 | writel(cmd, &ehci_regs->command); | ||
901 | reset_run = 1; | ||
902 | } | ||
903 | } | ||
764 | while (n > 0) { | 904 | while (n > 0) { |
765 | for (chunk = 0; chunk < DBGP_MAX_PACKET && n > 0; | 905 | for (chunk = 0; chunk < DBGP_MAX_PACKET && n > 0; |
766 | str++, chunk++, n--) { | 906 | str++, chunk++, n--) { |
@@ -775,8 +915,15 @@ static void early_dbgp_write(struct console *con, const char *str, u32 n) | |||
775 | use_cr = 0; | 915 | use_cr = 0; |
776 | buf[chunk] = *str; | 916 | buf[chunk] = *str; |
777 | } | 917 | } |
778 | ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, | 918 | if (chunk > 0) { |
779 | dbgp_endpoint_out, buf, chunk); | 919 | ret = dbgp_bulk_write(USB_DEBUG_DEVNUM, |
920 | dbgp_endpoint_out, buf, chunk); | ||
921 | } | ||
922 | } | ||
923 | if (unlikely(reset_run)) { | ||
924 | cmd = readl(&ehci_regs->command); | ||
925 | cmd &= ~CMD_RUN; | ||
926 | writel(cmd, &ehci_regs->command); | ||
780 | } | 927 | } |
781 | } | 928 | } |
782 | 929 | ||
@@ -786,4 +933,3 @@ struct console early_dbgp_console = { | |||
786 | .flags = CON_PRINTBUFFER, | 933 | .flags = CON_PRINTBUFFER, |
787 | .index = -1, | 934 | .index = -1, |
788 | }; | 935 | }; |
789 | |||