Patchwork [U-Boot,4/6] usb:command: Support for USB Download command

login
register
mail settings
Submitter Łukasz Majewski
Date April 12, 2012, 7:17 a.m.
Message ID <1334215049-20362-5-git-send-email-l.majewski@samsung.com>
Download mbox | patch
Permalink /patch/151990/
State Changes Requested
Delegated to: Marek Vasut
Headers show

Comments

Łukasz Majewski - April 12, 2012, 7:17 a.m.
Support for usbdownload command, which starts USB Downloading process
compliant with Samsung's THOR protocol.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Marek Vasut <marex@denx.de>
---
 common/Makefile   |    1 +
 common/cmd_usbd.c |  161 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 162 insertions(+), 0 deletions(-)
 create mode 100644 common/cmd_usbd.c
Marek Vasut - April 14, 2012, 10:04 a.m.
Dear Lukasz Majewski,

> Support for usbdownload command, which starts USB Downloading process
> compliant with Samsung's THOR protocol.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Marek Vasut <marex@denx.de>
> ---
>  common/Makefile   |    1 +
>  common/cmd_usbd.c |  161
> +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162
> insertions(+), 0 deletions(-)
>  create mode 100644 common/cmd_usbd.c
> 
> diff --git a/common/Makefile b/common/Makefile
> index d9f10f3..2392893 100644
> --- a/common/Makefile
> +++ b/common/Makefile
> @@ -161,6 +161,7 @@ COBJS-y += cmd_usb.o
>  COBJS-y += usb.o usb_hub.o
>  COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
>  endif
> +COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += cmd_usbd.o

CONFIG_USB_GADGET_DOWNLOAD please.

>  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_usbd.c b/common/cmd_usbd.c
> new file mode 100644
> index 0000000..583f2a5
> --- /dev/null
> +++ b/common/cmd_usbd.c
> @@ -0,0 +1,161 @@
> +/*
> + * cmd_usbd.c -- USB THOR Downloader gadget
> + *
> + * Copyright (C) 2012 Lukasz Majewski <l.majewski@samsung.com>
> + * All rights reserved.
> + *
> + * 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; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 
> USA + */
> +#define DEBUG
> +#include <common.h>
> +#include <usbd_thor.h>
> +#include <asm/errno.h>
> +#include <malloc.h>
> +#include <g_dnl.h>
> +
> +#define STR_SIZE 16
> +
> +static char dnl_tab[4][STR_SIZE];
> +
> +char *find_dnl_entry(char* s, char *name)
> +{
> +	char *st, *c;
> +
> +	for (; s; strsep(&s, ";"), st = s) {
> +		st = strchr(s, ' ');
> +
> +		if (!strncmp(s, name, st - s)) {
> +			for (c = s; c; strsep(&c, ";"))
> +				;
> +			return s;
> +		}
> +	}
> +	return NULL;

Don't we have some kind of function for this already? Also, do I see correctly 
that you use semicolon as a separator ?

> +}
> +
> +int img_store(struct g_dnl *dnl, int medium)
> +{
> +	char cmd_buf[128];
> +
> +	memset(cmd_buf, '\0', sizeof(cmd_buf));
> +
> +	switch (medium) {
> +	case MMC:
> +		sprintf(cmd_buf, "%s write 0x%x %s %s", &dnl_tab[1][0],
> +			(unsigned int) dnl->rx_buf, &dnl_tab[2][0],
> +			&dnl_tab[3][0]);
> +		break;
> +	case FAT:
> +		sprintf(cmd_buf, "%swrite mmc %s:%s 0x%x %s %x",
> +			&dnl_tab[1][0], &dnl_tab[2][0], &dnl_tab[3][0],
> +			(unsigned int) dnl->rx_buf, &dnl_tab[0][0],
> +			dnl->file_size);
> +		break;
> +	case RAW:
> +		sprintf(cmd_buf, "mmc write 0x%x %x %x",
> +			(unsigned int) dnl->rx_buf, dnl->p, dnl->packet_size);
> +		break;
> +	}
> +
> +	debug("%s: %s\n", __func__, cmd_buf);
> +	run_command(cmd_buf, 0);
> +
> +	return 0;
> +}
> +
> +int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const
> argv[]) +{
> +	/* Simple argv[0] passing is not working since 'usbdown' cmd can
> +	   be run by */
> +	/* 'usb', 'usbd' or 'usbdown' */
> +	char *str, *st, *str_env;
> +
> +	int ret = 0, i = 0;
> +	static char *s = "thor";
> +	static struct g_dnl *dnl;
> +
> +	dnl = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(struct g_dnl));
> +
> +	puts("THOR Downloader\n");
> +
> +	g_dnl_init(s, dnl);
> +
> +	ret = dnl_init(dnl);
> +	if (ret)
> +		printf("%s: USBDOWN failed\n", __func__);

