[coreboot-gerrit] Patch set updated for coreboot: 0b34de9 usbdebug: Use separate data toggle for each pipe

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Fri Aug 23 07:12:58 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/3865

-gerrit

commit 0b34de9aeda740ddb26876392a4f7de00227e09c
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Sat Aug 10 10:50:38 2013 +0300

    usbdebug: Use separate data toggle for each pipe
    
    USB defines a mechanism to detect certain cases of lost handshakes
    using an alternating data sequence number, referred to as data
    toggling. This patch fixes each pipe to have its own tracking of
    the data toggle state.
    
    Change-Id: I62420bdaeadd0842da3189428a37eeb10c646900
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/lib/usbdebug.c | 45 ++++++++++++++++++++++++++-------------------
 1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/src/lib/usbdebug.c b/src/lib/usbdebug.c
index 9e8f42c..aa79088 100644
--- a/src/lib/usbdebug.c
+++ b/src/lib/usbdebug.c
@@ -41,6 +41,7 @@ struct dbgp_pipe
 {
 	u8 devnum;
 	u8 endpoint;
+	u8 pid;
 	u8 status;
 	u8 bufidx;
 	char buf[8];
@@ -69,10 +70,6 @@ static int dbgp_enabled(void);
 
 #define USB_DEBUG_DEVNUM 127
 
-#define DBGP_DATA_TOGGLE	0x8800
-#define DBGP_PID_UPDATE(x, tok) \
-	((((x) ^ DBGP_DATA_TOGGLE) & 0xffff00) | ((tok) & 0xff))
-
 #define DBGP_LEN_UPDATE(x, len) (((x) & ~0x0f) | ((len) & 0x0f))
 /*
  * USB Packet IDs (PIDs)
@@ -154,14 +151,15 @@ static void dbgp_breath(void)
 static int dbgp_wait_until_done(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe,
 	unsigned ctrl, int loop)
 {
-	u32 pids, lpid;
+	u32 rd_ctrl, rd_pids;
+	u8 lpid;
 	int ret;
 
 retry:
 	write32((unsigned long)&ehci_debug->control, ctrl | DBGP_GO);
 	ret = dbgp_wait_until_complete(ehci_debug);
-	pids = read32((unsigned long)&ehci_debug->pids);
-	lpid = DBGP_PID_GET(pids);
+	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)
@@ -169,16 +167,29 @@ retry:
 		return ret;
 	}
 
+	lpid = DBGP_PID_GET(rd_pids);
+
+	/* If I get an ACK or in-sync DATA PID, we are done. */
+	if ((lpid == USB_PID_ACK) || (lpid == pipe->pid)) {
+		if (DBGP_LEN(rd_ctrl))
+			pipe->pid ^= USB_PID_DATA_TOGGLE;
+	}
+
 	/* If the port is getting full or it has dropped data
 	 * start pacing ourselves, not necessary but it's friendly.
 	 */
-	if ((lpid == USB_PID_NAK) || (lpid == USB_PID_NYET))
+	else if (lpid == USB_PID_NYET) {
 		dbgp_breath();
+		if (--loop > 0)
+			goto retry;
+		ret = -DBGP_ERR_BAD;
+	}
 
-	/* If I get a NACK reissue the transmission */
-	if (lpid == USB_PID_NAK) {
+	/* If I get a NACK or out-of-sync DATA PID, reissue the transmission. */
+	else if ((lpid == USB_PID_NAK) || (lpid == (pipe->pid ^ USB_PID_DATA_TOGGLE))) {
 		if (--loop > 0)
 			goto retry;
+		ret = -DBGP_ERR_BAD;
 	}
 
 	return ret;
@@ -223,14 +234,11 @@ static int dbgp_bulk_write(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *p
 		return -1;
 
 	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
-
-	pids = read32((unsigned long)&ehci_debug->pids);
-	pids = DBGP_PID_UPDATE(pids, USB_PID_OUT);
+	pids = DBGP_PID_SET(pipe->pid, USB_PID_OUT);
 
 	ctrl = read32((unsigned long)&ehci_debug->control);
 	ctrl = DBGP_LEN_UPDATE(ctrl, size);
 	ctrl |= DBGP_OUT;
-	ctrl |= DBGP_GO;
 
 	dbgp_set_data(ehci_debug, bytes, size);
 	write32((unsigned long)&ehci_debug->address, addr);
@@ -257,14 +265,11 @@ static int dbgp_bulk_read(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pi
 		return -1;
 
 	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
-
-	pids = read32((unsigned long)&ehci_debug->pids);
-	pids = DBGP_PID_UPDATE(pids, USB_PID_IN);
+	pids = DBGP_PID_SET(pipe->pid, USB_PID_IN);
 
 	ctrl = read32((unsigned long)&ehci_debug->control);
 	ctrl = DBGP_LEN_UPDATE(ctrl, size);
 	ctrl &= ~DBGP_OUT;
-	ctrl |= DBGP_GO;
 
 	write32((unsigned long)&ehci_debug->address, addr);
 	write32((unsigned long)&ehci_debug->pids, pids);
@@ -317,8 +322,9 @@ static int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, i
 
 	pipe->devnum = devnum;
 	pipe->endpoint = 0;
+	pipe->pid = USB_PID_DATA0;
 	addr = DBGP_EPADDR(pipe->devnum, pipe->endpoint);
-	pids = DBGP_PID_SET(USB_PID_DATA0, USB_PID_SETUP);
+	pids = DBGP_PID_SET(pipe->pid, USB_PID_SETUP);
 
 	ctrl = read32((unsigned long)&ehci_debug->control);
 	ctrl = DBGP_LEN_UPDATE(ctrl, sizeof(req));
@@ -594,6 +600,7 @@ debug_dev_found:
 	/* Prepare endpoint pipes. */
 	for (i=1; i<DBGP_MAX_ENDPOINTS; i++) {
 		info->ep_pipe[i].devnum = USB_DEBUG_DEVNUM;
+		info->ep_pipe[i].pid = USB_PID_DATA0;
 	}
 	info->ep_pipe[DBGP_CONSOLE_EPOUT].endpoint = dbgp_desc.bDebugOutEndpoint;
 	info->ep_pipe[DBGP_CONSOLE_EPIN].endpoint = dbgp_desc.bDebugInEndpoint;



More information about the coreboot-gerrit mailing list