]> git.sur5r.net Git - u-boot/commitdiff
Merge git://git.denx.de/u-boot-usb
authorTom Rini <trini@konsulko.com>
Mon, 7 Sep 2015 12:56:23 +0000 (08:56 -0400)
committerTom Rini <trini@konsulko.com>
Mon, 7 Sep 2015 12:56:23 +0000 (08:56 -0400)
28 files changed:
board/h2200/h2200.c
common/Makefile
common/cmd_dfu.c
common/cmd_fitupd.c
common/main.c
common/update.c
configs/am335x_boneblack_defconfig
doc/README.dfutftp [new file with mode: 0644]
doc/README.update
drivers/dfu/Kconfig
drivers/dfu/Makefile
drivers/dfu/dfu.c
drivers/dfu/dfu_tftp.c [new file with mode: 0644]
drivers/usb/gadget/f_thor.c
drivers/usb/gadget/f_thor.h
drivers/usb/host/ehci-hcd.c
drivers/usb/host/ehci.h
include/configs/bcm28155_ap.h
include/dfu.h
include/net.h
include/net/tftp.h [new file with mode: 0644]
net/bootp.c
net/net.c
net/rarp.c
net/tftp.c
net/tftp.h [deleted file]
test/dfu/README
test/dfu/dfu_gadget_test.sh

index 66ae4b6906b54568242ee1cdb34d758689c12b07..01f8e67be1456325358ded26ed1757be12cbb33c 100644 (file)
@@ -59,3 +59,15 @@ int dram_init(void)
        gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
        return 0;
 }
+
+#ifdef CONFIG_USB_GADGET_PXA2XX
+int board_usb_init(int index, enum usb_init_type init)
+{
+       return 0;
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+       return 0;
+}
+#endif
index f4ba8782f543594a94c0ee995f293875b4ca1a20..556fb07592927f3bdee71782a10fe3651595e36b 100644 (file)
@@ -210,6 +210,7 @@ obj-$(CONFIG_LYNXKDI) += lynxkdi.o
 obj-$(CONFIG_MENU) += menu.o
 obj-$(CONFIG_MODEM_SUPPORT) += modem.o
 obj-$(CONFIG_UPDATE_TFTP) += update.o
+obj-$(CONFIG_DFU_TFTP) += update.o
 obj-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
 obj-$(CONFIG_CMD_DFU) += cmd_dfu.o
 obj-$(CONFIG_CMD_GPT) += cmd_gpt.o
index 857148f8afef2562098358bc6615506d14716fc3..f060db75c6c8d161e71bd85374f0ac148457f14a 100644 (file)
@@ -1,6 +1,9 @@
 /*
  * cmd_dfu.c -- dfu command
  *
+ * Copyright (C) 2015
+ * Lukasz Majewski <l.majewski@majess.pl>
+ *
  * Copyright (C) 2012 Samsung Electronics
  * authors: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
  *         Lukasz Majewski <l.majewski@samsung.com>
@@ -13,6 +16,7 @@
 #include <dfu.h>
 #include <g_dnl.h>
 #include <usb.h>
+#include <net.h>
 
 static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
@@ -26,6 +30,15 @@ static int do_dfu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        char *devstring = argv[3];
 
        int ret, i = 0;
+#ifdef CONFIG_DFU_TFTP
+       unsigned long addr = 0;
+       if (!strcmp(argv[1], "tftp")) {
+               if (argc == 5)
+                       addr = simple_strtoul(argv[4], NULL, 0);
+
+               return update_tftp(addr, interface, devstring);
+       }
+#endif
 
        ret = dfu_init_env_entities(interface, devstring);
        if (ret)
@@ -89,4 +102,11 @@ U_BOOT_CMD(dfu, CONFIG_SYS_MAXARGS, 1, do_dfu,
        "    on device <dev>, attached to interface\n"
        "    <interface>\n"
        "    [list] - list available alt settings\n"
+#ifdef CONFIG_DFU_TFTP
+       "dfu tftp <interface> <dev> [<addr>]\n"
+       "  - device firmware upgrade via TFTP\n"
+       "    on device <dev>, attached to interface\n"
+       "    <interface>\n"
+       "    [<addr>] - address where FIT image has been stored\n"
+#endif
 );
index b0459744d98d075f8257e01bc6683edbc5a5988d..78b8747336a871c9131501a8fb9c2ccb2c7a1219 100644 (file)
@@ -23,7 +23,7 @@ static int do_fitupd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        if (argc == 2)
                addr = simple_strtoul(argv[1], NULL, 16);
 
-       return update_tftp(addr);
+       return update_tftp(addr, NULL, NULL);
 }
 
 U_BOOT_CMD(fitupd, 2, 0, do_fitupd,
index 2979fbed630ca22d7ae9a208c18a06ab1a3e21f0..ead0cd17aa8e37e3889ef5da184415a3332e9476 100644 (file)
@@ -75,7 +75,7 @@ void main_loop(void)
        run_preboot_environment_command();
 
 #if defined(CONFIG_UPDATE_TFTP)
-       update_tftp(0UL);
+       update_tftp(0UL, NULL, NULL);
 #endif /* CONFIG_UPDATE_TFTP */
 
        s = bootdelay_process();