What's "USBDOWN failed"? It's not expressive enough ;-)

> +
> +	ret = dnl_command(dnl);
> +	if (ret < 0)
> +		printf("%s: COMMAND failed: %d\n", __func__, ret);
> +
> +	debug("DNL: file:%s size:%d\n", dnl->file_name, dnl->file_size);
> +
> +	str_env = getenv("dnl_info");
> +	if (str_env == NULL) {
> +		puts("DNL: \"dnl_info\" variable not defined!\n");
> +		return -1;
> +	}
> +	debug("dnl_info: %s\n", str_env);
> +
> +	str = find_dnl_entry(str_env, dnl->file_name);
> +	if (str == NULL) {
> +		printf("File: %s not at \"dnl_info\"!\n", dnl->file_name);
> +		return -1;
> +	}
> +
> +	debug("%s:str: %s\n", __func__, str);
> +
> +	memset(dnl_tab, '\0', sizeof(dnl_tab));
> +	do {
> +		st = strsep(&str, " ");
> +		strncpy(&dnl_tab[i++][0], st, strlen(st));
> +
> +	} while (str);
> +
> +	if (strncmp(dnl->file_name, &dnl_tab[0][0], strlen(&dnl_tab[0][0]))) {
> +		printf("Parsed string not match file: %s!\n", dnl->file_name);
> +		return -1;
> +	}
> +
> +	debug("%s %s %s %s\n", &dnl_tab[0][0], &dnl_tab[1][0],
> +	       &dnl_tab[2][0], &dnl_tab[3][0]);
> +
> +	if (!strncmp(&dnl_tab[1][0], "mmc", strlen("mmc"))) {
> +		dnl->store = img_store;
> +		dnl->medium = MMC;
> +	} else if (!strncmp(&dnl_tab[1][0], "fat", strlen("fat"))) {
> +		dnl->store = img_store;
> +		dnl->medium = FAT;
> +	} else if (!strncmp(&dnl_tab[1][0], "raw", strlen("raw"))) {
> +		dnl->store = img_store;
> +		dnl->medium = RAW;
> +	} else {
> +		printf("DNL: Medium: %s not recognized!", &dnl_tab[1][0]);
> +	}
> +
> +	ret = dnl_download(dnl);
> +	if (ret < 0)
> +		printf("%s: DOWNLOAD failed: %d\n", __func__, ret);
> +
> +	ret = dnl_command(dnl);
> +	if (ret < 0)
> +		printf("%s: COMMAND failed: %d\n", __func__, ret);
> +
> +	return 0;
> +}
> +
> +U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
> +	   "Initialize USB device and Run  THOR USB downloader", NULL
> +);
Wolfgang Denk - April 14, 2012, 1:33 p.m.
Dear Lukasz Majewski,

In message <1334215049-20362-5-git-send-email-l.majewski@samsung.com> you wrote:
> Support for usbdownload command, which starts USB Downloading process
> compliant with Samsung's THOR protocol.
...
> +static char dnl_tab[4][STR_SIZE];
> +
> +char *find_dnl_entry(char* s, char *name)
...
> +int img_store(struct g_dnl *dnl, int medium)


etc.  Please add sufficient comments that allow to understand what
these functions are supposed to do.

