[coreboot-gerrit] New patch to review for coreboot: 0fda524 usbdebug: Refactor descriptor probing of dongle

Kyösti Mälkki (kyosti.malkki@gmail.com) gerrit at coreboot.org
Mon Oct 27 22:59:28 CET 2014


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/7209

-gerrit

commit 0fda524f1434658c272b3eaff646f6d1316e11e5
Author: Kyösti Mälkki <kyosti.malkki at gmail.com>
Date:   Mon Oct 27 14:07:28 2014 +0200

    usbdebug: Refactor descriptor probing of dongle
    
    Organized such that it is easy to support devices that do not
    export special Debug Descriptor. Some of these can still work
    in a fixed configuration and/or require additional initialisation
    for UART clocks etc.
    
    Change-Id: Id07fd6b69007332d67d9e9a456f58fdbca1999cd
    Signed-off-by: Kyösti Mälkki <kyosti.malkki at gmail.com>
---
 src/drivers/usb/ehci_debug.c | 119 +------------------------------------------
 src/drivers/usb/ehci_debug.h |   5 ++
 src/drivers/usb/gadget.c     | 111 ++++++++++++++++++++++++++++++++++++++++
 src/drivers/usb/usb_ch9.h    |  28 ++++++++++
 4 files changed, 145 insertions(+), 118 deletions(-)

diff --git a/src/drivers/usb/ehci_debug.c b/src/drivers/usb/ehci_debug.c
index 69530f1..acdb34d 100644
--- a/src/drivers/usb/ehci_debug.c
+++ b/src/drivers/usb/ehci_debug.c
@@ -31,11 +31,6 @@
 #include "usb_ch9.h"
 #include "ehci.h"
 
-#define DBGP_MAX_ENDPOINTS	4
-#define DBGP_SETUP_EP0		0	/* Compulsory endpoint 0. */
-#define DBGP_CONSOLE_EPOUT	1
-#define DBGP_CONSOLE_EPIN	2
-
 struct ehci_debug_info {
 	void *ehci_base;
 	void *ehci_debug;
@@ -54,33 +49,7 @@ static int dbgp_enabled(void);
 #endif
 
 #define DBGP_LEN_UPDATE(x, len) (((x) & ~0x0f) | ((len) & 0x0f))
-/*
- * USB Packet IDs (PIDs)
- */
 
-/* token */
-#define USB_PID_OUT		0xe1
-#define USB_PID_IN		0x69
-#define USB_PID_SOF		0xa5
-#define USB_PID_SETUP		0x2d
-/* handshake */
-#define USB_PID_ACK		0xd2
-#define USB_PID_NAK		0x5a
-#define USB_PID_STALL		0x1e
-#define USB_PID_NYET		0x96
-/* data */
-#define USB_PID_DATA0		0xc3
-#define USB_PID_DATA1		0x4b
-#define USB_PID_DATA2		0x87
-#define USB_PID_MDATA		0x0f
-/* Special */
-#define USB_PID_PREAMBLE	0x3c
-#define USB_PID_ERR		0x3c
-#define USB_PID_SPLIT		0x78
-#define USB_PID_PING		0xb4
-#define USB_PID_UNDEF_0		0xf0
-
-#define USB_PID_DATA_TOGGLE	0x88
 #define DBGP_CLAIM (DBGP_OWNER | DBGP_ENABLED | DBGP_INUSE)
 
 #define HUB_ROOT_RESET_TIME	50	/* times are in msec */
@@ -465,11 +434,9 @@ static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_
 	struct ehci_caps *ehci_caps;
 	struct ehci_regs *ehci_regs;
 
-	struct usb_debug_descriptor dbgp_desc;
 	u32 cmd, ctrl, status, portsc, hcs_params;
 	u32 debug_port, new_debug_port = 0, n_ports;
-	u32 devnum;
-	int ret, i, configured;
+	int ret, i;
 	int loop;
 	int port_map_tried;
 	int playtimes = 3;
@@ -615,90 +582,6 @@ try_next_port:
 		goto err;
 	}
 