index 1c6aa186d0d091af65d5148aba6c0b68eabcb1b0..1da80b70f2db6d1f01b5dca3141240a01ef1d169 100644 (file)
@@ -13,8 +13,8 @@
 #error "CONFIG_FIT and CONFIG_OF_LIBFDT are required for auto-update feature"
 #endif
 
-#if defined(CONFIG_SYS_NO_FLASH)
-#error "CONFIG_SYS_NO_FLASH defined, but FLASH is required for auto-update feature"
+#if defined(CONFIG_UPDATE_TFTP) && defined(CONFIG_SYS_NO_FLASH)
+#error "CONFIG_UPDATE_TFTP and CONFIG_SYS_NO_FLASH needed for legacy behaviour"
 #endif
 
 #include <command.h>
@@ -22,6 +22,8 @@
 #include <net.h>
 #include <net/tftp.h>
 #include <malloc.h>
+#include <dfu.h>
+#include <errno.h>
 
 /* env variable holding the location of the update file */
 #define UPDATE_FILE_ENV                "updatefile"
 
 extern ulong tftp_timeout_ms;
 extern int tftp_timeout_count_max;
-extern flash_info_t flash_info[];
 extern ulong load_addr;
-
+#ifndef CONFIG_SYS_NO_FLASH
+extern flash_info_t flash_info[];
 static uchar *saved_prot_info;
-
+#endif
 static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
 {
        int size, rv;
@@ -94,6 +96,7 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
        return rv;
 }
 
+#ifndef CONFIG_SYS_NO_FLASH
 static int update_flash_protect(int prot, ulong addr_first, ulong addr_last)
 {
        uchar *sp_info_ptr;
@@ -165,9 +168,11 @@ static int update_flash_protect(int prot, ulong addr_first, ulong addr_last)
 
        return 0;
 }
+#endif
 
 static int update_flash(ulong addr_source, ulong addr_first, ulong size)
 {
+#ifndef CONFIG_SYS_NO_FLASH
        ulong addr_last = addr_first + size - 1;
 
        /* round last address to the sector boundary */
@@ -203,7 +208,7 @@ static int update_flash(ulong addr_source, ulong addr_first, ulong size)
                printf("Error: could not protect flash sectors\n");
                return 1;
        }
-
+#endif
        return 0;
 }
 
@@ -223,13 +228,24 @@ static int update_fit_getparams(const void *fit, int noffset, ulong *addr,
        return 0;
 }
 
