diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/Makefile | 1 | ||||
-rw-r--r-- | common/cmd_dfu.c | 30 | ||||
-rw-r--r-- | common/cmd_thordown.c | 72 | ||||
-rw-r--r-- | common/cmd_usb_mass_storage.c | 44 | ||||
-rw-r--r-- | common/usb.c | 41 |
5 files changed, 152 insertions, 36 deletions
diff --git a/common/Makefile b/common/Makefile index 288690b..8daca5b 100644 --- a/common/Makefile +++ b/common/Makefile @@ -168,6 +168,7 @@ COBJS-y += usb.o usb_hub.o COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o endif COBJS-$(CONFIG_CMD_USB_MASS_STORAGE) += cmd_usb_mass_storage.o +COBJS-$(CONFIG_CMD_THOR_DOWNLOAD) += cmd_thordown.o COBJS-$(CONFIG_CMD_XIMG) += cmd_ximg.o COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o diff --git a/common/cmd_dfu.c b/common/cmd_dfu.c index 7ce92ce..5547678 100644 --- a/common/cmd_dfu.c +++ b/common/cmd_dfu.c @@ -11,27 +11,32 @@ #include <common.h> #include <dfu.h> #include <g_dnl.h> +#include <usb.h> static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { + if (argc < 4) + return CMD_RET_USAGE; + + char *usb_controller = argv[1]; + char *interface = argv[2]; + char *devstring = argv[3]; + char *s = "dfu"; int ret, i = 0; - if (argc < 3) - return CMD_RET_USAGE; - - ret = dfu_init_env_entities(argv[1], simple_strtoul(argv[2], NULL, 10)); + ret = dfu_init_env_entities(interface, simple_strtoul(devstring, + NULL, 10)); if (ret) return ret; - if (argc > 3 && strcmp(argv[3], "list") == 0) { + if (argc > 4 && strcmp(argv[4], "list") == 0) { dfu_show_entities(); goto done; } -#ifdef CONFIG_TRATS - board_usb_init(); -#endif + int controller_index = simple_strtoul(usb_controller, NULL, 0); + board_usb_init(controller_index, USB_INIT_DEVICE); g_dnl_register(s); while (1) { @@ -62,8 +67,9 @@ done: U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu, "Device Firmware Upgrade", - "<interface> <dev> [list]\n" - " - device firmware upgrade on a device <dev>\n" - " attached to interface <interface>\n" - " [list] - list available alt settings" + "<USB_controller> <interface> <dev> [list]\n" + " - device firmware upgrade via <USB_controller>\n" + " on device <dev>, attached to interface\n" + " <interface>\n" + " [list] - list available alt settings\n" ); diff --git a/common/cmd_thordown.c b/common/cmd_thordown.c new file mode 100644 index 0000000..c4b3511 --- /dev/null +++ b/common/cmd_thordown.c @@ -0,0 +1,72 @@ +/* + * cmd_thordown.c -- USB TIZEN "THOR" Downloader gadget + * + * Copyright (C) 2013 Lukasz Majewski <l.majewski@samsung.com> + * All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <thor.h> +#include <dfu.h> +#include <g_dnl.h> +#include <usb.h> + +int do_thor_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + if (argc < 4) + return CMD_RET_USAGE; + + char *usb_controller = argv[1]; + char *interface = argv[2]; + char *devstring = argv[3]; + + const char *s = "thor"; + int ret; + + puts("TIZEN \"THOR\" Downloader\n"); + + ret = dfu_init_env_entities(interface, simple_strtoul(devstring, + NULL, 10)); + if (ret) + return ret; + + int controller_index = simple_strtoul(usb_controller, NULL, 0); + ret = board_usb_init(controller_index, USB_INIT_DEVICE); + if (ret) { + error("USB init failed: %d", ret); + ret = CMD_RET_FAILURE; + goto exit; + } + + g_dnl_register(s); + + ret = thor_init(); + if (ret) { + error("THOR DOWNLOAD failed: %d", ret); + ret = CMD_RET_FAILURE; + goto exit; + } + + ret = thor_handle(); + if (ret) { + error("THOR failed: %d", ret); + ret = CMD_RET_FAILURE; + goto exit; + } + +exit: + g_dnl_unregister(); + dfu_free_entities(); + + return ret; +} + +U_BOOT_CMD(thordown, CONFIG_SYS_MAXARGS, 1, do_thor_down, + "TIZEN \"THOR\" downloader", + "<USB_controller> <interface> <dev>\n" + " - device software upgrade via LTHOR TIZEN dowload\n" + " program via <USB_controller> on device <dev>,\n" + " attached to interface <interface>\n" +); diff --git a/common/cmd_usb_mass_storage.c b/common/cmd_usb_mass_storage.c index ccf7195..f583caf 100644 --- a/common/cmd_usb_mass_storage.c +++ b/common/cmd_usb_mass_storage.c @@ -8,51 +8,53 @@ #include <common.h> #include <command.h> #include <g_dnl.h> +#include <usb.h> #include <usb_mass_storage.h> int do_usb_mass_storage(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - char *ep; - unsigned int dev_num = 0, offset = 0, part_size = 0; - int rc; + if (argc < 3) + return CMD_RET_USAGE; - struct ums_board_info *ums_info; - static char *s = "ums"; - - if (argc < 2) { - printf("usage: ums <dev> - e.g. ums 0\n"); - return 0; - } - - dev_num = (int)simple_strtoul(argv[1], &ep, 16); + const char *usb_controller = argv[1]; + const char *mmc_devstring = argv[2]; + unsigned int dev_num = (unsigned int)(simple_strtoul(mmc_devstring, + NULL, 0)); if (dev_num) { - puts("\nSet eMMC device to 0! - e.g. ums 0\n"); + error("Set eMMC device to 0! - e.g. ums 0"); goto fail; } - board_usb_init(); - ums_info = board_ums_init(dev_num, offset, part_size); + unsigned int controller_index = (unsigned int)(simple_strtoul( + usb_controller, NULL, 0)); + if (board_usb_init(controller_index, USB_INIT_DEVICE)) { + error("Couldn't init USB controller."); + goto fail; + } + struct ums_board_info *ums_info = board_ums_init(dev_num, 0, 0); if (!ums_info) { - printf("MMC: %d -> NOT available\n", dev_num); + error("MMC: %d -> NOT available", dev_num); goto fail; } - rc = fsg_init(ums_info); + + int rc = fsg_init(ums_info); if (rc) { - printf("cmd ums: fsg_init failed\n"); + error("fsg_init failed"); goto fail; } - g_dnl_register(s); + g_dnl_register("ums"); while (1) { /* Handle control-c and timeouts */ if (ctrlc()) { - printf("The remote end did not respond in time.\n"); + error("The remote end did not respond in time."); goto exit; } + usb_gadget_handle_interrupts(); /* Check if USB cable has been detached */ if (fsg_main_thread(NULL) == EIO) @@ -68,5 +70,5 @@ fail: U_BOOT_CMD(ums, CONFIG_SYS_MAXARGS, 1, do_usb_mass_storage, "Use the UMS [User Mass Storage]", - "ums - User Mass Storage Gadget" + "<USB_controller> <mmc_dev>" ); diff --git a/common/usb.c b/common/usb.c index c97f522..60daa10 100644 --- a/common/usb.c +++ b/common/usb.c @@ -33,6 +33,7 @@ #include <linux/ctype.h> #include <asm/byteorder.h> #include <asm/unaligned.h> +#include <compiler.h> #include <usb.h> #ifdef CONFIG_4xx @@ -74,7 +75,7 @@ int usb_init(void) for (i = 0; i < CONFIG_USB_MAX_CONTROLLER_COUNT; i++) { /* init low_level USB */ printf("USB%d: ", i); - if (usb_lowlevel_init(i, &ctrl)) { + if (usb_lowlevel_init(i, USB_INIT_HOST, &ctrl)) { puts("lowlevel init failed\n"); continue; } @@ -855,6 +856,16 @@ void usb_free_device(void) } /* + * XHCI issues Enable Slot command and thereafter + * allocates device contexts. Provide a weak alias + * function for the purpose, so that XHCI overrides it + * and EHCI/OHCI just work out of the box. + */ +__weak int usb_alloc_device(struct usb_device *udev) +{ + return 0; +} +/* * By the time we get here, the device has gotten a new device ID * and is in the default state. We need to identify the thing and * get the ball rolling.. @@ -867,6 +878,17 @@ int usb_new_device(struct usb_device *dev) int tmp; ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ); + /* + * Allocate usb 3.0 device context. + * USB 3.0 (xHCI) protocol tries to allocate device slot + * and related data structures first. This call does that. + * Refer to sec 4.3.2 in xHCI spec rev1.0 + */ + if (usb_alloc_device(dev)) { + printf("Cannot allocate device context to get SLOT_ID\n"); + return -1; + } + /* We still haven't set the Address yet */ addr = dev->devnum; dev->devnum = 0; @@ -897,7 +919,7 @@ int usb_new_device(struct usb_device *dev) * http://sourceforge.net/mailarchive/forum.php? * thread_id=5729457&forum_id=5398 */ - struct usb_device_descriptor *desc; + __maybe_unused struct usb_device_descriptor *desc; int port = -1; struct usb_device *parent = dev->parent; unsigned short portstatus; @@ -914,6 +936,13 @@ int usb_new_device(struct usb_device *dev) dev->epmaxpacketin[0] = 64; dev->epmaxpacketout[0] = 64; + /* + * XHCI needs to issue a Address device command to setup + * proper device context structures, before it can interact + * with the device. So a get_descriptor will fail before any + * of that is done for XHCI unlike EHCI. + */ +#ifndef CONFIG_USB_XHCI err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64); if (err < 0) { debug("usb_new_device: usb_get_descriptor() failed\n"); @@ -926,11 +955,12 @@ int usb_new_device(struct usb_device *dev) * to differentiate between HUB and DEVICE. */ dev->descriptor.bDeviceClass = desc->bDeviceClass; +#endif - /* find the port number we're at */ if (parent) { int j; + /* find the port number we're at */ for (j = 0; j < parent->maxchild; j++) { if (parent->children[j] == dev) { port = j; @@ -1037,4 +1067,9 @@ int usb_new_device(struct usb_device *dev) return 0; } +__weak +int board_usb_init(int index, enum usb_init_type init) +{ + return 0; +} /* EOF */ |