[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