-int update_tftp(ulong addr)
+int update_tftp(ulong addr, char *interface, char *devstring)
 {
-       char *filename, *env_addr;
-       int images_noffset, ndepth, noffset;
+       char *filename, *env_addr, *fit_image_name;
        ulong update_addr, update_fladdr, update_size;
-       void *fit;
+       int images_noffset, ndepth, noffset;
+       bool update_tftp_dfu;
        int ret = 0;
+       void *fit;
+
+       if (interface == NULL && devstring == NULL) {
+               update_tftp_dfu = false;
+       } else if (interface && devstring) {
+               update_tftp_dfu = true;
+       } else {
+               error("Interface: %s and devstring: %s not supported!\n",
+                     interface, devstring);
+               return -EINVAL;
+       }
 
        /* use already present image */
        if (addr)
@@ -278,8 +294,8 @@ got_update_file:
                if (ndepth != 1)
                        goto next_node;
 
-               printf("Processing update '%s' :",
-                       fit_get_name(fit, noffset, NULL));
+               fit_image_name = (char *)fit_get_name(fit, noffset, NULL);
+               printf("Processing update '%s' :", fit_image_name);
 
                if (!fit_image_verify(fit, noffset)) {
                        printf("Error: invalid update hash, aborting\n");
@@ -295,10 +311,20 @@ got_update_file:
                        ret = 1;
                        goto next_node;
                }
-               if (update_flash(update_addr, update_fladdr, update_size)) {
-                       printf("Error: can't flash update, aborting\n");
-                       ret = 1;
-                       goto next_node;
+
+               if (!update_tftp_dfu) {
+                       if (update_flash(update_addr, update_fladdr,
+                                        update_size)) {
+                               printf("Error: can't flash update, aborting\n");
+                               ret = 1;
+                               goto next_node;
+                       }
+               } else if (fit_image_check_type(fit, noffset,
+                                               IH_TYPE_FIRMWARE)) {
+                       ret = dfu_tftp_write(fit_image_name, update_addr,
+                                            update_size, interface, devstring);
+                       if (ret)
+                               return ret;
                }
 next_node:
                noffset = fdt_next_node(fit, noffset, &ndepth);
index 60339c8725e0f051a639476a629b587239daa46a..f1ff65fa835a5e74ab4f4a931f6425fced1c6262 100644 (file)
@@ -8,3 +8,4 @@ CONFIG_SYS_EXTRA_OPTIONS="EMMC_BOOT"
 # CONFIG_CMD_FLASH is not set
 # CONFIG_CMD_SETEXPR is not set
 CONFIG_SPI_FLASH=y
+CONFIG_DFU_TFTP=y
diff --git a/doc/README.dfutftp b/doc/README.dfutftp
new file mode 100644 (file)
index 0000000..0257f0d
--- /dev/null
@@ -0,0 +1,114 @@
+Device Firmware Upgrade (DFU) - extension to use TFTP
+=====================================================
+
+Why?
+----
+
+* Update TFTP (CONFIG_UPDATE_TFTP) only supports writing
+code to NAND memory via TFTP.
+* DFU supports writing data to the variety of mediums (NAND,
+eMMC, SD, partitions, RAM, etc) via USB.
+
+Combination of both solves their shortcomings!
+
+
+Overview
+--------
+
+This document briefly describes how to use DFU for
+upgrading firmware (e.g. kernel, u-boot, rootfs, etc.)
+via TFTP protocol.
+
+By using Ethernet (TFTP protocol to be precise) it is
+possible to overcome the major problem of USB based DFU -
+the relatively low transfer speed for large files.
+This was caused by DFU standard, which imposed utilization
+of only EP0 for transfer. By using Ethernet we can circumvent
+this shortcoming.
+
+Beagle Bone Black rev. C (BBB) powered by TI's am335x CPU has
+been used as a demo board.
+
+To utilize this feature, one needs to first enable support
+for USB based DFU (CONFIG_DFU_*) and DFU TFTP update
+(CONFIG_DFU_TFTP) described in ./doc/README.update.
+
+The "dfu" command has been extended to support transfer via TFTP - one
+needs to type for example "dfu tftp 0 mmc 0"
+
+This feature does not depend on "fitupd" command enabled.
+
+As of this writing (SHA1:8d77576371381ade83de475bb639949b44941e8c v2015.10-rc2)
+the update.c code is not enabled (CONFIG_UPDATE_TFTP) by any board in the
+contemporary u-boot tree.
+
+
+Environment variables
+---------------------
+
+The "dfu tftp" command can be used in the "preboot" environment variable
+(when it is enabled by defining CONFIG_PREBOOT).
+This is the preferable way of using this command in the early boot stage
+as opposed to legacy update_tftp() function invocation.
+
+
+Beagle Bone Black (BBB) setup
+-----------------------------
+
+1. Setup tftp env variables:
+   *  select desired eth device - 'ethact' variable ["ethact=cpsw"]
+      (use "bdinfo" to check current setting)
+   *  setup "serverip" and "ipaddr" variables
+   *  set "loadaddr" as a fixed buffer where incoming data is placed
+      ["loadaddr=0x81000000"]
+
+#########
+# BONUS #
+#########
+It is possible to use USB interface to emulate ETH connection by setting
+"ethact=usb_ether". In this way one can have very fast DFU transfer via USB.
+
+For 33MiB test image the transfer rate was 1MiB/s for ETH over USB and 200KiB/s
+for pure DFU USB transfer.
+
+2. Setup update_tftp variables:
+   *  set "updatefile" - the file name to be downloaded via TFTP (stored on
+      the HOST at e.g. /srv/tftp)
+
+3. If required, to update firmware on boot, put the "dfu tftp 0 mmc 0" in the
+    "preboot" env variable. Otherwise use this command from u-boot prompt.
+
+4. Inspect "dfu" specific variables:
+   * "dfu_alt_info" - information about available DFU entities
+   * "dfu_bufsiz"   - variable to set buffer size [in bytes] - when it is not
+                   possible to set large enough default buffer (8 MiB @ BBB)
+
+
+
+FIT image format for download
+-----------------------------
+
+To create FIT image for download one should follow the update tftp README file
+(./doc/README.update) with one notable difference:
+
+The original snippet of ./doc/uImage.FIT/update_uboot.its
+
+       images {
+               update@1 {
+                       description = "U-Boot binary";
+
+should look like
+
+       images {
+               u-boot.bin@1 {
+                       description = "U-Boot binary";
+
+where "u-boot.bin" is the DFU entity name to be stored.
+
+
+
+To do
+-----
+
+* Extend dfu-util command to support TFTP based transfers
+* Upload support (via TFTP)
index a7f4d9ebe5ddddb317f8ac50c85ee3839e65201b..eab124ce1d920e27aa0d7ef67e36d3cd8b7e6194 100644 (file)
@@ -93,3 +93,10 @@ Example .its files
   An example containing three updates. It can be used to update Linux kernel,
   ramdisk and FDT blob stored in Flash. The procedure for preparing the update
   file is similar to the example above.
+
+TFTP update via DFU
+-------------------
+
+- It is now possible to update firmware (bootloader, kernel, rootfs, etc.) via
+  TFTP by using DFU (Device Firmware Upgrade). More information can be found in
+  ./doc/README.dfutftp documentation entry.
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4fe22193b1480098cbb8001b5edc2cbfc11e442d 100644 (file)
@@ -0,0 +1,10 @@
+menu "DFU support"
+
+config DFU_TFTP
+       bool "DFU via TFTP"
+       help
+         This option allows performing update of DFU managed medium with data
+         send via TFTP boot.
+         Detailed description of this feature can be found at ./doc/README.dfutftp
+
+endmenu
index cebea30ac3c3a039a4c5e2c658016296c00daca0..61f2b71f918127f5b337a8afbb65c6f6e9c31a06 100644 (file)
@@ -10,3 +10,4 @@ obj-$(CONFIG_DFU_MMC) += dfu_mmc.o
 obj-$(CONFIG_DFU_NAND) += dfu_nand.o
 obj-$(CONFIG_DFU_RAM) += dfu_ram.o
 obj-$(CONFIG_DFU_SF) += dfu_sf.o
+obj-$(CONFIG_DFU_TFTP) += dfu_tftp.o
index 675162d927d8863a96952f407c0fced396e9c48c..6cf240de22d3ff41fe635c6330e907289521a77d 100644 (file)
@@ -76,7 +76,7 @@ int dfu_init_env_entities(char *interface, char *devstr)
 }
 
 static unsigned char *dfu_buf;
-static unsigned long dfu_buf_size = CONFIG_SYS_DFU_DATA_BUF_SIZE;
+static unsigned long dfu_buf_size;
 
 unsigned char *dfu_free_buf(void)
 {
@@ -568,3 +568,40 @@ int dfu_get_alt(char *name)
 
        return -ENODEV;
 }
+
+int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size)
+{
+       unsigned long dfu_buf_size, write, left = size;
+       int i, ret = 0;
+       void *dp = buf;
+
+       /*
+        * Here we must call dfu_get_buf(dfu) first to be sure that dfu_buf_size
+        * has been properly initialized - e.g. if "dfu_bufsiz" has been taken
+        * into account.
+        */
+       dfu_get_buf(dfu);
+       dfu_buf_size = dfu_get_buf_size();
+       debug("%s: dfu buf size: %lu\n", __func__, dfu_buf_size);
+
+       for (i = 0; left > 0; i++) {
+               write = min(dfu_buf_size, left);
+
+               debug("%s: dp: 0x%p left: %lu write: %lu\n", __func__,
+                     dp, left, write);
+               ret = dfu_write(dfu, dp, write, i);
+               if (ret) {
+                       error("DFU write failed\n");
+                       return ret;
+               }
+
+               dp += write;
+               left -= write;
+       }
+
+       ret = dfu_flush(dfu, NULL, 0, i);
+       if (ret)
+               error("DFU flush failed!");
+
+       return ret;
+}
diff --git a/drivers/dfu/dfu_tftp.c b/drivers/dfu/dfu_tftp.c
new file mode 100644 (file)
index 0000000..cd71708
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * (C) Copyright 2015
+ * Lukasz Majewski <l.majewski@majess.pl>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <dfu.h>
+
+int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
+                  char *interface, char *devstring)
+{
+       char *s, *sb;
+       int alt_setting_num, ret;
+       struct dfu_entity *dfu;
+
+       debug("%s: name: %s addr: 0x%x len: %d device: %s:%s\n", __func__,
+             dfu_entity_name, addr, len, interface, devstring);
+
+       ret = dfu_init_env_entities(interface, devstring);
+       if (ret)
+               goto done;
+
+       /*
+        * We need to copy name pointed by *dfu_entity_name since this text
+        * is the integral part of the FDT image.
+        * Any implicit modification (i.e. done by strsep()) will corrupt
+        * the FDT image and prevent other images to be stored.
+        */
+       s = strdup(dfu_entity_name);
+       sb = s;
+       if (!s) {
+               ret = -ENOMEM;
+               goto done;
+       }
+
+       strsep(&s, "@");
+       debug("%s: image name: %s strlen: %d\n", __func__, sb, strlen(sb));
+
+       alt_setting_num = dfu_get_alt(sb);
+       free(sb);
+       if (alt_setting_num < 0) {
+               error("Alt setting [%d] to write not found!",
+                     alt_setting_num);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       dfu = dfu_get_entity(alt_setting_num);
+       if (!dfu) {
+               error("DFU entity for alt: %d not found!", alt_setting_num);
+               ret = -ENODEV;
+               goto done;
+       }
+
+       ret = dfu_write_from_mem_addr(dfu, (void *)addr, len);
+
+done:
+       dfu_free_entities();
+
+       return ret;
+}
index 6346370cd67a863ebf8222fc3380a5641cb3e6db..06139ee04d2123f15d44a7613094e168962acb95 100644 (file)
@@ -123,6 +123,9 @@ static int process_rqt_cmd(const struct rqt_box *rqt)
                send_rsp(rsp);
                g_dnl_unregister();
                dfu_free_entities();
+#ifdef CONFIG_THOR_RESET_OFF
+               return RESET_DONE;
+#endif
                run_command("reset", 0);
                break;
        case RQT_CMD_POWEROFF:
@@ -728,6 +731,10 @@ int thor_handle(void)
 
                if (ret > 0) {
                        ret = process_data();
+#ifdef CONFIG_THOR_RESET_OFF
+                       if (ret == RESET_DONE)
+                               break;
+#endif
                        if (ret < 0)
                                return ret;
                } else {
@@ -768,7 +775,7 @@ static int thor_func_bind(struct usb_configuration *c, struct usb_function *f)
                goto fail;
        }
        dev->req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE,
-                                gadget->ep0->maxpacket);
+                                THOR_PACKET_SIZE);
        if (!dev->req->buf) {
                status = -ENOMEM;
                goto fail;
index 833a9d24ae7e632ba18173738491b5c6f65a1650..83412851dd17f6100f7c2eda67b0e30e8b69958d 100644 (file)
@@ -121,4 +121,7 @@ struct f_thor {
 #define F_NAME_BUF_SIZE 32
 #define THOR_PACKET_SIZE SZ_1M      /* 1 MiB */
 #define THOR_STORE_UNIT_SIZE SZ_32M /* 32 MiB */
+#ifdef CONFIG_THOR_RESET_OFF
+#define RESET_DONE 0xFFFFFFFF
+#endif
 #endif /* _USB_THOR_H_ */
index 3a0d32ee2ba1f0e3c9d49500e4570103e0f70487..88b670b7f8a76511fdc7c127e685b4c99b004270 100644 (file)
@@ -1645,8 +1645,10 @@ int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
        ctrl->hcor = hcor;
        ctrl->priv = ctrl;
 
-       if (init == USB_INIT_DEVICE)
+       ctrl->init = init;
+       if (ctrl->init == USB_INIT_DEVICE)
                goto done;
+
        ret = ehci_reset(ctrl);
        if (ret)
                goto err;
@@ -1666,6 +1668,9 @@ int ehci_deregister(struct udevice *dev)
 {
        struct ehci_ctrl *ctrl = dev_get_priv(dev);
 
+       if (ctrl->init == USB_INIT_DEVICE)
+               return 0;
+
        ehci_shutdown(ctrl);
 
        return 0;
index 3379c293c4dfafa310c2f933eba0bce6d846a000..b41c04a8b30a182a2370c066aca32e4e2d3280a3 100644 (file)
@@ -242,6 +242,7 @@ struct ehci_ops {
 };
 
 struct ehci_ctrl {
+       enum usb_init_type init;
        struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
        struct ehci_hcor *hcor;
        int rootdev;
index b7c5716eae435e2a73882dd1be659e33fc117de2..7b48875d63861ab9b971f3a8b7f888d462aa69c2 100644 (file)
 #define CONFIG_G_DNL_PRODUCT_NUM       0x0d02  /* nexus one */
 #define CONFIG_G_DNL_MANUFACTURER      "Broadcom Corporation"
 
+/* Fastboot and USB OTG */
+#define CONFIG_USB_FUNCTION_FASTBOOT
+#define CONFIG_CMD_FASTBOOT
+#define CONFIG_FASTBOOT_FLASH
+#define CONFIG_FASTBOOT_FLASH_MMC_DEV  0
+#define CONFIG_SYS_CACHELINE_SIZE      64
+#define CONFIG_USB_FASTBOOT_BUF_SIZE   (CONFIG_SYS_SDRAM_SIZE - SZ_1M)
+#define CONFIG_USB_FASTBOOT_BUF_ADDR   CONFIG_SYS_SDRAM_BASE
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW    0
+#define CONFIG_USB_GADGET_S3C_UDC_OTG
+#define CONFIG_USB_GADGET_BCM_UDC_OTG_PHY
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_USBID_ADDR              0x34052c46
+#define CONFIG_G_DNL_VENDOR_NUM                0x18d1  /* google */
+#define CONFIG_G_DNL_PRODUCT_NUM       0x0d02  /* nexus one */
+#define CONFIG_G_DNL_MANUFACTURER      "Broadcom Corporation"
+
 #endif /* __BCM28155_AP_H */
index 7d31abdf337dfc3c6ae2c8e3eaa7024dd9e61e14..6118dc27b95631e141408c7e93c6fcf294dc719a 100644 (file)
@@ -162,6 +162,21 @@ bool dfu_usb_get_reset(void);
 int dfu_read(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_write(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
 int dfu_flush(struct dfu_entity *de, void *buf, int size, int blk_seq_num);
+
+/**
+ * dfu_write_from_mem_addr - write data from memory to DFU managed medium
+ *
+ * This function adds support for writing data starting from fixed memory
+ * address (like $loadaddr) to dfu managed medium (e.g. NAND, MMC, file system)
+ *
+ * @param dfu - dfu entity to which we want to store data
+ * @param buf - fixed memory addres from where data starts
+ * @param size - number of bytes to write
+ *
+ * @return - 0 on success, other value on failure
+ */
+int dfu_write_from_mem_addr(struct dfu_entity *dfu, void *buf, int size);
+
 /* Device specific */
 #ifdef CONFIG_DFU_MMC
 extern int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *devstr, char *s);
@@ -207,5 +222,31 @@ static inline int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr,
 }
 #endif
 
+/**
+ * dfu_tftp_write - Write TFTP data to DFU medium
+ *
+ * This function is storing data received via TFTP on DFU supported medium.
+ *
+ * @param dfu_entity_name - name of DFU entity to write
+ * @param addr - address of data buffer to write
+ * @param len - number of bytes
+ * @param interface - destination DFU medium (e.g. "mmc")
+ * @param devstring - instance number of destination DFU medium (e.g. "1")
+ *
+ * @return 0 on success, otherwise error code
+ */
+#ifdef CONFIG_DFU_TFTP
+int dfu_tftp_write(char *dfu_entity_name, unsigned int addr, unsigned int len,
+                  char *interface, char *devstring);
+#else
+static inline int dfu_tftp_write(char *dfu_entity_name, unsigned int addr,
+                                unsigned int len, char *interface,
+                                char *devstring)
+{
+       puts("TFTP write support for DFU not available!\n");
+       return -ENOSYS;
+}
+#endif
+
 int dfu_add(struct usb_configuration *c);
 #endif /* __DFU_ENTITY_H_ */
index d09bec9de1560e8c2443269fb2045f95ea84e7f7..f1671e38deaf745224901ec9d252cccf62b179bd 100644 (file)
@@ -813,8 +813,18 @@ void copy_filename(char *dst, const char *src, int size);
 /* get a random source port */
 unsigned int random_port(void);
 
-/* Update U-Boot over TFTP */
-int update_tftp(ulong addr);
+/**
+ * update_tftp - Update firmware over TFTP (via DFU)
+ *
+ * This function updates board's firmware via TFTP
+ *
+ * @param addr - memory address where data is stored
+ * @param interface - the DFU medium name - e.g. "mmc"
+ * @param devstring - the DFU medium number - e.g. "1"
+ *
+ * @return - 0 on success, other value on failure
+ */
+int update_tftp(ulong addr, char *interface, char *devstring);
 
 /**********************************************************************/
 
diff --git a/include/net/tftp.h b/include/net/tftp.h
new file mode 100644 (file)
index 0000000..c411c9b
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ *     LiMon - BOOTP/TFTP.
+ *
+ *     Copyright 1994, 1995, 2000 Neil Russell.
+ *     Copyright 2011 Comelit Group SpA
+ *                    Luca Ceresoli <luca.ceresoli@comelit.it>
+ *     (See License)
+ */
+
+#ifndef __TFTP_H__
+#define __TFTP_H__
+
+/**********************************************************************/
+/*
+ *     Global functions and variables.
+ */
+
+/* tftp.c */
+void tftp_start(enum proto_t protocol);        /* Begin TFTP get/put */
+
+#ifdef CONFIG_CMD_TFTPSRV
+void tftp_start_server(void);  /* Wait for incoming TFTP put */
+#endif
+
+extern ulong tftp_timeout_ms;
+extern int tftp_timeout_count_max;
+
+/**********************************************************************/
+
+#endif /* __TFTP_H__ */
index 43466af2f39293f415b9c473e3da060a0e99766d..b2f8ad4ded932ddfdb2aefc86f803e2d4f0d894f 100644 (file)
@@ -11,8 +11,8 @@
 #include <common.h>
 #include <command.h>
 #include <net.h>
+#include <net/tftp.h>
 #include "bootp.h"
-#include "tftp.h"
 #include "nfs.h"
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
index 2a6efd85eae2179c97a0f798e0ec881a3d66a3b8..a115ce28927216532179bdcc842d22025e0ee092 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -86,6 +86,7 @@
 #include <environment.h>
 #include <errno.h>
 #include <net.h>
+#include <net/tftp.h>
 #if defined(CONFIG_STATUS_LED)
 #include <miiphy.h>
 #include <status_led.h>
 #if defined(CONFIG_CMD_SNTP)
 #include "sntp.h"
 #endif
-#include "tftp.h"
 
 DECLARE_GLOBAL_DATA_PTR;
 
index 4ce2f37a8a69c2b8ad70e3ea5e0f2605bf589bbc..1fa11b690d218fbda9fd80d26d99746acae10bf9 100644 (file)
@@ -8,10 +8,10 @@
 #include <common.h>
 #include <command.h>
 #include <net.h>
+#include <net/tftp.h>
 #include "nfs.h"
 #include "bootp.h"
 #include "rarp.h"
-#include "tftp.h"
 
 #define TIMEOUT 5000UL /* Milliseconds before trying BOOTP again */
 #ifndef        CONFIG_NET_RETRY_COUNT
index 18ce84c20214ccec75036d135ed0da246e485c5b..181f0f363e70d7ad45044910d1216def34e412a7 100644 (file)
@@ -10,7 +10,7 @@
 #include <command.h>
 #include <mapmem.h>
 #include <net.h>
-#include "tftp.h"
+#include <net/tftp.h>
 #include "bootp.h"
 #ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
 #include <flash.h>
diff --git a/net/tftp.h b/net/tftp.h
deleted file mode 100644 (file)
index c411c9b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *     LiMon - BOOTP/TFTP.
- *
- *     Copyright 1994, 1995, 2000 Neil Russell.
- *     Copyright 2011 Comelit Group SpA
- *                    Luca Ceresoli <luca.ceresoli@comelit.it>
- *     (See License)
- */
-
-#ifndef __TFTP_H__
-#define __TFTP_H__
-
-/**********************************************************************/
-/*
- *     Global functions and variables.
- */
-
-/* tftp.c */
-void tftp_start(enum proto_t protocol);        /* Begin TFTP get/put */
-
-#ifdef CONFIG_CMD_TFTPSRV
-void tftp_start_server(void);  /* Wait for incoming TFTP put */
-#endif
-
-extern ulong tftp_timeout_ms;
-extern int tftp_timeout_count_max;
-
-/**********************************************************************/
-
-#endif /* __TFTP_H__ */
index 5176aba632cedc96f364e8ac47ac8db04d0edaea..408d5594219a4f3ccd062f70f5c3e3b09bd4b193 100644 (file)
@@ -26,12 +26,19 @@ Example usage:
    setenv dfu_alt_info dfu_test.bin fat 0 6\;dfudummy.bin fat 0 6
    dfu 0 mmc 0
 2. On the host:
-   test/dfu/dfu_gadget_test.sh X Y  [test file name]
+   test/dfu/dfu_gadget_test.sh X Y [test file name] [usb device vendor:product]
    e.g. test/dfu/dfu_gadget_test.sh 0 1
    or
    e.g. test/dfu/dfu_gadget_test.sh 0 1 ./dat_960.img
+   or
+   e.g. test/dfu/dfu_gadget_test.sh 0 1 0451:d022
+   or
+   e.g. test/dfu/dfu_gadget_test.sh 0 1 ./dat_960.img 0451:d022
 
 ... where X and Y are dfu_test.bin's and dfudummy.bin's alt setting numbers.
 They can be obtained from dfu-util -l or $dfu_alt_info.
 It is also possible to pass optional [test file name] to force the script to
 test one particular file.
+If many DFU devices are connected, it may be useful to filter on USB
+vendor/product ID (0451:d022).
+One can get them by running "lsusb" command on a host PC.
index 2f5b7db58d41f20cab39aabec835d00414ef0a68..9c7942257b44f76a7892fcd264a1a559b659b438 100755 (executable)
@@ -45,18 +45,18 @@ dfu_test_file () {
     printf "$COLOUR_GREEN ========================================================================================= $COLOUR_DEFAULT\n"
     printf "File:$COLOUR_GREEN %s $COLOUR_DEFAULT\n" $1
 
-    dfu-util -D $1 -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
+    dfu-util $USB_DEV -D $1 -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
 
     echo -n "TX: "
     calculate_md5sum $1
 
     MD5_TX=$MD5SUM
 
-    dfu-util -D ${DIR}/dfudummy.bin -a $TARGET_ALT_SETTING_B >> $LOG_FILE 2>&1 || die $?
+    dfu-util $USB_DEV -D ${DIR}/dfudummy.bin -a $TARGET_ALT_SETTING_B >> $LOG_FILE 2>&1 || die $?
 
     N_FILE=$DIR$RCV_DIR${1:2}"_rcv"
 
-    dfu-util -U $N_FILE -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
+    dfu-util $USB_DEV -U $N_FILE -a $TARGET_ALT_SETTING >> $LOG_FILE 2>&1 || die $?
 
     echo -n "RX: "
     calculate_md5sum $N_FILE
@@ -89,13 +89,17 @@ fi
 TARGET_ALT_SETTING=$1
 TARGET_ALT_SETTING_B=$2
 
-if [ -n "$3" ]
+file=$3
+[[ $3 == *':'* ]] && USB_DEV="-d $3" && file=""
+[ $# -eq 4 ] && USB_DEV="-d $4"
+
+if [ -n "$file" ]
 then
-       dfu_test_file $3
+       dfu_test_file $file
 else
-       for file in $DIR*.$SUFFIX
+       for f in $DIR*.$SUFFIX
        do
-           dfu_test_file $file
+           dfu_test_file $f
        done
 fi