-	/* Find the debug device and make it device number 127 */
-	devnum = 0;
-debug_dev_retry:
-	memset(&dbgp_desc, 0, sizeof(dbgp_desc));
-	ret = dbgp_control_msg(ehci_debug, devnum,
-		USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-		USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,
-		&dbgp_desc, sizeof(dbgp_desc));
-	if (ret == sizeof(dbgp_desc)) {
-		if (dbgp_desc.bLength == sizeof(dbgp_desc) && dbgp_desc.bDescriptorType==USB_DT_DEBUG)
-			goto debug_dev_found;
-		else
-			dprintk(BIOS_INFO, "Invalid debug device descriptor.\n");
-	}
-	if (devnum == 0) {
-		devnum = USB_DEBUG_DEVNUM;
-		goto debug_dev_retry;
-	} else {
-		dprintk(BIOS_INFO, "Could not find attached debug device.\n");
-		ret = -5;
-		goto err;
-	}
-debug_dev_found:
-
-	/* Move the device to 127 if it isn't already there */
-	if (devnum != USB_DEBUG_DEVNUM) {
-		ret = dbgp_control_msg(ehci_debug, devnum,
-			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-			USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
-		if (ret < 0) {
-			dprintk(BIOS_INFO, "Could not move attached device to %d.\n",
-				USB_DEBUG_DEVNUM);
-			ret = -7;
-			goto err;
-		}
-		devnum = USB_DEBUG_DEVNUM;
-		dprintk(BIOS_INFO, "EHCI debug device renamed to 127.\n");
-	}
-
-	/* Enable the debug interface */
-	ret = dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
-		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-		USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0);
-	if (ret < 0) {
-		dprintk(BIOS_INFO, "Could not enable EHCI debug device.\n");
-		ret = -8;
-		goto err;
-	}
-	dprintk(BIOS_INFO, "EHCI debug interface enabled.\n");
-
-	/* 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[i].timeout = 1000;
-	}
-	info->ep_pipe[DBGP_CONSOLE_EPOUT].endpoint = dbgp_desc.bDebugOutEndpoint;
-	info->ep_pipe[DBGP_CONSOLE_EPIN].endpoint = dbgp_desc.bDebugInEndpoint;
-
-	/* Perform a small write. */
-	configured = 0;
-small_write:
-	ret = dbgp_bulk_write(ehci_debug, &info->ep_pipe[DBGP_CONSOLE_EPOUT], "USB\r\n",5);
-	if (ret < 0) {
-		dprintk(BIOS_INFO, "dbgp_bulk_write failed: %d\n", ret);
-		if (!configured) {
-			/* Send Set Configure request to device. This is required for FX2
-			   (CY7C68013) to transfer from USB state Addressed to Configured,
-			   only then endpoints other than 0 are enabled. */
-			if (dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
-				USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
-				USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0) >= 0) {
-				configured = 1;
-				goto small_write;
-			}
-		}
-		ret = -9;
-		goto err;
-	}
-	dprintk(BIOS_INFO, "Test write done\n");
-
-	info->ep_pipe[DBGP_SETUP_EP0].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
-	info->ep_pipe[DBGP_CONSOLE_EPOUT].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
-	info->ep_pipe[DBGP_CONSOLE_EPIN].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
 	return 0;
 err:
 	/* Things didn't work so remove my claim */
diff --git a/src/drivers/usb/ehci_debug.h b/src/drivers/usb/ehci_debug.h
index d7ea91b..c060a70 100644
--- a/src/drivers/usb/ehci_debug.h
+++ b/src/drivers/usb/ehci_debug.h
@@ -37,6 +37,11 @@ void ehci_debug_select_port(unsigned int port);
 #define DBGP_EP_BUSY		(1<<2)
 #define DBGP_EP_STATMASK	(DBGP_EP_VALID | DBGP_EP_ENABLED)
 
+#define DBGP_MAX_ENDPOINTS	4
+#define DBGP_SETUP_EP0		0	/* Compulsory endpoint 0. */
+#define DBGP_CONSOLE_EPOUT	1
+#define DBGP_CONSOLE_EPIN	2
+
 struct ehci_dbg_port;
 
 struct dbgp_pipe
diff --git a/src/drivers/usb/gadget.c b/src/drivers/usb/gadget.c
index d3b4963..5dd7993 100644
--- a/src/drivers/usb/gadget.c
+++ b/src/drivers/usb/gadget.c
@@ -17,11 +17,13 @@
 
 #include <stddef.h>
 #include <console/console.h>
+#include <string.h>
 
 #include "ehci_debug.h"
 #include "usb_ch9.h"
 #include "ehci.h"
 
+#define dprintk printk
 
 #define USB_HUB_PORT_CONNECTION		0
 #define USB_HUB_PORT_ENABLED		1
@@ -120,6 +122,108 @@ err:
 	return -1;
 }
 
