diff options
author | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-10-27 14:07:28 +0200 |
---|---|---|
committer | Kyösti Mälkki <kyosti.malkki@gmail.com> | 2014-11-23 20:35:51 +0100 |
commit | 46249be26753319877d67b2958c5070f179b5937 (patch) | |
tree | c05cf8c54383d3e54ff9e284080a787a3a720a2a /src/drivers/usb | |
parent | 83fe6d7fd270aeca7b703dbd0f7e23902144840b (diff) | |
download | coreboot-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.c | 119 | ||||
-rw-r--r-- | src/drivers/usb/ehci_debug.h | 5 | ||||
-rw-r--r-- | src/drivers/usb/gadget.c | 111 | ||||
-rw-r--r-- | 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 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; |