All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget
@ 2012-04-12  7:17 Lukasz Majewski
  2012-04-12  7:17 ` [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions Lukasz Majewski
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

This patch series provides a composite gadget for downloading code
to u-boot targets.

The Linux's composite gadget framework is used. For this series a 
special function (f_usbd_thor) has been added. It supports a THOR 
protocol for sending data.

Other functions and protocols backends can be easily added - for 
instance supporting DFU.

---
Dependences (commits):
- usb:udc: Remove duplicated USB definitions from include/linux/usb/ch9.h file
- usb:gadget:composite Composite framework (separate patch series)
- usb:udc:samsung Add functions for storing private gadget data in UDC driver


Lukasz Majewski (6):
  usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading
    functions
  usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol
  usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor
    function
  usb:command: Support for USB Download command
  usb:g_dnl: Support for g_dnl download usb gadget for GONI board
  usb:g_dnl: Support for g_dnl download usb gadget for TRATS board

 board/samsung/goni/goni.c        |    8 +
 board/samsung/trats/trats.c      |    8 +
 common/Makefile                  |    1 +
 common/cmd_usbd.c                |  161 ++++++++
 drivers/usb/gadget/Makefile      |    2 +
 drivers/usb/gadget/f_usbd_thor.c |  808 ++++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/g_dnl.c       |  231 +++++++++++
 drivers/usb/gadget/prot_thor.c   |  247 ++++++++++++
 drivers/usb/gadget/prot_thor.h   |  112 ++++++
 include/configs/s5p_goni.h       |   33 ++-
 include/configs/trats.h          |   17 +
 include/g_dnl.h                  |   97 +++++
 include/linux/usb/f_usbd_thor.h  |   62 +++
 include/usbd_thor.h              |  108 +++++
 14 files changed, 1889 insertions(+), 6 deletions(-)
 create mode 100644 common/cmd_usbd.c
 create mode 100644 drivers/usb/gadget/f_usbd_thor.c
 create mode 100644 drivers/usb/gadget/g_dnl.c
 create mode 100644 drivers/usb/gadget/prot_thor.c
 create mode 100644 drivers/usb/gadget/prot_thor.h
 create mode 100644 include/g_dnl.h
 create mode 100644 include/linux/usb/f_usbd_thor.h
 create mode 100644 include/usbd_thor.h

-- 
1.7.2.3

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14  9:55   ` Marek Vasut
  2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

Composite USB download gadget (g_dnl) for download functions (e.g. DFU,
THOR, others)

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Marek Vasut <marex@denx.de>
---
 drivers/usb/gadget/Makefile |    1 +
 drivers/usb/gadget/g_dnl.c  |  231 +++++++++++++++++++++++++++++++++++++++++++
 include/g_dnl.h             |   97 ++++++++++++++++++
 3 files changed, 329 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/gadget/g_dnl.c
 create mode 100644 include/g_dnl.h

diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 87d1918..2c067c8 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -29,6 +29,7 @@ LIB	:= $(obj)libusb_gadget.o
 ifdef CONFIG_USB_GADGET
 COBJS-y += epautoconf.o config.o usbstring.o
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 endif
 ifdef CONFIG_USB_ETHER
 COBJS-y += ether.o epautoconf.o config.o usbstring.o
diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
new file mode 100644
index 0000000..425f4f6
--- /dev/null
+++ b/drivers/usb/gadget/g_dnl.c
@@ -0,0 +1,231 @@
+/*
+ * g_dnl.c -- USB Downloader Gadget
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Lukasz Majewski  <l.majewski@samsung.com>
+ *
+ * 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
+ */
+#undef DEBUG
+#define DEBUG
+#include <errno.h>
+#include <common.h>
+#include <malloc.h>
+#include <linux/usb/ch9.h>
+#include <usbdescriptors.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/f_usbd_thor.h>
+
+#include <mmc.h>
+#include <part.h>
+
+#include <g_dnl.h>
+
+#include "usbd_thor.h"
+#include "gadget_chips.h"
+
+#include "composite.c"
+
+#define DRIVER_VERSION		"usb_dnl 2.0"
+
+static const char shortname[] = "usb_dnl_";
+static const char product[] = "SLP USB download gadget";
+static const char manufacturer[] = "Samsung";
+
+static struct usb_device_descriptor device_desc = {
+	.bLength =		sizeof device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+	.bDeviceClass =		USB_CLASS_COMM,
+	.bDeviceSubClass =      0x02,	/*0x02:CDC-modem , 0x00:CDC-serial*/
+
+	.idVendor =		__constant_cpu_to_le16(DRIVER_VENDOR_NUM),
+	.idProduct =		__constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
+	.iProduct =		STRING_PRODUCT,
+	.bNumConfigurations =	1,
+};
+
+static const struct usb_descriptor_header *otg_desc[] = {
+	(struct usb_descriptor_header *) &(struct usb_otg_descriptor){
+		.bLength =		sizeof(struct usb_otg_descriptor),
+		.bDescriptorType =	USB_DT_OTG,
+		.bmAttributes =		USB_OTG_SRP,
+	},
+	NULL,
+};
+
+/* static strings, in UTF-8 */
+static struct usb_string odin_string_defs[] = {
+	{ 0, manufacturer, },
+	{ 1, product, },
+};
+
+static struct usb_gadget_strings odin_string_tab = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= odin_string_defs,
+};
+
+static struct usb_gadget_strings *g_dnl_composite_strings[] = {
+	&odin_string_tab,
+	NULL,
+};
+
+static int g_dnl_unbind(struct usb_composite_dev *cdev)
+{
+	debug("%s\n", __func__);
+	return 0;
+}
+
+static int g_dnl_do_config(struct usb_configuration *c)
+{
+	int ret = -1;
+	char *s = (char *) c->cdev->driver->name;
+
+	debug("%s: c: 0x%p cdev: 0x%p\n", __func__, c, c->cdev);
+
+	if (gadget_is_otg(c->cdev->gadget)) {
+		c->descriptors = otg_desc;
+		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
+	}
+
+	printf("GADGET DRIVER: %s\n", s);
+
+	if (!strcmp(s, "usb_dnl_thor"))
+		ret = f_usbd_add(c);
+
+	return ret;
+}
+
+static int g_dnl_config_register(struct usb_composite_dev *cdev)
+{
+	debug("%s:\n", __func__);
+	static struct usb_configuration config = {
+		.label = "usbd_thor_download",
+		.bmAttributes =	USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
+		.bConfigurationValue =	CONFIG_USBDOWNLOADER,
+		.iConfiguration =	STRING_USBDOWN,
+
+		.bind = g_dnl_do_config,
+	};
+
+	return usb_add_config(cdev, &config);
+}
+
+static int g_dnl_bind(struct usb_composite_dev *cdev)
+{
+	int			gcnum;
+	int id, ret;
+	struct usb_gadget	*gadget = cdev->gadget;
+
+	debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev);
+
+	id = usb_string_id(cdev);
+
+	if (id < 0)
+		return id;
+	odin_string_defs[0].id = id;
+	device_desc.iManufacturer = id;
+
+	id = usb_string_id(cdev);
+	if (id < 0)
+		return id;
+
+	odin_string_defs[1].id = id;
+	device_desc.iProduct = id;
+
+	ret = g_dnl_config_register(cdev);
+	if (ret)
+		goto error;
+
+
+	gcnum = usb_gadget_controller_number(gadget);
+
+	debug("gcnum: %d\n", gcnum);
+	if (gcnum >= 0)
+		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
+	else {
+		printf("%s: controller '%s' not recognized\n",
+			shortname, gadget->name);
+		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
+	}
+
+	return 0;
+
+ error:
+	g_dnl_unbind(cdev);
+	return -ENOMEM;
+}
+
+static void g_dnl_suspend(struct usb_composite_dev *cdev)
+{
+	if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
+		return;
+
+	debug("suspend\n");
+}
+
+static void g_dnl_resume(struct usb_composite_dev *cdev)
+{
+	debug("resume\n");
+}
+
+static struct usb_composite_driver g_dnl_driver = {
+	.name		= shortname,
+	.dev		= &device_desc,
+	.strings	= g_dnl_composite_strings,
+
+	.bind		= g_dnl_bind,
+	.unbind		= g_dnl_unbind,
+
+	.suspend	= g_dnl_suspend,
+	.resume		= g_dnl_resume,
+};
+
+int g_dnl_init(char *s, struct g_dnl *dnl)
+{
+
+	int ret;
+	static char str[16];
+
+	memset(str, 0x00, sizeof(str));
+	strncpy(str, shortname, sizeof(shortname));
+
+	if (!strncmp(s, "thor", sizeof(s))) {
+		strncat(str, s, sizeof(str));
+	} else {
+		printf("%s: unknown command: %s\n", __func__, s);
+		return -EINVAL;
+	}
+
+	strncpy((char *) g_dnl_driver.name, (const char *) str, sizeof(str));
+
+	usbd_thor_udc_probe();
+	set_udc_gadget_private_data(dnl);
+
+	ret = usb_composite_register(&g_dnl_driver);
+
+	if (ret) {
+		printf("%s: failed!, error:%d ", __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+void g_dnl_cleanup(void)
+{
+	usb_composite_unregister(&g_dnl_driver);
+}
diff --git a/include/g_dnl.h b/include/g_dnl.h
new file mode 100644
index 0000000..9777b60
--- /dev/null
+++ b/include/g_dnl.h
@@ -0,0 +1,97 @@
+/*
+ *  Copyright (C) 2012 Samsung Electronics
+ *  Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * 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
+ */
+
+#ifndef __G_DOWNLOAD_H_
+#define __G_DOWNLOAD_H_
+
+#include <mmc.h>
+#include <linux/usb/ch9.h>
+#include <usbdescriptors.h>
+#include <linux/usb/gadget.h>
+
+enum { THOR = 1 };
+enum {MMC = 1, FAT = 2, RAW = 3};
+
+struct g_dnl {
+	int prot;
+
+	char *file_name;
+	int file_size;
+
+	int (*init) (struct g_dnl *dnl);
+	int (*info) (void);
+
+	int (*dl) (struct g_dnl *dnl);
+	int (*ul) (struct g_dnl *dnl);
+
+	unsigned int *rx_buf;
+	unsigned int *tx_buf;
+
+	int (*cmd) (struct g_dnl *dnl);
+
+	int medium;
+	int (*store) (struct g_dnl *dnl, int medium);
+	unsigned int p; /* private */
+
+	int packet_size;
+};
+
+/**
+ * dnl_init - initialize code downloader
+ * @dnl: Interface to download functions
+ *
+ * returns zero, or a negative error code.
+ */
+static inline int dnl_init(struct g_dnl *dnl)
+{
+	return dnl->init(dnl);
+}
+
+/**
+ * dnl_download - handle download operation
+ * @dnl: Interface to download functions
+ *
+ * returns zero on success or a negative error code.
+ *
+ */
+static inline int dnl_download(struct g_dnl *dnl)
+{
+	return dnl->dl(dnl);
+}
+
+/**
+ * dnl_command - handle various commands
+ * @dnl: Interface to download functions
+ *
+ * returns zero on success or a negative error code.
+ *
+ */
+static inline int dnl_command(struct g_dnl *dnl)
+{
+	return dnl->cmd(dnl);
+}
+
+int g_dnl_init(char *s, struct g_dnl *dnl);
+void set_udc_gadget_private_data(void *);
+struct g_dnl *get_udc_gadget_private_data(struct usb_gadget *gadget);
+
+void usbd_thor_udc_probe(void);
+
+#endif /* __G_DOWNLOAD_H_ */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
  2012-04-12  7:17 ` [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14  9:58   ` Marek Vasut
                     ` (2 more replies)
  2012-04-12  7:17 ` [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function Lukasz Majewski
                   ` (3 subsequent siblings)
  5 siblings, 3 replies; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

Implementation of USB Download function supporting 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>
---
 drivers/usb/gadget/Makefile      |    1 +
 drivers/usb/gadget/f_usbd_thor.c |  808 ++++++++++++++++++++++++++++++++++++++
 include/linux/usb/f_usbd_thor.h  |   62 +++
 3 files changed, 871 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/gadget/f_usbd_thor.c
 create mode 100644 include/linux/usb/f_usbd_thor.h

diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index 2c067c8..0c48368 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -29,6 +29,7 @@ LIB	:= $(obj)libusb_gadget.o
 ifdef CONFIG_USB_GADGET
 COBJS-y += epautoconf.o config.o usbstring.o
 COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
+COBJS-$(CONFIG_USBDOWNLOAD_FUNCTION) += f_usbd_thor.o prot_thor.o
 COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
 endif
 ifdef CONFIG_USB_ETHER
diff --git a/drivers/usb/gadget/f_usbd_thor.c b/drivers/usb/gadget/f_usbd_thor.c
new file mode 100644
index 0000000..e2394e3
--- /dev/null
+++ b/drivers/usb/gadget/f_usbd_thor.c
@@ -0,0 +1,808 @@
+/*
+ * f_usbd_thor.c -- USB THOR Downloader gadget function
+ *
+ * Copyright (C) 2011-2012 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * 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
+ */
+#undef DEBUG
+#include <errno.h>
+#include <common.h>
+#include <malloc.h>
+#include <linux/usb/ch9.h>
+#include <usbdescriptors.h>
+#include <linux/usb/gadget.h>
+#include <linux/usb/composite.h>
+#include <linux/usb/f_usbd_thor.h>
+#include <linux/usb/cdc.h>
+
+#include <g_dnl.h>
+#include <mmc.h>
+#include <part.h>
+
+#include "usbd_thor.h"
+#include "prot_thor.h"
+#include "gadget_chips.h"
+
+#define DMA_BUFFER_SIZE	(4096*4)
+
+static struct f_usbd *usbd_func;
+static const unsigned buflen = 512; /* Standard request buffer length */
+
+struct usbd_dev {
+	struct usb_gadget	*gadget;
+	struct usb_request	*req;		/* for control responses */
+
+	/* IN/OUT EP's and correspoinding requests */
+	struct usb_ep		*in_ep, *out_ep, *int_ep;
+	struct usb_request	*in_req, *out_req;
+
+	/* Control flow variables*/
+	int configuration_done;
+	int stop_done;
+	int rxdata;
+	int txdata;
+};
+
+struct f_usbd {
+	struct usb_function		usb_function;
+	struct usbd_dev *dev;
+};
+
+static inline struct f_usbd *func_to_usbd(struct usb_function *f)
+{
+	return container_of(f, struct f_usbd, usb_function);
+}
+
+/* maxpacket and other transfer characteristics vary by speed. */
+static inline struct usb_endpoint_descriptor *
+ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
+		struct usb_endpoint_descriptor *fs)
+{
+	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
+		return hs;
+	return fs;
+}
+
+/* one interface in each configuration */
+static struct usb_interface_descriptor usb_downloader_intf_data = {
+	.bLength =		sizeof usb_downloader_intf_data,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	2,
+	.bInterfaceClass =	USB_CLASS_CDC_DATA,
+};
+
+
+/* two full speed bulk endpoints; their use is config-dependent */
+static struct usb_endpoint_descriptor fs_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usb_endpoint_descriptor fs_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	USB_DIR_OUT,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+};
+
+/* CDC configuration */
+
+static struct usb_interface_descriptor usb_downloader_intf_int = {
+	.bLength =		sizeof usb_downloader_intf_int,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	1,
+	.bInterfaceClass =	USB_CLASS_COMM,
+	 /* 0x02 Abstract Line Control Model */
+	.bInterfaceSubClass =   COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
+	/* 0x01 Common AT commands */
+	.bInterfaceProtocol =   COMMUNICATIONS_V25TER_PROTOCOL,
+};
+
+static struct usb_class_header_function_descriptor usb_downloader_cdc_header = {
+	.bFunctionLength =    sizeof usb_downloader_cdc_header,
+	.bDescriptorType =    CS_INTERFACE, /* 0x24 */
+	.bDescriptorSubtype = 0x00,	/* 0x00 */
+	.bcdCDC =             0x0110,
+};
+
+
+static struct usb_class_call_management_descriptor usb_downloader_cdc_call = {
+	.bFunctionLength =    sizeof usb_downloader_cdc_call,
+	.bDescriptorType =    CS_INTERFACE, /* 0x24 */
+	.bDescriptorSubtype = 0x01,	/* 0x01 */
+	.bmCapabilities =     0x00,
+	.bDataInterface =     0x01,
+};
+
+struct usb_class_abstract_control_descriptor usb_downloader_cdc_abstract = {
+	.bFunctionLength =    sizeof usb_downloader_cdc_abstract,
+	.bDescriptorType =    CS_INTERFACE,
+	.bDescriptorSubtype = 0x02,	/* 0x02 */
+	.bmCapabilities =     0x00,
+};
+
+struct usb_class_union_function_descriptor usb_downloader_cdc_union = {
+	.bFunctionLength =     sizeof usb_downloader_cdc_union,
+	.bDescriptorType =     CS_INTERFACE,
+	.bDescriptorSubtype =  0x06,	/* 0x06 */
+};
+
+
+static struct usb_endpoint_descriptor fs_int_desc = {
+	.bLength = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+
+	.bEndpointAddress = 3 | USB_DIR_IN,
+	.bmAttributes = USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize = __constant_cpu_to_le16(16),
+
+	.bInterval = 0x9,
+};
+
+static struct usb_interface_assoc_descriptor
+usbd_iad_descriptor = {
+	.bLength =		sizeof usbd_iad_descriptor,
+	.bDescriptorType =	USB_DT_INTERFACE_ASSOCIATION,
+
+	.bFirstInterface =	0,
+	.bInterfaceCount =	2,	/* control + data */
+	.bFunctionClass =	USB_CLASS_COMM,
+	.bFunctionSubClass =	USB_CDC_SUBCLASS_ACM,
+	.bFunctionProtocol =	USB_CDC_PROTO_NONE,
+	/* .iFunction = DYNAMIC */
+};
+
+
+/*
+ * usb 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ *
+ */
+
+static struct usb_endpoint_descriptor hs_in_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_out_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16(512),
+};
+
+static struct usb_endpoint_descriptor hs_int_desc = {
+	.bLength = USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType = USB_DT_ENDPOINT,
+
+	.bmAttributes = USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize = __constant_cpu_to_le16(16),
+
+	.bInterval = 0x9,
+};
+
+static struct usb_qualifier_descriptor dev_qualifier = {
+	.bLength =		sizeof dev_qualifier,
+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
+
+	.bcdUSB =		__constant_cpu_to_le16(0x0200),
+	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
+
+	.bNumConfigurations =	2,
+};
+
+static const struct usb_descriptor_header *hs_usb_downloader_function[] = {
+	/* (struct usb_descriptor_header *) &otg_descriptor, */
+	(struct usb_descriptor_header *) &usbd_iad_descriptor,
+
+	(struct usb_descriptor_header *) &usb_downloader_intf_int,
+	(struct usb_descriptor_header *) &usb_downloader_cdc_header,
+	(struct usb_descriptor_header *) &usb_downloader_cdc_call,
+	(struct usb_descriptor_header *) &usb_downloader_cdc_abstract,
+	(struct usb_descriptor_header *) &usb_downloader_cdc_union,
+	(struct usb_descriptor_header *) &hs_int_desc,
+
+	(struct usb_descriptor_header *) &usb_downloader_intf_data,
+	(struct usb_descriptor_header *) &hs_in_desc,
+	(struct usb_descriptor_header *) &hs_out_desc,
+	NULL,
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
+{
+	struct usb_request	*req;
+
+	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
+	if (req) {
+		req->length = length;
+		req->buf = malloc(length);
+		if (!req->buf) {
+			usb_ep_free_request(ep, req);
+			req = NULL;
+		}
+	}
+	return req;
+}
+
+unsigned int usbd_rx_data(void)
+{
+	int status;
+	struct usbd_dev *dev = usbd_func->dev;
+
+	static int data_to_rx = 0, tmp;
+
+	data_to_rx = dev->out_req->length;
+	tmp = data_to_rx;
+
+	do {
+
+		if (data_to_rx > DMA_BUFFER_SIZE)
+			dev->out_req->length = DMA_BUFFER_SIZE;
+		else
+			dev->out_req->length = data_to_rx;
+
+		debug("dev->out_req->length:%d dev->rxdata:%d\n",
+		     dev->out_req->length, dev->rxdata);
+
+		status = usb_ep_queue(dev->out_ep, dev->out_req, GFP_ATOMIC);
+		if (status) {
+			printf("kill %s:  resubmit %d bytes --> %d\n",
+			       dev->out_ep->name, dev->out_req->length, status);
+			usb_ep_set_halt(dev->out_ep);
+			/* FIXME recover later ... somehow */
+			return -1;
+		}
+
+		while (!dev->rxdata)
+			usb_gadget_handle_interrupts();
+
+		dev->rxdata = 0;
+
+		if (data_to_rx > DMA_BUFFER_SIZE)
+			dev->out_req->buf += DMA_BUFFER_SIZE;
+
+		data_to_rx -= dev->out_req->actual;
+
+	} while (data_to_rx);
+
+	return tmp;
+}
+
+void usbd_tx_data(char *data, int len)
+{
+	int status;
+	struct usbd_dev *dev = usbd_func->dev;
+
+	unsigned char *ptr = dev->in_req->buf;
+
+	memset(ptr, '\0', len);
+	memcpy(ptr, data, len);
+
+	dev->in_req->length = len;
+
+	debug("%s: dev->in_req->length:%d to_cpy:%d\n", __func__,
+	    dev->in_req->length, sizeof(data));
+
+	status = usb_ep_queue(dev->in_ep, dev->in_req, GFP_ATOMIC);
+	if (status) {
+		printf("kill %s:  resubmit %d bytes --> %d\n",
+		       dev->in_ep->name, dev->in_req->length, status);
+		usb_ep_set_halt(dev->in_ep);
+		/* FIXME recover later ... somehow */
+	}
+
+	/* Wait until tx interrupt received */
+	while (!dev->txdata)
+		usb_gadget_handle_interrupts();
+
+	dev->txdata = 0;
+}
+
+static void usbd_rx_tx_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	int		status = req->status;
+	struct usbd_dev *dev = usbd_func->dev;
+
+	debug("%s: ep_ptr:%p, req_ptr:%p\n", __func__, ep, req);
+	switch (status) {
+
+	case 0:				/* normal completion? */
+		if (ep == dev->out_ep)
+			dev->rxdata = 1;
+		else
+			dev->txdata = 1;
+
+		break;
+
+	/* this endpoint is normally active while we're configured */
+	case -ECONNABORTED:		/* hardware forced ep reset */
+	case -ECONNRESET:		/* request dequeued */
+	case -ESHUTDOWN:		/* disconnect from host */
+		/* Exeptional situation - print error message */
+
+	case -EOVERFLOW:
+		printf("%s: ERROR:%d\n", __func__, status);
+	default:
+		debug("%s complete --> %d, %d/%d\n", ep->name,
+				status, req->actual, req->length);
+	case -EREMOTEIO:		/* short read */
+		break;
+	}
+}
+
+static struct usb_request *usbd_start_ep(struct usb_ep *ep)
+{
+	struct usb_request	*req;
+
+	req = alloc_ep_req(ep, buflen);
+	debug("%s: ep:%p req:%p\n", __func__, ep, req);
+
+	if (!req)
+		return NULL;
+
+	memset(req->buf, 0, req->length);
+	req->complete = usbd_rx_tx_complete;
+
+	memset(req->buf, 0x55, req->length);
+
+	return req;
+}
+
+static void usbd_setup_complete(struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->status || req->actual != req->length)
+		debug("setup complete --> %d, %d/%d\n",
+		    req->status, req->actual, req->length);
+}
+
+static int
+usbd_func_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+{
+	int value = 0;
+	struct usbd_dev         *dev = usbd_func->dev;
+	struct usb_request      *req = dev->req;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	u16 len = le16_to_cpu(ctrl->wLength);
+	u16 wValue = le16_to_cpu(ctrl->wValue);
+
+	debug("Req_Type: 0x%x Req: 0x%x wValue: 0x%x wIndex: 0x%x wLen: 0x%x\n",
+	       ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex,
+	       ctrl->wLength);
+
+	switch (ctrl->bRequest) {
+	case SET_CONTROL_LINE_STATE:
+		value = 0;
+
+		switch (wValue) {
+		case DEACTIVATE_CARRIER:
+			/* Before reset wait for all ACM requests to be done */
+			dev->stop_done = 1;
+			break;
+		case ACTIVATE_CARRIER:
+			break;
+		default:
+			printf("usbd_setup:SetControlLine-unknown wValue: %d\n",
+			       wValue);
+		}
+		break;
+	case SET_LINE_CODING:
+		value = len;
+
+		/* Line Coding set done = configuration done */
+		usbd_func->dev->configuration_done = 1;
+		break;
+
+	default:
+		printf("usbd_setup: unknown request: %d\n", ctrl->bRequest);
+	}
+
+	if (value >= 0) {
+		req->length = value;
+		req->zero = value < len;
+		value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
+		if (value < 0) {
+			debug("ep_queue --> %d\n", value);
+			req->status = 0;
+		}
+	}
+
+	return value;
+}
+
+/* Specific to the USBD_THOR protocol */
+void usbd_set_dma(char *addr, int len)
+{
+	struct usbd_dev *dev = usbd_func->dev;
+
+	debug("in_req:%p, out_req:%p\n", dev->in_req, dev->out_req);
+	debug("addr:%p, len:%d\n", addr, len);
+
+	dev->out_req->buf = addr;
+	dev->out_req->length = len;
+
+}
+
+static void usbd_cancel(int mode)
+{
+
+	switch (mode) {
+	case END_BOOT:
+		run_command("run bootcmd", 0);
+		break;
+	default:
+		break;
+	}
+}
+
+__attribute__ ((__aligned__ (__alignof__ (long long))))
+static char usbd_tx_buf[TX_DATA_LEN];
+__attribute__ ((__aligned__ (__alignof__ (long long))))
+static char usbd_rx_buf[RX_DATA_LEN];
+
+char *usbd_tx_data_buf = usbd_tx_buf;
+char *usbd_rx_data_buf = usbd_rx_buf;
+
+static const char *recv_key = "THOR";
+static const char *tx_key = "ROHT";
+
+static int usbd_init(struct g_dnl *dnl)
+{
+	int ret;
+	struct usbd_dev *dev = usbd_func->dev;
+
+	/* Wait for a device enumeration and configuration settings */
+	debug("USBD enumeration/configuration setting....\n");
+	while (!dev->configuration_done)
+		usb_gadget_handle_interrupts();
+
+	usbd_set_dma(usbd_rx_data_buf, strlen(recv_key));
+	/* detect the download request from Host PC */
+	ret = usbd_rx_data();
+
+	if (strncmp(usbd_rx_data_buf, recv_key, strlen(recv_key)) == 0) {
+		printf("Download request from the Host PC\n");
+		msleep(30);
+
+		strncpy(usbd_tx_data_buf, tx_key, strlen(tx_key));
+		usbd_tx_data(usbd_tx_data_buf, strlen(tx_key));
+	} else {
+		puts("Wrong reply information\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int usbd_handle(struct g_dnl *dnl)
+{
+	int ret;
+
+	debug("USBD Handle start....\n");
+
+	/* receive the data from Host PC */
+	while (1) {
+		usbd_set_dma(usbd_rx_data_buf, sizeof(rqt_box));
+		ret = usbd_rx_data();
+
+		if (ret > 0) {
+			ret = process_data(dnl);
+
+			if (ret < 0)
+				return -1;
+			else if (ret == 0)
+				return 0;
+		} else {
+			puts("No data received!\n");
+			usbd_cancel(END_BOOT);
+		}
+	}
+
+	return 0;
+}
+
+
+/* USB Downloader's specific definitions - required for this framework */
+
+void usbd_fill_dnl(struct g_dnl *dnl)
+{
+	dnl->prot = THOR;
+	dnl->init = &usbd_init;
+	dnl->dl = &usbd_handle;
+	dnl->cmd = &usbd_handle;
+
+	/* If the following pointers are set to NULL -> error */
+	dnl->rx_buf = (unsigned int *) CONFIG_SYS_DOWN_ADDR;
+	dnl->tx_buf = NULL;
+}
+
+static int usbd_func_bind(struct usb_configuration *c, struct usb_function *f)
+{
+	int status;
+	struct usb_ep		*ep;
+	struct usbd_dev		*dev;
+	struct f_usbd           *f_usbd = func_to_usbd(f);
+	struct usb_gadget       *gadget = c->cdev->gadget;
+	struct g_dnl            *dnl = get_udc_gadget_private_data(gadget);
+
+	usbd_func = f_usbd;
+	dev = calloc(sizeof(*dev), 1);
+	if (!dev)
+		return -ENOMEM;
+
+	dev->gadget = gadget;
+
+	f_usbd->dev = dev;
+	f_usbd->dev->configuration_done = 0;
+	f_usbd->dev->rxdata = 0;
+	f_usbd->dev->txdata = 0;
+
+	debug("%s: usb_configuration: 0x%p usb_function: 0x%p\n",
+	    __func__, c, f);
+	debug("f_usbd: 0x%p usbd: 0x%p\n", f_usbd, dev);
+
+	/* EP0  */
+	/* preallocate control response and buffer */
+	dev->req = usb_ep_alloc_request(gadget->ep0, 0);
+	if (!dev->req) {
+		status = -ENOMEM;
+		goto fail;
+	}
+	dev->req->buf = malloc(buflen);
+	if (!dev->req->buf) {
+		status = -ENOMEM;
+		goto fail;
+	}
+
+	dev->req->complete = usbd_setup_complete;
+
+	/* DYNAMIC interface numbers assignments */
+	status = usb_interface_id(c, f);
+
+	if (status < 0)
+		goto fail;
+
+	usb_downloader_intf_int.bInterfaceNumber = status;
+	usb_downloader_cdc_union.bMasterInterface = status;
+
+	status = usb_interface_id(c, f);
+
+	if (status < 0)
+		goto fail;
+
+	usb_downloader_intf_data.bInterfaceNumber = status;
+	usb_downloader_cdc_union.bSlaveInterface0 = status;
+
+
+	/* allocate instance-specific endpoints */
+	ep = usb_ep_autoconfig(gadget, &fs_in_desc);
+	if (!ep) {
+		status = -ENODEV;
+		goto fail;
+	}
+
+	if (gadget_is_dualspeed(gadget)) {
+		hs_in_desc.bEndpointAddress =
+				fs_in_desc.bEndpointAddress;
+	}
+
+	dev->in_ep = ep; /* Store IN EP for enabling @ setup */
+
+
+
+	ep = usb_ep_autoconfig(gadget, &fs_out_desc);
+	if (!ep) {
+		status = -ENODEV;
+		goto fail;
+	}
+
+	if (gadget_is_dualspeed(gadget)) {
+		hs_out_desc.bEndpointAddress =
+				fs_out_desc.bEndpointAddress;
+	}
+
+	dev->out_ep = ep; /* Store OUT EP for enabling @ setup */
+
+	/* note:  a status/notification endpoint is, strictly speaking,
+	 * optional.  We don't treat it that way though!  It's simpler,
+	 * and some newer profiles don't treat it as optional.
+	 */
+	ep = usb_ep_autoconfig(gadget, &fs_int_desc);
+	if (!ep) {
+		status = -ENODEV;
+		goto fail;
+	}
+
+	dev->int_ep = ep;
+
+	if (gadget_is_dualspeed(gadget)) {
+		hs_int_desc.bEndpointAddress =
+				fs_int_desc.bEndpointAddress;
+
+		/* copy descriptors, and track endpoint copies */
+		f->hs_descriptors = (struct usb_descriptor_header **)
+			&hs_usb_downloader_function;
+
+		if (!f->hs_descriptors)
+			goto fail;
+	}
+
+	debug("%s: out_ep:%p out_req:%p\n",
+	      __func__, dev->out_ep, dev->out_req);
+	printf("%s: dnl: 0x%p\n", __func__, dnl);
+	usbd_fill_dnl(dnl);
+
+	return 0;
+
+ fail:
+	free(dev);
+	return status;
+}
+
+static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+{
+	free(req->buf);
+	usb_ep_free_request(ep, req);
+}
+
+static void usbd_func_disable(struct usb_function *f)
+{
+	struct f_usbd   *f_usbd = func_to_usbd(f);
+	struct usbd_dev *dev = f_usbd->dev;
+
+	debug("%s:\n", __func__);
+
+	/* Avoid freeing memory when ep is still claimed */
+	if (dev->in_ep->driver_data) {
+		free_ep_req(dev->in_ep, dev->in_req);
+		usb_ep_disable(dev->in_ep);
+		dev->in_ep->driver_data = NULL;
+	}
+
+	if (dev->out_ep->driver_data) {
+		free_ep_req(dev->out_ep, dev->out_req);
+		usb_ep_disable(dev->out_ep);
+		dev->out_ep->driver_data = NULL;
+	}
+
+	if (dev->int_ep->driver_data) {
+		usb_ep_disable(dev->int_ep);
+		dev->int_ep->driver_data = NULL;
+	}
+}
+
+static int usbd_eps_setup(struct usb_function *f)
+{
+	int result;
+	struct usb_composite_dev *cdev = f->config->cdev;
+	struct usb_ep		*ep;
+	struct usb_request      *req;
+	struct usb_gadget       *gadget = cdev->gadget;
+	struct usbd_dev         *dev = usbd_func->dev;
+
+	struct usb_endpoint_descriptor	*d;
+
+	ep = dev->in_ep;
+	d = ep_desc(gadget, &hs_in_desc, &fs_in_desc);
+	debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
+
+	result = usb_ep_enable(ep, d);
+
+	if (result == 0) {
+		ep->driver_data = cdev; /* claim */
+		req = usbd_start_ep(ep);
+		if (req != NULL) {
+			dev->in_req = req;
+		} else {
+			usb_ep_disable(ep);
+			result = -EIO;
+		}
+	} else
+		goto exit;
+
+	ep = dev->out_ep;
+	d = ep_desc(gadget, &hs_out_desc, &fs_out_desc);
+	debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
+
+	result = usb_ep_enable(ep, d);
+
+	if (result == 0) {
+		ep->driver_data = cdev; /* claim */
+		req = usbd_start_ep(ep);
+		if (req != NULL) {
+			dev->out_req = req;
+		} else {
+			usb_ep_disable(ep);
+			result = -EIO;
+		}
+	} else
+		goto exit;
+
+	/* ACM control EP */
+	ep = dev->int_ep;
+	ep->driver_data = cdev;	/* claim */
+
+ exit:
+	return result;
+}
+
+static int usbd_func_set_alt(struct usb_function *f,
+			     unsigned intf, unsigned alt)
+{
+	int result;
+	debug("%s: func: %s intf: %d alt: %d\n",
+	    __func__, f->name, intf, alt);
+
+	switch (intf) {
+	case 0:
+		debug("ACM INTR interface\n");
+		break;
+	case 1:
+		debug("Communication Data interface\n");
+
+		result = usbd_eps_setup(f);
+		if (result)
+			printf("%s: EPs setup failed!\n", __func__);
+		break;
+	}
+
+	return 0;
+}
+
+static int usbd_func_init(struct usb_configuration *c)
+{
+	int status;
+	struct f_usbd *f_usbd;
+
+	debug("%s: cdev: 0x%p\n", __func__, c->cdev);
+
+	f_usbd = calloc(sizeof(*f_usbd), 1);
+	if (!f_usbd)
+		return -ENOMEM;
+
+	f_usbd->usb_function.name = "f_usbd";
+	f_usbd->usb_function.bind = usbd_func_bind;
+	f_usbd->usb_function.setup = usbd_func_setup;
+	f_usbd->usb_function.set_alt = usbd_func_set_alt;
+	f_usbd->usb_function.disable = usbd_func_disable;
+
+	status = usb_add_function(c, &f_usbd->usb_function);
+	if (status)
+		free(f_usbd);
+
+	return status;
+}
+
+int f_usbd_add(struct usb_configuration *c)
+{
+	debug("%s:\n", __func__);
+
+	return usbd_func_init(c);
+}
diff --git a/include/linux/usb/f_usbd_thor.h b/include/linux/usb/f_usbd_thor.h
new file mode 100644
index 0000000..8002791
--- /dev/null
+++ b/include/linux/usb/f_usbd_thor.h
@@ -0,0 +1,62 @@
+/*
+ * USB THOR Downloader
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Lukasz Majewski  <l.majewski@samsung.com>
+ *
+ * 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
+ */
+
+#ifndef _USB_THOR_H_
+#define _USB_THOR_H_
+
+#include <linux/usb/composite.h>
+
+/* ACM -> THOR GADGET download */
+#define DEACTIVATE_CARRIER 0x0000
+#define ACTIVATE_CARRIER 0x0003
+
+#define SET_LINE_CODING 0x0020
+#define SET_CONTROL_LINE_STATE 0x0022
+
+/* THOR Composite Gadget */
+
+#define STRING_MANUFACTURER_IDX		0
+#define STRING_PRODUCT_IDX		1
+#define STRING_SERIAL_IDX		2
+
+/* Samsung's IDs */
+#define DRIVER_VENDOR_NUM 0x04E8
+#define DRIVER_PRODUCT_NUM 0x6601
+
+#define STRING_MANUFACTURER 25
+#define STRING_PRODUCT 2
+#define STRING_USBDOWN 2
+#define	CONFIG_USBDOWNLOADER 2
+
+int f_usbd_add(struct usb_configuration *c);
+
+/* Interface to THOR protocol */
+#define TX_DATA_LEN 64
+#define RX_DATA_LEN 1024
+
+extern char *usbd_tx_data_buf;
+extern char *usbd_rx_data_buf;
+
+extern void usbd_set_dma(char *addr, int len);
+extern unsigned int usbd_rx_data(void);
+extern void usbd_tx_data(char *data, int len);
+
+#endif /* _USB_THOR_H_ */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
  2012-04-12  7:17 ` [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions Lukasz Majewski
  2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14 10:00   ` Marek Vasut
  2012-04-14 13:30   ` Wolfgang Denk
  2012-04-12  7:17 ` [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command Lukasz Majewski
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

Support for THOR download protocol. Those files are necessary for
proper f_usbd_thor function proper work.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Marek Vasut <marex@denx.de>
---
 drivers/usb/gadget/prot_thor.c |  247 ++++++++++++++++++++++++++++++++++++++++
 drivers/usb/gadget/prot_thor.h |  112 ++++++++++++++++++
 include/usbd_thor.h            |  108 +++++++++++++++++
 3 files changed, 467 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/gadget/prot_thor.c
 create mode 100644 drivers/usb/gadget/prot_thor.h
 create mode 100644 include/usbd_thor.h

diff --git a/drivers/usb/gadget/prot_thor.c b/drivers/usb/gadget/prot_thor.c
new file mode 100644
index 0000000..9b2610d
--- /dev/null
+++ b/drivers/usb/gadget/prot_thor.c
@@ -0,0 +1,247 @@
+/*
+ * prot_thor.c -- USB THOR Downloader protocol
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * 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
+ *
+ */
+#undef DEBUG
+#include <common.h>
+#include <errno.h>
+#include <g_dnl.h>
+#include "prot_thor.h"
+
+static void send_rsp(const rsp_box *rsp)
+{
+	/* should be copy on dma duffer */
+	memcpy(usbd_tx_data_buf, rsp, sizeof(rsp_box));
+	pkt_upload(usbd_tx_data_buf, sizeof(rsp_box));
+
+	debug("-RSP: %d, %d\n", rsp->rsp, rsp->rsp_data);
+}
+
+static void send_data_rsp(s32 ack, s32 count)
+{
+	data_rsp_box rsp;
+
+	rsp.ack = ack;
+	rsp.count = count;
+
+	/* should be copy on dma duffer */
+	memcpy(usbd_tx_data_buf, &rsp, sizeof(data_rsp_box));
+	pkt_upload(usbd_tx_data_buf, sizeof(data_rsp_box));
+
+	debug("-DATA RSP: %d, %d\n", ack, count);
+}
+
+static int process_rqt_info(const rqt_box *rqt)
+{
+	rsp_box rsp = {0, };
+
+	rsp.rsp = rqt->rqt;
+	rsp.rsp_data = rqt->rqt_data;
+
+	switch (rqt->rqt_data) {
+	case RQT_INFO_VER_PROTOCOL:
+		rsp.int_data[0] = VER_PROTOCOL_MAJOR;
+		rsp.int_data[1] = VER_PROTOCOL_MINOR;
+		break;
+	case RQT_INIT_VER_HW:
+		sprintf(rsp.str_data[0], "%x", checkboard());
+		break;
+	case RQT_INIT_VER_BOOT:
+		sprintf(rsp.str_data[0], "%s", getenv("ver"));
+		break;
+	case RQT_INIT_VER_KERNEL:
+		sprintf(rsp.str_data[0], "%s", "k unknown");
+		break;
+	case RQT_INIT_VER_PLATFORM:
+		sprintf(rsp.str_data[0], "%s", "p unknown");
+		break;
+	case RQT_INIT_VER_CSC:
+		sprintf(rsp.str_data[0], "%s", "c unknown");
+		break;
+	default:
+		return 0;
+	}
+
+	send_rsp(&rsp);
+	return 1;
+}
+
+static int process_rqt_cmd(const rqt_box *rqt)
+{
+	rsp_box rsp = {0, };
+
+	rsp.rsp = rqt->rqt;
+	rsp.rsp_data = rqt->rqt_data;
+
+	switch (rqt->rqt_data) {
+	case RQT_CMD_REBOOT:
+		debug("TARGET RESET\n");
+		send_rsp(&rsp);
+		run_command("reset", 0);
+		break;
+	case RQT_CMD_POWEROFF:
+	case RQT_CMD_EFSCLEAR:
+		send_rsp(&rsp);
+	default:
+		printf("Command not supported -> cmd: %d\n", rqt->rqt_data);
+		return -1;
+	}
+
+	return 0;
+}
+
+static unsigned long download(unsigned int total, unsigned int packet_size,
+			      struct g_dnl *dnl)
+{
+	int count = 0;
+	unsigned int rcv_cnt;
+	static int sect_start = 92160; /* Hardcoded -> will be fixed -> */
+	unsigned int dma_buffer_address = CONFIG_SYS_DOWN_ADDR;
+
+	do {
+		if (packet_size == PKT_DOWNLOAD_SIZE)
+			dma_buffer_address =
+				CONFIG_SYS_DOWN_ADDR + (count * packet_size);
+
+		usbd_set_dma((char *) dma_buffer_address,
+			     packet_size);
+
+		rcv_cnt += usbd_rx_data();
+		debug("RCV data count: %u\n", rcv_cnt);
+
+		/* Store data after receiving a "chunk" packet */
+		if (packet_size == PKT_DOWNLOAD_CHUNK_SIZE &&
+		    (rcv_cnt % PKT_DOWNLOAD_CHUNK_SIZE) == 0) {
+			dnl->p = (sect_start + count *
+				  (PKT_DOWNLOAD_CHUNK_SIZE >> 9));
+			debug("DNL STORE dnl->p: %d\n", dnl->p);
+			dnl->store(dnl, dnl->medium);
+		}
+		send_data_rsp(0, ++count);
+	} while (rcv_cnt < total);
+
+	debug("rcv: %d dnl: %d\n", rcv_cnt, total);
+
+	return rcv_cnt;
+}
+
+static int process_rqt_download(const rqt_box *rqt, struct g_dnl *dnl)
+{
+	static unsigned long download_total_size, cnt;
+	static char f_name[F_NAME_BUF_SIZE];
+	rsp_box rsp = {0, };
+	int file_type;
+	int ret = 1;
+
+	rsp.rsp = rqt->rqt;
+	rsp.rsp_data = rqt->rqt_data;
+
+	switch (rqt->rqt_data) {
+	case RQT_DL_INIT:
+		download_total_size = rqt->int_data[0];
+
+		debug("INIT: total %d bytes\n", rqt->int_data[0]);
+		break;
+	case RQT_DL_FILE_INFO:
+		file_type = rqt->int_data[0];
+		if (file_type == FILE_TYPE_PIT) {
+			puts("PIT table file - not supported\n");
+			return -1;
+		}
+
+		dnl->file_size = rqt->int_data[1];
+		memcpy(f_name, rqt->str_data[0], sizeof(f_name));
+
+		debug("INFO: name(%s, %d), size(%d), type(%d)\n",
+		       f_name, 0, dnl->file_size, file_type);
+
+		if (dnl->file_size > PKT_DOWNLOAD_CHUNK_SIZE)
+			dnl->packet_size = PKT_DOWNLOAD_CHUNK_SIZE;
+		else
+			dnl->packet_size = PKT_DOWNLOAD_SIZE;
+
+		printf("%s: dnl->file_size: %d dnl->packet_size: %d\n",
+		       __func__, dnl->file_size, dnl->packet_size);
+
+		rsp.int_data[0] = dnl->packet_size;
+
+		dnl->file_name = f_name;
+		ret = 0;
+
+		break;
+	case RQT_DL_FILE_START:
+		send_rsp(&rsp);
+
+		cnt = download(download_total_size, dnl->packet_size, dnl);
+
+		dnl->store(dnl, dnl->medium);
+
+		return cnt;
+	case RQT_DL_FILE_END:
+		debug("DL FILE_END\n");
+		break;
+	case RQT_DL_EXIT:
+		debug("DL EXIT\n");
+		ret = 0;
+
+		break;
+	default:
+		printf("Operation not supported: %d\n", rqt->rqt_data);
+		return -1;
+	}
+
+	send_rsp(&rsp);
+	return ret;
+}
+
+int process_data(struct g_dnl *dnl)
+{
+	rqt_box rqt;
+	int ret = 1;
+
+	memset(&rqt, 0, sizeof(rqt));
+	memcpy(&rqt, usbd_rx_data_buf, sizeof(rqt));
+
+	debug("+RQT: %d, %d\n", rqt.rqt, rqt.rqt_data);
+
+	switch (rqt.rqt) {
+	case RQT_INFO:
+		ret = process_rqt_info(&rqt);
+		break;
+	case RQT_CMD:
+		ret = process_rqt_cmd(&rqt);
+		break;
+	case RQT_DL:
+		ret = process_rqt_download(&rqt, dnl);
+		break;
+	case RQT_UL:
+		puts("RQT: UPLOAD not supported!\n");
+		break;
+	default:
+		printf("unknown request (%d)\n", rqt.rqt);
+		ret = 0;
+	}
+
+	/* exit code: */
+	/* 0 - success */
+	/* < 0 - Error code */
+
+	return ret;
+}
diff --git a/drivers/usb/gadget/prot_thor.h b/drivers/usb/gadget/prot_thor.h
new file mode 100644
index 0000000..6e72c75
--- /dev/null
+++ b/drivers/usb/gadget/prot_thor.h
@@ -0,0 +1,112 @@
+/*
+ * THOR protocol internals
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * Lukasz Majewski <l.majewski@samsung.com>
+ *
+ * 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
+ */
+
+#ifndef __PROT_THOR_H_
+#define __PROT_THOR_H_
+
+#include <common.h>
+#include <linux/usb/f_usbd_thor.h>
+
+#define VER_PROTOCOL_MAJOR	4
+#define VER_PROTOCOL_MINOR	0
+
+enum rqt {
+	RQT_INFO = 200,
+	RQT_CMD,
+	RQT_DL,
+	RQT_UL,
+};
+
+enum rqt_data {
+	/* RQT_INFO */
+	RQT_INFO_VER_PROTOCOL = 1,
+	RQT_INIT_VER_HW,
+	RQT_INIT_VER_BOOT,
+	RQT_INIT_VER_KERNEL,
+	RQT_INIT_VER_PLATFORM,
+	RQT_INIT_VER_CSC,
+
+	/* RQT_CMD */
+	RQT_CMD_REBOOT = 1,
+	RQT_CMD_POWEROFF,
+	RQT_CMD_EFSCLEAR,
+
+	/* RQT_DL */
+	RQT_DL_INIT = 1,
+	RQT_DL_FILE_INFO,
+	RQT_DL_FILE_START,
+	RQT_DL_FILE_END,
+	RQT_DL_EXIT,
+
+	/* RQT_UL */
+	RQT_UL_INIT = 1,
+	RQT_UL_START,
+	RQT_UL_END,
+	RQT_UL_EXIT,
+};
+
+typedef struct _rqt_box {	/* total: 256B */
+	s32 rqt;		/* request id */
+	s32 rqt_data;		/* request data id */
+	s32 int_data[14];	/* int data */
+	char str_data[5][32];	/* string data */
+	char md5[32];		/* md5 checksum */
+} __attribute__((packed)) rqt_box;
+
+typedef struct _rsp_box {	/* total: 128B */
+	s32 rsp;		/* response id (= request id) */
+	s32 rsp_data;		/* response data id */
+	s32 ack;		/* ack */
+	s32 int_data[5];	/* int data */
+	char str_data[3][32];	/* string data */
+} __attribute__((packed)) rsp_box;
+
+typedef struct _data_rsp_box {	/* total: 8B */
+	s32 ack;		/* response id (= request id) */
+	s32 count;		/* response data id */
+} __attribute__((packed)) data_rsp_box;
+
+enum {
+	FILE_TYPE_NORMAL,
+	FILE_TYPE_PIT,
+};
+
+#define F_NAME_BUF_SIZE 32
+
+/* download packet size */
+#define PKT_DOWNLOAD_SIZE (1 << 20) /* 1 MiB */
+#define PKT_DOWNLOAD_CHUNK_SIZE (32 << 20) /* 32 MiB */
+
+int process_data(struct g_dnl *dnl);
+
+static inline int pkt_download(void *dest, const int size)
+{
+	usbd_set_dma((char *)dest, size);
+	return usbd_rx_data();
+}
+
+static inline void pkt_upload(void *src, const int size)
+{
+	usbd_tx_data((char *)src, size);
+}
+
+#endif /*  __PROT_THOR_H__ */
diff --git a/include/usbd_thor.h b/include/usbd_thor.h
new file mode 100644
index 0000000..d31bb35
--- /dev/null
+++ b/include/usbd_thor.h
@@ -0,0 +1,108 @@
+/*
+ * USB Downloader for SLP
+ *
+ * Copyright (C) 2011-2012 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ * Sanghee Kim <sh0130.kim@samsung.com>
+ * Lukasz Majewski  <l.majewski@samsung.com>
+ *
+ */
+
+#ifndef _USBD_H_
+#define _USBD_H_
+
+#define msleep(a)	udelay(a * 1000)
+
+/*
+ * updateflag is consist of below bit.
+ * 7: RESERVED.
+ * 6: RESERVED.
+ * 5: RESERVED.
+ * 4: SLP_MMC_RESIZE_REQUIRED
+ * 3: SLP_ROOTFS_NEW
+ * 2: SLP_KERNEL_NEW
+ * 1: SLP_SBL_NEW
+ * 0: SLP_PBL_NEW
+ */
+enum {
+	SLP_PBL_NEW = 0,
+	SLP_SBL_NEW,
+	SLP_KERNEL_NEW,
+	SLP_ROOTFS_NEW,
+	SLP_MMC_RESIZE_REQUIRED
+};
+
+/* status definition */
+enum {
+	STATUS_DONE = 0,
+	STATUS_RETRY,
+	STATUS_ERROR,
+};
+
+/* download mode definition */
+enum {
+	MODE_NORMAL = 0,
+	MODE_FORCE,
+};
+
+/* end mode */
+enum {
+	END_BOOT = 0,
+	END_RETRY,
+	END_FAIL,
+	END_NORMAL,
+};
+/*
+ * USB Downloader Operations
+ * All functions and valuable are mandatory
+ *
+ * usb_init	: initialize the USB Controller and check the connection
+ * usb_stop	: stop and release USB
+ * send_data	: send the data (BULK ONLY!!)
+ * recv_data	: receive the data and returns received size (BULK ONLY!!)
+ * recv_setup	: setup download address, length and DMA setting for receive
+ * tx_data	: send data address
+ * rx_data	: receive data address
+ * tx_len	: size of send data
+ * rx_len	: size of receive data
+ * ram_addr	: address of will be stored data on RAM
+ *
+ * mmc_dev	: device number of mmc
+ * mmc_max	: number of max blocks
+ * mmc_blk	: mmc block size
+ * mmc_total	: mmc total blocks
+ */
+struct usbd_ops {
+	int (*usb_init)(void);
+	void (*usb_stop)(void);
+	void (*send_data)(char *, int);
+	int (*recv_data)(void);
+	void (*recv_setup)(char *, int);
+#ifdef CONFIG_USB_S5PC_DMA
+	void (*prepare_dma)(void * , u32 , uchar);
+	void (*dma_done)(int);
+#endif
+	char *tx_data;
+	char *rx_data;
+	ulong tx_len;
+	ulong rx_len;
+	ulong ram_addr;
+
+	/* mmc device info */
+	uint mmc_dev;
+	uint mmc_max;
+	uint mmc_blk;
+	uint mmc_total;
+
+	void (*set_logo)(char *, int);
+	void (*set_progress)(int);
+	void (*cpu_reset)(void);
+	void (*down_start)(void);
+	void (*down_cancel)(int);
+};
+
+/* This function is interfaced between USB Device Controller and USB Downloader
+ * Must Implementation this function at USB Controller!! */
+struct usbd_ops *usbd_set_interface(struct usbd_ops *);
+
+#endif /* _USBD_H_ */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
                   ` (2 preceding siblings ...)
  2012-04-12  7:17 ` [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14 10:04   ` Marek Vasut
  2012-04-14 13:33   ` Wolfgang Denk
  2012-04-12  7:17 ` [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board Lukasz Majewski
  2012-04-12  7:17 ` [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board Lukasz Majewski
  5 siblings, 2 replies; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

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
 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
+);
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
                   ` (3 preceding siblings ...)
  2012-04-12  7:17 ` [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14 13:39   ` Wolfgang Denk
  2012-04-12  7:17 ` [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board Lukasz Majewski
  5 siblings, 1 reply; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

Support for g_dnl download usb gadget driver for Samsung's GONI target.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Minkyu Kang <mk7.kang@samsung.com>
---
 board/samsung/goni/goni.c  |    8 ++++++++
 include/configs/s5p_goni.h |   33 +++++++++++++++++++++++++++------
 2 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/board/samsung/goni/goni.c b/board/samsung/goni/goni.c
index e8fb1ea..ec92baf 100644
--- a/board/samsung/goni/goni.c
+++ b/board/samsung/goni/goni.c
@@ -146,3 +146,11 @@ struct s3c_plat_otg_data s5pc110_otg_data = {
 	.usb_phy_ctrl = S5PC110_USB_PHY_CONTROL,
 };
 #endif
+
+#ifdef CONFIG_USBDOWNLOAD_GADGET
+void usbd_thor_udc_probe(void)
+{
+	puts("USB_udc_probe\n");
+	s3c_udc_probe(&s5pc110_otg_data);
+}
+#endif
diff --git a/include/configs/s5p_goni.h b/include/configs/s5p_goni.h
index 56b5547..638bf39 100644
--- a/include/configs/s5p_goni.h
+++ b/include/configs/s5p_goni.h
@@ -87,6 +87,14 @@
 #define CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 
+/* FAT */
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+
+/* USB Composite download gadget - g_dnl */
+#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USBDOWNLOAD_FUNCTION
+
 #define CONFIG_BOOTDELAY		1
 #define CONFIG_ZERO_BOOTDELAY_CHECK
 
@@ -107,7 +115,7 @@
 
 #define NORMAL_MTDPARTS_DEFAULT MTDPARTS_DEFAULT
 
-#define CONFIG_BOOTCOMMAND	"run ubifsboot"
+#define CONFIG_BOOTCOMMAND	"run mmcboot"
 
 #define CONFIG_DEFAULT_CONSOLE	"console=ttySAC2,115200n8\0"
 
@@ -126,6 +134,12 @@
 
 #define CONFIG_UBIFS_OPTION	"rootflags=bulk_read,no_chk_data_crc"
 
+#define CONFIG_DNL_INFO \
+	"dnl_info=" \
+	"u-boot mmc 80 200;" \
+	"uImage fat 0 2;" \
+	"platform.img raw 0 3\0" \
+
 #define CONFIG_ENV_OVERWRITE
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
 #define CONFIG_EXTRA_ENV_SETTINGS					\
@@ -155,10 +169,9 @@
 	"ramboot=" \
 		"set bootargs " CONFIG_RAMDISK_BOOT \
 		" initrd=0x33000000,8M ramdisk=8192\0" \
-	"mmcboot=" \
-		"set bootargs root=${mmcblk} rootfstype=${rootfstype}" \
-		CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \
-		CONFIG_COMMON_BOOT "; run bootk\0" \
+	"mmcboot=set bootargs root=/dev/mmcblk${mmcdev}p${mmcrootpart} " \
+		"rootwait ${console} ${meminfo} ${opts} ${lcdinfo}; " \
+		"run loaduimage; bootm 0x30007FC0\0" \
 	"boottrace=setenv opts initcall_debug; run bootcmd\0" \
 	"bootchart=set opts init=/sbin/bootchartd; run bootcmd\0" \
 	"verify=n\0" \
@@ -170,7 +183,12 @@
 	"bootblock=9\0" \
 	"ubiblock=8\0" \
 	"ubi=enabled\0" \
-	"opts=always_resume=1"
+	"loaduimage=fatload mmc ${mmcdev}:${mmcbootpart} 0x30007FC0 uImage\0" \
+	"mmcdev=0\0" \
+	"mmcbootpart=2\0" \
+	"mmcrootpart=3\0" \
+	"opts=always_resume=1\0" \
+	CONFIG_DNL_INFO
 
 /* Miscellaneous configurable options */
 #define CONFIG_SYS_LONGHELP		/* undef to save memory */
@@ -240,5 +258,8 @@
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
 #define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW	2
+
+#define CONFIG_SYS_DOWN_ADDR	CONFIG_SYS_SDRAM_BASE
 
 #endif	/* __CONFIG_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board
  2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
                   ` (4 preceding siblings ...)
  2012-04-12  7:17 ` [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board Lukasz Majewski
@ 2012-04-12  7:17 ` Lukasz Majewski
  2012-04-14 13:40   ` Wolfgang Denk
  5 siblings, 1 reply; 17+ messages in thread
From: Lukasz Majewski @ 2012-04-12  7:17 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: Minkyu Kang <mk7.kang@samsung.com>
---
 board/samsung/trats/trats.c |    8 ++++++++
 include/configs/trats.h     |   17 +++++++++++++++++
 2 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/board/samsung/trats/trats.c b/board/samsung/trats/trats.c
index a7b4e4a..31826a0 100644
--- a/board/samsung/trats/trats.c
+++ b/board/samsung/trats/trats.c
@@ -244,6 +244,14 @@ struct s3c_plat_otg_data s5pc210_otg_data = {
 };
 #endif
 
+#ifdef CONFIG_USBDOWNLOAD_GADGET
+void usbd_thor_udc_probe(void)
+{
+	puts("USB_udc_probe\n");
+	s3c_udc_probe(&s5pc210_otg_data);
+}
+#endif
+
 static void pmic_reset(void)
 {
 	struct exynos4_gpio_part2 *gpio =
diff --git a/include/configs/trats.h b/include/configs/trats.h
index 585fd71..af0bbd1 100644
--- a/include/configs/trats.h
+++ b/include/configs/trats.h
@@ -95,6 +95,14 @@
 #undef CONFIG_CMD_MTDPARTS
 #define CONFIG_CMD_MMC
 
+/* FAT */
+#define CONFIG_CMD_FAT
+#define CONFIG_FAT_WRITE
+
+/* USB Composite download gadget - g_dnl */
+#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USBDOWNLOAD_FUNCTION
+
 #define CONFIG_BOOTDELAY		1
 #define CONFIG_ZERO_BOOTDELAY_CHECK
 #define CONFIG_BOOTARGS			"Please use defined boot"
@@ -104,6 +112,12 @@
 #define CONFIG_BOOTBLOCK		"10"
 #define CONFIG_ENV_COMMON_BOOT		"${console} ${meminfo}"
 
+#define CONFIG_DNL_INFO \
+	"dnl_info=" \
+	"u-boot mmc 80 200;" \
+	"uImage fat 0 2;" \
+	"platform.img raw 0 3\0" \
+
 #define CONFIG_ENV_OVERWRITE
 #define CONFIG_SYS_CONSOLE_INFO_QUIET
 #define CONFIG_SYS_CONSOLE_IS_IN_ENV
@@ -213,5 +227,8 @@
 #define CONFIG_USB_GADGET
 #define CONFIG_USB_GADGET_S3C_UDC_OTG
 #define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW	2
+
+#define CONFIG_SYS_DOWN_ADDR	CONFIG_SYS_SDRAM_BASE
 
 #endif	/* __CONFIG_H */
-- 
1.7.2.3

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions
  2012-04-12  7:17 ` [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions Lukasz Majewski
@ 2012-04-14  9:55   ` Marek Vasut
  0 siblings, 0 replies; 17+ messages in thread
From: Marek Vasut @ 2012-04-14  9:55 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

> Composite USB download gadget (g_dnl) for download functions (e.g. DFU,
> THOR, others)
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Marek Vasut <marex@denx.de>
> ---
>  drivers/usb/gadget/Makefile |    1 +
>  drivers/usb/gadget/g_dnl.c  |  231
> +++++++++++++++++++++++++++++++++++++++++++ include/g_dnl.h             | 
>  97 ++++++++++++++++++
>  3 files changed, 329 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/usb/gadget/g_dnl.c
>  create mode 100644 include/g_dnl.h
> 
> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
> index 87d1918..2c067c8 100644
> --- a/drivers/usb/gadget/Makefile
> +++ b/drivers/usb/gadget/Makefile
> @@ -29,6 +29,7 @@ LIB	:= $(obj)libusb_gadget.o
>  ifdef CONFIG_USB_GADGET
>  COBJS-y += epautoconf.o config.o usbstring.o
>  COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
> +COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
>  endif
>  ifdef CONFIG_USB_ETHER
>  COBJS-y += ether.o epautoconf.o config.o usbstring.o
> diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c
> new file mode 100644
> index 0000000..425f4f6
> --- /dev/null
> +++ b/drivers/usb/gadget/g_dnl.c
> @@ -0,0 +1,231 @@
> +/*
> + * g_dnl.c -- USB Downloader Gadget
> + *
> + * Copyright (C) 2012 Samsung Electronics
> + * Lukasz Majewski  <l.majewski@samsung.com>
> + *
> + * 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 + */
> +#undef DEBUG
> +#define DEBUG
> +#include <errno.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <linux/usb/ch9.h>
> +#include <usbdescriptors.h>
> +#include <linux/usb/gadget.h>
> +#include <linux/usb/f_usbd_thor.h>
> +
> +#include <mmc.h>
> +#include <part.h>
> +
> +#include <g_dnl.h>
> +
> +#include "usbd_thor.h"
> +#include "gadget_chips.h"
> +
> +#include "composite.c"
> +
> +#define DRIVER_VERSION		"usb_dnl 2.0"
> +
> +static const char shortname[] = "usb_dnl_";
> +static const char product[] = "SLP USB download gadget";
> +static const char manufacturer[] = "Samsung";
> +
> +static struct usb_device_descriptor device_desc = {
> +	.bLength =		sizeof device_desc,
> +	.bDescriptorType =	USB_DT_DEVICE,
> +
> +	.bcdUSB =		__constant_cpu_to_le16(0x0200),
> +	.bDeviceClass =		USB_CLASS_COMM,
> +	.bDeviceSubClass =      0x02,	/*0x02:CDC-modem , 0x00:CDC-serial*/
> +
> +	.idVendor =		__constant_cpu_to_le16(DRIVER_VENDOR_NUM),
> +	.idProduct =		__constant_cpu_to_le16(DRIVER_PRODUCT_NUM),
> +	.iProduct =		STRING_PRODUCT,
> +	.bNumConfigurations =	1,
> +};
> +
> +static const struct usb_descriptor_header *otg_desc[] = {
> +	(struct usb_descriptor_header *) &(struct usb_otg_descriptor){
> +		.bLength =		sizeof(struct usb_otg_descriptor),
> +		.bDescriptorType =	USB_DT_OTG,
> +		.bmAttributes =		USB_OTG_SRP,
> +	},
> +	NULL,
> +};
> +
> +/* static strings, in UTF-8 */
> +static struct usb_string odin_string_defs[] = {
> +	{ 0, manufacturer, },
> +	{ 1, product, },
> +};
> +
> +static struct usb_gadget_strings odin_string_tab = {
> +	.language	= 0x0409,	/* en-us */
> +	.strings	= odin_string_defs,
> +};
> +
> +static struct usb_gadget_strings *g_dnl_composite_strings[] = {
> +	&odin_string_tab,
> +	NULL,
> +};
> +
> +static int g_dnl_unbind(struct usb_composite_dev *cdev)
> +{
> +	debug("%s\n", __func__);
> +	return 0;
> +}
> +
> +static int g_dnl_do_config(struct usb_configuration *c)
> +{
> +	int ret = -1;
> +	char *s = (char *) c->cdev->driver->name;
> +
> +	debug("%s: c: 0x%p cdev: 0x%p\n", __func__, c, c->cdev);
> +
> +	if (gadget_is_otg(c->cdev->gadget)) {
> +		c->descriptors = otg_desc;
> +		c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
> +	}
> +
> +	printf("GADGET DRIVER: %s\n", s);

Drop this printf()

> +
> +	if (!strcmp(s, "usb_dnl_thor"))
> +		ret = f_usbd_add(c);
> +
> +	return ret;
> +}
> +
> +static int g_dnl_config_register(struct usb_composite_dev *cdev)
> +{
> +	debug("%s:\n", __func__);
> +	static struct usb_configuration config = {
> +		.label = "usbd_thor_download",
> +		.bmAttributes =	USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
> +		.bConfigurationValue =	CONFIG_USBDOWNLOADER,
> +		.iConfiguration =	STRING_USBDOWN,
> +
> +		.bind = g_dnl_do_config,
> +	};
> +
> +	return usb_add_config(cdev, &config);
> +}
> +
> +static int g_dnl_bind(struct usb_composite_dev *cdev)
> +{
> +	int			gcnum;
> +	int id, ret;
> +	struct usb_gadget	*gadget = cdev->gadget;
> +
> +	debug("%s: gadget: 0x%p cdev: 0x%p\n", __func__, gadget, cdev);
> +
> +	id = usb_string_id(cdev);
> +
> +	if (id < 0)
> +		return id;
> +	odin_string_defs[0].id = id;
> +	device_desc.iManufacturer = id;
> +
> +	id = usb_string_id(cdev);
> +	if (id < 0)
> +		return id;
> +
> +	odin_string_defs[1].id = id;
> +	device_desc.iProduct = id;
> +
> +	ret = g_dnl_config_register(cdev);
> +	if (ret)
> +		goto error;
> +
> +
> +	gcnum = usb_gadget_controller_number(gadget);
> +
> +	debug("gcnum: %d\n", gcnum);
> +	if (gcnum >= 0)
> +		device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
> +	else {
> +		printf("%s: controller '%s' not recognized\n",
> +			shortname, gadget->name);
> +		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
> +	}
> +
> +	return 0;
> +
> + error:
> +	g_dnl_unbind(cdev);
> +	return -ENOMEM;
> +}
> +
> +static void g_dnl_suspend(struct usb_composite_dev *cdev)
> +{
> +	if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
> +		return;
> +
> +	debug("suspend\n");
> +}
> +
> +static void g_dnl_resume(struct usb_composite_dev *cdev)
> +{
> +	debug("resume\n");

__FILE__, __func__, __LINE__ ?

> +}
> +
> +static struct usb_composite_driver g_dnl_driver = {
> +	.name		= shortname,
> +	.dev		= &device_desc,
> +	.strings	= g_dnl_composite_strings,
> +
> +	.bind		= g_dnl_bind,
> +	.unbind		= g_dnl_unbind,
> +
> +	.suspend	= g_dnl_suspend,
> +	.resume		= g_dnl_resume,
> +};
> +
> +int g_dnl_init(char *s, struct g_dnl *dnl)
> +{
> +
> +	int ret;
> +	static char str[16];
> +
> +	memset(str, 0x00, sizeof(str));
> +	strncpy(str, shortname, sizeof(shortname));
> +
> +	if (!strncmp(s, "thor", sizeof(s))) {
> +		strncat(str, s, sizeof(str));
> +	} else {
> +		printf("%s: unknown command: %s\n", __func__, s);
> +		return -EINVAL;
> +	}
> +
> +	strncpy((char *) g_dnl_driver.name, (const char *) str, sizeof(str));
> +
> +	usbd_thor_udc_probe();
> +	set_udc_gadget_private_data(dnl);
> +
> +	ret = usb_composite_register(&g_dnl_driver);
> +
> +	if (ret) {
> +		printf("%s: failed!, error:%d ", __func__, ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +void g_dnl_cleanup(void)
> +{
> +	usb_composite_unregister(&g_dnl_driver);
> +}
> diff --git a/include/g_dnl.h b/include/g_dnl.h
> new file mode 100644
> index 0000000..9777b60
> --- /dev/null
> +++ b/include/g_dnl.h
> @@ -0,0 +1,97 @@
> +/*
> + *  Copyright (C) 2012 Samsung Electronics
> + *  Lukasz Majewski <l.majewski@samsung.com>
> + *
> + * 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
> + */
> +
> +#ifndef __G_DOWNLOAD_H_
> +#define __G_DOWNLOAD_H_
> +
> +#include <mmc.h>
> +#include <linux/usb/ch9.h>
> +#include <usbdescriptors.h>
> +#include <linux/usb/gadget.h>
> +
> +enum { THOR = 1 };
> +enum {MMC = 1, FAT = 2, RAW = 3};
> +
> +struct g_dnl {
> +	int prot;
> +
> +	char *file_name;
> +	int file_size;
> +
> +	int (*init) (struct g_dnl *dnl);
> +	int (*info) (void);
> +
> +	int (*dl) (struct g_dnl *dnl);
> +	int (*ul) (struct g_dnl *dnl);
> +
> +	unsigned int *rx_buf;
> +	unsigned int *tx_buf;
> +
> +	int (*cmd) (struct g_dnl *dnl);
> +
> +	int medium;
> +	int (*store) (struct g_dnl *dnl, int medium);
> +	unsigned int p; /* private */
> +
> +	int packet_size;
> +};
> +
> +/**
> + * dnl_init - initialize code downloader
> + * @dnl: Interface to download functions
> + *
> + * returns zero, or a negative error code.
> + */
> +static inline int dnl_init(struct g_dnl *dnl)
> +{
> +	return dnl->init(dnl);
> +}
> +
> +/**
> + * dnl_download - handle download operation
> + * @dnl: Interface to download functions
> + *
> + * returns zero on success or a negative error code.
> + *
> + */
> +static inline int dnl_download(struct g_dnl *dnl)
> +{
> +	return dnl->dl(dnl);
> +}
> +
> +/**
> + * dnl_command - handle various commands
> + * @dnl: Interface to download functions
> + *
> + * returns zero on success or a negative error code.
> + *
> + */
> +static inline int dnl_command(struct g_dnl *dnl)
> +{
> +	return dnl->cmd(dnl);
> +}
> +
> +int g_dnl_init(char *s, struct g_dnl *dnl);
> +void set_udc_gadget_private_data(void *);
> +struct g_dnl *get_udc_gadget_private_data(struct usb_gadget *gadget);
> +
> +void usbd_thor_udc_probe(void);
> +
> +#endif /* __G_DOWNLOAD_H_ */

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol
  2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
@ 2012-04-14  9:58   ` Marek Vasut
  2012-04-14 13:12   ` Wolfgang Denk
  2012-04-14 13:29   ` Wolfgang Denk
  2 siblings, 0 replies; 17+ messages in thread
From: Marek Vasut @ 2012-04-14  9:58 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

> Implementation of USB Download function supporting 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>
> ---
>  drivers/usb/gadget/Makefile      |    1 +
>  drivers/usb/gadget/f_usbd_thor.c |  808
> ++++++++++++++++++++++++++++++++++++++ include/linux/usb/f_usbd_thor.h  | 
>  62 +++
>  3 files changed, 871 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/usb/gadget/f_usbd_thor.c
>  create mode 100644 include/linux/usb/f_usbd_thor.h
> 
> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
> index 2c067c8..0c48368 100644
> --- a/drivers/usb/gadget/Makefile
> +++ b/drivers/usb/gadget/Makefile
> @@ -29,6 +29,7 @@ LIB	:= $(obj)libusb_gadget.o
>  ifdef CONFIG_USB_GADGET
>  COBJS-y += epautoconf.o config.o usbstring.o
>  COBJS-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
> +COBJS-$(CONFIG_USBDOWNLOAD_FUNCTION) += f_usbd_thor.o prot_thor.o
>  COBJS-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
>  endif
>  ifdef CONFIG_USB_ETHER
> diff --git a/drivers/usb/gadget/f_usbd_thor.c
> b/drivers/usb/gadget/f_usbd_thor.c new file mode 100644
> index 0000000..e2394e3
> --- /dev/null
> +++ b/drivers/usb/gadget/f_usbd_thor.c
> @@ -0,0 +1,808 @@
> +/*
> + * f_usbd_thor.c -- USB THOR Downloader gadget function
> + *
> + * Copyright (C) 2011-2012 Samsung Electronics
> + * Lukasz Majewski <l.majewski@samsung.com>
> + *
> + * 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 + */
> +#undef DEBUG
> +#include <errno.h>
> +#include <common.h>
> +#include <malloc.h>
> +#include <linux/usb/ch9.h>
> +#include <usbdescriptors.h>
> +#include <linux/usb/gadget.h>
> +#include <linux/usb/composite.h>
> +#include <linux/usb/f_usbd_thor.h>
> +#include <linux/usb/cdc.h>
> +
> +#include <g_dnl.h>
> +#include <mmc.h>
> +#include <part.h>
> +
> +#include "usbd_thor.h"
> +#include "prot_thor.h"
> +#include "gadget_chips.h"
> +
> +#define DMA_BUFFER_SIZE	(4096*4)
> +
> +static struct f_usbd *usbd_func;
> +static const unsigned buflen = 512; /* Standard request buffer length */
> +
> +struct usbd_dev {
> +	struct usb_gadget	*gadget;
> +	struct usb_request	*req;		/* for control responses */
> +
> +	/* IN/OUT EP's and correspoinding requests */
> +	struct usb_ep		*in_ep, *out_ep, *int_ep;
> +	struct usb_request	*in_req, *out_req;
> +
> +	/* Control flow variables*/
> +	int configuration_done;
> +	int stop_done;
> +	int rxdata;
> +	int txdata;
> +};
> +
> +struct f_usbd {
> +	struct usb_function		usb_function;
> +	struct usbd_dev *dev;
> +};
> +
> +static inline struct f_usbd *func_to_usbd(struct usb_function *f)
> +{
> +	return container_of(f, struct f_usbd, usb_function);
> +}
> +
> +/* maxpacket and other transfer characteristics vary by speed. */
> +static inline struct usb_endpoint_descriptor *
> +ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs,
> +		struct usb_endpoint_descriptor *fs)
> +{
> +	if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
> +		return hs;
> +	return fs;
> +}
> +
> +/* one interface in each configuration */
> +static struct usb_interface_descriptor usb_downloader_intf_data = {
> +	.bLength =		sizeof usb_downloader_intf_data,
> +	.bDescriptorType =	USB_DT_INTERFACE,
> +
> +	.bNumEndpoints =	2,
> +	.bInterfaceClass =	USB_CLASS_CDC_DATA,
> +};
> +
> +
> +/* two full speed bulk endpoints; their use is config-dependent */
> +static struct usb_endpoint_descriptor fs_in_desc = {
> +	.bLength =		USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType =	USB_DT_ENDPOINT,
> +
> +	.bEndpointAddress =	USB_DIR_IN,
> +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
> +};
> +
> +static struct usb_endpoint_descriptor fs_out_desc = {
> +	.bLength =		USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType =	USB_DT_ENDPOINT,
> +
> +	.bEndpointAddress =	USB_DIR_OUT,
> +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
> +};
> +
> +/* CDC configuration */
> +
> +static struct usb_interface_descriptor usb_downloader_intf_int = {
> +	.bLength =		sizeof usb_downloader_intf_int,
> +	.bDescriptorType =	USB_DT_INTERFACE,
> +
> +	.bNumEndpoints =	1,
> +	.bInterfaceClass =	USB_CLASS_COMM,
> +	 /* 0x02 Abstract Line Control Model */
> +	.bInterfaceSubClass =   COMMUNICATIONS_INTERFACE_CLASS_CONTROL,
> +	/* 0x01 Common AT commands */
> +	.bInterfaceProtocol =   COMMUNICATIONS_V25TER_PROTOCOL,
> +};
> +
> +static struct usb_class_header_function_descriptor
> usb_downloader_cdc_header = { +	.bFunctionLength =    sizeof
> usb_downloader_cdc_header,
> +	.bDescriptorType =    CS_INTERFACE, /* 0x24 */
> +	.bDescriptorSubtype = 0x00,	/* 0x00 */
> +	.bcdCDC =             0x0110,
> +};
> +
> +
> +static struct usb_class_call_management_descriptor usb_downloader_cdc_call
> = { +	.bFunctionLength =    sizeof usb_downloader_cdc_call,
> +	.bDescriptorType =    CS_INTERFACE, /* 0x24 */
> +	.bDescriptorSubtype = 0x01,	/* 0x01 */
> +	.bmCapabilities =     0x00,
> +	.bDataInterface =     0x01,
> +};
> +
> +struct usb_class_abstract_control_descriptor usb_downloader_cdc_abstract =
> { +	.bFunctionLength =    sizeof usb_downloader_cdc_abstract,
> +	.bDescriptorType =    CS_INTERFACE,
> +	.bDescriptorSubtype = 0x02,	/* 0x02 */
> +	.bmCapabilities =     0x00,
> +};
> +
> +struct usb_class_union_function_descriptor usb_downloader_cdc_union = {
> +	.bFunctionLength =     sizeof usb_downloader_cdc_union,
> +	.bDescriptorType =     CS_INTERFACE,
> +	.bDescriptorSubtype =  0x06,	/* 0x06 */
> +};
> +
> +
> +static struct usb_endpoint_descriptor fs_int_desc = {
> +	.bLength = USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType = USB_DT_ENDPOINT,
> +
> +	.bEndpointAddress = 3 | USB_DIR_IN,
> +	.bmAttributes = USB_ENDPOINT_XFER_INT,
> +	.wMaxPacketSize = __constant_cpu_to_le16(16),
> +
> +	.bInterval = 0x9,
> +};
> +
> +static struct usb_interface_assoc_descriptor
> +usbd_iad_descriptor = {
> +	.bLength =		sizeof usbd_iad_descriptor,
> +	.bDescriptorType =	USB_DT_INTERFACE_ASSOCIATION,
> +
> +	.bFirstInterface =	0,
> +	.bInterfaceCount =	2,	/* control + data */
> +	.bFunctionClass =	USB_CLASS_COMM,
> +	.bFunctionSubClass =	USB_CDC_SUBCLASS_ACM,
> +	.bFunctionProtocol =	USB_CDC_PROTO_NONE,
> +	/* .iFunction = DYNAMIC */
> +};
> +
> +
> +/*
> + * usb 2.0 devices need to expose both high speed and full speed
> + * descriptors, unless they only run at full speed.
> + *
> + */
> +
> +static struct usb_endpoint_descriptor hs_in_desc = {
> +	.bLength =		USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType =	USB_DT_ENDPOINT,
> +
> +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
> +	.wMaxPacketSize =	__constant_cpu_to_le16(512),
> +};
> +
> +static struct usb_endpoint_descriptor hs_out_desc = {
> +	.bLength =		USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType =	USB_DT_ENDPOINT,
> +
> +	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
> +	.wMaxPacketSize =	__constant_cpu_to_le16(512),
> +};
> +
> +static struct usb_endpoint_descriptor hs_int_desc = {
> +	.bLength = USB_DT_ENDPOINT_SIZE,
> +	.bDescriptorType = USB_DT_ENDPOINT,
> +
> +	.bmAttributes = USB_ENDPOINT_XFER_INT,
> +	.wMaxPacketSize = __constant_cpu_to_le16(16),
> +
> +	.bInterval = 0x9,
> +};
> +
> +static struct usb_qualifier_descriptor dev_qualifier = {
> +	.bLength =		sizeof dev_qualifier,
> +	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
> +
> +	.bcdUSB =		__constant_cpu_to_le16(0x0200),
> +	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
> +
> +	.bNumConfigurations =	2,
> +};
> +
> +static const struct usb_descriptor_header *hs_usb_downloader_function[] =
> { +	/* (struct usb_descriptor_header *) &otg_descriptor, */
> +	(struct usb_descriptor_header *) &usbd_iad_descriptor,
> +
> +	(struct usb_descriptor_header *) &usb_downloader_intf_int,
> +	(struct usb_descriptor_header *) &usb_downloader_cdc_header,
> +	(struct usb_descriptor_header *) &usb_downloader_cdc_call,
> +	(struct usb_descriptor_header *) &usb_downloader_cdc_abstract,
> +	(struct usb_descriptor_header *) &usb_downloader_cdc_union,
> +	(struct usb_descriptor_header *) &hs_int_desc,
> +
> +	(struct usb_descriptor_header *) &usb_downloader_intf_data,
> +	(struct usb_descriptor_header *) &hs_in_desc,
> +	(struct usb_descriptor_header *) &hs_out_desc,
> +	NULL,
> +};
> +
> +/*------------------------------------------------------------------------
> -*/ +
> +
> +static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned
> length) +{
> +	struct usb_request	*req;
> +
> +	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
> +	if (req) {
> +		req->length = length;
> +		req->buf = malloc(length);
> +		if (!req->buf) {
> +			usb_ep_free_request(ep, req);
> +			req = NULL;
> +		}
> +	}
> +	return req;
> +}
> +
> +unsigned int usbd_rx_data(void)
> +{
> +	int status;
> +	struct usbd_dev *dev = usbd_func->dev;
> +
> +	static int data_to_rx = 0, tmp;
> +
> +	data_to_rx = dev->out_req->length;
> +	tmp = data_to_rx;
> +
> +	do {
> +
> +		if (data_to_rx > DMA_BUFFER_SIZE)
> +			dev->out_req->length = DMA_BUFFER_SIZE;
> +		else
> +			dev->out_req->length = data_to_rx;
> +
> +		debug("dev->out_req->length:%d dev->rxdata:%d\n",
> +		     dev->out_req->length, dev->rxdata);
> +
> +		status = usb_ep_queue(dev->out_ep, dev->out_req, GFP_ATOMIC);
> +		if (status) {
> +			printf("kill %s:  resubmit %d bytes --> %d\n",
> +			       dev->out_ep->name, dev->out_req->length, status);
> +			usb_ep_set_halt(dev->out_ep);
> +			/* FIXME recover later ... somehow */

How? :-)

> +			return -1;
> +		}
> +
> +		while (!dev->rxdata)
> +			usb_gadget_handle_interrupts();
> +
> +		dev->rxdata = 0;
> +
> +		if (data_to_rx > DMA_BUFFER_SIZE)
> +			dev->out_req->buf += DMA_BUFFER_SIZE;
> +
> +		data_to_rx -= dev->out_req->actual;
> +
> +	} while (data_to_rx);
> +
> +	return tmp;
> +}
> +
> +void usbd_tx_data(char *data, int len)
> +{
> +	int status;
> +	struct usbd_dev *dev = usbd_func->dev;
> +
> +	unsigned char *ptr = dev->in_req->buf;
> +
> +	memset(ptr, '\0', len);

memset(ptr, 0, len) ?

> +	memcpy(ptr, data, len);
> +
> +	dev->in_req->length = len;
> +
> +	debug("%s: dev->in_req->length:%d to_cpy:%d\n", __func__,
> +	    dev->in_req->length, sizeof(data));
> +
> +	status = usb_ep_queue(dev->in_ep, dev->in_req, GFP_ATOMIC);
> +	if (status) {
> +		printf("kill %s:  resubmit %d bytes --> %d\n",
> +		       dev->in_ep->name, dev->in_req->length, status);
> +		usb_ep_set_halt(dev->in_ep);
> +		/* FIXME recover later ... somehow */
> +	}
> +
> +	/* Wait until tx interrupt received */
> +	while (!dev->txdata)
> +		usb_gadget_handle_interrupts();
> +
> +	dev->txdata = 0;
> +}
> +
> +static void usbd_rx_tx_complete(struct usb_ep *ep, struct usb_request
> *req) +{
> +	int		status = req->status;
> +	struct usbd_dev *dev = usbd_func->dev;
> +
> +	debug("%s: ep_ptr:%p, req_ptr:%p\n", __func__, ep, req);
> +	switch (status) {
> +

Drop newline please

> +	case 0:				/* normal completion? */
> +		if (ep == dev->out_ep)
> +			dev->rxdata = 1;
> +		else
> +			dev->txdata = 1;
> +
> +		break;
> +
> +	/* this endpoint is normally active while we're configured */
> +	case -ECONNABORTED:		/* hardware forced ep reset */
> +	case -ECONNRESET:		/* request dequeued */
> +	case -ESHUTDOWN:		/* disconnect from host */
> +		/* Exeptional situation - print error message */
> +
> +	case -EOVERFLOW:
> +		printf("%s: ERROR:%d\n", __func__, status);
> +	default:
> +		debug("%s complete --> %d, %d/%d\n", ep->name,
> +				status, req->actual, req->length);
> +	case -EREMOTEIO:		/* short read */
> +		break;
> +	}
> +}
> +
> +static struct usb_request *usbd_start_ep(struct usb_ep *ep)
> +{
> +	struct usb_request	*req;
> +
> +	req = alloc_ep_req(ep, buflen);
> +	debug("%s: ep:%p req:%p\n", __func__, ep, req);
> +
> +	if (!req)
> +		return NULL;
> +
> +	memset(req->buf, 0, req->length);
> +	req->complete = usbd_rx_tx_complete;
> +
> +	memset(req->buf, 0x55, req->length);
> +
> +	return req;
> +}
> +
> +static void usbd_setup_complete(struct usb_ep *ep, struct usb_request
> *req) +{
> +	if (req->status || req->actual != req->length)
> +		debug("setup complete --> %d, %d/%d\n",
> +		    req->status, req->actual, req->length);
> +}
> +
> +static int
> +usbd_func_setup(struct usb_function *f, const struct usb_ctrlrequest
> *ctrl) +{
> +	int value = 0;
> +	struct usbd_dev         *dev = usbd_func->dev;
> +	struct usb_request      *req = dev->req;
> +	struct usb_gadget	*gadget = dev->gadget;
> +
> +	u16 len = le16_to_cpu(ctrl->wLength);
> +	u16 wValue = le16_to_cpu(ctrl->wValue);
> +
> +	debug("Req_Type: 0x%x Req: 0x%x wValue: 0x%x wIndex: 0x%x wLen: 0x%x\n",
> +	       ctrl->bRequestType, ctrl->bRequest, ctrl->wValue, ctrl->wIndex,
> +	       ctrl->wLength);
> +
> +	switch (ctrl->bRequest) {
> +	case SET_CONTROL_LINE_STATE:
> +		value = 0;
> +
> +		switch (wValue) {
> +		case DEACTIVATE_CARRIER:
> +			/* Before reset wait for all ACM requests to be done */
> +			dev->stop_done = 1;
> +			break;
> +		case ACTIVATE_CARRIER:
> +			break;
> +		default:
> +			printf("usbd_setup:SetControlLine-unknown wValue: %d\n",
> +			       wValue);
> +		}
> +		break;
> +	case SET_LINE_CODING:
> +		value = len;
> +
> +		/* Line Coding set done = configuration done */
> +		usbd_func->dev->configuration_done = 1;
> +		break;
> +
> +	default:
> +		printf("usbd_setup: unknown request: %d\n", ctrl->bRequest);
> +	}
> +
> +	if (value >= 0) {
> +		req->length = value;
> +		req->zero = value < len;
> +		value = usb_ep_queue(gadget->ep0, req, GFP_ATOMIC);
> +		if (value < 0) {
> +			debug("ep_queue --> %d\n", value);
> +			req->status = 0;
> +		}
> +	}
> +
> +	return value;
> +}
> +
> +/* Specific to the USBD_THOR protocol */
> +void usbd_set_dma(char *addr, int len)
> +{
> +	struct usbd_dev *dev = usbd_func->dev;
> +
> +	debug("in_req:%p, out_req:%p\n", dev->in_req, dev->out_req);
> +	debug("addr:%p, len:%d\n", addr, len);
> +
> +	dev->out_req->buf = addr;
> +	dev->out_req->length = len;

Newline

> +
> +}
> +
> +static void usbd_cancel(int mode)
> +{
> +
> +	switch (mode) {
> +	case END_BOOT:
> +		run_command("run bootcmd", 0);
> +		break;
> +	default:
> +		break;
> +	}
> +}
> +
> +__attribute__ ((__aligned__ (__alignof__ (long long))))
> +static char usbd_tx_buf[TX_DATA_LEN];
> +__attribute__ ((__aligned__ (__alignof__ (long long))))
> +static char usbd_rx_buf[RX_DATA_LEN];
> +
> +char *usbd_tx_data_buf = usbd_tx_buf;
> +char *usbd_rx_data_buf = usbd_rx_buf;
> +
> +static const char *recv_key = "THOR";
> +static const char *tx_key = "ROHT";
> +
> +static int usbd_init(struct g_dnl *dnl)
> +{
> +	int ret;
> +	struct usbd_dev *dev = usbd_func->dev;
> +
> +	/* Wait for a device enumeration and configuration settings */
> +	debug("USBD enumeration/configuration setting....\n");
> +	while (!dev->configuration_done)
> +		usb_gadget_handle_interrupts();
> +
> +	usbd_set_dma(usbd_rx_data_buf, strlen(recv_key));
> +	/* detect the download request from Host PC */
> +	ret = usbd_rx_data();
> +
> +	if (strncmp(usbd_rx_data_buf, recv_key, strlen(recv_key)) == 0) {
> +		printf("Download request from the Host PC\n");
> +		msleep(30);
> +
> +		strncpy(usbd_tx_data_buf, tx_key, strlen(tx_key));
> +		usbd_tx_data(usbd_tx_data_buf, strlen(tx_key));
> +	} else {
> +		puts("Wrong reply information\n");
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static int usbd_handle(struct g_dnl *dnl)
> +{
> +	int ret;
> +
> +	debug("USBD Handle start....\n");
> +
> +	/* receive the data from Host PC */
> +	while (1) {
> +		usbd_set_dma(usbd_rx_data_buf, sizeof(rqt_box));
> +		ret = usbd_rx_data();
> +
> +		if (ret > 0) {
> +			ret = process_data(dnl);
> +
> +			if (ret < 0)
> +				return -1;
> +			else if (ret == 0)
> +				return 0;
> +		} else {
> +			puts("No data received!\n");
> +			usbd_cancel(END_BOOT);
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +
> +/* USB Downloader's specific definitions - required for this framework */
> +
> +void usbd_fill_dnl(struct g_dnl *dnl)
> +{
> +	dnl->prot = THOR;
> +	dnl->init = &usbd_init;
> +	dnl->dl = &usbd_handle;
> +	dnl->cmd = &usbd_handle;
> +
> +	/* If the following pointers are set to NULL -> error */
> +	dnl->rx_buf = (unsigned int *) CONFIG_SYS_DOWN_ADDR;
> +	dnl->tx_buf = NULL;
> +}
> +
> +static int usbd_func_bind(struct usb_configuration *c, struct usb_function
> *f) +{
> +	int status;
> +	struct usb_ep		*ep;
> +	struct usbd_dev		*dev;
> +	struct f_usbd           *f_usbd = func_to_usbd(f);
> +	struct usb_gadget       *gadget = c->cdev->gadget;
> +	struct g_dnl            *dnl = get_udc_gadget_private_data(gadget);
> +
> +	usbd_func = f_usbd;
> +	dev = calloc(sizeof(*dev), 1);
> +	if (!dev)
> +		return -ENOMEM;
> +
> +	dev->gadget = gadget;
> +
> +	f_usbd->dev = dev;
> +	f_usbd->dev->configuration_done = 0;
> +	f_usbd->dev->rxdata = 0;
> +	f_usbd->dev->txdata = 0;
> +
> +	debug("%s: usb_configuration: 0x%p usb_function: 0x%p\n",
> +	    __func__, c, f);
> +	debug("f_usbd: 0x%p usbd: 0x%p\n", f_usbd, dev);
> +
> +	/* EP0  */
> +	/* preallocate control response and buffer */
> +	dev->req = usb_ep_alloc_request(gadget->ep0, 0);
> +	if (!dev->req) {
> +		status = -ENOMEM;
> +		goto fail;
> +	}
> +	dev->req->buf = malloc(buflen);
> +	if (!dev->req->buf) {
> +		status = -ENOMEM;
> +		goto fail;
> +	}
> +
> +	dev->req->complete = usbd_setup_complete;
> +
> +	/* DYNAMIC interface numbers assignments */
> +	status = usb_interface_id(c, f);
> +
> +	if (status < 0)
> +		goto fail;
> +
> +	usb_downloader_intf_int.bInterfaceNumber = status;
> +	usb_downloader_cdc_union.bMasterInterface = status;
> +
> +	status = usb_interface_id(c, f);
> +
> +	if (status < 0)
> +		goto fail;
> +
> +	usb_downloader_intf_data.bInterfaceNumber = status;
> +	usb_downloader_cdc_union.bSlaveInterface0 = status;
> +
> +
> +	/* allocate instance-specific endpoints */
> +	ep = usb_ep_autoconfig(gadget, &fs_in_desc);
> +	if (!ep) {
> +		status = -ENODEV;
> +		goto fail;
> +	}
> +
> +	if (gadget_is_dualspeed(gadget)) {
> +		hs_in_desc.bEndpointAddress =
> +				fs_in_desc.bEndpointAddress;
> +	}
> +
> +	dev->in_ep = ep; /* Store IN EP for enabling @ setup */
> +
> +

Too many newlines?

> +
> +	ep = usb_ep_autoconfig(gadget, &fs_out_desc);
> +	if (!ep) {
> +		status = -ENODEV;
> +		goto fail;
> +	}
> +
> +	if (gadget_is_dualspeed(gadget)) {
> +		hs_out_desc.bEndpointAddress =
> +				fs_out_desc.bEndpointAddress;
> +	}
> +
> +	dev->out_ep = ep; /* Store OUT EP for enabling @ setup */
> +
> +	/* note:  a status/notification endpoint is, strictly speaking,
> +	 * optional.  We don't treat it that way though!  It's simpler,
> +	 * and some newer profiles don't treat it as optional.
> +	 */
> +	ep = usb_ep_autoconfig(gadget, &fs_int_desc);
> +	if (!ep) {
> +		status = -ENODEV;
> +		goto fail;
> +	}
> +
> +	dev->int_ep = ep;
> +
> +	if (gadget_is_dualspeed(gadget)) {
> +		hs_int_desc.bEndpointAddress =
> +				fs_int_desc.bEndpointAddress;
> +
> +		/* copy descriptors, and track endpoint copies */
> +		f->hs_descriptors = (struct usb_descriptor_header **)
> +			&hs_usb_downloader_function;
> +
> +		if (!f->hs_descriptors)
> +			goto fail;
> +	}
> +
> +	debug("%s: out_ep:%p out_req:%p\n",
> +	      __func__, dev->out_ep, dev->out_req);
> +	printf("%s: dnl: 0x%p\n", __func__, dnl);
> +	usbd_fill_dnl(dnl);
> +
> +	return 0;
> +
> + fail:
> +	free(dev);
> +	return status;
> +}
> +
> +static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
> +{
> +	free(req->buf);
> +	usb_ep_free_request(ep, req);
> +}
> +
> +static void usbd_func_disable(struct usb_function *f)
> +{
> +	struct f_usbd   *f_usbd = func_to_usbd(f);
> +	struct usbd_dev *dev = f_usbd->dev;
> +
> +	debug("%s:\n", __func__);
> +
> +	/* Avoid freeing memory when ep is still claimed */
> +	if (dev->in_ep->driver_data) {
> +		free_ep_req(dev->in_ep, dev->in_req);
> +		usb_ep_disable(dev->in_ep);
> +		dev->in_ep->driver_data = NULL;
> +	}
> +
> +	if (dev->out_ep->driver_data) {
> +		free_ep_req(dev->out_ep, dev->out_req);
> +		usb_ep_disable(dev->out_ep);
> +		dev->out_ep->driver_data = NULL;
> +	}
> +
> +	if (dev->int_ep->driver_data) {
> +		usb_ep_disable(dev->int_ep);
> +		dev->int_ep->driver_data = NULL;
> +	}
> +}
> +
> +static int usbd_eps_setup(struct usb_function *f)
> +{
> +	int result;
> +	struct usb_composite_dev *cdev = f->config->cdev;
> +	struct usb_ep		*ep;
> +	struct usb_request      *req;
> +	struct usb_gadget       *gadget = cdev->gadget;
> +	struct usbd_dev         *dev = usbd_func->dev;
> +
> +	struct usb_endpoint_descriptor	*d;
> +
> +	ep = dev->in_ep;
> +	d = ep_desc(gadget, &hs_in_desc, &fs_in_desc);
> +	debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
> +
> +	result = usb_ep_enable(ep, d);
> +
> +	if (result == 0) {
> +		ep->driver_data = cdev; /* claim */
> +		req = usbd_start_ep(ep);
> +		if (req != NULL) {
> +			dev->in_req = req;
> +		} else {
> +			usb_ep_disable(ep);
> +			result = -EIO;
> +		}
> +	} else
> +		goto exit;
> +
> +	ep = dev->out_ep;
> +	d = ep_desc(gadget, &hs_out_desc, &fs_out_desc);
> +	debug("(d)bEndpointAddress: 0x%x\n", d->bEndpointAddress);
> +
> +	result = usb_ep_enable(ep, d);
> +
> +	if (result == 0) {
> +		ep->driver_data = cdev; /* claim */
> +		req = usbd_start_ep(ep);
> +		if (req != NULL) {
> +			dev->out_req = req;
> +		} else {
> +			usb_ep_disable(ep);
> +			result = -EIO;
> +		}
> +	} else
> +		goto exit;
> +
> +	/* ACM control EP */
> +	ep = dev->int_ep;
> +	ep->driver_data = cdev;	/* claim */
> +
> + exit:
> +	return result;
> +}
> +
> +static int usbd_func_set_alt(struct usb_function *f,
> +			     unsigned intf, unsigned alt)
> +{
> +	int result;
> +	debug("%s: func: %s intf: %d alt: %d\n",
> +	    __func__, f->name, intf, alt);
> +
> +	switch (intf) {
> +	case 0:
> +		debug("ACM INTR interface\n");
> +		break;
> +	case 1:
> +		debug("Communication Data interface\n");
> +
> +		result = usbd_eps_setup(f);
> +		if (result)
> +			printf("%s: EPs setup failed!\n", __func__);
> +		break;
> +	}
> +
> +	return 0;
> +}
> +
> +static int usbd_func_init(struct usb_configuration *c)
> +{
> +	int status;
> +	struct f_usbd *f_usbd;
> +
> +	debug("%s: cdev: 0x%p\n", __func__, c->cdev);
> +
> +	f_usbd = calloc(sizeof(*f_usbd), 1);
> +	if (!f_usbd)
> +		return -ENOMEM;
> +
> +	f_usbd->usb_function.name = "f_usbd";
> +	f_usbd->usb_function.bind = usbd_func_bind;
> +	f_usbd->usb_function.setup = usbd_func_setup;
> +	f_usbd->usb_function.set_alt = usbd_func_set_alt;
> +	f_usbd->usb_function.disable = usbd_func_disable;
> +
> +	status = usb_add_function(c, &f_usbd->usb_function);
> +	if (status)
> +		free(f_usbd);
> +
> +	return status;
> +}
> +
> +int f_usbd_add(struct usb_configuration *c)
> +{
> +	debug("%s:\n", __func__);
> +
> +	return usbd_func_init(c);
> +}
> diff --git a/include/linux/usb/f_usbd_thor.h
> b/include/linux/usb/f_usbd_thor.h new file mode 100644
> index 0000000..8002791
> --- /dev/null
> +++ b/include/linux/usb/f_usbd_thor.h
> @@ -0,0 +1,62 @@
> +/*
> + * USB THOR Downloader
> + *
> + * Copyright (C) 2012 Samsung Electronics
> + * Lukasz Majewski  <l.majewski@samsung.com>
> + *
> + * 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 + */
> +
> +#ifndef _USB_THOR_H_
> +#define _USB_THOR_H_
> +
> +#include <linux/usb/composite.h>
> +
> +/* ACM -> THOR GADGET download */
> +#define DEACTIVATE_CARRIER 0x0000
> +#define ACTIVATE_CARRIER 0x0003
> +
> +#define SET_LINE_CODING 0x0020
> +#define SET_CONTROL_LINE_STATE 0x0022
> +
> +/* THOR Composite Gadget */
> +
> +#define STRING_MANUFACTURER_IDX		0
> +#define STRING_PRODUCT_IDX		1
> +#define STRING_SERIAL_IDX		2
> +
> +/* Samsung's IDs */
> +#define DRIVER_VENDOR_NUM 0x04E8
> +#define DRIVER_PRODUCT_NUM 0x6601
> +
> +#define STRING_MANUFACTURER 25
> +#define STRING_PRODUCT 2
> +#define STRING_USBDOWN 2
> +#define	CONFIG_USBDOWNLOADER 2
> +
> +int f_usbd_add(struct usb_configuration *c);
> +
> +/* Interface to THOR protocol */
> +#define TX_DATA_LEN 64
> +#define RX_DATA_LEN 1024
> +
> +extern char *usbd_tx_data_buf;
> +extern char *usbd_rx_data_buf;
> +
> +extern void usbd_set_dma(char *addr, int len);
> +extern unsigned int usbd_rx_data(void);
> +extern void usbd_tx_data(char *data, int len);
> +
> +#endif /* _USB_THOR_H_ */

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function
  2012-04-12  7:17 ` [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function Lukasz Majewski
@ 2012-04-14 10:00   ` Marek Vasut
  2012-04-14 13:30   ` Wolfgang Denk
  1 sibling, 0 replies; 17+ messages in thread
From: Marek Vasut @ 2012-04-14 10:00 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

> Support for THOR download protocol. Those files are necessary for
> proper f_usbd_thor function proper work.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Marek Vasut <marex@denx.de>
> ---
>  drivers/usb/gadget/prot_thor.c |  247
> ++++++++++++++++++++++++++++++++++++++++ drivers/usb/gadget/prot_thor.h | 
> 112 ++++++++++++++++++
>  include/usbd_thor.h            |  108 +++++++++++++++++
>  3 files changed, 467 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/usb/gadget/prot_thor.c
>  create mode 100644 drivers/usb/gadget/prot_thor.h
>  create mode 100644 include/usbd_thor.h
> 
> diff --git a/drivers/usb/gadget/prot_thor.c
> b/drivers/usb/gadget/prot_thor.c new file mode 100644
> index 0000000..9b2610d
> --- /dev/null
> +++ b/drivers/usb/gadget/prot_thor.c
> @@ -0,0 +1,247 @@
> +/*
> + * prot_thor.c -- USB THOR Downloader protocol
> + *
> + * Copyright (C) 2012 Samsung Electronics
> + * Lukasz Majewski <l.majewski@samsung.com>
> + *
> + * 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 + *
> + */
> +#undef DEBUG
> +#include <common.h>
> +#include <errno.h>
> +#include <g_dnl.h>
> +#include "prot_thor.h"
> +
> +static void send_rsp(const rsp_box *rsp)
> +{
> +	/* should be copy on dma duffer */
> +	memcpy(usbd_tx_data_buf, rsp, sizeof(rsp_box));
> +	pkt_upload(usbd_tx_data_buf, sizeof(rsp_box));
> +
> +	debug("-RSP: %d, %d\n", rsp->rsp, rsp->rsp_data);

You should really unify these debug outputs

> +}
> +
> +static void send_data_rsp(s32 ack, s32 count)
> +{
> +	data_rsp_box rsp;
> +
> +	rsp.ack = ack;
> +	rsp.count = count;
> +
> +	/* should be copy on dma duffer */
> +	memcpy(usbd_tx_data_buf, &rsp, sizeof(data_rsp_box));
> +	pkt_upload(usbd_tx_data_buf, sizeof(data_rsp_box));
> +
> +	debug("-DATA RSP: %d, %d\n", ack, count);
> +}
> +
> +static int process_rqt_info(const rqt_box *rqt)
> +{
> +	rsp_box rsp = {0, };
> +
> +	rsp.rsp = rqt->rqt;
> +	rsp.rsp_data = rqt->rqt_data;
> +
> +	switch (rqt->rqt_data) {
> +	case RQT_INFO_VER_PROTOCOL:
> +		rsp.int_data[0] = VER_PROTOCOL_MAJOR;
> +		rsp.int_data[1] = VER_PROTOCOL_MINOR;
> +		break;
> +	case RQT_INIT_VER_HW:
> +		sprintf(rsp.str_data[0], "%x", checkboard());
> +		break;
> +	case RQT_INIT_VER_BOOT:
> +		sprintf(rsp.str_data[0], "%s", getenv("ver"));
> +		break;
> +	case RQT_INIT_VER_KERNEL:
> +		sprintf(rsp.str_data[0], "%s", "k unknown");
> +		break;
> +	case RQT_INIT_VER_PLATFORM:
> +		sprintf(rsp.str_data[0], "%s", "p unknown");
> +		break;
> +	case RQT_INIT_VER_CSC:
> +		sprintf(rsp.str_data[0], "%s", "c unknown");
> +		break;
> +	default:
> +		return 0;
> +	}
> +
> +	send_rsp(&rsp);
> +	return 1;
> +}
> +
> +static int process_rqt_cmd(const rqt_box *rqt)
> +{
> +	rsp_box rsp = {0, };
> +
> +	rsp.rsp = rqt->rqt;
> +	rsp.rsp_data = rqt->rqt_data;
> +
> +	switch (rqt->rqt_data) {
> +	case RQT_CMD_REBOOT:
> +		debug("TARGET RESET\n");
> +		send_rsp(&rsp);
> +		run_command("reset", 0);
> +		break;
> +	case RQT_CMD_POWEROFF:
> +	case RQT_CMD_EFSCLEAR:
> +		send_rsp(&rsp);
> +	default:
> +		printf("Command not supported -> cmd: %d\n", rqt->rqt_data);
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
> +static unsigned long download(unsigned int total, unsigned int
> packet_size, +			      struct g_dnl *dnl)
> +{
> +	int count = 0;
> +	unsigned int rcv_cnt;
> +	static int sect_start = 92160; /* Hardcoded -> will be fixed -> */
> +	unsigned int dma_buffer_address = CONFIG_SYS_DOWN_ADDR;
> +
> +	do {
> +		if (packet_size == PKT_DOWNLOAD_SIZE)
> +			dma_buffer_address =
> +				CONFIG_SYS_DOWN_ADDR + (count * packet_size);
> +
> +		usbd_set_dma((char *) dma_buffer_address,
> +			     packet_size);
> +
> +		rcv_cnt += usbd_rx_data();
> +		debug("RCV data count: %u\n", rcv_cnt);
> +
> +		/* Store data after receiving a "chunk" packet */
> +		if (packet_size == PKT_DOWNLOAD_CHUNK_SIZE &&
> +		    (rcv_cnt % PKT_DOWNLOAD_CHUNK_SIZE) == 0) {
> +			dnl->p = (sect_start + count *
> +				  (PKT_DOWNLOAD_CHUNK_SIZE >> 9));
> +			debug("DNL STORE dnl->p: %d\n", dnl->p);
> +			dnl->store(dnl, dnl->medium);
> +		}
> +		send_data_rsp(0, ++count);
> +	} while (rcv_cnt < total);
> +
> +	debug("rcv: %d dnl: %d\n", rcv_cnt, total);
> +
> +	return rcv_cnt;
> +}
> +
> +static int process_rqt_download(const rqt_box *rqt, struct g_dnl *dnl)
> +{
> +	static unsigned long download_total_size, cnt;
> +	static char f_name[F_NAME_BUF_SIZE];
> +	rsp_box rsp = {0, };
> +	int file_type;
> +	int ret = 1;
> +
> +	rsp.rsp = rqt->rqt;
> +	rsp.rsp_data = rqt->rqt_data;
> +
> +	switch (rqt->rqt_data) {
> +	case RQT_DL_INIT:
> +		download_total_size = rqt->int_data[0];
> +
> +		debug("INIT: total %d bytes\n", rqt->int_data[0]);
> +		break;
> +	case RQT_DL_FILE_INFO:
> +		file_type = rqt->int_data[0];
> +		if (file_type == FILE_TYPE_PIT) {
> +			puts("PIT table file - not supported\n");
> +			return -1;
> +		}
> +
> +		dnl->file_size = rqt->int_data[1];
> +		memcpy(f_name, rqt->str_data[0], sizeof(f_name));
> +
> +		debug("INFO: name(%s, %d), size(%d), type(%d)\n",
> +		       f_name, 0, dnl->file_size, file_type);
> +
> +		if (dnl->file_size > PKT_DOWNLOAD_CHUNK_SIZE)
> +			dnl->packet_size = PKT_DOWNLOAD_CHUNK_SIZE;
> +		else
> +			dnl->packet_size = PKT_DOWNLOAD_SIZE;
> +
> +		printf("%s: dnl->file_size: %d dnl->packet_size: %d\n",
> +		       __func__, dnl->file_size, dnl->packet_size);

Make this debug or sanitize?

> +
> +		rsp.int_data[0] = dnl->packet_size;
> +
> +		dnl->file_name = f_name;
> +		ret = 0;
> +
> +		break;
> +	case RQT_DL_FILE_START:
> +		send_rsp(&rsp);
> +
> +		cnt = download(download_total_size, dnl->packet_size, dnl);
> +
> +		dnl->store(dnl, dnl->medium);
> +
> +		return cnt;
> +	case RQT_DL_FILE_END:
> +		debug("DL FILE_END\n");
> +		break;
> +	case RQT_DL_EXIT:
> +		debug("DL EXIT\n");
> +		ret = 0;
> +
> +		break;
> +	default:
> +		printf("Operation not supported: %d\n", rqt->rqt_data);
> +		return -1;
> +	}
> +
> +	send_rsp(&rsp);
> +	return ret;
> +}
> +
> +int process_data(struct g_dnl *dnl)
> +{
> +	rqt_box rqt;
> +	int ret = 1;
> +
> +	memset(&rqt, 0, sizeof(rqt));
> +	memcpy(&rqt, usbd_rx_data_buf, sizeof(rqt));
> +
> +	debug("+RQT: %d, %d\n", rqt.rqt, rqt.rqt_data);
> +
> +	switch (rqt.rqt) {
> +	case RQT_INFO:
> +		ret = process_rqt_info(&rqt);
> +		break;
> +	case RQT_CMD:
> +		ret = process_rqt_cmd(&rqt);
> +		break;
> +	case RQT_DL:
> +		ret = process_rqt_download(&rqt, dnl);
> +		break;
> +	case RQT_UL:
> +		puts("RQT: UPLOAD not supported!\n");
> +		break;
> +	default:
> +		printf("unknown request (%d)\n", rqt.rqt);
> +		ret = 0;
> +	}
> +
> +	/* exit code: */
> +	/* 0 - success */
> +	/* < 0 - Error code */
> +
> +	return ret;
> +}
> diff --git a/drivers/usb/gadget/prot_thor.h
> b/drivers/usb/gadget/prot_thor.h new file mode 100644
> index 0000000..6e72c75
> --- /dev/null
> +++ b/drivers/usb/gadget/prot_thor.h
> @@ -0,0 +1,112 @@
> +/*
> + * THOR protocol internals
> + *
> + * Copyright (C) 2012 Samsung Electronics
> + * Lukasz Majewski <l.majewski@samsung.com>
> + *
> + * 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
> + */
> +
> +#ifndef __PROT_THOR_H_
> +#define __PROT_THOR_H_
> +
> +#include <common.h>
> +#include <linux/usb/f_usbd_thor.h>
> +
> +#define VER_PROTOCOL_MAJOR	4
> +#define VER_PROTOCOL_MINOR	0
> +
> +enum rqt {
> +	RQT_INFO = 200,
> +	RQT_CMD,
> +	RQT_DL,
> +	RQT_UL,
> +};
> +
> +enum rqt_data {
> +	/* RQT_INFO */
> +	RQT_INFO_VER_PROTOCOL = 1,
> +	RQT_INIT_VER_HW,
> +	RQT_INIT_VER_BOOT,
> +	RQT_INIT_VER_KERNEL,
> +	RQT_INIT_VER_PLATFORM,
> +	RQT_INIT_VER_CSC,
> +
> +	/* RQT_CMD */
> +	RQT_CMD_REBOOT = 1,
> +	RQT_CMD_POWEROFF,
> +	RQT_CMD_EFSCLEAR,
> +
> +	/* RQT_DL */
> +	RQT_DL_INIT = 1,
> +	RQT_DL_FILE_INFO,
> +	RQT_DL_FILE_START,
> +	RQT_DL_FILE_END,
> +	RQT_DL_EXIT,
> +
> +	/* RQT_UL */
> +	RQT_UL_INIT = 1,
> +	RQT_UL_START,
> +	RQT_UL_END,
> +	RQT_UL_EXIT,
> +};
> +
> +typedef struct _rqt_box {	/* total: 256B */
> +	s32 rqt;		/* request id */
> +	s32 rqt_data;		/* request data id */
> +	s32 int_data[14];	/* int data */
> +	char str_data[5][32];	/* string data */
> +	char md5[32];		/* md5 checksum */
> +} __attribute__((packed)) rqt_box;
> +
> +typedef struct _rsp_box {	/* total: 128B */
> +	s32 rsp;		/* response id (= request id) */
> +	s32 rsp_data;		/* response data id */
> +	s32 ack;		/* ack */
> +	s32 int_data[5];	/* int data */
> +	char str_data[3][32];	/* string data */
> +} __attribute__((packed)) rsp_box;
> +
> +typedef struct _data_rsp_box {	/* total: 8B */
> +	s32 ack;		/* response id (= request id) */
> +	s32 count;		/* response data id */
> +} __attribute__((packed)) data_rsp_box;
> +
> +enum {
> +	FILE_TYPE_NORMAL,
> +	FILE_TYPE_PIT,
> +};
> +
> +#define F_NAME_BUF_SIZE 32
> +
> +/* download packet size */
> +#define PKT_DOWNLOAD_SIZE (1 << 20) /* 1 MiB */
> +#define PKT_DOWNLOAD_CHUNK_SIZE (32 << 20) /* 32 MiB */
> +
> +int process_data(struct g_dnl *dnl);
> +
> +static inline int pkt_download(void *dest, const int size)
> +{
> +	usbd_set_dma((char *)dest, size);
> +	return usbd_rx_data();
> +}
> +
> +static inline void pkt_upload(void *src, const int size)
> +{
> +	usbd_tx_data((char *)src, size);
> +}
> +
> +#endif /*  __PROT_THOR_H__ */
> diff --git a/include/usbd_thor.h b/include/usbd_thor.h
> new file mode 100644
> index 0000000..d31bb35
> --- /dev/null
> +++ b/include/usbd_thor.h
> @@ -0,0 +1,108 @@
> +/*
> + * USB Downloader for SLP
> + *
> + * Copyright (C) 2011-2012 Samsung Electronics
> + * Minkyu Kang <mk7.kang@samsung.com>
> + * Sanghee Kim <sh0130.kim@samsung.com>
> + * Lukasz Majewski  <l.majewski@samsung.com>
> + *
> + */
> +
> +#ifndef _USBD_H_
> +#define _USBD_H_
> +
> +#define msleep(a)	udelay(a * 1000)
> +
> +/*
> + * updateflag is consist of below bit.
> + * 7: RESERVED.
> + * 6: RESERVED.
> + * 5: RESERVED.
> + * 4: SLP_MMC_RESIZE_REQUIRED
> + * 3: SLP_ROOTFS_NEW
> + * 2: SLP_KERNEL_NEW
> + * 1: SLP_SBL_NEW
> + * 0: SLP_PBL_NEW
> + */
> +enum {
> +	SLP_PBL_NEW = 0,
> +	SLP_SBL_NEW,
> +	SLP_KERNEL_NEW,
> +	SLP_ROOTFS_NEW,
> +	SLP_MMC_RESIZE_REQUIRED
> +};
> +
> +/* status definition */
> +enum {
> +	STATUS_DONE = 0,
> +	STATUS_RETRY,
> +	STATUS_ERROR,
> +};
> +
> +/* download mode definition */
> +enum {
> +	MODE_NORMAL = 0,
> +	MODE_FORCE,
> +};
> +
> +/* end mode */
> +enum {
> +	END_BOOT = 0,
> +	END_RETRY,
> +	END_FAIL,
> +	END_NORMAL,
> +};
> +/*
> + * USB Downloader Operations
> + * All functions and valuable are mandatory
> + *
> + * usb_init	: initialize the USB Controller and check the connection
> + * usb_stop	: stop and release USB
> + * send_data	: send the data (BULK ONLY!!)
> + * recv_data	: receive the data and returns received size (BULK ONLY!!)
> + * recv_setup	: setup download address, length and DMA setting for 
receive
> + * tx_data	: send data address
> + * rx_data	: receive data address
> + * tx_len	: size of send data
> + * rx_len	: size of receive data
> + * ram_addr	: address of will be stored data on RAM
> + *
> + * mmc_dev	: device number of mmc
> + * mmc_max	: number of max blocks
> + * mmc_blk	: mmc block size
> + * mmc_total	: mmc total blocks
> + */
> +struct usbd_ops {
> +	int (*usb_init)(void);
> +	void (*usb_stop)(void);
> +	void (*send_data)(char *, int);
> +	int (*recv_data)(void);
> +	void (*recv_setup)(char *, int);
> +#ifdef CONFIG_USB_S5PC_DMA
> +	void (*prepare_dma)(void * , u32 , uchar);
> +	void (*dma_done)(int);
> +#endif
> +	char *tx_data;
> +	char *rx_data;
> +	ulong tx_len;
> +	ulong rx_len;
> +	ulong ram_addr;
> +
> +	/* mmc device info */
> +	uint mmc_dev;
> +	uint mmc_max;
> +	uint mmc_blk;
> +	uint mmc_total;
> +
> +	void (*set_logo)(char *, int);
> +	void (*set_progress)(int);
> +	void (*cpu_reset)(void);
> +	void (*down_start)(void);
> +	void (*down_cancel)(int);
> +};
> +
> +/* This function is interfaced between USB Device Controller and USB
> Downloader + * Must Implementation this function at USB Controller!! */
> +struct usbd_ops *usbd_set_interface(struct usbd_ops *);
> +
> +#endif /* _USBD_H_ */

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command
  2012-04-12  7:17 ` [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command Lukasz Majewski
@ 2012-04-14 10:04   ` Marek Vasut
  2012-04-14 13:33   ` Wolfgang Denk
  1 sibling, 0 replies; 17+ messages in thread
From: Marek Vasut @ 2012-04-14 10:04 UTC (permalink / raw)
  To: u-boot

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
> +);

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol
  2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
  2012-04-14  9:58   ` Marek Vasut
@ 2012-04-14 13:12   ` Wolfgang Denk
  2012-04-14 13:29   ` Wolfgang Denk
  2 siblings, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:12 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

In message <1334215049-20362-3-git-send-email-l.majewski@samsung.com> you wrote:
> Implementation of USB Download function supporting THOR protocol.

Please add documentation what THOR is, with links to specifications,
other (reference) implementations, etc.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"I've finally learned what `upward compatible' means. It means we get
to keep all our old mistakes." - Dennie van Tassel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol
  2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
  2012-04-14  9:58   ` Marek Vasut
  2012-04-14 13:12   ` Wolfgang Denk
@ 2012-04-14 13:29   ` Wolfgang Denk
  2 siblings, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:29 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

In message <1334215049-20362-3-git-send-email-l.majewski@samsung.com> you wrote:
> Implementation of USB Download function supporting THOR protocol.

Sorry, I hit "send" too fast...

> +	.bDescriptorSubtype = 0x00,	/* 0x00 */
> +	.bcdCDC =             0x0110,
...
> +	.bDescriptorType =    CS_INTERFACE, /* 0x24 */
> +	.bDescriptorSubtype = 0x01,	/* 0x01 */
> +	.bmCapabilities =     0x00,
> +	.bDataInterface =     0x01,
...
> +	.bDescriptorSubtype = 0x02,	/* 0x02 */
> +	.bmCapabilities =     0x00,
...
> +	.bDescriptorSubtype =  0x06,	/* 0x06 */
...
> +	.bEndpointAddress = 3 | USB_DIR_IN,
...
> +	.bInterval = 0x9,
...

There should be some header file with symbolic names for akll these
hard coded magic numbers.

> +};
> +
> +/*-------------------------------------------------------------------------*/
> +
> +

Drop that.   A single blank line is sufficient.

> +static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
> +{
> +	struct usb_request	*req;
> +
> +	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
> +	if (req) {
> +		req->length = length;
> +		req->buf = malloc(length);
> +		if (!req->buf) {
> +			usb_ep_free_request(ep, req);
> +			req = NULL;
> +		}
> +	}
> +	return req;

Turn logic around to avoid deepo nesting of code - please apply
globally.  For example here:

	req = usb_ep_alloc_request(ep, GFP_ATOMIC);
	if (req == NULL)
		return NULL;

	req->buf = malloc(length);
	if (!req->buf) {
		usb_ep_free_request(ep, req);
		return NULL;
	}

	req->length = length;

	return req;

> +		debug("dev->out_req->length:%d dev->rxdata:%d\n",
> +		     dev->out_req->length, dev->rxdata);

Indentation by tAB only, please.


Also make sure to run your patches through checkpatch:

WARNING: space prohibited between function name and open parenthesis
'('
#588: FILE: drivers/usb/gadget/f_usbd_thor.c:465:
+__attribute__ ((__aligned__ (__alignof__ (long long))))

WARNING: space prohibited between function name and open parenthesis
'('
#588: FILE: drivers/usb/gadget/f_usbd_thor.c:465:
+__attribute__ ((__aligned__ (__alignof__ (long long))))

WARNING: __aligned(size) is preferred over
__attribute__((aligned(size)))
#588: FILE: drivers/usb/gadget/f_usbd_thor.c:465:
+__attribute__ ((__aligned__ (__alignof__ (long long))))

WARNING: space prohibited between function name and open parenthesis
'('
#590: FILE: drivers/usb/gadget/f_usbd_thor.c:467:
+__attribute__ ((__aligned__ (__alignof__ (long long))))

WARNING: space prohibited between function name and open parenthesis
'('
#590: FILE: drivers/usb/gadget/f_usbd_thor.c:467:
+__attribute__ ((__aligned__ (__alignof__ (long long))))

WARNING: __aligned(size) is preferred over
__attribute__((aligned(size)))
#590: FILE: drivers/usb/gadget/f_usbd_thor.c:467:
+__attribute__ ((__aligned__ (__alignof__ (long long))))



> +	switch (mode) {
> +	case END_BOOT:
> +		run_command("run bootcmd", 0);
> +		break;
> +	default:
> +		break;
> +	}

if ... else ... ?

> +	if (strncmp(usbd_rx_data_buf, recv_key, strlen(recv_key)) == 0) {
> +		printf("Download request from the Host PC\n");

Make this debug() ?

> +		msleep(30);

Are you sure it is a PC?

> +		strncpy(usbd_tx_data_buf, tx_key, strlen(tx_key));
> +		usbd_tx_data(usbd_tx_data_buf, strlen(tx_key));
> +	} else {
> +		puts("Wrong reply information\n");

It might be useful to print information about whart was received, and
what was expected?

> +		if (ret > 0) {
> +			ret = process_data(dnl);
> +
> +			if (ret < 0)
> +				return -1;
> +			else if (ret == 0)
> +				return 0;

Isn't this overkill?

			return process_data(dnl);

should be equivalent ?

> +	/* If the following pointers are set to NULL -> error */
> +	dnl->rx_buf = (unsigned int *) CONFIG_SYS_DOWN_ADDR;

Does it make sense to hardwire this address, and have it the same on
all boards?  Or would it be more useful if this could be changed by
the user (like by storing it in an environment variable) ?

> +	usb_downloader_intf_int.bInterfaceNumber = status;
> +	usb_downloader_cdc_union.bMasterInterface = status;

BTW:  CamelCaps names are forbidden in U-Boot.  Please fix globally.

Actually you should probably re-read the CodingStyle document and
re-think most variable names.

> +	/* note:  a status/notification endpoint is, strictly speaking,
> +	 * optional.  We don't treat it that way though!  It's simpler,
> +	 * and some newer profiles don't treat it as optional.
> +	 */

Incorrect multiline comment style.  Please fix globally.

> +	debug("%s: out_ep:%p out_req:%p\n",
> +	      __func__, dev->out_ep, dev->out_req);
> +	printf("%s: dnl: 0x%p\n", __func__, dnl);

Is this really useful and needed output for production mode?
Please check output globally, this seems to be way too verbose (OK for
testing, but not for production).

> +/* Samsung's IDs */
> +#define DRIVER_VENDOR_NUM 0x04E8
> +#define DRIVER_PRODUCT_NUM 0x6601
> +#define STRING_MANUFACTURER 25

Are there chances that other vendor / product / manufacurer ID's need
to be used here?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
If I had to live my life again,  I'd  make  the  same  mistakes, only
sooner.                                          -- Tallulah Bankhead

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function
  2012-04-12  7:17 ` [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function Lukasz Majewski
  2012-04-14 10:00   ` Marek Vasut
@ 2012-04-14 13:30   ` Wolfgang Denk
  1 sibling, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:30 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

In message <1334215049-20362-4-git-send-email-l.majewski@samsung.com> you wrote:
> Support for THOR download protocol. Those files are necessary for
> proper f_usbd_thor function proper work.
> 
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Marek Vasut <marex@denx.de>
> ---
>  drivers/usb/gadget/prot_thor.c |  247 ++++++++++++++++++++++++++++++++++++++++
>  drivers/usb/gadget/prot_thor.h |  112 ++++++++++++++++++
>  include/usbd_thor.h            |  108 +++++++++++++++++
>  3 files changed, 467 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/usb/gadget/prot_thor.c
>  create mode 100644 drivers/usb/gadget/prot_thor.h
>  create mode 100644 include/usbd_thor.h

Please see previous comments, and fix checkpatch warnings.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Only a fool fights in a burning house.
	-- Kank the Klingon, "Day of the Dove", stardate unknown

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command
  2012-04-12  7:17 ` [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command Lukasz Majewski
  2012-04-14 10:04   ` Marek Vasut
@ 2012-04-14 13:33   ` Wolfgang Denk
  1 sibling, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:33 UTC (permalink / raw)
  To: u-boot

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

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"I can call spirits from the vasty deep."
"Why so can I, or so can any man; but will they come when you do call
for them?"          - Shakespeare, 1 King Henry IV, Act III, Scene I.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board
  2012-04-12  7:17 ` [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board Lukasz Majewski
@ 2012-04-14 13:39   ` Wolfgang Denk
  0 siblings, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:39 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

In message <1334215049-20362-6-git-send-email-l.majewski@samsung.com> you wrote:
> Support for g_dnl download usb gadget driver for Samsung's GONI target.
...
> +void usbd_thor_udc_probe(void)
> +{
> +	puts("USB_udc_probe\n");
> +	s3c_udc_probe(&s5pc110_otg_data);

Less verbose?

> -#define CONFIG_BOOTCOMMAND	"run ubifsboot"
> +#define CONFIG_BOOTCOMMAND	"run mmcboot"

This appears tio be an unrelated change, please submit separately.


> +#define CONFIG_DNL_INFO \
> +	"dnl_info=" \
> +	"u-boot mmc 80 200;" \
> +	"uImage fat 0 2;" \
> +	"platform.img raw 0 3\0" \

Here we really see that documentation is missing.  It is not clear how
this is supposed to be used.  As is, it appears as if this concept
didn't scale.


> -	"mmcboot=" \
> -		"set bootargs root=${mmcblk} rootfstype=${rootfstype}" \
> -		CONFIG_UBI_MTD " ${opts} ${lcdinfo} " \
> -		CONFIG_COMMON_BOOT "; run bootk\0" \
> +	"mmcboot=set bootargs root=/dev/mmcblk${mmcdev}p${mmcrootpart} " \
> +		"rootwait ${console} ${meminfo} ${opts} ${lcdinfo}; " \
> +		"run loaduimage; bootm 0x30007FC0\0" \

Unrelated change.

> -	"opts=always_resume=1"
> +	"loaduimage=fatload mmc ${mmcdev}:${mmcbootpart} 0x30007FC0 uImage\0" \
> +	"mmcdev=0\0" \
> +	"mmcbootpart=2\0" \
> +	"mmcrootpart=3\0" \
> +	"opts=always_resume=1\0" \

Unrelated changes.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
About the use of language: it is impossible to sharpen a pencil  with
a  blunt  ax.  It is equally vain to try to do it with ten blunt axes
instead.                                           -- Edsger Dijkstra

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board
  2012-04-12  7:17 ` [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board Lukasz Majewski
@ 2012-04-14 13:40   ` Wolfgang Denk
  0 siblings, 0 replies; 17+ messages in thread
From: Wolfgang Denk @ 2012-04-14 13:40 UTC (permalink / raw)
  To: u-boot

Dear Lukasz Majewski,

In message <1334215049-20362-7-git-send-email-l.majewski@samsung.com> you wrote:
> Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
> Cc: Minkyu Kang <mk7.kang@samsung.com>

See comments as for GONI board.

> +#ifdef CONFIG_USBDOWNLOAD_GADGET
> +void usbd_thor_udc_probe(void)
> +{
> +	puts("USB_udc_probe\n");
> +	s3c_udc_probe(&s5pc210_otg_data);
> +}
> +#endif

Duplicated code.  Please move to common location and avoid
duplication.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I think there's a world market for about five computers.
         -- attr. Thomas J. Watson (Chairman of the Board, IBM), 1943

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-04-14 13:40 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-12  7:17 [U-Boot] [PATCH 0/6] usb:composite:download Composite download gadget Lukasz Majewski
2012-04-12  7:17 ` [U-Boot] [PATCH 1/6] usb:composite:g_dnl: Composite gadget (g_dnl) for USB downloading functions Lukasz Majewski
2012-04-14  9:55   ` Marek Vasut
2012-04-12  7:17 ` [U-Boot] [PATCH 2/6] usb:g_dnl:f_usbd_thor: USB Download function to support THOR protocol Lukasz Majewski
2012-04-14  9:58   ` Marek Vasut
2012-04-14 13:12   ` Wolfgang Denk
2012-04-14 13:29   ` Wolfgang Denk
2012-04-12  7:17 ` [U-Boot] [PATCH 3/6] usb:g_dnl:thor: THOR protocol back end support for f_usbd_thor function Lukasz Majewski
2012-04-14 10:00   ` Marek Vasut
2012-04-14 13:30   ` Wolfgang Denk
2012-04-12  7:17 ` [U-Boot] [PATCH 4/6] usb:command: Support for USB Download command Lukasz Majewski
2012-04-14 10:04   ` Marek Vasut
2012-04-14 13:33   ` Wolfgang Denk
2012-04-12  7:17 ` [U-Boot] [PATCH 5/6] usb:g_dnl: Support for g_dnl download usb gadget for GONI board Lukasz Majewski
2012-04-14 13:39   ` Wolfgang Denk
2012-04-12  7:17 ` [U-Boot] [PATCH 6/6] usb:g_dnl: Support for g_dnl download usb gadget for TRATS board Lukasz Majewski
2012-04-14 13:40   ` Wolfgang Denk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.