+static void ack_set_configuration(struct dbgp_pipe *pipe, u8 devnum, int timeout)
+{
+	int i = DBGP_SETUP_EP0;
+	while (++i < DBGP_MAX_ENDPOINTS) {
+		if (pipe[i].endpoint != 0) {
+			pipe[i].devnum = devnum;
+			pipe[i].pid = USB_PID_DATA0;
+			pipe[i].timeout = timeout;
+		}
+	}
+}
+
+static void activate_endpoints(struct dbgp_pipe *pipe)
+{
+	int i = DBGP_SETUP_EP0;
+	pipe[i].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
+	while (++i < DBGP_MAX_ENDPOINTS) {
+		if (pipe[i].endpoint != 0)
+			pipe[i].status |= DBGP_EP_ENABLED | DBGP_EP_VALID;
+	}
+}
+
+static int probe_for_debug_descriptor(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
+{
+	struct usb_debug_descriptor dbgp_desc;
+	int configured = 0, ret;
+	u8 devnum = 0;
+
+	/* Find the debug device and make it device number 127 */
+debug_dev_retry:
+	memset(&dbgp_desc, 0, sizeof(dbgp_desc));
+	ret = dbgp_control_msg(ehci_debug, devnum,
+		USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+		USB_REQ_GET_DESCRIPTOR, (USB_DT_DEBUG << 8), 0,
+		&dbgp_desc, sizeof(dbgp_desc));
+	if (ret == sizeof(dbgp_desc)) {
+		if (dbgp_desc.bLength == sizeof(dbgp_desc) && dbgp_desc.bDescriptorType==USB_DT_DEBUG)
+			goto debug_dev_found;
+		else
+			dprintk(BIOS_INFO, "Invalid debug device descriptor.\n");
+	}
+	if (devnum == 0) {
+		devnum = USB_DEBUG_DEVNUM;
+		goto debug_dev_retry;
+	} else {
+		dprintk(BIOS_INFO, "Could not find attached debug device.\n");
+		return -1;
+	}
+debug_dev_found:
+
+	/* Move the device to 127 if it isn't already there */
+	if (devnum != USB_DEBUG_DEVNUM) {
+		ret = dbgp_control_msg(ehci_debug, devnum,
+			USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+			USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
+		if (ret < 0) {
+			dprintk(BIOS_INFO, "Could not move attached device to %d.\n",
+				USB_DEBUG_DEVNUM);
+			return -2;
+		}
+		devnum = USB_DEBUG_DEVNUM;
+		dprintk(BIOS_INFO, "EHCI debug device renamed to 127.\n");
+	}
+
+	/* Enable the debug interface */
+	ret = dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
+		USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+		USB_REQ_SET_FEATURE, USB_DEVICE_DEBUG_MODE, 0, NULL, 0);
+	if (ret < 0) {
+		dprintk(BIOS_INFO, "Could not enable EHCI debug device.\n");
+		return -3;
+	}
+	dprintk(BIOS_INFO, "EHCI debug interface enabled.\n");
+
+	pipe[DBGP_CONSOLE_EPOUT].endpoint = dbgp_desc.bDebugOutEndpoint;
+	pipe[DBGP_CONSOLE_EPIN].endpoint = dbgp_desc.bDebugInEndpoint;
+
+	ack_set_configuration(pipe, devnum, 1000);
+
+	/* Perform a small write. */
+	configured = 0;
+small_write:
+	ret = dbgp_bulk_write_x(&pipe[DBGP_CONSOLE_EPOUT], "USB\r\n",5);
+	if (ret < 0) {
+		dprintk(BIOS_INFO, "dbgp_bulk_write failed: %d\n", ret);
+		if (!configured) {
+			/* Send Set Configure request to device. This is required for FX2
+			   (CY7C68013) to transfer from USB state Addressed to Configured,
+			   only then endpoints other than 0 are enabled. */
+			if (dbgp_control_msg(ehci_debug, USB_DEBUG_DEVNUM,
+				USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
+				USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0) >= 0) {
+				configured = 1;
+				goto small_write;
+			}
+		}
+		return -4;
+	}
+	dprintk(BIOS_INFO, "Test write done\n");
+	return 0;
+}
+
 
 int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
 {
@@ -134,5 +238,12 @@ int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
 		}
 	}
 
+	ret = probe_for_debug_descriptor(ehci_debug, pipe);
+	if (ret < 0) {
+		dprintk(BIOS_INFO, "Could not enable gadget using Debug Descriptor.\n");
+		return ret;
+	}
+
+	activate_endpoints(pipe);
 	return 0;
 }
diff --git a/src/drivers/usb/usb_ch9.h b/src/drivers/usb/usb_ch9.h
index a609bdb..a4a3722 100644
--- a/src/drivers/usb/usb_ch9.h
+++ b/src/drivers/usb/usb_ch9.h
@@ -81,6 +81,34 @@
 
 #define USB_DEVICE_DEBUG_MODE           6       /* (special devices only) */
 
+/*
+ * USB Packet IDs (PIDs)
+ */
+
+/* token */
+#define USB_PID_OUT		0xe1
+#define USB_PID_IN		0x69
+#define USB_PID_SOF		0xa5
+#define USB_PID_SETUP		0x2d
+/* handshake */
+#define USB_PID_ACK		0xd2
+#define USB_PID_NAK		0x5a
+#define USB_PID_STALL		0x1e
+#define USB_PID_NYET		0x96
+/* data */
+#define USB_PID_DATA0		0xc3
+#define USB_PID_DATA1		0x4b
+#define USB_PID_DATA2		0x87
+#define USB_PID_MDATA		0x0f
+/* Special */
+#define USB_PID_PREAMBLE	0x3c
+#define USB_PID_ERR		0x3c
+#define USB_PID_SPLIT		0x78
+#define USB_PID_PING		0xb4
+#define USB_PID_UNDEF_0		0xf0
+
+#define USB_PID_DATA_TOGGLE	0x88
+
 struct usb_ctrlrequest {
         u8  bRequestType;
         u8  bRequest;



More information about the coreboot-gerrit mailing list