summaryrefslogtreecommitdiff
path: root/src/drivers/usb
diff options
context:
space:
mode:
authorKyösti Mälkki <kyosti.malkki@gmail.com>2014-10-27 14:07:28 +0200
committerKyösti Mälkki <kyosti.malkki@gmail.com>2014-11-23 20:35:51 +0100
commit46249be26753319877d67b2958c5070f179b5937 (patch)
treec05cf8c54383d3e54ff9e284080a787a3a720a2a /src/drivers/usb
parent83fe6d7fd270aeca7b703dbd0f7e23902144840b (diff)
downloadcoreboot-46249be26753319877d67b2958c5070f179b5937.tar.xz
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@gmail.com> Reviewed-on: http://review.coreboot.org/7209 Reviewed-by: Nico Huber <nico.h@gmx.de> Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/drivers/usb')
-rw-r--r--src/drivers/usb/ehci_debug.c119
-rw-r--r--src/drivers/usb/ehci_debug.h5
-rw-r--r--src/drivers/usb/gadget.c111
-rw-r--r--src/drivers/usb/usb_ch9.h28
4 files changed, 145 insertions, 118 deletions
diff --git a/src/drivers/usb/ehci_debug.c b/src/drivers/usb/ehci_debug.c
index cb6b23ecd5..55530b73b4 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 d7ea91b4f9..c060a70db3 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 d3b496375d..5dd7993b5a 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 a609bdb207..a4a3722ee8 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;