[coreboot-gerrit] New patch to review for coreboot: 69c95e2 usbdebug: Adjust transaction retries

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Fri Aug 23 07:13:01 CEST 2013


Kyösti Mälkki (kyosti.malkki at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3881

-gerrit

commit 69c95e23b3944f4921a58ffd12c491513d206e3f
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Mon Aug 19 12:45:16 2013 +0300

    usbdebug: Adjust transaction retries
    
    Transaction consistently completes with 80 to 150 status reads on my
    setups. Hardware should always be able to complete this within 125us
    as the debug port is serviced at the beginning of each microframe.
    
    Timeout is set to DBGP_MICROFRAME_TIMEOUT_US=1000 status reads. Do not
    retry transactions if this timeout is reached as the host controller
    probably needs full re-initialisation to recover.
    
    If this timeout is not reached, but a transaction is corrupted
    on the wire, or it is otherwise not properly delivered to the USB device,
    transaction is retried upto DBGP_MICROFRAME_RETRIES=10 times.
    
    Change-Id: I44bc0a1bd194cdb5a2c13d5b81fc39bc568ae054
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/lib/usbdebug.c | 25 +++++++++++++++++--------
 1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/lib/usbdebug.c b/src/lib/usbdebug.c
index 60a0aa6..4ff2deb 100644
--- a/src/lib/usbdebug.c
+++ b/src/lib/usbdebug.c
@@ -107,6 +107,8 @@ static int dbgp_enabled(void);
 #define HUB_LONG_RESET_TIME	200
 #define HUB_RESET_TIMEOUT	500
 
+#define DBGP_MICROFRAME_TIMEOUT_US	1000
+#define DBGP_MICROFRAME_RETRIES		10
 #define DBGP_MAX_PACKET		8
 #define DBGP_LOOPS 1000
 
@@ -124,17 +126,17 @@ static inline struct ehci_debug_info *dbgp_ehci_info(void)
 static int dbgp_wait_until_complete(struct ehci_dbg_port *ehci_debug)
 {
 	u32 ctrl;
-	int loop = 0x100000;
+	int loop = 0;
 
 	do {
 		ctrl = read32((unsigned long)&ehci_debug->control);
 		/* Stop when the transaction is finished */
 		if (ctrl & DBGP_DONE)
 			break;
-	} while (--loop > 0);
+	} while (++loop < DBGP_MICROFRAME_TIMEOUT_US);
 
-	if (!loop)
-		return -1;
+	if (! (ctrl & DBGP_DONE))
+		return -DBGP_ERR_SIGNAL;
 
 	/* Now that we have observed the completed transaction,
 	 * clear the done bit.
@@ -153,18 +155,25 @@ static int dbgp_wait_until_done(struct ehci_dbg_port *ehci_debug, struct dbgp_pi
 {
 	u32 rd_ctrl, rd_pids;
 	u8 lpid;
-	int ret;
+	int ret, host_retries;
 
 retry:
+	host_retries = 0;
+host_retry:
+	if (host_retries++ >= DBGP_MICROFRAME_RETRIES)
+		return -DBGP_ERR_BAD;
 	write32((unsigned long)&ehci_debug->control, ctrl | DBGP_GO);
 	ret = dbgp_wait_until_complete(ehci_debug);
 	rd_ctrl = read32((unsigned long)&ehci_debug->control);
 	rd_pids = read32((unsigned long)&ehci_debug->pids);
 
-	if (ret < 0) {
-		if (ret == -DBGP_ERR_BAD && --loop > 0)
-			goto retry;
+	/* Controller hardware failure. */
+	if (ret == -DBGP_ERR_SIGNAL) {
 		return ret;
+
+	/* Bus failure (corrupted microframe). */
+	} else if (ret == -DBGP_ERR_BAD) {
+		goto host_retry;
 	}
 
 	lpid = DBGP_PID_GET(rd_pids);



More information about the coreboot-gerrit mailing list