[coreboot-gerrit] New patch to review for coreboot: c78fc79 libpayload: Enforce strict packet handling order in ChipIdea driver
Patrick Georgi (pgeorgi@google.com)
gerrit at coreboot.org
Fri Apr 17 13:16:15 CEST 2015
Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/9788
-gerrit
commit c78fc792cc0cd92de15a45fd400a3757daf777f7
Author: Patrick Georgi <pgeorgi at google.com>
Date: Tue Mar 10 12:51:31 2015 +0100
libpayload: Enforce strict packet handling order in ChipIdea driver
First handle IN packets, then OUT packets and finally SETUP packets.
This makes OS X happy. It isn't implemented as the data sheet recommends
but it avoids implementing a state machine and should always produce
observable effects identical to that of the stateful solution.
BRANCH=none
BUG=none
TEST=`fastboot getvar version` on OSX works
Change-Id: Ic7b27387771d6a7794fba12fc822fccc48770ea8
Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
Original-Commit-Id: f0e59547519d50b1d34f6abdc6132330125f94f3
Original-Change-Id: Iada1cff011f11e7d5cb1a1b34896ab590f488ec7
Original-Signed-off-by: Patrick Georgi <pgeorgi at chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/258062
Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
---
payloads/libpayload/drivers/udc/chipidea.c | 48 ++++++++++++++++++++++--------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/payloads/libpayload/drivers/udc/chipidea.c b/payloads/libpayload/drivers/udc/chipidea.c
index a399e8c..8299a08 100644
--- a/payloads/libpayload/drivers/udc/chipidea.c
+++ b/payloads/libpayload/drivers/udc/chipidea.c
@@ -359,30 +359,54 @@ static int chipidea_poll(struct usbdev_ctrl *this)
}
if (sts & (USBSTS_UEI | USBSTS_UI)) {
- uint32_t bitmap = readl(&p->opreg->epsetupstat);
- int ep = 0;
+ uint32_t bitmap;
+ int ep;
+
+ /* This slightly deviates from the recommendation in the
+ * data sheets, but the strict ordering is to simplify
+ * handling control transfers, which are initialized in
+ * the third step with a SETUP packet, then proceed in
+ * the next poll loop with in transfers (either data or
+ * status phase), then optionally out transfers (status
+ * phase).
+ */
+
+ /* in transfers */
+ bitmap = (readl(&p->opreg->epcomplete) >> 16) & 0xffff;
+ ep = 0;
while (bitmap) {
if (bitmap & 1) {
- debug("incoming packet on EP %d (setup)\n", ep);
- start_setup(this, ep);
+ debug("incoming packet on EP %d (in)\n", ep);
+ handle_endpoint(this, ep, 1);
+ clear_ep(p, ep & 0xf, 1);
+ }
+ bitmap >>= 1;
+ ep++;
+ }
+
+ /* out transfers */
+ bitmap = readl(&p->opreg->epcomplete) & 0xffff;
+ ep = 0;
+ while (bitmap) {
+ if (bitmap & 1) {
+ debug("incoming packet on EP %d (out)\n", ep);
+ handle_endpoint(this, ep, 0);
+ clear_ep(p, ep, 0);
}
bitmap >>= 1;
ep++;
}
- bitmap = readl(&p->opreg->epcomplete);
+
+ /* setup transfers */
+ bitmap = readl(&p->opreg->epsetupstat);
ep = 0;
- int dir_in = 0;
while (bitmap) {
if (bitmap & 1) {
- debug("incoming packet on EP %d (%s)\n",
- ep, dir_in ? "intr/in" : "out");
- handle_endpoint(this, ep & 0xf, dir_in);
- clear_ep(p, ep & 0xf, dir_in);
+ debug("incoming packet on EP %d (setup)\n", ep);
+ start_setup(this, ep);
}
bitmap >>= 1;
ep++;
- if (ep == 16)
- dir_in = 1;
}
}
More information about the coreboot-gerrit
mailing list