Kyösti Mälkki (kyosti.malkki@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/7208
-gerrit
commit b7cc499d93fd1c3451c847264e6a2fc1defc429d Author: Kyösti Mälkki kyosti.malkki@gmail.com Date: Tue Feb 25 20:11:52 2014 +0200
usbdebug: Move initialisation of the optional hub
Add new file for device-specific initialisation transactions.
Change-Id: I339df400a41675f178c7af613f03b2b44c826189 Signed-off-by: Kyösti Mälkki kyosti.malkki@gmail.com --- src/drivers/usb/Makefile.inc | 4 +- src/drivers/usb/ehci.h | 3 + src/drivers/usb/ehci_debug.c | 107 ++------------------------------- src/drivers/usb/ehci_debug.h | 8 +++ src/drivers/usb/gadget.c | 138 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 155 insertions(+), 105 deletions(-)
diff --git a/src/drivers/usb/Makefile.inc b/src/drivers/usb/Makefile.inc index bab6737..ff9a124 100644 --- a/src/drivers/usb/Makefile.inc +++ b/src/drivers/usb/Makefile.inc @@ -1,3 +1,3 @@ -romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += ehci_debug.c pci_ehci.c console.c +romstage-$(CONFIG_USBDEBUG_IN_ROMSTAGE) += ehci_debug.c pci_ehci.c console.c gadget.c
-ramstage-$(CONFIG_USBDEBUG) += ehci_debug.c pci_ehci.c console.c +ramstage-$(CONFIG_USBDEBUG) += ehci_debug.c pci_ehci.c console.c gadget.c diff --git a/src/drivers/usb/ehci.h b/src/drivers/usb/ehci.h index f920352..6904656 100644 --- a/src/drivers/usb/ehci.h +++ b/src/drivers/usb/ehci.h @@ -197,4 +197,7 @@ struct ehci_dbg_port { u32 address; #define DBGP_EPADDR(dev, ep) (((dev)<<8)|(ep)) } __attribute__ ((packed)); + +#define USB_DEBUG_DEVNUM 127 + #endif diff --git a/src/drivers/usb/ehci_debug.c b/src/drivers/usb/ehci_debug.c index 002dfd7..69530f1 100644 --- a/src/drivers/usb/ehci_debug.c +++ b/src/drivers/usb/ehci_debug.c @@ -53,8 +53,6 @@ static int dbgp_enabled(void); # define dprintk(LEVEL, args...) do {} while(0) #endif
-#define USB_DEBUG_DEVNUM 127 - #define DBGP_LEN_UPDATE(x, len) (((x) & ~0x0f) | ((len) & 0x0f)) /* * USB Packet IDs (PIDs) @@ -319,7 +317,7 @@ int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size) return dbgp_bulk_read(dbg_info->ehci_debug, pipe, data, size); }
-static void dbgp_mdelay(int ms) +void dbgp_mdelay(int ms) { int i;
@@ -329,7 +327,7 @@ static void dbgp_mdelay(int ms) } }
-static int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, int requesttype, +int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, int requesttype, int request, int value, int index, void *data, int size) { struct ehci_debug_info *info = dbgp_ehci_info(); @@ -460,101 +458,6 @@ static int ehci_wait_for_port(struct ehci_regs *ehci_regs, int port) return -1; //-ENOTCONN; }
-#define USB_HUB_PORT_CONNECTION 0 -#define USB_HUB_PORT_ENABLED 1 -#define USB_HUB_PORT_RESET 4 -#define USB_HUB_PORT_POWER 8 -#define USB_HUB_C_PORT_CONNECTION 16 -#define USB_HUB_C_PORT_RESET 20 - -#if CONFIG_USBDEBUG_OPTIONAL_HUB_PORT - -static int hub_port_status(const char * buf, int feature) -{ - return !!(buf[feature>>3] & (1<<(feature&0x7))); -} - -static int dbgp_hub_enable(struct ehci_dbg_port *ehci_debug, unsigned int port) -{ - const u8 hub_addr = USB_DEBUG_DEVNUM-1; - char status[8]; - int ret, loop; - - /* Move hub to address 126. */ - ret = dbgp_control_msg(ehci_debug, 0, - USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, - USB_REQ_SET_ADDRESS, hub_addr, 0, NULL, 0); - if (ret < 0) - goto err; - - /* Enter configured state on hub. */ - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, - USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0); - if (ret < 0) - goto err; - - /* Set PORT_POWER, poll for PORT_CONNECTION. */ - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_SET_FEATURE, USB_HUB_PORT_POWER, port, NULL, 0); - if (ret < 0) - goto err; - - loop = 100; - do { - dbgp_mdelay(10); - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_GET_STATUS, 0, port, status, 4); - if (ret < 0) - goto err; - if (hub_port_status(status, USB_HUB_PORT_CONNECTION)) - break; - } while (--loop); - if (! loop) - goto err; - - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_CONNECTION, port, NULL, 0); - if (ret < 0) - goto err; - - - /* Set PORT_RESET, poll for C_PORT_RESET. */ - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_SET_FEATURE, USB_HUB_PORT_RESET, port, NULL, 0); - if (ret < 0) - goto err; - - loop = 100; - do { - dbgp_mdelay(10); - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_GET_STATUS, 0, port, status, 4); - if (ret < 0) - goto err; - if (hub_port_status(status, USB_HUB_C_PORT_RESET)) - break; - } while (--loop); - if (! loop) - goto err; - - ret = dbgp_control_msg(ehci_debug, hub_addr, - USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, - USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_RESET, port, NULL, 0); - if (ret < 0) - goto err; - - if (hub_port_status(status, USB_HUB_PORT_ENABLED)) - return 0; -err: - return -1; -} -#endif /* CONFIG_USBDEBUG_OPTIONAL_HUB_PORT */
static int usbdebug_init_(unsigned ehci_bar, unsigned offset, struct ehci_debug_info *info) @@ -705,14 +608,12 @@ try_next_port:
dbgp_mdelay(100);
-#if CONFIG_USBDEBUG_OPTIONAL_HUB_PORT - ret = dbgp_hub_enable(ehci_debug, CONFIG_USBDEBUG_OPTIONAL_HUB_PORT); + ret = dbgp_probe_gadget(info->ehci_debug, &info->ep_pipe[0]); if (ret < 0) { - dprintk(BIOS_INFO, "Could not enable USB hub on debug port.\n"); + dprintk(BIOS_INFO, "Could not probe gadget on debug port.\n"); ret = -6; goto err; } -#endif
/* Find the debug device and make it device number 127 */ devnum = 0; diff --git a/src/drivers/usb/ehci_debug.h b/src/drivers/usb/ehci_debug.h index 39f5f72..d7ea91b 100644 --- a/src/drivers/usb/ehci_debug.h +++ b/src/drivers/usb/ehci_debug.h @@ -37,6 +37,8 @@ void ehci_debug_select_port(unsigned int port); #define DBGP_EP_BUSY (1<<2) #define DBGP_EP_STATMASK (DBGP_EP_VALID | DBGP_EP_ENABLED)
+struct ehci_dbg_port; + struct dbgp_pipe { u8 devnum; @@ -59,4 +61,10 @@ int dbgp_ep_is_active(struct dbgp_pipe *pipe); int dbgp_bulk_write_x(struct dbgp_pipe *pipe, const char *bytes, int size); int dbgp_bulk_read_x(struct dbgp_pipe *pipe, void *data, int size);
+int dbgp_control_msg(struct ehci_dbg_port *ehci_debug, unsigned devnum, + int requesttype, int request, int value, int index, void *data, int size); +void dbgp_mdelay(int ms); + +int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe); + #endif /* _EHCI_DEBUG_H_ */ diff --git a/src/drivers/usb/gadget.c b/src/drivers/usb/gadget.c new file mode 100644 index 0000000..d3b4963 --- /dev/null +++ b/src/drivers/usb/gadget.c @@ -0,0 +1,138 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA + */ + +#include <stddef.h> +#include <console/console.h> + +#include "ehci_debug.h" +#include "usb_ch9.h" +#include "ehci.h" + + +#define USB_HUB_PORT_CONNECTION 0 +#define USB_HUB_PORT_ENABLED 1 +#define USB_HUB_PORT_RESET 4 +#define USB_HUB_PORT_POWER 8 +#define USB_HUB_C_PORT_CONNECTION 16 +#define USB_HUB_C_PORT_RESET 20 + + +static int hub_port_status(const char * buf, int feature) +{ + return !!(buf[feature>>3] & (1<<(feature&0x7))); +} + +/* After USB port reset, treat device number 0 as an USB hub. Assign it with + * a device number hub_addr. Then apply enable and reset on downstream port. + */ + static int dbgp_hub_enable(struct ehci_dbg_port *ehci_debug, unsigned char hub_addr, + unsigned char port) +{ + char status[8]; + int ret, loop; + + /* Assign a devicenumber for the hub. */ + ret = dbgp_control_msg(ehci_debug, 0, + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, + USB_REQ_SET_ADDRESS, hub_addr, 0, NULL, 0); + if (ret < 0) + goto err; + + /* Enter configured state on hub. */ + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE, + USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0); + if (ret < 0) + goto err; + + /* Set PORT_POWER, poll for PORT_CONNECTION. */ + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_SET_FEATURE, USB_HUB_PORT_POWER, port, NULL, 0); + if (ret < 0) + goto err; + + loop = 100; + do { + dbgp_mdelay(10); + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_GET_STATUS, 0, port, status, 4); + if (ret < 0) + goto err; + if (hub_port_status(status, USB_HUB_PORT_CONNECTION)) + break; + } while (--loop); + if (! loop) + goto err; + + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_CONNECTION, port, NULL, 0); + if (ret < 0) + goto err; + + + /* Set PORT_RESET, poll for C_PORT_RESET. */ + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_SET_FEATURE, USB_HUB_PORT_RESET, port, NULL, 0); + if (ret < 0) + goto err; + + loop = 100; + do { + dbgp_mdelay(10); + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_GET_STATUS, 0, port, status, 4); + if (ret < 0) + goto err; + if (hub_port_status(status, USB_HUB_C_PORT_RESET)) + break; + } while (--loop); + if (! loop) + goto err; + + ret = dbgp_control_msg(ehci_debug, hub_addr, + USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_OTHER, + USB_REQ_CLEAR_FEATURE, USB_HUB_C_PORT_RESET, port, NULL, 0); + if (ret < 0) + goto err; + + if (hub_port_status(status, USB_HUB_PORT_ENABLED)) + return 0; +err: + return -1; +} + + +int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe) +{ + int ret; + + if (CONFIG_USBDEBUG_OPTIONAL_HUB_PORT != 0) { + ret = dbgp_hub_enable(ehci_debug, USB_DEBUG_DEVNUM-1, + CONFIG_USBDEBUG_OPTIONAL_HUB_PORT); + if (ret < 0) { + printk(BIOS_INFO, "Could not enable USB hub on debug port.\n"); + return ret; + } + } + + return 0; +}