> +int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +{
> +	/* Simple argv[0] passing is not working since 'usbdown' cmd can
> +	   be run by */
> +	/* 'usb', 'usbd' or 'usbdown' */

Incorrect multiline comment style,  and I have to admit that I don;t
understand what you are trying to tell us here.

Also note that "usb" is already in use.

> +	puts("THOR Downloader\n");

Please less verbose (see prvious comments).



Best regards,

Wolfgang Denk

Patch

diff --git a/common/Makefile b/common/Makefile
index d9f10f3..2392893 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -161,6 +161,7 @@  COBJS-y += cmd_usb.o
 COBJS-y += usb.o usb_hub.o
 COBJS-$(CONFIG_USB_STORAGE) += usb_storage.o
 endif
+COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += cmd_usbd.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_usbd.c b/common/cmd_usbd.c
new file mode 100644
index 0000000..583f2a5
--- /dev/null
+++ b/common/cmd_usbd.c
@@ -0,0 +1,161 @@ 
+/*
+ * cmd_usbd.c -- USB THOR Downloader gadget
+ *
+ * Copyright (C) 2012 Lukasz Majewski <l.majewski@samsung.com>
+ * All rights reserved.
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#define DEBUG
+#include <common.h>
+#include <usbd_thor.h>
+#include <asm/errno.h>
+#include <malloc.h>
+#include <g_dnl.h>
+
+#define STR_SIZE 16
+
+static char dnl_tab[4][STR_SIZE];
+
+char *find_dnl_entry(char* s, char *name)
+{
+	char *st, *c;
+
+	for (; s; strsep(&s, ";"), st = s) {
+		st = strchr(s, ' ');
+
+		if (!strncmp(s, name, st - s)) {
+			for (c = s; c; strsep(&c, ";"))
+				;
+			return s;
+		}
+	}
+	return NULL;
+}
+
+int img_store(struct g_dnl *dnl, int medium)
+{
+	char cmd_buf[128];
+
+	memset(cmd_buf, '\0', sizeof(cmd_buf));
+
+	switch (medium) {
+	case MMC:
+		sprintf(cmd_buf, "%s write 0x%x %s %s", &dnl_tab[1][0],
+			(unsigned int) dnl->rx_buf, &dnl_tab[2][0],
+			&dnl_tab[3][0]);
+		break;
+	case FAT:
+		sprintf(cmd_buf, "%swrite mmc %s:%s 0x%x %s %x",
+			&dnl_tab[1][0], &dnl_tab[2][0], &dnl_tab[3][0],
+			(unsigned int) dnl->rx_buf, &dnl_tab[0][0],
+			dnl->file_size);
+		break;
+	case RAW:
+		sprintf(cmd_buf, "mmc write 0x%x %x %x",
+			(unsigned int) dnl->rx_buf, dnl->p, dnl->packet_size);
+		break;
+	}
+
+	debug("%s: %s\n", __func__, cmd_buf);
+	run_command(cmd_buf, 0);
+
+	return 0;
+}
+
+int do_usbd_down(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	/* Simple argv[0] passing is not working since 'usbdown' cmd can
+	   be run by */
+	/* 'usb', 'usbd' or 'usbdown' */
+	char *str, *st, *str_env;
+
+	int ret = 0, i = 0;
+	static char *s = "thor";
+	static struct g_dnl *dnl;
+
+	dnl = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(struct g_dnl));
+
+	puts("THOR Downloader\n");
+
+	g_dnl_init(s, dnl);
+
+	ret = dnl_init(dnl);
+	if (ret)
+		printf("%s: USBDOWN failed\n", __func__);
+
+	ret = dnl_command(dnl);
+	if (ret < 0)
+		printf("%s: COMMAND failed: %d\n", __func__, ret);
+
+	debug("DNL: file:%s size:%d\n", dnl->file_name, dnl->file_size);
+
+	str_env = getenv("dnl_info");
+	if (str_env == NULL) {
+		puts("DNL: \"dnl_info\" variable not defined!\n");
+		return -1;
+	}
+	debug("dnl_info: %s\n", str_env);
+
+	str = find_dnl_entry(str_env, dnl->file_name);
+	if (str == NULL) {
+		printf("File: %s not at \"dnl_info\"!\n", dnl->file_name);
+		return -1;
+	}
+
+	debug("%s:str: %s\n", __func__, str);
+
+	memset(dnl_tab, '\0', sizeof(dnl_tab));
+	do {
+		st = strsep(&str, " ");
+		strncpy(&dnl_tab[i++][0], st, strlen(st));
+
+	} while (str);
+
+	if (strncmp(dnl->file_name, &dnl_tab[0][0], strlen(&dnl_tab[0][0]))) {
+		printf("Parsed string not match file: %s!\n", dnl->file_name);
+		return -1;
+	}
+
+	debug("%s %s %s %s\n", &dnl_tab[0][0], &dnl_tab[1][0],
+	       &dnl_tab[2][0], &dnl_tab[3][0]);
+
+	if (!strncmp(&dnl_tab[1][0], "mmc", strlen("mmc"))) {
+		dnl->store = img_store;
+		dnl->medium = MMC;
+	} else if (!strncmp(&dnl_tab[1][0], "fat", strlen("fat"))) {
+		dnl->store = img_store;
+		dnl->medium = FAT;
+	} else if (!strncmp(&dnl_tab[1][0], "raw", strlen("raw"))) {
+		dnl->store = img_store;
+		dnl->medium = RAW;
+	} else {
+		printf("DNL: Medium: %s not recognized!", &dnl_tab[1][0]);
+	}
+
+	ret = dnl_download(dnl);
+	if (ret < 0)
+		printf("%s: DOWNLOAD failed: %d\n", __func__, ret);
+
+	ret = dnl_command(dnl);
+	if (ret < 0)
+		printf("%s: COMMAND failed: %d\n", __func__, ret);
+
+	return 0;
+}
+
+U_BOOT_CMD(usbdown, CONFIG_SYS_MAXARGS, 1, do_usbd_down,
+	   "Initialize USB device and Run  THOR USB downloader", NULL
+);