diff options
author | Bill Richardson <wfrichar@chromium.org> | 2016-02-24 15:45:59 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-02-25 08:52:16 -0800 |
commit | a58c24ee374068a017a72c344729d209b2e5bc85 (patch) | |
tree | e5492719a8a0afd4c1ab78490e3fee7bc390786c | |
parent | 4f15d2189f384dba0c84594cf42a7849a9f0e562 (diff) | |
download | chrome-ec-a58c24ee374068a017a72c344729d209b2e5bc85.tar.gz |
Cr50: Fix USB two-stage control transfers
This cleans up a great deal of flakiness that we've seen on the
USB for a long time. I was misinterpreting and/or misimplementing
some of the documentation. This seems to make all the difference.
BUG=chrome-os-partner:50370
BRANCH=none
CQ-DEPEND=CL:328979,CL:*249229
TEST=make buildall, and test on Cr50
Before this CL, the USB connection would only work on USB2.0
buses, connected directly to my workstation. With this CL, it
works on USB2.0, USB3.0, through hubs, etc. Yay!
Change-Id: Icfa1910bf34f73332e2f8fc4f0d6789541549493
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/329262
Reviewed-by: Patrick Georgi <pgeorgi@chromium.org>
-rw-r--r-- | chip/g/usb.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/chip/g/usb.c b/chip/g/usb.c index 8c0f1d5500..83c1089a40 100644 --- a/chip/g/usb.c +++ b/chip/g/usb.c @@ -893,11 +893,9 @@ static void ep0_interrupt(uint32_t intr_on_out, uint32_t intr_on_in) case NO_DATA_STAGE: if (intr_on_in && (diepint & DIEPINT_XFERCOMPL)) { - print_later("Status phase complete", 0, 0, 0, 0, 0); + print_later("IN descriptor processed", 0, 0, 0, 0, 0); /* Let the IN proceed */ GR_USB_DIEPCTL(0) = DXEPCTL_EPENA; - /* We've already prepared the OUT descriptor. */ - what_am_i_doing = WAITING_FOR_SETUP_PACKET; } /* Done unless we got an OUT interrupt */ @@ -906,6 +904,8 @@ static void ep0_interrupt(uint32_t intr_on_out, uint32_t intr_on_in) if (tc == TABLE_CASE_B) { print_later("IN has been detected...", 0, 0, 0, 0, 0); + /* Let the IN proceed */ + GR_USB_DIEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA; /* Reenable the previously prepared OUT descriptor. */ GR_USB_DOEPCTL(0) = DXEPCTL_CNAK | DXEPCTL_EPENA; break; @@ -920,8 +920,9 @@ static void ep0_interrupt(uint32_t intr_on_out, uint32_t intr_on_in) } } - /* Some other kind of OUT interrupt instead. */ - report_error(tc); + /* Anything else means get ready for a Setup packet */ + print_later("Status phase complete. Maybe.", + 0, 0, 0, 0, 0); expect_setup_packet(); break; } |