summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-omap2/boot-common.c10
-rw-r--r--arch/arm/mach-omap2/utils.c4
-rw-r--r--arch/arm/mach-rockchip/rk3128-board.c4
-rw-r--r--arch/arm/mach-rockchip/rk322x-board.c4
-rw-r--r--board/amazon/kc1/kc1.c2
-rw-r--r--board/lg/sniper/sniper.c2
-rw-r--r--board/ti/am57xx/board.c10
-rw-r--r--board/ti/common/Kconfig1
-rw-r--r--board/ti/dra7xx/evm.c10
-rw-r--r--cmd/Kconfig22
-rw-r--r--cmd/fastboot.c91
-rw-r--r--cmd/mmc.c14
-rw-r--r--common/Makefile14
-rw-r--r--configs/A13-OLinuXino_defconfig1
-rw-r--r--configs/A20-OLinuXino-Lime2-eMMC_defconfig1
-rw-r--r--configs/A20-OLinuXino-Lime2_defconfig1
-rw-r--r--configs/A20-Olimex-SOM204-EVB-eMMC_defconfig1
-rw-r--r--configs/A20-Olimex-SOM204-EVB_defconfig1
-rw-r--r--configs/Bananapi_m2m_defconfig1
-rw-r--r--configs/Cubietruck_defconfig1
-rw-r--r--configs/Sinlinx_SinA33_defconfig1
-rw-r--r--configs/am335x_boneblack_defconfig7
-rw-r--r--configs/am335x_boneblack_vboot_defconfig2
-rw-r--r--configs/am335x_evm_defconfig2
-rw-r--r--configs/am335x_evm_nor_defconfig2
-rw-r--r--configs/am335x_evm_norboot_defconfig2
-rw-r--r--configs/am335x_evm_spiboot_defconfig2
-rw-r--r--configs/am335x_evm_usbspl_defconfig2
-rw-r--r--configs/am57xx_evm_defconfig13
-rw-r--r--configs/am57xx_hs_evm_defconfig13
-rw-r--r--configs/bcm23550_w1d_defconfig2
-rw-r--r--configs/bcm28155_ap_defconfig2
-rw-r--r--configs/birdland_bav335a_defconfig2
-rw-r--r--configs/birdland_bav335b_defconfig2
-rw-r--r--configs/cgtqmx6eval_defconfig2
-rw-r--r--configs/chromebit_mickey_defconfig5
-rw-r--r--configs/chromebook_jerry_defconfig5
-rw-r--r--configs/chromebook_minnie_defconfig5
-rw-r--r--configs/dra7xx_evm_defconfig11
-rw-r--r--configs/dra7xx_hs_evm_defconfig11
-rw-r--r--configs/evb-rk3036_defconfig5
-rw-r--r--configs/evb-rk3128_defconfig9
-rw-r--r--configs/evb-rk3229_defconfig5
-rw-r--r--configs/evb-rk3288_defconfig5
-rw-r--r--configs/evb-rk3328_defconfig7
-rw-r--r--configs/fennec-rk3288_defconfig5
-rw-r--r--configs/firefly-rk3288_defconfig5
-rw-r--r--configs/imx6dl_mamoj_defconfig2
-rw-r--r--configs/kc1_defconfig2
-rw-r--r--configs/kylin-rk3036_defconfig5
-rw-r--r--configs/miqi-rk3288_defconfig5
-rw-r--r--configs/mx6qsabrelite_defconfig2
-rw-r--r--configs/mx6sabresd_defconfig2
-rw-r--r--configs/nitrogen6dl2g_defconfig2
-rw-r--r--configs/nitrogen6dl_defconfig2
-rw-r--r--configs/nitrogen6q2g_defconfig2
-rw-r--r--configs/nitrogen6q_defconfig2
-rw-r--r--configs/nitrogen6s1g_defconfig2
-rw-r--r--configs/nitrogen6s_defconfig2
-rw-r--r--configs/omap3_beagle_defconfig2
-rw-r--r--configs/omap3_evm_defconfig2
-rw-r--r--configs/omap3_logic_defconfig2
-rw-r--r--configs/parrot_r16_defconfig1
-rw-r--r--configs/phycore-rk3288_defconfig5
-rw-r--r--configs/popmetal-rk3288_defconfig5
-rw-r--r--configs/rock2_defconfig5
-rw-r--r--configs/sniper_defconfig2
-rw-r--r--configs/stih410-b2260_defconfig11
-rw-r--r--configs/tbs_a711_defconfig1
-rw-r--r--configs/tinker-rk3288_defconfig5
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig7
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig2
-rw-r--r--configs/xilinx_zynqmp_zcu102_rev1_0_defconfig7
-rw-r--r--configs/xilinx_zynqmp_zcu102_revA_defconfig7
-rw-r--r--configs/xilinx_zynqmp_zcu102_revB_defconfig7
-rw-r--r--configs/xilinx_zynqmp_zcu106_revA_defconfig7
-rw-r--r--doc/README.android-fastboot240
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/fastboot/Kconfig (renamed from cmd/fastboot/Kconfig)63
-rw-r--r--drivers/fastboot/Makefile7
-rw-r--r--drivers/fastboot/fb_command.c335
-rw-r--r--drivers/fastboot/fb_common.c169
-rw-r--r--drivers/fastboot/fb_getvar.c230
-rw-r--r--drivers/fastboot/fb_mmc.c (renamed from common/fb_mmc.c)216
-rw-r--r--drivers/fastboot/fb_nand.c (renamed from common/fb_nand.c)69
-rw-r--r--drivers/usb/gadget/f_fastboot.c347
-rw-r--r--drivers/usb/gadget/f_thor.c65
-rw-r--r--drivers/usb/host/xhci-rcar.c5
-rw-r--r--drivers/usb/host/xhci-rockchip.c16
-rw-r--r--drivers/usb/host/xhci.c14
-rw-r--r--fs/fs.c13
-rw-r--r--include/fastboot-internal.h36
-rw-r--r--include/fastboot.h137
-rw-r--r--include/fb_mmc.h35
-rw-r--r--include/fb_nand.h37
-rw-r--r--include/fs.h10
-rw-r--r--include/image-sparse.h4
-rw-r--r--include/net.h2
-rw-r--r--include/net/fastboot.h21
-rw-r--r--lib/Kconfig11
-rw-r--r--lib/Makefile1
-rw-r--r--lib/image-sparse.c (renamed from common/image-sparse.c)38
-rw-r--r--net/Makefile1
-rw-r--r--net/fastboot.c317
-rw-r--r--net/net.c7
-rw-r--r--scripts/config_whitelist.txt2
108 files changed, 2141 insertions, 749 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 582e84cf40..dde422bc5d 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1258,9 +1258,7 @@ config ARCH_ROCKCHIP
select DM_REGULATOR
select ENABLE_ARM_SOC_BOOT0_HOOK
select SPI
- imply CMD_FASTBOOT
imply DISTRO_DEFAULTS
- imply FASTBOOT
imply FAT_WRITE
imply USB_FUNCTION_FASTBOOT
imply SPL_SYSRESET
diff --git a/arch/arm/mach-omap2/boot-common.c b/arch/arm/mach-omap2/boot-common.c
index 0e9fd03fef..d4a1e2e42c 100644
--- a/arch/arm/mach-omap2/boot-common.c
+++ b/arch/arm/mach-omap2/boot-common.c
@@ -236,13 +236,3 @@ void arch_preboot_os(void)
ahci_reset((void __iomem *)DWC_AHSATA_BASE);
}
#endif
-
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
-int fb_set_reboot_flag(void)
-{
- printf("Setting reboot to fastboot flag ...\n");
- env_set("dofastboot", "1");
- env_save();
- return 0;
-}
-#endif
diff --git a/arch/arm/mach-omap2/utils.c b/arch/arm/mach-omap2/utils.c
index dc7b37f164..edf5edcb68 100644
--- a/arch/arm/mach-omap2/utils.c
+++ b/arch/arm/mach-omap2/utils.c
@@ -85,7 +85,7 @@ static void omap_set_fastboot_board_rev(void)
env_set("fastboot.board_rev", board_rev);
}
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
+#ifdef CONFIG_FASTBOOT_FLASH_MMC
static u32 omap_mmc_get_part_size(const char *part)
{
int res;
@@ -128,7 +128,7 @@ static void omap_set_fastboot_userdata_size(void)
static inline void omap_set_fastboot_userdata_size(void)
{
}
-#endif /* CONFIG_FASTBOOT_FLASH_MMC_DEV */
+#endif /* CONFIG_FASTBOOT_FLASH_MMC */
void omap_set_fastboot_vars(void)
{
omap_set_fastboot_cpu();
diff --git a/arch/arm/mach-rockchip/rk3128-board.c b/arch/arm/mach-rockchip/rk3128-board.c
index 48cd8ba81e..7fd667a0b8 100644
--- a/arch/arm/mach-rockchip/rk3128-board.c
+++ b/arch/arm/mach-rockchip/rk3128-board.c
@@ -111,8 +111,8 @@ int board_usb_cleanup(int index, enum usb_init_type init)
}
#endif
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
-int fb_set_reboot_flag(void)
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(void)
{
struct rk3128_grf *grf;
diff --git a/arch/arm/mach-rockchip/rk322x-board.c b/arch/arm/mach-rockchip/rk322x-board.c
index 99a60c4e2e..7366d45ab6 100644
--- a/arch/arm/mach-rockchip/rk322x-board.c
+++ b/arch/arm/mach-rockchip/rk322x-board.c
@@ -139,8 +139,8 @@ int board_usb_cleanup(int index, enum usb_init_type init)
}
#endif
-#if defined(CONFIG_USB_FUNCTION_FASTBOOT)
-int fb_set_reboot_flag(void)
+#if CONFIG_IS_ENABLED(FASTBOOT)
+int fastboot_set_reboot_flag(void)
{
struct rk322x_grf *grf;
diff --git a/board/amazon/kc1/kc1.c b/board/amazon/kc1/kc1.c
index d9ca18363c..031fd11092 100644
--- a/board/amazon/kc1/kc1.c
+++ b/board/amazon/kc1/kc1.c
@@ -161,7 +161,7 @@ void get_board_serial(struct tag_serialnr *serialnr)
omap_die_id_get_board_serial(serialnr);
}
-int fb_set_reboot_flag(void)
+int fastboot_set_reboot_flag(void)
{
return omap_reboot_mode_store("b");
}
diff --git a/board/lg/sniper/sniper.c b/board/lg/sniper/sniper.c
index 34a7a11f05..a7de4c2167 100644
--- a/board/lg/sniper/sniper.c
+++ b/board/lg/sniper/sniper.c
@@ -173,7 +173,7 @@ void reset_misc(void)
omap_reboot_mode_store(reboot_mode);
}
-int fb_set_reboot_flag(void)
+int fastboot_set_reboot_flag(void)
{
return omap_reboot_mode_store("b");
}
diff --git a/board/ti/am57xx/board.c b/board/ti/am57xx/board.c
index fd9d20779b..177a3246c3 100644
--- a/board/ti/am57xx/board.c
+++ b/board/ti/am57xx/board.c
@@ -1178,5 +1178,15 @@ void board_tee_image_process(ulong tee_image, size_t tee_size)
secure_tee_install((u32)tee_image);
}
+#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
+int fastboot_set_reboot_flag(void)
+{
+ printf("Setting reboot to fastboot flag ...\n");
+ env_set("dofastboot", "1");
+ env_save();
+ return 0;
+}
+#endif
+
U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, board_tee_image_process);
#endif
diff --git a/board/ti/common/Kconfig b/board/ti/common/Kconfig
index c21eb8c2d2..b1956b8100 100644
--- a/board/ti/common/Kconfig
+++ b/board/ti/common/Kconfig
@@ -25,7 +25,6 @@ config TI_COMMON_CMD_OPTIONS
imply CMD_EXT2
imply CMD_EXT4
imply CMD_EXT4_WRITE
- imply CMD_FASTBOOT if FASTBOOT
imply CMD_FAT
imply FAT_WRITE if CMD_FAT
imply CMD_FS_GENERIC
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 6918f4de01..bbe54450ae 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -1188,5 +1188,15 @@ void board_tee_image_process(ulong tee_image, size_t tee_size)
secure_tee_install((u32)tee_image);
}
+#if CONFIG_IS_ENABLED(FASTBOOT) && !CONFIG_IS_ENABLED(ENV_IS_NOWHERE)
+int fastboot_set_reboot_flag(void)
+{
+ printf("Setting reboot to fastboot flag ...\n");
+ env_set("dofastboot", "1");
+ env_save();
+ return 0;
+}
+#endif
+
U_BOOT_FIT_LOADABLE_HANDLER(IH_TYPE_TEE, board_tee_image_process);
#endif
diff --git a/cmd/Kconfig b/cmd/Kconfig
index 1a1ca60237..48a2a5720c 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -137,8 +137,6 @@ config AUTOBOOT_STOP_STR_SHA256
endmenu
-source "cmd/fastboot/Kconfig"
-
config BUILD_BIN2C
bool
@@ -650,6 +648,18 @@ config CMD_DM
can be useful to see the state of driver model for debugging or
interest.
+config CMD_FASTBOOT
+ bool "fastboot - Android fastboot support"
+ depends on FASTBOOT
+ help
+ This enables the command "fastboot" which enables the Android
+ fastboot mode for the platform. Fastboot is a protocol for
+ downloading images, flashing and device control used on
+ Android devices. Fastboot requires either the network stack
+ enabled or support for acting as a USB device.
+
+ See doc/README.android-fastboot for more information.
+
config CMD_FDC
bool "fdcboot - Boot from floppy device"
help
@@ -823,6 +833,14 @@ config CMD_MMC_RPMB
Enable the commands for reading, writing and programming the
key for the Replay Protection Memory Block partition in eMMC.
+config CMD_MMC_SWRITE
+ bool "mmc swrite"
+ depends on CMD_MMC && MMC_WRITE
+ select IMAGE_SPARSE
+ help
+ Enable support for the "mmc swrite" command to write Android sparse
+ images to eMMC.
+
config CMD_NAND
bool "nand"
default y if NAND_SUNXI
diff --git a/cmd/fastboot.c b/cmd/fastboot.c
index a5ec5f46f6..557257aef8 100644
--- a/cmd/fastboot.c
+++ b/cmd/fastboot.c
@@ -10,10 +10,32 @@
#include <command.h>
#include <console.h>
#include <g_dnl.h>
+#include <fastboot.h>
+#include <net.h>
#include <usb.h>
-static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+static int do_fastboot_udp(int argc, char *const argv[],
+ uintptr_t buf_addr, size_t buf_size)
{
+#if CONFIG_IS_ENABLED(UDP_FUNCTION_FASTBOOT)
+ int err = net_loop(FASTBOOT);
+
+ if (err < 0) {
+ printf("fastboot udp error: %d\n", err);
+ return CMD_RET_FAILURE;
+ }
+
+ return CMD_RET_SUCCESS;
+#else
+ pr_err("Fastboot UDP not enabled\n");
+ return CMD_RET_FAILURE;
+#endif
+}
+
+static int do_fastboot_usb(int argc, char *const argv[],
+ uintptr_t buf_addr, size_t buf_size)
+{
+#if CONFIG_IS_ENABLED(USB_FUNCTION_FASTBOOT)
int controller_index;
char *usb_controller;
int ret;
@@ -58,11 +80,70 @@ exit:
board_usb_cleanup(controller_index, USB_INIT_DEVICE);
return ret;
+#else
+ pr_err("Fastboot USB not enabled\n");
+ return CMD_RET_FAILURE;
+#endif
+}
+
+static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+ uintptr_t buf_addr = (uintptr_t)NULL;
+ size_t buf_size = 0;
+
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ while (argc > 1 && **(argv + 1) == '-') {
+ char *arg = *++argv;
+
+ --argc;
+ while (*++arg) {
+ switch (*arg) {
+ case 'l':
+ if (--argc <= 0)
+ return CMD_RET_USAGE;
+ buf_addr = simple_strtoul(*++argv, NULL, 16);
+ goto NXTARG;
+
+ case 's':
+ if (--argc <= 0)
+ return CMD_RET_USAGE;
+ buf_size = simple_strtoul(*++argv, NULL, 16);
+ goto NXTARG;
+
+ default:
+ return CMD_RET_USAGE;
+ }
+ }
+NXTARG:
+ ;
+ }
+
+ fastboot_init((void *)buf_addr, buf_size);
+
+ if (!strcmp(argv[1], "udp"))
+ return do_fastboot_udp(argc, argv, buf_addr, buf_size);
+
+ if (!strcmp(argv[1], "usb")) {
+ argv++;
+ argc--;
+ }
+
+ return do_fastboot_usb(argc, argv, buf_addr, buf_size);
}
+#ifdef CONFIG_SYS_LONGHELP
+static char fastboot_help_text[] =
+ "[-l addr] [-s size] usb <controller> | udp\n"
+ "\taddr - address of buffer used during data transfers ("
+ __stringify(CONFIG_FASTBOOT_BUF_ADDR) ")\n"
+ "\tsize - size of buffer used during data transfers ("
+ __stringify(CONFIG_FASTBOOT_BUF_SIZE) ")"
+ ;
+#endif
+
U_BOOT_CMD(
- fastboot, 2, 1, do_fastboot,
- "use USB Fastboot protocol",
- "<USB_controller>\n"
- " - run as a fastboot usb device"
+ fastboot, CONFIG_SYS_MAXARGS, 1, do_fastboot,
+ "run as a fastboot usb or udp device", fastboot_help_text
);
diff --git a/cmd/mmc.c b/cmd/mmc.c
index a3357eff8f..c2ee2d9c0a 100644
--- a/cmd/mmc.c
+++ b/cmd/mmc.c
@@ -308,8 +308,7 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
}
-#if CONFIG_IS_ENABLED(MMC_WRITE)
-#if defined(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
static lbaint_t mmc_sparse_write(struct sparse_storage *info, lbaint_t blk,
lbaint_t blkcnt, const void *buffer)
{
@@ -367,13 +366,14 @@ static int do_mmc_sparse_write(cmd_tbl_t *cmdtp, int flag,
sparse.mssg = NULL;
sprintf(dest, "0x" LBAF, sparse.start * sparse.blksz);
- if (write_sparse_image(&sparse, dest, addr))
+ if (write_sparse_image(&sparse, dest, addr, NULL))
return CMD_RET_FAILURE;
else
return CMD_RET_SUCCESS;
}
#endif
+#if CONFIG_IS_ENABLED(MMC_WRITE)
static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
int argc, char * const argv[])
{
@@ -868,11 +868,11 @@ static cmd_tbl_t cmd_mmc[] = {
U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
#if CONFIG_IS_ENABLED(MMC_WRITE)
U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
-#if defined(CONFIG_FASTBOOT_FLASH)
- U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
-#endif
U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
#endif
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
+ U_BOOT_CMD_MKENT(swrite, 3, 0, do_mmc_sparse_write, "", ""),
+#endif
U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
@@ -927,7 +927,7 @@ U_BOOT_CMD(
"info - display info of the current MMC device\n"
"mmc read addr blk# cnt\n"
"mmc write addr blk# cnt\n"
-#if defined(CONFIG_FASTBOOT_FLASH)
+#if CONFIG_IS_ENABLED(CMD_MMC_SWRITE)
"mmc swrite addr blk#\n"
#endif
"mmc erase blk# cnt\n"
diff --git a/common/Makefile b/common/Makefile
index d0681c7dd9..b3da72ebb2 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_CMD_BOOTI) += bootm.o bootm_os.o
obj-$(CONFIG_CMD_BEDBUG) += bedbug.o
obj-$(CONFIG_$(SPL_TPL_)OF_LIBFDT) += fdt_support.o
-
obj-$(CONFIG_MII) += miiphyutil.o
obj-$(CONFIG_CMD_MII) += miiphyutil.o
obj-$(CONFIG_PHYLIB) += miiphyutil.o
@@ -109,19 +108,6 @@ obj-$(CONFIG_IO_TRACE) += iotrace.o
obj-y += memsize.o
obj-y += stdio.o
-ifndef CONFIG_SPL_BUILD
-# This option is not just y/n - it can have a numeric value
-ifdef CONFIG_FASTBOOT_FLASH
-obj-y += image-sparse.o
-ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-obj-y += fb_mmc.o
-endif
-ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-obj-y += fb_nand.o
-endif
-endif
-endif
-
ifdef CONFIG_CMD_EEPROM_LAYOUT
obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
endif
diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig
index 8e160d7cc4..b8ec1e54db 100644
--- a/configs/A13-OLinuXino_defconfig
+++ b/configs/A13-OLinuXino_defconfig
@@ -22,6 +22,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_AXP_ALDO3_VOLT=3300
CONFIG_CONS_INDEX=2
CONFIG_USB_EHCI_HCD=y
diff --git a/configs/A20-OLinuXino-Lime2-eMMC_defconfig b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
index 9d043e856a..5657fc2594 100644
--- a/configs/A20-OLinuXino-Lime2-eMMC_defconfig
+++ b/configs/A20-OLinuXino-Lime2-eMMC_defconfig
@@ -20,6 +20,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SCSI_AHCI=y
CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_RGMII=y
CONFIG_SUN7I_GMAC=y
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index f2997c6fe5..134d1d3fef 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -19,6 +19,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SCSI_AHCI=y
CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_RGMII=y
CONFIG_SUN7I_GMAC=y
diff --git a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
index 847945b649..3bb8c4c7e6 100644
--- a/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB-eMMC_defconfig
@@ -18,6 +18,7 @@ CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SCSI_AHCI=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_PHY_ADDR=3
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/A20-Olimex-SOM204-EVB_defconfig b/configs/A20-Olimex-SOM204-EVB_defconfig
index e56f2c7110..cfb7ffa556 100644
--- a/configs/A20-Olimex-SOM204-EVB_defconfig
+++ b/configs/A20-Olimex-SOM204-EVB_defconfig
@@ -17,6 +17,7 @@ CONFIG_SPL_I2C_SUPPORT=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SCSI_AHCI=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_PHY_ADDR=3
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
diff --git a/configs/Bananapi_m2m_defconfig b/configs/Bananapi_m2m_defconfig
index 2032a4aef8..2316437c94 100644
--- a/configs/Bananapi_m2m_defconfig
+++ b/configs/Bananapi_m2m_defconfig
@@ -13,6 +13,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-r16-bananapi-m2m"
# CONFIG_CMD_FLASH is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_USB_FUNCTION_MASS_STORAGE=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index f0bb4c9d5c..601eb3ca0c 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -21,6 +21,7 @@ CONFIG_CMD_USB_MASS_STORAGE=y
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_SCSI_AHCI=y
CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_RGMII=y
CONFIG_SUN7I_GMAC=y
diff --git a/configs/Sinlinx_SinA33_defconfig b/configs/Sinlinx_SinA33_defconfig
index 9e6267200b..394534b8b5 100644
--- a/configs/Sinlinx_SinA33_defconfig
+++ b/configs/Sinlinx_SinA33_defconfig
@@ -18,6 +18,7 @@ CONFIG_CMD_DFU=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
CONFIG_DFU_RAM=y
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y
diff --git a/configs/am335x_boneblack_defconfig b/configs/am335x_boneblack_defconfig
index 5c01b20dff..31d2fe9cbf 100644
--- a/configs/am335x_boneblack_defconfig
+++ b/configs/am335x_boneblack_defconfig
@@ -16,9 +16,6 @@ CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
CONFIG_AUTOBOOT_DELAY_STR="d"
CONFIG_AUTOBOOT_STOP_STR=" "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_CMD_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
@@ -28,6 +25,10 @@ CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_DFU_TFTP=y
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_MMC_OMAP_HS=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_WINBOND=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index abbacdc77e..baaae36d28 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -19,7 +19,7 @@ CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n"
CONFIG_AUTOBOOT_DELAY_STR="d"
CONFIG_AUTOBOOT_STOP_STR=" "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_CMD_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 6732013b03..cc556d1c3d 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -13,7 +13,7 @@ CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_NAND_OFS=0x00080000
# CONFIG_CMD_FLASH is not set
diff --git a/configs/am335x_evm_nor_defconfig b/configs/am335x_evm_nor_defconfig
index bbde07fb1d..41a5c79604 100644
--- a/configs/am335x_evm_nor_defconfig
+++ b/configs/am335x_evm_nor_defconfig
@@ -12,7 +12,7 @@ CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_NAND_OFS=0x00080000
CONFIG_CMD_NAND=y
diff --git a/configs/am335x_evm_norboot_defconfig b/configs/am335x_evm_norboot_defconfig
index 3ddcf64942..75d0793f2d 100644
--- a/configs/am335x_evm_norboot_defconfig
+++ b/configs/am335x_evm_norboot_defconfig
@@ -12,7 +12,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_MTDPARTS=y
CONFIG_MTDIDS_DEFAULT="nor0=physmap-flash.0"
diff --git a/configs/am335x_evm_spiboot_defconfig b/configs/am335x_evm_spiboot_defconfig
index 10eb0fe1ee..b2678875ec 100644
--- a/configs/am335x_evm_spiboot_defconfig
+++ b/configs/am335x_evm_spiboot_defconfig
@@ -15,7 +15,7 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_MTDPARTS=y
diff --git a/configs/am335x_evm_usbspl_defconfig b/configs/am335x_evm_usbspl_defconfig
index dc9ac216c2..44012919a3 100644
--- a/configs/am335x_evm_usbspl_defconfig
+++ b/configs/am335x_evm_usbspl_defconfig
@@ -19,7 +19,7 @@ CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_USB_GADGET_SUPPORT=y
CONFIG_SPL_USB_ETHER=y
# CONFIG_SPL_YMODEM_SUPPORT is not set
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_NAND_OFS=0x00080000
# CONFIG_CMD_FLASH is not set
diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig
index 0e99268441..2d8e64e613 100644
--- a/configs/am57xx_evm_defconfig
+++ b/configs/am57xx_evm_defconfig
@@ -24,12 +24,6 @@ CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_USB_DEV=1
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_CMD_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
@@ -45,6 +39,13 @@ CONFIG_SCSI_AHCI=y
# CONFIG_BLK is not set
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_DM_MMC=y
diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig
index 165c2a40ba..3a73fdb2ca 100644
--- a/configs/am57xx_hs_evm_defconfig
+++ b/configs/am57xx_hs_evm_defconfig
@@ -29,12 +29,6 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_USB_DEV=1
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_OF_CONTROL=y
@@ -48,6 +42,13 @@ CONFIG_SCSI_AHCI=y
# CONFIG_BLK is not set
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_USB_DEV=1
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_DM_I2C=y
CONFIG_DM_MMC=y
diff --git a/configs/bcm23550_w1d_defconfig b/configs/bcm23550_w1d_defconfig
index 9a986ca9ae..de4fa60df7 100644
--- a/configs/bcm23550_w1d_defconfig
+++ b/configs/bcm23550_w1d_defconfig
@@ -7,7 +7,7 @@ CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x80000000
CONFIG_FASTBOOT_BUF_SIZE=0x1D000000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/bcm28155_ap_defconfig b/configs/bcm28155_ap_defconfig
index d26cde5b0e..4f7a58e362 100644
--- a/configs/bcm28155_ap_defconfig
+++ b/configs/bcm28155_ap_defconfig
@@ -8,7 +8,7 @@ CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_HUSH_PARSER=y
# CONFIG_AUTOBOOT is not set
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x80000000
CONFIG_FASTBOOT_BUF_SIZE=0x7FF00000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig
index 51b3e6b4e1..3efd5669a7 100644
--- a/configs/birdland_bav335a_defconfig
+++ b/configs/birdland_bav335a_defconfig
@@ -25,7 +25,7 @@ CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_POWER_SUPPORT=y
CONFIG_SPL_YMODEM_SUPPORT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_CMD_SPL=y
CONFIG_CMD_ASKENV=y
diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig
index 29b223a580..2f98116873 100644
--- a/configs/birdland_bav335b_defconfig
+++ b/configs/birdland_bav335b_defconfig
@@ -25,7 +25,7 @@ CONFIG_SPL_MUSB_NEW_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_POWER_SUPPORT=y
CONFIG_SPL_YMODEM_SUPPORT=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_CMD_SPL=y
CONFIG_CMD_ASKENV=y
diff --git a/configs/cgtqmx6eval_defconfig b/configs/cgtqmx6eval_defconfig
index d4204aa712..241e9582a5 100644
--- a/configs/cgtqmx6eval_defconfig
+++ b/configs/cgtqmx6eval_defconfig
@@ -24,7 +24,7 @@ CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="CGT-QMX6-Quad U-Boot > "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_DFU=y
diff --git a/configs/chromebit_mickey_defconfig b/configs/chromebit_mickey_defconfig
index d1728ef639..72ecdc69f6 100644
--- a/configs/chromebit_mickey_defconfig
+++ b/configs/chromebit_mickey_defconfig
@@ -16,8 +16,6 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -44,6 +42,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/chromebook_jerry_defconfig b/configs/chromebook_jerry_defconfig
index 43d93f4637..fb8400d06e 100644
--- a/configs/chromebook_jerry_defconfig
+++ b/configs/chromebook_jerry_defconfig
@@ -18,8 +18,6 @@ CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -46,6 +44,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/chromebook_minnie_defconfig b/configs/chromebook_minnie_defconfig
index 706809ca53..a8776c9adf 100644
--- a/configs/chromebook_minnie_defconfig
+++ b/configs/chromebook_minnie_defconfig
@@ -17,8 +17,6 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -45,6 +43,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_I2C_CROS_EC_TUNNEL=y
CONFIG_SYS_I2C_ROCKCHIP=y
diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig
index 9b81b0cc71..182f9a9ebf 100644
--- a/configs/dra7xx_evm_defconfig
+++ b/configs/dra7xx_evm_defconfig
@@ -25,11 +25,6 @@ CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_CMD_SPL=y
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
@@ -50,6 +45,12 @@ CONFIG_DWC_AHCI=y
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_DFU_SF=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_PCF8575_GPIO=y
CONFIG_DM_I2C=y
diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig
index 536946eb29..8584d41f1a 100644
--- a/configs/dra7xx_hs_evm_defconfig
+++ b/configs/dra7xx_hs_evm_defconfig
@@ -30,11 +30,6 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_SEPARATE_BSS=y
CONFIG_SPL_DMA_SUPPORT=y
CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x82000000
-CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_OF_CONTROL=y
@@ -50,6 +45,12 @@ CONFIG_DWC_AHCI=y
CONFIG_DFU_MMC=y
CONFIG_DFU_RAM=y
CONFIG_DFU_SF=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x82000000
+CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_DM_GPIO=y
CONFIG_PCF8575_GPIO=y
CONFIG_DM_I2C=y
diff --git a/configs/evb-rk3036_defconfig b/configs/evb-rk3036_defconfig
index 33775e8cdd..b9242e83e0 100644
--- a/configs/evb-rk3036_defconfig
+++ b/configs/evb-rk3036_defconfig
@@ -15,8 +15,6 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x0
CONFIG_DISPLAY_BOARDINFO_LATE=y
# CONFIG_SPL_FRAMEWORK is not set
CONFIG_SPL_STACK_R=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
@@ -31,6 +29,9 @@ CONFIG_SPL_PARTITION_UUIDS=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
diff --git a/configs/evb-rk3128_defconfig b/configs/evb-rk3128_defconfig
index 796d0ec92e..9c8252e95f 100644
--- a/configs/evb-rk3128_defconfig
+++ b/configs/evb-rk3128_defconfig
@@ -7,10 +7,6 @@ CONFIG_DEBUG_UART=y
CONFIG_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_FASTBOOT_BUF_ADDR=0x60800800
-CONFIG_FASTBOOT_BUF_SIZE=0x04000000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
@@ -20,6 +16,11 @@ CONFIG_CMD_TIME=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x60800800
+CONFIG_FASTBOOT_BUF_SIZE=0x04000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/evb-rk3229_defconfig b/configs/evb-rk3229_defconfig
index 710b0b4e1a..7298bf1963 100644
--- a/configs/evb-rk3229_defconfig
+++ b/configs/evb-rk3229_defconfig
@@ -14,8 +14,6 @@ CONFIG_DEBUG_UART=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x200
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
# CONFIG_CMD_SETEXPR is not set
@@ -30,6 +28,9 @@ CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig
index 7695277daf..a7beaa6728 100644
--- a/configs/evb-rk3288_defconfig
+++ b/configs/evb-rk3288_defconfig
@@ -14,8 +14,6 @@ CONFIG_SILENT_CONSOLE=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -41,6 +39,9 @@ CONFIG_SYSCON=y
CONFIG_SPL_SYSCON=y
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
diff --git a/configs/evb-rk3328_defconfig b/configs/evb-rk3328_defconfig
index 78ae24b56b..59bf9e5197 100644
--- a/configs/evb-rk3328_defconfig
+++ b/configs/evb-rk3328_defconfig
@@ -8,9 +8,6 @@ CONFIG_DEBUG_UART=y
CONFIG_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_DISPLAY_BOARDINFO_LATE=y
-CONFIG_FASTBOOT_BUF_ADDR=0x800800
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=1
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
@@ -23,6 +20,10 @@ CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_FASTBOOT_BUF_ADDR=0x800800
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=1
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/fennec-rk3288_defconfig b/configs/fennec-rk3288_defconfig
index efdd583cf6..dbd6be55e2 100644
--- a/configs/fennec-rk3288_defconfig
+++ b/configs/fennec-rk3288_defconfig
@@ -15,8 +15,6 @@ CONFIG_CONSOLE_MUX=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/firefly-rk3288_defconfig b/configs/firefly-rk3288_defconfig
index b252d27464..83b4968c4a 100644
--- a/configs/firefly-rk3288_defconfig
+++ b/configs/firefly-rk3288_defconfig
@@ -14,8 +14,6 @@ CONFIG_SILENT_CONSOLE=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_DM_KEYBOARD=y
diff --git a/configs/imx6dl_mamoj_defconfig b/configs/imx6dl_mamoj_defconfig
index 0001457f5d..40a128b8cb 100644
--- a/configs/imx6dl_mamoj_defconfig
+++ b/configs/imx6dl_mamoj_defconfig
@@ -9,7 +9,7 @@ CONFIG_DEFAULT_DEVICE_TREE="imx6dl-mamoj"
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/mach-imx/spl_sd.cfg"
CONFIG_BOOTDELAY=3
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_FASTBOOT_BUF_SIZE=0x10000000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/kc1_defconfig b/configs/kc1_defconfig
index 534d60484a..ce71e37011 100644
--- a/configs/kc1_defconfig
+++ b/configs/kc1_defconfig
@@ -12,7 +12,7 @@ CONFIG_SYS_CONSOLE_IS_IN_ENV=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2
CONFIG_SYS_PROMPT="kc1 # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_FASTBOOT_BUF_SIZE=0x2000000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/kylin-rk3036_defconfig b/configs/kylin-rk3036_defconfig
index ca53005ecb..373764aaf1 100644
--- a/configs/kylin-rk3036_defconfig
+++ b/configs/kylin-rk3036_defconfig
@@ -14,8 +14,6 @@ CONFIG_SPL_SYS_MALLOC_F_LEN=0x0
CONFIG_DISPLAY_BOARDINFO_LATE=y
# CONFIG_SPL_FRAMEWORK is not set
CONFIG_SPL_STACK_R=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
@@ -31,6 +29,9 @@ CONFIG_ENV_IS_IN_MMC=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_LED=y
diff --git a/configs/miqi-rk3288_defconfig b/configs/miqi-rk3288_defconfig
index f44537c88f..5bfcb0c90b 100644
--- a/configs/miqi-rk3288_defconfig
+++ b/configs/miqi-rk3288_defconfig
@@ -14,8 +14,6 @@ CONFIG_SILENT_CONSOLE=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/mx6qsabrelite_defconfig b/configs/mx6qsabrelite_defconfig
index 966e823b40..a4740d49cf 100644
--- a/configs/mx6qsabrelite_defconfig
+++ b/configs/mx6qsabrelite_defconfig
@@ -9,7 +9,7 @@ CONFIG_BOOTDELAY=3
# CONFIG_USE_BOOTCOMMAND is not set
CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_ALT_MEMTEST=y
diff --git a/configs/mx6sabresd_defconfig b/configs/mx6sabresd_defconfig
index ca37d8bef8..5c8e9de081 100644
--- a/configs/mx6sabresd_defconfig
+++ b/configs/mx6sabresd_defconfig
@@ -22,7 +22,7 @@ CONFIG_SPL_USB_HOST_SUPPORT=y
CONFIG_SPL_USB_GADGET_SUPPORT=y
CONFIG_SPL_USB_SDP_SUPPORT=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_FASTBOOT_BUF_SIZE=0x10000000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/nitrogen6dl2g_defconfig b/configs/nitrogen6dl2g_defconfig
index 6ef4226db9..cfb2ed8889 100644
--- a/configs/nitrogen6dl2g_defconfig
+++ b/configs/nitrogen6dl2g_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6dl_defconfig b/configs/nitrogen6dl_defconfig
index b9784a2d23..9cb7ac22d5 100644
--- a/configs/nitrogen6dl_defconfig
+++ b/configs/nitrogen6dl_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6q2g_defconfig b/configs/nitrogen6q2g_defconfig
index 61688ba49e..e31521a060 100644
--- a/configs/nitrogen6q2g_defconfig
+++ b/configs/nitrogen6q2g_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6q_defconfig b/configs/nitrogen6q_defconfig
index cfee7ba889..85c352c6f0 100644
--- a/configs/nitrogen6q_defconfig
+++ b/configs/nitrogen6q_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6s1g_defconfig b/configs/nitrogen6s1g_defconfig
index 0f29a56c46..1f3732019d 100644
--- a/configs/nitrogen6s1g_defconfig
+++ b/configs/nitrogen6s1g_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/nitrogen6s_defconfig b/configs/nitrogen6s_defconfig
index 7ad1584af2..0696f09d5e 100644
--- a/configs/nitrogen6s_defconfig
+++ b/configs/nitrogen6s_defconfig
@@ -9,7 +9,7 @@ CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
CONFIG_SUPPORT_RAW_INITRD=y
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x12000000
CONFIG_CMD_BOOTZ=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig
index 7b81b039c9..05dc73755f 100644
--- a/configs/omap3_beagle_defconfig
+++ b/configs/omap3_beagle_defconfig
@@ -13,7 +13,7 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="BeagleBoard # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_NAND_OFS=0x280000
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index 20795c3170..52285cc165 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -12,7 +12,7 @@ CONFIG_VERSION_VARIABLE=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="OMAP3_EVM # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_CMD_SPL=y
CONFIG_CMD_SPL_NAND_OFS=0x280000
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index 5a31e46dba..953980c95c 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -13,7 +13,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_MTD_SUPPORT=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="OMAP Logic # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
# CONFIG_CMD_IMI is not set
CONFIG_CMD_SPL=y
diff --git a/configs/parrot_r16_defconfig b/configs/parrot_r16_defconfig
index 991e9b99aa..553a8d6572 100644
--- a/configs/parrot_r16_defconfig
+++ b/configs/parrot_r16_defconfig
@@ -15,6 +15,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-r16-parrot"
# CONFIG_CMD_FLASH is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_PARTITION_UUIDS is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_CONS_INDEX=5
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/phycore-rk3288_defconfig b/configs/phycore-rk3288_defconfig
index d78b6d57b6..fc3b81c43c 100644
--- a/configs/phycore-rk3288_defconfig
+++ b/configs/phycore-rk3288_defconfig
@@ -17,8 +17,6 @@ CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_I2C_SUPPORT=y
CONFIG_SPL_POWER_SUPPORT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -44,6 +42,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
diff --git a/configs/popmetal-rk3288_defconfig b/configs/popmetal-rk3288_defconfig
index 2670b4b75a..84c099560f 100644
--- a/configs/popmetal-rk3288_defconfig
+++ b/configs/popmetal-rk3288_defconfig
@@ -15,8 +15,6 @@ CONFIG_CONSOLE_MUX=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/rock2_defconfig b/configs/rock2_defconfig
index cd9a821974..01d53ac1c3 100644
--- a/configs/rock2_defconfig
+++ b/configs/rock2_defconfig
@@ -14,8 +14,6 @@ CONFIG_SILENT_CONSOLE=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -42,6 +40,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MMC_DW=y
diff --git a/configs/sniper_defconfig b/configs/sniper_defconfig
index ad22a1cbe2..70e485fab2 100644
--- a/configs/sniper_defconfig
+++ b/configs/sniper_defconfig
@@ -13,7 +13,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION=2
# CONFIG_SPL_EXT_SUPPORT is not set
CONFIG_SYS_PROMPT="sniper # "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
CONFIG_FASTBOOT_BUF_SIZE=0x2000000
CONFIG_FASTBOOT_FLASH=y
diff --git a/configs/stih410-b2260_defconfig b/configs/stih410-b2260_defconfig
index 67391bdfdf..ba1ff25d35 100644
--- a/configs/stih410-b2260_defconfig
+++ b/configs/stih410-b2260_defconfig
@@ -10,11 +10,6 @@ CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="console=ttyAS1,115200 CONSOLE=/dev/ttyAS1 consoleblank=0 root=/dev/mmcblk0p2 rootfstype=ext4 rw rootwait mem=992M@0x40000000 vmalloc=256m"
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_SYS_PROMPT="stih410-b2260 => "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_BUF_ADDR=0x40000000
-CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPT=y
CONFIG_CMD_MMC=y
CONFIG_CMD_USB=y
@@ -26,6 +21,12 @@ CONFIG_OF_CONTROL=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_CLK=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x40000000
+CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_MISC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_STI=y
diff --git a/configs/tbs_a711_defconfig b/configs/tbs_a711_defconfig
index 3e3de4fbb3..5d58f5ceb4 100644
--- a/configs/tbs_a711_defconfig
+++ b/configs/tbs_a711_defconfig
@@ -16,6 +16,7 @@ CONFIG_DEFAULT_DEVICE_TREE="sun8i-a83t-tbs-a711"
# CONFIG_CMD_FLASH is not set
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_AXP_DCDC5_VOLT=1200
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_MUSB_GADGET=y
diff --git a/configs/tinker-rk3288_defconfig b/configs/tinker-rk3288_defconfig
index fb6bfa57ad..e1c99c3828 100644
--- a/configs/tinker-rk3288_defconfig
+++ b/configs/tinker-rk3288_defconfig
@@ -16,8 +16,6 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000
CONFIG_SPL_I2C_SUPPORT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_I2C=y
@@ -43,6 +41,9 @@ CONFIG_SPL_SYSCON=y
# CONFIG_SPL_SIMPLE_BUS is not set
CONFIG_CLK=y
CONFIG_SPL_CLK=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_ROCKCHIP_GPIO=y
CONFIG_SYS_I2C_ROCKCHIP=y
CONFIG_MISC=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
index f5a33342fa..b4521aab43 100644
--- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
@@ -19,9 +19,6 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_MEMTEST=y
CONFIG_SYS_ALT_MEMTEST=y
@@ -47,6 +44,10 @@ CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
index 7f7ee558ee..9d9216f5fe 100644
--- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
@@ -20,7 +20,7 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_FLASH=y
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_MEMTEST=y
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 4cb3959f36..976640cae0 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -19,9 +19,6 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_EEPROM=y
CONFIG_CMD_MEMTEST=y
@@ -50,6 +47,10 @@ CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index e989d1635c..3420ce5dc3 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -19,9 +19,6 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_EEPROM=y
CONFIG_CMD_MEMTEST=y
@@ -50,6 +47,10 @@ CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index bd67df904a..a9ba4a17e9 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -19,9 +19,6 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_EEPROM=y
CONFIG_CMD_MEMTEST=y
@@ -50,6 +47,10 @@ CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig
index a5fa33e366..32c6f23210 100644
--- a/configs/xilinx_zynqmp_zcu106_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig
@@ -18,9 +18,6 @@ CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
CONFIG_SPL_ATF=y
CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_CMD_THOR_DOWNLOAD=y
CONFIG_CMD_EEPROM=y
CONFIG_CMD_MEMTEST=y
@@ -48,6 +45,10 @@ CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/doc/README.android-fastboot b/doc/README.android-fastboot
index 2c3ee7810a..431191c473 100644
--- a/doc/README.android-fastboot
+++ b/doc/README.android-fastboot
@@ -1,142 +1,214 @@
+================
Android Fastboot
-~~~~~~~~~~~~~~~~
+================
Overview
========
-The protocol that is used over USB is described in
-README.android-fastboot-protocol in same directory.
-The current implementation is a minimal support of the erase command,the
-"oem format" command and flash command;it only supports eMMC devices.
+The protocol that is used over USB and UDP is described in the
+``README.android-fastboot-protocol`` file in the same directory.
+
+The current implementation supports the following standard commands:
+
+- ``boot``
+- ``continue``
+- ``download``
+- ``erase`` (if enabled)
+- ``flash`` (if enabled)
+- ``getvar``
+- ``reboot``
+- ``reboot-bootloader``
+- ``set_active`` (only a stub implementation which always succeeds)
+
+The following OEM commands are supported (if enabled):
+
+- oem format - this executes ``gpt write mmc %x $partitions``
+
+Support for both eMMC and NAND devices is included.
Client installation
===================
-The counterpart to this gadget is the fastboot client which can
-be found in Android's platform/system/core repository in the fastboot
-folder. It runs on Windows, Linux and even OSX. Linux user are lucky since
-they only need libusb.
-Windows users need to bring some time until they have Android SDK (currently
-http://dl.google.com/android/installer_r12-windows.exe) installed. You
-need to install ADB package which contains the required glue libraries for
-accessing USB. Also you need "Google USB driver package" and "SDK platform
-tools". Once installed the usb driver is placed in your SDK folder under
-extras\google\usb_driver. The android_winusb.inf needs a line like
-
- %SingleBootLoaderInterface% = USB_Install, USB\VID_0451&PID_D022
-
-either in the [Google.NTx86] section for 32bit Windows or [Google.NTamd64]
-for 64bit Windows. VID and PID should match whatever the fastboot is
-advertising.
+
+The counterpart to this is the fastboot client which can be found in
+Android's ``platform/system/core`` repository in the fastboot
+folder. It runs on Windows, Linux and OSX. The fastboot client is
+part of the Android SDK Platform-Tools and can be downloaded from:
+
+https://developer.android.com/studio/releases/platform-tools
Board specific
==============
+
+USB configuration
+-----------------
+
The fastboot gadget relies on the USB download gadget, so the following
options must be configured:
-CONFIG_USB_GADGET_DOWNLOAD
-CONFIG_USB_GADGET_VENDOR_NUM
-CONFIG_USB_GADGET_PRODUCT_NUM
-CONFIG_USB_GADGET_MANUFACTURER
+::
+
+ CONFIG_USB_GADGET_DOWNLOAD
+ CONFIG_USB_GADGET_VENDOR_NUM
+ CONFIG_USB_GADGET_PRODUCT_NUM
+ CONFIG_USB_GADGET_MANUFACTURER
-NOTE: The CONFIG_USB_GADGET_VENDOR_NUM must be one of the numbers supported by
-the fastboot client. The list of vendor IDs supported can be found in the
-fastboot client source code (fastboot.c) mentioned above.
+NOTE: The ``CONFIG_USB_GADGET_VENDOR_NUM`` must be one of the numbers
+supported by the fastboot client. The list of vendor IDs supported can
+be found in the fastboot client source code.
-The fastboot function is enabled by defining CONFIG_USB_FUNCTION_FASTBOOT,
-CONFIG_CMD_FASTBOOT and CONFIG_ANDROID_BOOT_IMAGE.
+General configuration
+---------------------
-The fastboot protocol requires a large memory buffer for downloads. This
-buffer should be as large as possible for a platform. The location of the
-buffer and size are set with CONFIG_FASTBOOT_BUF_ADDR and
-CONFIG_FASTBOOT_BUF_SIZE.
+The fastboot protocol requires a large memory buffer for
+downloads. This buffer should be as large as possible for a
+platform. The location of the buffer and size are set with
+``CONFIG_FASTBOOT_BUF_ADDR`` and ``CONFIG_FASTBOOT_BUF_SIZE``. These
+may be overridden on the fastboot command line using ``-l`` and
+``-s``.
+
+Fastboot environment variables
+==============================
+
+Partition aliases
+-----------------
Fastboot partition aliases can also be defined for devices where GPT
limitations prevent user-friendly partition names such as "boot", "system"
and "cache". Or, where the actual partition name doesn't match a standard
-partition name used commonly with fastboot. Current implentation checks
-aliases when accessing partitions by name (flash_write and erase functions).
-To define a partition alias add an environment variable similar to:
-fastboot_partition_alias_<alias partition name>=<actual partition name>
-Example: fastboot_partition_alias_boot=LNX
+partition name used commonly with fastboot.
+
+The current implementation checks aliases when accessing partitions by
+name (flash_write and erase functions). To define a partition alias
+add an environment variable similar to:
+
+``fastboot_partition_alias_<alias partition name>=<actual partition name>``
+
+for example:
+
+``fastboot_partition_alias_boot=LNX``
+
+Variable overrides
+------------------
+
+Variables retrived through ``getvar`` can be overridden by defining
+environment variables of the form ``fastboot.<variable>``. These are
+looked up first so can be used to override values which would
+otherwise be returned. Using this mechanism you can also return types
+for NAND filesystems, as the fully parameterised variable is looked
+up, e.g.
+
+``fastboot.partition-type:boot=jffs2``
+
+Boot command
+------------
+
+When executing the fastboot ``boot`` command, if ``fastboot_bootcmd`` is set then
+that will be executed in place of ``bootm <CONFIG_FASTBOOT_BUF_ADDR>``.
Partition Names
===============
-The Fastboot implementation in U-boot allows to write images into disk
-partitions (currently on eMMC). Target partitions are referred on the host
-computer by their names.
+
+The Fastboot implementation in U-Boot allows to write images into disk
+partitions. Target partitions are referred on the host computer by
+their names.
For GPT/EFI the respective partition name is used.
For MBR the partitions are referred by generic names according to the
following schema:
- <device type> <device index letter> <partition index>
+ <device type><device index letter><partition index>
-Example: hda3, sdb1, usbda1
+Example: ``hda3``, ``sdb1``, ``usbda1``
The device type is as follows:
- * IDE, ATAPI and SATA disks: hd
- * SCSI disks: sd
- * USB media: usbd
- * MMC and SD cards: mmcsd
- * Disk on chip: docd
- * other: xx
+ * IDE, ATAPI and SATA disks: ``hd``
+ * SCSI disks: ``sd``
+ * USB media: ``usbd``
+ * MMC and SD cards: ``mmcsd``
+ * Disk on chip: ``docd``
+ * other: ``xx``
-The device index starts from 'a' and refers to the interface (e.g. USB
+The device index starts from ``a`` and refers to the interface (e.g. USB
controller, SD/MMC controller) or disk index. The partition index starts
-from 1 and describes the partition number on the particular device.
+from ``1`` and describes the partition number on the particular device.
Writing Partition Table
=======================
+
Fastboot also allows to write the partition table to the media. This can be
done by writing the respective partition table image to a special target
"gpt" or "mbr". These names can be customized by defining the following
configuration options:
-CONFIG_FASTBOOT_GPT_NAME
-CONFIG_FASTBOOT_MBR_NAME
+::
+
+ CONFIG_FASTBOOT_GPT_NAME
+ CONFIG_FASTBOOT_MBR_NAME
In Action
=========
-Enter into fastboot by executing the fastboot command in u-boot and you
-should see:
-|GADGET DRIVER: usb_dnl_fastboot
+
+Enter into fastboot by executing the fastboot command in U-Boot for either USB:
+
+::
+
+ => fastboot usb 0
+
+or UDP:
+
+::
+
+ => fastboot udp
+ link up on port 0, speed 100, full duplex
+ Using ethernet@4a100000 device
+ Listening for fastboot command on 192.168.0.102
On the client side you can fetch the bootloader version for instance:
-|>fastboot getvar bootloader-version
-|bootloader-version: U-Boot 2014.04-00005-gd24cabc
-|finished. total time: 0.000s
+
+::
+
+ $ fastboot getvar bootloader-version
+ bootloader-version: U-Boot 2014.04-00005-gd24cabc
+ finished. total time: 0.000s
or initiate a reboot:
-|>fastboot reboot
+
+::
+
+ $ fastboot reboot
and once the client comes back, the board should reset.
You can also specify a kernel image to boot. You have to either specify
-the an image in Android format _or_ pass a binary kernel and let the
+the an image in Android format *or* pass a binary kernel and let the
fastboot client wrap the Android suite around it. On OMAP for instance you
take zImage kernel and pass it to the fastboot client:
-|>fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0
-| mem=128M" boot zImage
-|creating boot image...
-|creating boot image - 1847296 bytes
-|downloading 'boot.img'...
-|OKAY [ 2.766s]
-|booting...
-|OKAY [ -0.000s]
-|finished. total time: 2.766s
-
-and on the gadget side you should see:
-|Starting download of 1847296 bytes
-|........................................................
-|downloading of 1847296 bytes finished
-|Booting kernel..
-|## Booting Android Image at 0x81000000 ...
-|Kernel load addr 0x80008000 size 1801 KiB
-|Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
-| Loading Kernel Image ... OK
-|OK
-|
-|Starting kernel ...
+::
+
+ $ fastboot -b 0x80000000 -c "console=ttyO2 earlyprintk root=/dev/ram0 mem=128M" boot zImage
+ creating boot image...
+ creating boot image - 1847296 bytes
+ downloading 'boot.img'...
+ OKAY [ 2.766s]
+ booting...
+ OKAY [ -0.000s]
+ finished. total time: 2.766s
+
+and on the U-Boot side you should see:
+
+::
+
+ Starting download of 1847296 bytes
+ ........................................................
+ downloading of 1847296 bytes finished
+ Booting kernel..
+ ## Booting Android Image at 0x81000000 ...
+ Kernel load addr 0x80008000 size 1801 KiB
+ Kernel command line: console=ttyO2 earlyprintk root=/dev/ram0 mem=128M
+ Loading Kernel Image ... OK
+ OK
+
+ Starting kernel ...
diff --git a/drivers/Kconfig b/drivers/Kconfig
index c2e813f5ad..8424898dbd 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -28,6 +28,8 @@ source "drivers/dfu/Kconfig"
source "drivers/dma/Kconfig"
+source "drivers/fastboot/Kconfig"
+
source "drivers/firmware/Kconfig"
source "drivers/fpga/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index b3f1b600a5..d29a6e467b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -71,6 +71,7 @@ obj-y += block/
obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
obj-$(CONFIG_CPU) += cpu/
obj-y += crypto/
+obj-$(CONFIG_FASTBOOT) += fastboot/
obj-y += firmware/
obj-$(CONFIG_FPGA) += fpga/
obj-y += misc/
diff --git a/cmd/fastboot/Kconfig b/drivers/fastboot/Kconfig
index 0d2c2f131e..bc25ea1d9c 100644
--- a/cmd/fastboot/Kconfig
+++ b/drivers/fastboot/Kconfig
@@ -1,32 +1,27 @@
-comment "FASTBOOT"
+menu "Fastboot support"
-menuconfig FASTBOOT
- bool "Fastboot support"
- depends on USB_GADGET
- default y if ARCH_SUNXI && USB_MUSB_GADGET
-
-if FASTBOOT
+config FASTBOOT
+ bool
+ imply ANDROID_BOOT_IMAGE
+ imply CMD_FASTBOOT
config USB_FUNCTION_FASTBOOT
bool "Enable USB fastboot gadget"
- default y
+ depends on USB_GADGET
+ default y if ARCH_SUNXI && USB_MUSB_GADGET
+ select FASTBOOT
select USB_GADGET_DOWNLOAD
- imply ANDROID_BOOT_IMAGE
- imply CMD_FASTBOOT
help
This enables the USB part of the fastboot gadget.
-config CMD_FASTBOOT
- bool "Enable FASTBOOT command"
+config UDP_FUNCTION_FASTBOOT
+ depends on NET
+ select FASTBOOT
+ bool "Enable fastboot protocol over UDP"
help
- This enables the command "fastboot" which enables the Android
- fastboot mode for the platform's USB device. Fastboot is a USB
- protocol for downloading images, flashing and device control
- used on Android devices.
-
- See doc/README.android-fastboot for more information.
+ This enables the fastboot protocol over UDP.
-if USB_FUNCTION_FASTBOOT
+if FASTBOOT
config FASTBOOT_BUF_ADDR
hex "Define FASTBOOT buffer address"
@@ -58,6 +53,7 @@ config FASTBOOT_BUF_SIZE
config FASTBOOT_USB_DEV
int "USB controller number"
+ depends on USB_FUNCTION_FASTBOOT
default 0
help
Some boards have USB OTG controller other than 0. Define this
@@ -67,6 +63,8 @@ config FASTBOOT_USB_DEV
config FASTBOOT_FLASH
bool "Enable FASTBOOT FLASH command"
default y if ARCH_SUNXI
+ depends on MMC || (NAND && CMD_MTDPARTS)
+ select IMAGE_SPARSE
help
The fastboot protocol includes a "flash" command for writing
the downloaded image to a non-volatile storage device. Define
@@ -82,7 +80,7 @@ config FASTBOOT_FLASH_MMC
config FASTBOOT_FLASH_NAND
bool "FASTBOOT on NAND"
- depends on NAND
+ depends on NAND && CMD_MTDPARTS
endchoice
@@ -96,19 +94,16 @@ config FASTBOOT_FLASH_MMC_DEV
regarding the non-volatile storage device. Define this to
the eMMC device that fastboot should use to store the image.
-config FASTBOOT_FLASH_NAND_DEV
- int "Define FASTBOOT NAND FLASH default device"
+config FASTBOOT_FLASH_NAND_TRIMFFS
+ bool "Skip empty pages when flashing NAND"
depends on FASTBOOT_FLASH_NAND
- depends on CMD_MTDPARTS
- default 0 if ARCH_SUNXI && NAND_SUNXI
help
- The fastboot "flash" command requires additional information
- regarding the non-volatile storage device. Define this to
- the NAND device that fastboot should use to store the image.
+ When flashing NAND enable the DROP_FFS flag to drop trailing all-0xff
+ pages.
config FASTBOOT_GPT_NAME
string "Target name for updating GPT"
- depends on FASTBOOT_FLASH
+ depends on FASTBOOT_FLASH_MMC && EFI_PARTITION
default "gpt"
help
The fastboot "flash" command supports writing the downloaded
@@ -121,7 +116,7 @@ config FASTBOOT_GPT_NAME
config FASTBOOT_MBR_NAME
string "Target name for updating MBR"
- depends on FASTBOOT_FLASH
+ depends on FASTBOOT_FLASH_MMC && DOS_PARTITION
default "mbr"
help
The fastboot "flash" command allows to write the downloaded image
@@ -129,6 +124,14 @@ config FASTBOOT_MBR_NAME
specified on the "fastboot flash" command line matches the value
defined here. The default target name for updating MBR is "mbr".
-endif # USB_FUNCTION_FASTBOOT
+config FASTBOOT_CMD_OEM_FORMAT
+ bool "Enable the 'oem format' command"
+ depends on FASTBOOT_FLASH_MMC && CMD_GPT
+ help
+ Add support for the "oem format" command from a client. This
+ relies on the env variable partitions to contain the list of
+ partitions as required by the gpt command.
endif # FASTBOOT
+
+endmenu
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
new file mode 100644
index 0000000000..a2421565e2
--- /dev/null
+++ b/drivers/fastboot/Makefile
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += fb_common.o
+obj-y += fb_getvar.o
+obj-y += fb_command.o
+obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_mmc.o
+obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o
diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c
new file mode 100644
index 0000000000..200f9910c5
--- /dev/null
+++ b/drivers/fastboot/fb_command.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <fastboot-internal.h>
+#include <fb_mmc.h>
+#include <fb_nand.h>
+#include <part.h>
+#include <stdlib.h>
+
+/**
+ * image_size - final fastboot image size
+ */
+static u32 image_size;
+
+/**
+ * fastboot_bytes_received - number of bytes received in the current download
+ */
+static u32 fastboot_bytes_received;
+
+/**
+ * fastboot_bytes_expected - number of bytes expected in the current download
+ */
+static u32 fastboot_bytes_expected;
+
+static void okay(char *, char *);
+static void getvar(char *, char *);
+static void download(char *, char *);
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void flash(char *, char *);
+static void erase(char *, char *);
+#endif
+static void reboot_bootloader(char *, char *);
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+static void oem_format(char *, char *);
+#endif
+
+static const struct {
+ const char *command;
+ void (*dispatch)(char *cmd_parameter, char *response);
+} commands[FASTBOOT_COMMAND_COUNT] = {
+ [FASTBOOT_COMMAND_GETVAR] = {
+ .command = "getvar",
+ .dispatch = getvar
+ },
+ [FASTBOOT_COMMAND_DOWNLOAD] = {
+ .command = "download",
+ .dispatch = download
+ },
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+ [FASTBOOT_COMMAND_FLASH] = {
+ .command = "flash",
+ .dispatch = flash
+ },
+ [FASTBOOT_COMMAND_ERASE] = {
+ .command = "erase",
+ .dispatch = erase
+ },
+#endif
+ [FASTBOOT_COMMAND_BOOT] = {
+ .command = "boot",
+ .dispatch = okay
+ },
+ [FASTBOOT_COMMAND_CONTINUE] = {
+ .command = "continue",
+ .dispatch = okay
+ },
+ [FASTBOOT_COMMAND_REBOOT] = {
+ .command = "reboot",
+ .dispatch = okay
+ },
+ [FASTBOOT_COMMAND_REBOOT_BOOTLOADER] = {
+ .command = "reboot-bootloader",
+ .dispatch = reboot_bootloader
+ },
+ [FASTBOOT_COMMAND_SET_ACTIVE] = {
+ .command = "set_active",
+ .dispatch = okay
+ },
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+ [FASTBOOT_COMMAND_OEM_FORMAT] = {
+ .command = "oem format",
+ .dispatch = oem_format,
+ },
+#endif
+};
+
+/**
+ * fastboot_handle_command - Handle fastboot command
+ *
+ * @cmd_string: Pointer to command string
+ * @response: Pointer to fastboot response buffer
+ *
+ * Return: Executed command, or -1 if not recognized
+ */
+int fastboot_handle_command(char *cmd_string, char *response)
+{
+ int i;
+ char *cmd_parameter;
+
+ cmd_parameter = cmd_string;
+ strsep(&cmd_parameter, ":");
+
+ for (i = 0; i < FASTBOOT_COMMAND_COUNT; i++) {
+ if (!strcmp(commands[i].command, cmd_string)) {
+ if (commands[i].dispatch) {
+ commands[i].dispatch(cmd_parameter,
+ response);
+ return i;
+ } else {
+ break;
+ }
+ }
+ }
+
+ pr_err("command %s not recognized.\n", cmd_string);
+ fastboot_fail("unrecognized command", response);
+ return -1;
+}
+
+/**
+ * okay() - Send bare OKAY response
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Send a bare OKAY fastboot response. This is used where the command is
+ * valid, but all the work is done after the response has been sent (e.g.
+ * boot, reboot etc.)
+ */
+static void okay(char *cmd_parameter, char *response)
+{
+ fastboot_okay(NULL, response);
+}
+
+/**
+ * getvar() - Read a config/version variable
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void getvar(char *cmd_parameter, char *response)
+{
+ fastboot_getvar(cmd_parameter, response);
+}
+
+/**
+ * fastboot_download() - Start a download transfer from the client
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void download(char *cmd_parameter, char *response)
+{
+ char *tmp;
+
+ if (!cmd_parameter) {
+ fastboot_fail("Expected command parameter", response);
+ return;
+ }
+ fastboot_bytes_received = 0;
+ fastboot_bytes_expected = simple_strtoul(cmd_parameter, &tmp, 16);
+ if (fastboot_bytes_expected == 0) {
+ fastboot_fail("Expected nonzero image size", response);
+ return;
+ }
+ /*
+ * Nothing to download yet. Response is of the form:
+ * [DATA|FAIL]$cmd_parameter
+ *
+ * where cmd_parameter is an 8 digit hexadecimal number
+ */
+ if (fastboot_bytes_expected > fastboot_buf_size) {
+ fastboot_fail(cmd_parameter, response);
+ } else {
+ printf("Starting download of %d bytes\n",
+ fastboot_bytes_expected);
+ fastboot_response("DATA", response, "%s", cmd_parameter);
+ }
+}
+
+/**
+ * fastboot_data_remaining() - return bytes remaining in current transfer
+ *
+ * Return: Number of bytes left in the current download
+ */
+u32 fastboot_data_remaining(void)
+{
+ return fastboot_bytes_expected - fastboot_bytes_received;
+}
+
+/**
+ * fastboot_data_download() - Copy image data to fastboot_buf_addr.
+ *
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @response: Pointer to fastboot response buffer
+ *
+ * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
+ * response. fastboot_bytes_received is updated to indicate the number
+ * of bytes that have been transferred.
+ *
+ * On completion sets image_size and ${filesize} to the total size of the
+ * downloaded image.
+ */
+void fastboot_data_download(const void *fastboot_data,
+ unsigned int fastboot_data_len,
+ char *response)
+{
+#define BYTES_PER_DOT 0x20000
+ u32 pre_dot_num, now_dot_num;
+
+ if (fastboot_data_len == 0 ||
+ (fastboot_bytes_received + fastboot_data_len) >
+ fastboot_bytes_expected) {
+ fastboot_fail("Received invalid data length",
+ response);
+ return;
+ }
+ /* Download data to fastboot_buf_addr */
+ memcpy(fastboot_buf_addr + fastboot_bytes_received,
+ fastboot_data, fastboot_data_len);
+
+ pre_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
+ fastboot_bytes_received += fastboot_data_len;
+ now_dot_num = fastboot_bytes_received / BYTES_PER_DOT;
+
+ if (pre_dot_num != now_dot_num) {
+ putc('.');
+ if (!(now_dot_num % 74))
+ putc('\n');
+ }
+ *response = '\0';
+}
+
+/**
+ * fastboot_data_complete() - Mark current transfer complete
+ *
+ * @response: Pointer to fastboot response buffer
+ *
+ * Set image_size and ${filesize} to the total size of the downloaded image.
+ */
+void fastboot_data_complete(char *response)
+{
+ /* Download complete. Respond with "OKAY" */
+ fastboot_okay(NULL, response);
+ printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received);
+ image_size = fastboot_bytes_received;
+ env_set_hex("filesize", image_size);
+ fastboot_bytes_expected = 0;
+ fastboot_bytes_received = 0;
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+/**
+ * flash() - write the downloaded image to the indicated partition.
+ *
+ * @cmd_parameter: Pointer to partition name
+ * @response: Pointer to fastboot response buffer
+ *
+ * Writes the previously downloaded image to the partition indicated by
+ * cmd_parameter. Writes to response.
+ */
+static void flash(char *cmd_parameter, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+ fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
+ response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+ fastboot_nand_flash_write(cmd_parameter, fastboot_buf_addr, image_size,
+ response);
+#endif
+}
+
+/**
+ * erase() - erase the indicated partition.
+ *
+ * @cmd_parameter: Pointer to partition name
+ * @response: Pointer to fastboot response buffer
+ *
+ * Erases the partition indicated by cmd_parameter (clear to 0x00s). Writes
+ * to response.
+ */
+static void erase(char *cmd_parameter, char *response)
+{
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+ fastboot_mmc_erase(cmd_parameter, response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+ fastboot_nand_erase(cmd_parameter, response);
+#endif
+}
+#endif
+
+/**
+ * reboot_bootloader() - Sets reboot bootloader flag.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void reboot_bootloader(char *cmd_parameter, char *response)
+{
+ if (fastboot_set_reboot_flag())
+ fastboot_fail("Cannot set reboot flag", response);
+ else
+ fastboot_okay(NULL, response);
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+/**
+ * oem_format() - Execute the OEM format command
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ */
+static void oem_format(char *cmd_parameter, char *response)
+{
+ char cmdbuf[32];
+
+ if (!env_get("partitions")) {
+ fastboot_fail("partitions not set", response);
+ } else {
+ sprintf(cmdbuf, "gpt write mmc %x $partitions",
+ CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ if (run_command(cmdbuf, 0))
+ fastboot_fail("", response);
+ else
+ fastboot_okay(NULL, response);
+ }
+}
+#endif
diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c
new file mode 100644
index 0000000000..c6e06aab7a
--- /dev/null
+++ b/drivers/fastboot/fb_common.c
@@ -0,0 +1,169 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2008 - 2009
+ * Windriver, <www.windriver.com>
+ * Tom Rix <Tom.Rix@windriver.com>
+ *
+ * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+ *
+ * Copyright 2014 Linaro, Ltd.
+ * Rob Herring <robh@kernel.org>
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <net/fastboot.h>
+
+/**
+ * fastboot_buf_addr - base address of the fastboot download buffer
+ */
+void *fastboot_buf_addr;
+
+/**
+ * fastboot_buf_size - size of the fastboot download buffer
+ */
+u32 fastboot_buf_size;
+
+/**
+ * fastboot_progress_callback - callback executed during long operations
+ */
+void (*fastboot_progress_callback)(const char *msg);
+
+/**
+ * fastboot_response() - Writes a response of the form "$tag$reason".
+ *
+ * @tag: The first part of the response
+ * @response: Pointer to fastboot response buffer
+ * @format: printf style format string
+ */
+void fastboot_response(const char *tag, char *response,
+ const char *format, ...)
+{
+ va_list args;
+
+ strlcpy(response, tag, FASTBOOT_RESPONSE_LEN);
+ if (format) {
+ va_start(args, format);
+ vsnprintf(response + strlen(response),
+ FASTBOOT_RESPONSE_LEN - strlen(response) - 1,
+ format, args);
+ va_end(args);
+ }
+}
+
+/**
+ * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
+ *
+ * @reason: Pointer to returned reason string
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_fail(const char *reason, char *response)
+{
+ fastboot_response("FAIL", response, "%s", reason);
+}
+
+/**
+ * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
+ *
+ * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_okay(const char *reason, char *response)
+{
+ if (reason)
+ fastboot_response("OKAY", response, "%s", reason);
+ else
+ fastboot_response("OKAY", response, NULL);
+}
+
+/**
+ * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
+ *
+ * Set flag which indicates that we should reboot into the bootloader
+ * following the reboot that fastboot executes after this function.
+ *
+ * This function should be overridden in your board file with one
+ * which sets whatever flag your board specific Android bootloader flow
+ * requires in order to re-enter the bootloader.
+ */
+int __weak fastboot_set_reboot_flag(void)
+{
+ return -ENOSYS;
+}
+
+/**
+ * fastboot_get_progress_callback() - Return progress callback
+ *
+ * Return: Pointer to function called during long operations
+ */
+void (*fastboot_get_progress_callback(void))(const char *)
+{
+ return fastboot_progress_callback;
+}
+
+/**
+ * fastboot_boot() - Execute fastboot boot command
+ *
+ * If ${fastboot_bootcmd} is set, run that command to execute the boot
+ * process, if that returns, then exit the fastboot server and return
+ * control to the caller.
+ *
+ * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
+ * the board.
+ */
+void fastboot_boot(void)
+{
+ char *s;
+
+ s = env_get("fastboot_bootcmd");
+ if (s) {
+ run_command(s, CMD_FLAG_ENV);
+ } else {
+ static char boot_addr_start[12];
+ static char *const bootm_args[] = {
+ "bootm", boot_addr_start, NULL
+ };
+
+ snprintf(boot_addr_start, sizeof(boot_addr_start) - 1,
+ "0x%p", fastboot_buf_addr);
+ printf("Booting kernel at %s...\n\n\n", boot_addr_start);
+
+ do_bootm(NULL, 0, 2, bootm_args);
+
+ /*
+ * This only happens if image is somehow faulty so we start
+ * over. We deliberately leave this policy to the invocation
+ * of fastbootcmd if that's what's being run
+ */
+ do_reset(NULL, 0, 0, NULL);
+ }
+}
+
+/**
+ * fastboot_set_progress_callback() - set progress callback
+ *
+ * @progress: Pointer to progress callback
+ *
+ * Set a callback which is invoked periodically during long running operations
+ * (flash and erase). This can be used (for example) by the UDP transport to
+ * send INFO responses to keep the client alive whilst those commands are
+ * executing.
+ */
+void fastboot_set_progress_callback(void (*progress)(const char *msg))
+{
+ fastboot_progress_callback = progress;
+}
+
+/*
+ * fastboot_init() - initialise new fastboot protocol session
+ *
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ */
+void fastboot_init(void *buf_addr, u32 buf_size)
+{
+ fastboot_buf_addr = buf_addr ? buf_addr :
+ (void *)CONFIG_FASTBOOT_BUF_ADDR;
+ fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE;
+ fastboot_set_progress_callback(NULL);
+}
diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c
new file mode 100644
index 0000000000..4d264c985d
--- /dev/null
+++ b/drivers/fastboot/fb_getvar.c
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <fastboot-internal.h>
+#include <fb_mmc.h>
+#include <fb_nand.h>
+#include <fs.h>
+#include <version.h>
+
+static void getvar_version(char *var_parameter, char *response);
+static void getvar_bootloader_version(char *var_parameter, char *response);
+static void getvar_downloadsize(char *var_parameter, char *response);
+static void getvar_serialno(char *var_parameter, char *response);
+static void getvar_version_baseband(char *var_parameter, char *response);
+static void getvar_product(char *var_parameter, char *response);
+static void getvar_current_slot(char *var_parameter, char *response);
+static void getvar_slot_suffixes(char *var_parameter, char *response);
+static void getvar_has_slot(char *var_parameter, char *response);
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+static void getvar_partition_type(char *part_name, char *response);
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void getvar_partition_size(char *part_name, char *response);
+#endif
+
+static const struct {
+ const char *variable;
+ void (*dispatch)(char *var_parameter, char *response);
+} getvar_dispatch[] = {
+ {
+ .variable = "version",
+ .dispatch = getvar_version
+ }, {
+ .variable = "bootloader-version",
+ .dispatch = getvar_bootloader_version
+ }, {
+ .variable = "version-bootloader",
+ .dispatch = getvar_bootloader_version
+ }, {
+ .variable = "downloadsize",
+ .dispatch = getvar_downloadsize
+ }, {
+ .variable = "max-download-size",
+ .dispatch = getvar_downloadsize
+ }, {
+ .variable = "serialno",
+ .dispatch = getvar_serialno
+ }, {
+ .variable = "version-baseband",
+ .dispatch = getvar_version_baseband
+ }, {
+ .variable = "product",
+ .dispatch = getvar_product
+ }, {
+ .variable = "current-slot",
+ .dispatch = getvar_current_slot
+ }, {
+ .variable = "slot-suffixes",
+ .dispatch = getvar_slot_suffixes
+ }, {
+ .variable = "has_slot",
+ .dispatch = getvar_has_slot
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+ }, {
+ .variable = "partition-type",
+ .dispatch = getvar_partition_type
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+ }, {
+ .variable = "partition-size",
+ .dispatch = getvar_partition_size
+#endif
+ }
+};
+
+static void getvar_version(char *var_parameter, char *response)
+{
+ fastboot_okay(FASTBOOT_VERSION, response);
+}
+
+static void getvar_bootloader_version(char *var_parameter, char *response)
+{
+ fastboot_okay(U_BOOT_VERSION, response);
+}
+
+static void getvar_downloadsize(char *var_parameter, char *response)
+{
+ fastboot_response("OKAY", response, "0x%08x", fastboot_buf_size);
+}
+
+static void getvar_serialno(char *var_parameter, char *response)
+{
+ const char *tmp = env_get("serial#");
+
+ if (tmp)
+ fastboot_okay(tmp, response);
+ else
+ fastboot_fail("Value not set", response);
+}
+
+static void getvar_version_baseband(char *var_parameter, char *response)
+{
+ fastboot_okay("N/A", response);
+}
+
+static void getvar_product(char *var_parameter, char *response)
+{
+ const char *board = env_get("board");
+
+ if (board)
+ fastboot_okay(board, response);
+ else
+ fastboot_fail("Board not set", response);
+}
+
+static void getvar_current_slot(char *var_parameter, char *response)
+{
+ /* A/B not implemented, for now always return _a */
+ fastboot_okay("_a", response);
+}
+
+static void getvar_slot_suffixes(char *var_parameter, char *response)
+{
+ fastboot_okay("_a,_b", response);
+}
+
+static void getvar_has_slot(char *part_name, char *response)
+{
+ if (part_name && (!strcmp(part_name, "boot") ||
+ !strcmp(part_name, "system")))
+ fastboot_okay("yes", response);
+ else
+ fastboot_okay("no", response);
+}
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+static void getvar_partition_type(char *part_name, char *response)
+{
+ int r;
+ struct blk_desc *dev_desc;
+ disk_partition_t part_info;
+
+ r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
+ response);
+ if (r >= 0) {
+ r = fs_set_blk_dev_with_part(dev_desc, r);
+ if (r < 0)
+ fastboot_fail("failed to set partition", response);
+ else
+ fastboot_okay(fs_get_type_name(), response);
+ }
+}
+#endif
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+static void getvar_partition_size(char *part_name, char *response)
+{
+ int r;
+ size_t size;
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC)
+ struct blk_desc *dev_desc;
+ disk_partition_t part_info;
+
+ r = fastboot_mmc_get_part_info(part_name, &dev_desc, &part_info,
+ response);
+ if (r >= 0)
+ size = part_info.size;
+#endif
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH_NAND)
+ struct part_info *part_info;
+
+ r = fastboot_nand_get_part_info(part_name, &part_info, response);
+ if (r >= 0)
+ size = part_info->size;
+#endif
+ if (r >= 0)
+ fastboot_response("OKAY", response, "0x%016zx", size);
+}
+#endif
+
+/**
+ * fastboot_getvar() - Writes variable indicated by cmd_parameter to response.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Look up cmd_parameter first as an environment variable of the form
+ * fastboot.<cmd_parameter>, if that exists return use its value to set
+ * response.
+ *
+ * Otherwise lookup the name of variable and execute the appropriate
+ * function to return the requested value.
+ */
+void fastboot_getvar(char *cmd_parameter, char *response)
+{
+ if (!cmd_parameter) {
+ fastboot_fail("missing var", response);
+ } else {
+#define FASTBOOT_ENV_PREFIX "fastboot."
+ int i;
+ char *var_parameter = cmd_parameter;
+ char envstr[FASTBOOT_RESPONSE_LEN];
+ const char *s;
+
+ snprintf(envstr, sizeof(envstr) - 1,
+ FASTBOOT_ENV_PREFIX "%s", cmd_parameter);
+ s = env_get(envstr);
+ if (s) {
+ fastboot_response("OKAY", response, "%s", s);
+ return;
+ }
+
+ strsep(&var_parameter, ":");
+ for (i = 0; i < ARRAY_SIZE(getvar_dispatch); ++i) {
+ if (!strcmp(getvar_dispatch[i].variable,
+ cmd_parameter)) {
+ getvar_dispatch[i].dispatch(var_parameter,
+ response);
+ return;
+ }
+ }
+ pr_warn("WARNING: unknown variable: %s\n", cmd_parameter);
+ fastboot_fail("Variable not implemented", response);
+ }
+}
diff --git a/common/fb_mmc.c b/drivers/fastboot/fb_mmc.c
index 46f0073dbc..4c1c7fd2cd 100644
--- a/common/fb_mmc.c
+++ b/drivers/fastboot/fb_mmc.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <blk.h>
#include <fastboot.h>
+#include <fastboot-internal.h>
#include <fb_mmc.h>
#include <image-sparse.h>
#include <part.h>
@@ -15,18 +16,7 @@
#include <linux/compat.h>
#include <android_image.h>
-/*
- * FIXME: Ensure we always set these names via Kconfig once xxx_PARTITION is
- * migrated
- */
-#ifndef CONFIG_FASTBOOT_GPT_NAME
-#define CONFIG_FASTBOOT_GPT_NAME "gpt"
-#endif
-
-
-#ifndef CONFIG_FASTBOOT_MBR_NAME
-#define CONFIG_FASTBOOT_MBR_NAME "mbr"
-#endif
+#define FASTBOOT_MAX_BLK_WRITE 16384
#define BOOT_PARTITION_NAME "boot"
@@ -56,13 +46,48 @@ static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
return ret;
}
+/**
+ * fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE
+ *
+ * @block_dev: Pointer to block device
+ * @start: First block to write/erase
+ * @blkcnt: Count of blocks
+ * @buffer: Pointer to data buffer for write or NULL for erase
+ */
+static lbaint_t fb_mmc_blk_write(struct blk_desc *block_dev, lbaint_t start,
+ lbaint_t blkcnt, const void *buffer)
+{
+ lbaint_t blk = start;
+ lbaint_t blks_written;
+ lbaint_t cur_blkcnt;
+ lbaint_t blks = 0;
+ int i;
+
+ for (i = 0; i < blkcnt; i += FASTBOOT_MAX_BLK_WRITE) {
+ cur_blkcnt = min((int)blkcnt - i, FASTBOOT_MAX_BLK_WRITE);
+ if (buffer) {
+ if (fastboot_progress_callback)
+ fastboot_progress_callback("writing");
+ blks_written = blk_dwrite(block_dev, blk, cur_blkcnt,
+ buffer + (i * block_dev->blksz));
+ } else {
+ if (fastboot_progress_callback)
+ fastboot_progress_callback("erasing");
+ blks_written = blk_derase(block_dev, blk, cur_blkcnt);
+ }
+ blk += blks_written;
+ blks += blks_written;
+ }
+ return blks;
+}
+
static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
lbaint_t blk, lbaint_t blkcnt, const void *buffer)
{
struct fb_mmc_sparse *sparse = info->priv;
struct blk_desc *dev_desc = sparse->dev_desc;
- return blk_dwrite(dev_desc, blk, blkcnt, buffer);
+ return fb_mmc_blk_write(dev_desc, blk, blkcnt, buffer);
}
static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
@@ -73,7 +98,7 @@ static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
const char *part_name, void *buffer,
- unsigned int download_bytes)
+ u32 download_bytes, char *response)
{
lbaint_t blkcnt;
lbaint_t blks;
@@ -84,22 +109,23 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
if (blkcnt > info->size) {
pr_err("too large for partition: '%s'\n", part_name);
- fastboot_fail("too large for partition");
+ fastboot_fail("too large for partition", response);
return;
}
puts("Flashing Raw Image\n");
- blks = blk_dwrite(dev_desc, info->start, blkcnt, buffer);
+ blks = fb_mmc_blk_write(dev_desc, info->start, blkcnt, buffer);
+
if (blks != blkcnt) {
pr_err("failed writing to device %d\n", dev_desc->devnum);
- fastboot_fail("failed writing to device");
+ fastboot_fail("failed writing to device", response);
return;
}
printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
part_name);
- fastboot_okay("");
+ fastboot_okay(NULL, response);
}
#ifdef CONFIG_ANDROID_BOOT_IMAGE
@@ -114,7 +140,8 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
*/
static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
disk_partition_t *info,
- struct andr_img_hdr *hdr)
+ struct andr_img_hdr *hdr,
+ char *response)
{
ulong sector_size; /* boot partition sector size */
lbaint_t hdr_sectors; /* boot image header sectors count */
@@ -124,24 +151,25 @@ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
sector_size = info->blksz;
hdr_sectors = DIV_ROUND_UP(sizeof(struct andr_img_hdr), sector_size);
if (hdr_sectors == 0) {
- pr_err("invalid number of boot sectors: 0");
- fastboot_fail("invalid number of boot sectors: 0");
+ pr_err("invalid number of boot sectors: 0\n");
+ fastboot_fail("invalid number of boot sectors: 0", response);
return 0;
}
/* Read the boot image header */
res = blk_dread(dev_desc, info->start, hdr_sectors, (void *)hdr);
if (res != hdr_sectors) {
- pr_err("cannot read header from boot partition");
- fastboot_fail("cannot read header from boot partition");
+ pr_err("cannot read header from boot partition\n");
+ fastboot_fail("cannot read header from boot partition",
+ response);
return 0;
}
/* Check boot header magic string */
res = android_image_check_header(hdr);
if (res != 0) {
- pr_err("bad boot image magic");
- fastboot_fail("boot partition not initialized");
+ pr_err("bad boot image magic\n");
+ fastboot_fail("boot partition not initialized", response);
return 0;
}
@@ -159,7 +187,8 @@ static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
*/
static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
void *download_buffer,
- unsigned int download_bytes)
+ u32 download_bytes,
+ char *response)
{
uintptr_t hdr_addr; /* boot image header address */
struct andr_img_hdr *hdr; /* boot image header */
@@ -178,8 +207,8 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
/* Get boot partition info */
res = part_get_info_by_name(dev_desc, BOOT_PARTITION_NAME, &info);
if (res < 0) {
- pr_err("cannot find boot partition");
- fastboot_fail("cannot find boot partition");
+ pr_err("cannot find boot partition\n");
+ fastboot_fail("cannot find boot partition", response);
return -1;
}
@@ -188,17 +217,18 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
hdr = (struct andr_img_hdr *)hdr_addr;
/* Read boot image header */
- hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
+ hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr, response);
if (hdr_sectors == 0) {
- pr_err("unable to read boot image header");
- fastboot_fail("unable to read boot image header");
+ pr_err("unable to read boot image header\n");
+ fastboot_fail("unable to read boot image header", response);
return -1;
}
/* Check if boot image has second stage in it (we don't support it) */
if (hdr->second_size > 0) {
- pr_err("moving second stage is not supported yet");
- fastboot_fail("moving second stage is not supported yet");
+ pr_err("moving second stage is not supported yet\n");
+ fastboot_fail("moving second stage is not supported yet",
+ response);
return -1;
}
@@ -215,8 +245,9 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
res = blk_dread(dev_desc, ramdisk_sector_start, ramdisk_sectors,
ramdisk_buffer);
if (res != ramdisk_sectors) {
- pr_err("cannot read ramdisk from boot partition");
- fastboot_fail("cannot read ramdisk from boot partition");
+ pr_err("cannot read ramdisk from boot partition\n");
+ fastboot_fail("cannot read ramdisk from boot partition",
+ response);
return -1;
}
@@ -224,8 +255,8 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
hdr->kernel_size = download_bytes;
res = blk_dwrite(dev_desc, info.start, hdr_sectors, (void *)hdr);
if (res == 0) {
- pr_err("cannot writeback boot image header");
- fastboot_fail("cannot write back boot image header");
+ pr_err("cannot writeback boot image header\n");
+ fastboot_fail("cannot write back boot image header", response);
return -1;
}
@@ -236,8 +267,8 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
res = blk_dwrite(dev_desc, kernel_sector_start, kernel_sectors,
download_buffer);
if (res == 0) {
- pr_err("cannot write new kernel");
- fastboot_fail("cannot write new kernel");
+ pr_err("cannot write new kernel\n");
+ fastboot_fail("cannot write new kernel", response);
return -1;
}
@@ -248,19 +279,59 @@ static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
res = blk_dwrite(dev_desc, ramdisk_sector_start, ramdisk_sectors,
ramdisk_buffer);
if (res == 0) {
- pr_err("cannot write back original ramdisk");
- fastboot_fail("cannot write back original ramdisk");
+ pr_err("cannot write back original ramdisk\n");
+ fastboot_fail("cannot write back original ramdisk", response);
return -1;
}
puts("........ zImage was updated in boot partition\n");
- fastboot_okay("");
+ fastboot_okay(NULL, response);
return 0;
}
#endif
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes)
+/**
+ * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
+ *
+ * @part_name: Named partition to lookup
+ * @dev_desc: Pointer to returned blk_desc pointer
+ * @part_info: Pointer to returned disk_partition_t
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
+ disk_partition_t *part_info, char *response)
+{
+ int r;
+
+ *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
+ if (!*dev_desc) {
+ fastboot_fail("block device not found", response);
+ return -ENOENT;
+ }
+ if (!part_name) {
+ fastboot_fail("partition not found", response);
+ return -ENOENT;
+ }
+
+ r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info);
+ if (r < 0) {
+ fastboot_fail("partition not found", response);
+ return r;
+ }
+
+ return r;
+}
+
+/**
+ * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
+ *
+ * @cmd: Named partition to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
+ u32 download_bytes, char *response)
{
struct blk_desc *dev_desc;
disk_partition_t info;
@@ -268,7 +339,7 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
pr_err("invalid mmc device\n");
- fastboot_fail("invalid mmc device");
+ fastboot_fail("invalid mmc device", response);
return;
}
@@ -279,16 +350,17 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
if (is_valid_gpt_buf(dev_desc, download_buffer)) {
printf("%s: invalid GPT - refusing to write to flash\n",
__func__);
- fastboot_fail("invalid GPT partition");
+ fastboot_fail("invalid GPT partition", response);
return;
}
if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
printf("%s: writing GPT partitions failed\n", __func__);
- fastboot_fail("writing GPT partitions failed");
+ fastboot_fail("writing GPT partitions failed",
+ response);
return;
}
printf("........ success\n");
- fastboot_okay("");
+ fastboot_okay(NULL, response);
return;
}
#endif
@@ -299,30 +371,32 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
if (is_valid_dos_buf(download_buffer)) {
printf("%s: invalid MBR - refusing to write to flash\n",
__func__);
- fastboot_fail("invalid MBR partition");
+ fastboot_fail("invalid MBR partition", response);
return;
}
if (write_mbr_partition(dev_desc, download_buffer)) {
printf("%s: writing MBR partition failed\n", __func__);
- fastboot_fail("writing MBR partition failed");
+ fastboot_fail("writing MBR partition failed",
+ response);
return;
}
printf("........ success\n");
- fastboot_okay("");
+ fastboot_okay(NULL, response);
return;
}
#endif
#ifdef CONFIG_ANDROID_BOOT_IMAGE
if (strncasecmp(cmd, "zimage", 6) == 0) {
- fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
+ fb_mmc_update_zimage(dev_desc, download_buffer,
+ download_bytes, response);
return;
}
#endif
if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) {
pr_err("cannot find partition: '%s'\n", cmd);
- fastboot_fail("cannot find partition");
+ fastboot_fail("cannot find partition", response);
return;
}
@@ -344,16 +418,23 @@ void fb_mmc_flash_write(const char *cmd, void *download_buffer,
sparse.start);
sparse.priv = &sparse_priv;
- err = write_sparse_image(&sparse, cmd, download_buffer);
+ err = write_sparse_image(&sparse, cmd, download_buffer,
+ response);
if (!err)
- fastboot_okay("");
+ fastboot_okay(NULL, response);
} else {
write_raw_image(dev_desc, &info, cmd, download_buffer,
- download_bytes);
+ download_bytes, response);
}
}
-void fb_mmc_erase(const char *cmd)
+/**
+ * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
+ *
+ * @cmd: Named partition to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_erase(const char *cmd, char *response)
{
int ret;
struct blk_desc *dev_desc;
@@ -362,22 +443,22 @@ void fb_mmc_erase(const char *cmd)
struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (mmc == NULL) {
- pr_err("invalid mmc device");
- fastboot_fail("invalid mmc device");
+ pr_err("invalid mmc device\n");
+ fastboot_fail("invalid mmc device", response);
return;
}
dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
- pr_err("invalid mmc device");
- fastboot_fail("invalid mmc device");
+ pr_err("invalid mmc device\n");
+ fastboot_fail("invalid mmc device", response);
return;
}
ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info);
if (ret < 0) {
- pr_err("cannot find partition: '%s'", cmd);
- fastboot_fail("cannot find partition");
+ pr_err("cannot find partition: '%s'\n", cmd);
+ fastboot_fail("cannot find partition", response);
return;
}
@@ -393,14 +474,15 @@ void fb_mmc_erase(const char *cmd)
printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n",
blks_start, blks_start + blks_size);
- blks = blk_derase(dev_desc, blks_start, blks_size);
+ blks = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL);
+
if (blks != blks_size) {
- pr_err("failed erasing from device %d", dev_desc->devnum);
- fastboot_fail("failed erasing from device");
+ pr_err("failed erasing from device %d\n", dev_desc->devnum);
+ fastboot_fail("failed erasing from device", response);
return;
}
printf("........ erased " LBAFU " bytes from '%s'\n",
blks_size * info.blksz, cmd);
- fastboot_okay("");
+ fastboot_okay(NULL, response);
}
diff --git a/common/fb_nand.c b/drivers/fastboot/fb_nand.c
index c07655e49e..526bc12307 100644
--- a/common/fb_nand.c
+++ b/drivers/fastboot/fb_nand.c
@@ -31,7 +31,8 @@ __weak int board_fastboot_write_partition_setup(char *name)
static int fb_nand_lookup(const char *partname,
struct mtd_info **mtd,
- struct part_info **part)
+ struct part_info **part,
+ char *response)
{
struct mtd_device *dev;
int ret;
@@ -40,21 +41,21 @@ static int fb_nand_lookup(const char *partname,
ret = mtdparts_init();
if (ret) {
pr_err("Cannot initialize MTD partitions\n");
- fastboot_fail("cannot init mtdparts");
+ fastboot_fail("cannot init mtdparts", response);
return ret;
}
ret = find_dev_and_part(partname, &dev, &pnum, part);
if (ret) {
pr_err("cannot find partition: '%s'", partname);
- fastboot_fail("cannot find partition");
+ fastboot_fail("cannot find partition", response);
return ret;
}
if (dev->id->type != MTD_DEV_TYPE_NAND) {
pr_err("partition '%s' is not stored on a NAND device",
partname);
- fastboot_fail("not a NAND device");
+ fastboot_fail("not a NAND device", response);
return -EINVAL;
}
@@ -87,8 +88,8 @@ static int _fb_nand_erase(struct mtd_info *mtd, struct part_info *part)
}
static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
- void *buffer, unsigned int offset,
- unsigned int length, size_t *written)
+ void *buffer, u32 offset,
+ size_t length, size_t *written)
{
int flags = WITH_WR_VERIFY;
@@ -144,17 +145,40 @@ static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info,
return blkcnt + bad_blocks;
}
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes)
+/**
+ * fastboot_nand_get_part_info() - Lookup NAND partion by name
+ *
+ * @part_name: Named device to lookup
+ * @part_info: Pointer to returned part_info pointer
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_nand_get_part_info(char *part_name, struct part_info **part_info,
+ char *response)
+{
+ struct mtd_info *mtd = NULL;
+
+ return fb_nand_lookup(part_name, &mtd, part_info, response);
+}
+
+/**
+ * fastboot_nand_flash_write() - Write image to NAND for fastboot
+ *
+ * @cmd: Named device to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_flash_write(const char *cmd, void *download_buffer,
+ u32 download_bytes, char *response)
{
struct part_info *part;
struct mtd_info *mtd = NULL;
int ret;
- ret = fb_nand_lookup(cmd, &mtd, &part);
+ ret = fb_nand_lookup(cmd, &mtd, &part, response);
if (ret) {
pr_err("invalid NAND device");
- fastboot_fail("invalid NAND device");
+ fastboot_fail("invalid NAND device", response);
return;
}
@@ -180,9 +204,10 @@ void fb_nand_flash_write(const char *cmd, void *download_buffer,
sparse.start);
sparse.priv = &sparse_priv;
- ret = write_sparse_image(&sparse, cmd, download_buffer);
+ ret = write_sparse_image(&sparse, cmd, download_buffer,
+ response);
if (!ret)
- fastboot_okay("");
+ fastboot_okay(NULL, response);
} else {
printf("Flashing raw image at offset 0x%llx\n",
part->offset);
@@ -195,23 +220,29 @@ void fb_nand_flash_write(const char *cmd, void *download_buffer,
}
if (ret) {
- fastboot_fail("error writing the image");
+ fastboot_fail("error writing the image", response);
return;
}
- fastboot_okay("");
+ fastboot_okay(NULL, response);
}
-void fb_nand_erase(const char *cmd)
+/**
+ * fastboot_nand_flash_erase() - Erase NAND for fastboot
+ *
+ * @cmd: Named device to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_erase(const char *cmd, char *response)
{
struct part_info *part;
struct mtd_info *mtd = NULL;
int ret;
- ret = fb_nand_lookup(cmd, &mtd, &part);
+ ret = fb_nand_lookup(cmd, &mtd, &part, response);
if (ret) {
pr_err("invalid NAND device");
- fastboot_fail("invalid NAND device");
+ fastboot_fail("invalid NAND device", response);
return;
}
@@ -222,9 +253,9 @@ void fb_nand_erase(const char *cmd)
ret = _fb_nand_erase(mtd, part);
if (ret) {
pr_err("failed erasing from device %s", mtd->name);
- fastboot_fail("failed erasing from device");
+ fastboot_fail("failed erasing from device", response);
return;
}
- fastboot_okay("");
+ fastboot_okay(NULL, response);
}
diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c
index 3acadae8b1..3ad4346f2d 100644
--- a/drivers/usb/gadget/f_fastboot.c
+++ b/drivers/usb/gadget/f_fastboot.c
@@ -18,16 +18,7 @@
#include <linux/usb/gadget.h>
#include <linux/usb/composite.h>
#include <linux/compiler.h>
-#include <version.h>
#include <g_dnl.h>
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-#include <fb_mmc.h>
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
-#include <fb_nand.h>
-#endif
-
-#define FASTBOOT_VERSION "0.4"
#define FASTBOOT_INTERFACE_CLASS 0xff
#define FASTBOOT_INTERFACE_SUB_CLASS 0x42
@@ -58,8 +49,6 @@ static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
}
static struct f_fastboot *fastboot_func;
-static unsigned int download_size;
-static unsigned int download_bytes;
static struct usb_endpoint_descriptor fs_ep_in = {
.bLength = USB_DT_ENDPOINT_SIZE,
@@ -147,22 +136,6 @@ static struct usb_gadget_strings *fastboot_strings[] = {
};
static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
-static int strcmp_l1(const char *s1, const char *s2);
-
-
-static char *fb_response_str;
-
-void fastboot_fail(const char *reason)
-{
- strncpy(fb_response_str, "FAIL\0", 5);
- strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
-}
-
-void fastboot_okay(const char *reason)
-{
- strncpy(fb_response_str, "OKAY\0", 5);
- strncat(fb_response_str, reason, FASTBOOT_RESPONSE_LEN - 4 - 1);
-}
static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
{
@@ -372,90 +345,9 @@ static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
do_reset(NULL, 0, 0, NULL);
}
-int __weak fb_set_reboot_flag(void)
-{
- return -ENOSYS;
-}
-
-static void cb_reboot(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmd = req->buf;
- if (!strcmp_l1("reboot-bootloader", cmd)) {
- if (fb_set_reboot_flag()) {
- fastboot_tx_write_str("FAILCannot set reboot flag");
- return;
- }
- }
- fastboot_func->in_req->complete = compl_do_reset;
- fastboot_tx_write_str("OKAY");
-}
-
-static int strcmp_l1(const char *s1, const char *s2)
-{
- if (!s1 || !s2)
- return -1;
- return strncmp(s1, s2, strlen(s1));
-}
-
-static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmd = req->buf;
- char response[FASTBOOT_RESPONSE_LEN];
- const char *s;
- size_t chars_left;
-
- strcpy(response, "OKAY");
- chars_left = sizeof(response) - strlen(response) - 1;
-
- strsep(&cmd, ":");
- if (!cmd) {
- pr_err("missing variable");
- fastboot_tx_write_str("FAILmissing var");
- return;
- }
-
- if (!strcmp_l1("version", cmd)) {
- strncat(response, FASTBOOT_VERSION, chars_left);
- } else if (!strcmp_l1("bootloader-version", cmd)) {
- strncat(response, U_BOOT_VERSION, chars_left);
- } else if (!strcmp_l1("downloadsize", cmd) ||
- !strcmp_l1("max-download-size", cmd)) {
- char str_num[12];
-
- sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
- strncat(response, str_num, chars_left);
- } else if (!strcmp_l1("serialno", cmd)) {
- s = env_get("serial#");
- if (s)
- strncat(response, s, chars_left);
- else
- strcpy(response, "FAILValue not set");
- } else {
- char *envstr;
-
- envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1);
- if (!envstr) {
- fastboot_tx_write_str("FAILmalloc error");
- return;
- }
-
- sprintf(envstr, "fastboot.%s", cmd);
- s = env_get(envstr);
- if (s) {
- strncat(response, s, chars_left);
- } else {
- printf("WARNING: unknown variable: %s\n", cmd);
- strcpy(response, "FAILVariable not implemented");
- }
-
- free(envstr);
- }
- fastboot_tx_write_str(response);
-}
-
static unsigned int rx_bytes_expected(struct usb_ep *ep)
{
- int rx_remain = download_size - download_bytes;
+ int rx_remain = fastboot_data_remaining();
unsigned int rem;
unsigned int maxpacket = ep->maxpacket;
@@ -477,14 +369,12 @@ static unsigned int rx_bytes_expected(struct usb_ep *ep)
return rx_remain;
}
-#define BYTES_PER_DOT 0x20000
static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
{
- char response[FASTBOOT_RESPONSE_LEN];
- unsigned int transfer_size = download_size - download_bytes;
+ char response[FASTBOOT_RESPONSE_LEN] = {0};
+ unsigned int transfer_size = fastboot_data_remaining();
const unsigned char *buffer = req->buf;
unsigned int buffer_size = req->actual;
- unsigned int pre_dot_num, now_dot_num;
if (req->status != 0) {
printf("Bad status: %d\n", req->status);
@@ -494,33 +384,19 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
if (buffer_size < transfer_size)
transfer_size = buffer_size;
- memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
- buffer, transfer_size);
-
- pre_dot_num = download_bytes / BYTES_PER_DOT;
- download_bytes += transfer_size;
- now_dot_num = download_bytes / BYTES_PER_DOT;
-
- if (pre_dot_num != now_dot_num) {
- putc('.');
- if (!(now_dot_num % 74))
- putc('\n');
- }
+ fastboot_data_download(buffer, transfer_size, response);
+ if (response[0]) {
+ fastboot_tx_write_str(response);
+ } else if (!fastboot_data_remaining()) {
+ fastboot_data_complete(response);
- /* Check if transfer is done */
- if (download_bytes >= download_size) {
/*
- * Reset global transfer variable, keep download_bytes because
- * it will be used in the next possible flashing command
+ * Reset global transfer variable
*/
- download_size = 0;
req->complete = rx_handler_command;
req->length = EP_BUFFER_SIZE;
- strcpy(response, "OKAY");
fastboot_tx_write_str(response);
-
- printf("\ndownloading of %d bytes finished\n", download_bytes);
} else {
req->length = rx_bytes_expected(ep);
}
@@ -529,204 +405,55 @@ static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
usb_ep_queue(ep, req, 0);
}
-static void cb_download(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmd = req->buf;
- char response[FASTBOOT_RESPONSE_LEN];
-
- strsep(&cmd, ":");
- download_size = simple_strtoul(cmd, NULL, 16);
- download_bytes = 0;
-
- printf("Starting download of %d bytes\n", download_size);
-
- if (0 == download_size) {
- strcpy(response, "FAILdata invalid size");
- } else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
- download_size = 0;
- strcpy(response, "FAILdata too large");
- } else {
- sprintf(response, "DATA%08x", download_size);
- req->complete = rx_handler_dl_image;
- req->length = rx_bytes_expected(ep);
- }
- fastboot_tx_write_str(response);
-}
-
-static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
-{
- char boot_addr_start[12];
- char *bootm_args[] = { "bootm", boot_addr_start, NULL };
-
- puts("Booting kernel..\n");
-
- sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR);
- do_bootm(NULL, 0, 2, bootm_args);
-
- /* This only happens if image is somehow faulty so we start over */
- do_reset(NULL, 0, 0, NULL);
-}
-
-static void cb_boot(struct usb_ep *ep, struct usb_request *req)
-{
- fastboot_func->in_req->complete = do_bootm_on_complete;
- fastboot_tx_write_str("OKAY");
-}
-
static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
{
g_dnl_trigger_detach();
}
-static void cb_continue(struct usb_ep *ep, struct usb_request *req)
+static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
{
- fastboot_func->in_req->complete = do_exit_on_complete;
- fastboot_tx_write_str("OKAY");
+ fastboot_boot();
+ do_exit_on_complete(ep, req);
}
-#ifdef CONFIG_FASTBOOT_FLASH
-static void cb_flash(struct usb_ep *ep, struct usb_request *req)
+static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
{
- char *cmd = req->buf;
- char response[FASTBOOT_RESPONSE_LEN];
+ char *cmdbuf = req->buf;
+ char response[FASTBOOT_RESPONSE_LEN] = {0};
+ int cmd = -1;
- strsep(&cmd, ":");
- if (!cmd) {
- pr_err("missing partition name");
- fastboot_tx_write_str("FAILmissing partition name");
+ if (req->status != 0 || req->length == 0)
return;
- }
-
- /* initialize the response buffer */
- fb_response_str = response;
-
- fastboot_fail("no flash device defined");
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
- fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
- download_bytes);
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
- fb_nand_flash_write(cmd,
- (void *)CONFIG_FASTBOOT_BUF_ADDR,
- download_bytes);
-#endif
- fastboot_tx_write_str(response);
-}
-#endif
-static void cb_oem(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmd = req->buf;
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
- if (strncmp("format", cmd + 4, 6) == 0) {
- char cmdbuf[32];
- sprintf(cmdbuf, "gpt write mmc %x $partitions",
- CONFIG_FASTBOOT_FLASH_MMC_DEV);
- if (run_command(cmdbuf, 0))
- fastboot_tx_write_str("FAIL");
- else
- fastboot_tx_write_str("OKAY");
- } else
-#endif
- if (strncmp("unlock", cmd + 4, 8) == 0) {
- fastboot_tx_write_str("FAILnot implemented");
- }
- else {
- fastboot_tx_write_str("FAILunknown oem command");
+ if (req->actual < req->length) {
+ cmdbuf[req->actual] = '\0';
+ cmd = fastboot_handle_command(cmdbuf, response);
+ } else {
+ pr_err("buffer overflow");
+ fastboot_fail("buffer overflow", response);
}
-}
-
-#ifdef CONFIG_FASTBOOT_FLASH
-static void cb_erase(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmd = req->buf;
- char response[FASTBOOT_RESPONSE_LEN];
- strsep(&cmd, ":");
- if (!cmd) {
- pr_err("missing partition name");
- fastboot_tx_write_str("FAILmissing partition name");
- return;
+ if (!strncmp("DATA", response, 4)) {
+ req->complete = rx_handler_dl_image;
+ req->length = rx_bytes_expected(ep);
}
- /* initialize the response buffer */
- fb_response_str = response;
-
- fastboot_fail("no flash device defined");
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
- fb_mmc_erase(cmd);
-#endif
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
- fb_nand_erase(cmd);
-#endif
fastboot_tx_write_str(response);
-}
-#endif
-
-struct cmd_dispatch_info {
- char *cmd;
- void (*cb)(struct usb_ep *ep, struct usb_request *req);
-};
-
-static const struct cmd_dispatch_info cmd_dispatch_info[] = {
- {
- .cmd = "reboot",
- .cb = cb_reboot,
- }, {
- .cmd = "getvar:",
- .cb = cb_getvar,
- }, {
- .cmd = "download:",
- .cb = cb_download,
- }, {
- .cmd = "boot",
- .cb = cb_boot,
- }, {
- .cmd = "continue",
- .cb = cb_continue,
- },
-#ifdef CONFIG_FASTBOOT_FLASH
- {
- .cmd = "flash",
- .cb = cb_flash,
- }, {
- .cmd = "erase",
- .cb = cb_erase,
- },
-#endif
- {
- .cmd = "oem",
- .cb = cb_oem,
- },
-};
-
-static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
-{
- char *cmdbuf = req->buf;
- void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
- int i;
- if (req->status != 0 || req->length == 0)
- return;
+ if (!strncmp("OKAY", response, 4)) {
+ switch (cmd) {
+ case FASTBOOT_COMMAND_BOOT:
+ fastboot_func->in_req->complete = do_bootm_on_complete;
+ break;
- for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
- if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
- func_cb = cmd_dispatch_info[i].cb;
+ case FASTBOOT_COMMAND_CONTINUE:
+ fastboot_func->in_req->complete = do_exit_on_complete;
break;
- }
- }
- if (!func_cb) {
- pr_err("unknown command: %.*s", req->actual, cmdbuf);
- fastboot_tx_write_str("FAILunknown command");
- } else {
- if (req->actual < req->length) {
- u8 *buf = (u8 *)req->buf;
- buf[req->actual] = 0;
- func_cb(ep, req);
- } else {
- pr_err("buffer overflow");
- fastboot_tx_write_str("FAILbuffer overflow");
+ case FASTBOOT_COMMAND_REBOOT:
+ case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
+ fastboot_func->in_req->complete = compl_do_reset;
+ break;
}
}
diff --git a/drivers/usb/gadget/f_thor.c b/drivers/usb/gadget/f_thor.c
index c8eda05832..1aa6be44bb 100644
--- a/drivers/usb/gadget/f_thor.c
+++ b/drivers/usb/gadget/f_thor.c
@@ -620,22 +620,6 @@ static void thor_rx_tx_complete(struct usb_ep *ep, struct usb_request *req)
status, req->actual, req->length);
}
-static struct usb_request *thor_start_ep(struct usb_ep *ep)
-{
- struct usb_request *req;
-
- req = alloc_ep_req(ep, THOR_PACKET_SIZE);
- debug("%s: ep:%p req:%p\n", __func__, ep, req);
-
- if (!req)
- return NULL;
-
- memset(req->buf, 0, req->length);
- req->complete = thor_rx_tx_complete;
-
- return req;
-}
-
static void thor_setup_complete(struct usb_ep *ep, struct usb_request *req)
{
if (req->status || req->actual != req->length)
@@ -752,6 +736,13 @@ int thor_handle(void)
return 0;
}
+static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
+{
+ if (req->buf)
+ free(req->buf);
+ usb_ep_free_request(ep, req);
+}
+
static int thor_func_bind(struct usb_configuration *c, struct usb_function *f)
{
struct usb_gadget *gadget = c->cdev->gadget;
@@ -860,21 +851,18 @@ static int thor_func_bind(struct usb_configuration *c, struct usb_function *f)
return 0;
fail:
+ if (dev->req)
+ free_ep_req(gadget->ep0, dev->req);
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 thor_unbind(struct usb_configuration *c, struct usb_function *f)
{
struct f_thor *f_thor = func_to_thor(f);
struct thor_dev *dev = f_thor->dev;
+ free_ep_req(dev->gadget->ep0, dev->req);
free(dev);
memset(thor_func, 0, sizeof(*thor_func));
thor_func = NULL;
@@ -895,8 +883,6 @@ static void thor_func_disable(struct usb_function *f)
}
if (dev->out_ep->driver_data) {
- free(dev->out_req->buf);
- dev->out_req->buf = NULL;
usb_ep_free_request(dev->out_ep, dev->out_req);
usb_ep_disable(dev->out_ep);
dev->out_ep->driver_data = NULL;
@@ -924,16 +910,17 @@ static int thor_eps_setup(struct usb_function *f)
result = usb_ep_enable(ep, d);
if (result)
- goto exit;
+ goto err;
ep->driver_data = cdev; /* claim */
- req = thor_start_ep(ep);
+ req = alloc_ep_req(ep, THOR_PACKET_SIZE);
if (!req) {
- usb_ep_disable(ep);
result = -EIO;
- goto exit;
+ goto err_disable_in_ep;
}
+ memset(req->buf, 0, req->length);
+ req->complete = thor_rx_tx_complete;
dev->in_req = req;
ep = dev->out_ep;
d = ep_desc(gadget, &hs_out_desc, &fs_out_desc);
@@ -941,22 +928,34 @@ static int thor_eps_setup(struct usb_function *f)
result = usb_ep_enable(ep, d);
if (result)
- goto exit;
+ goto err_free_in_req;
ep->driver_data = cdev; /* claim */
- req = thor_start_ep(ep);
+ req = usb_ep_alloc_request(ep, 0);
if (!req) {
- usb_ep_disable(ep);
result = -EIO;
- goto exit;
+ goto err_disable_out_ep;
}
+ req->complete = thor_rx_tx_complete;
dev->out_req = req;
/* ACM control EP */
ep = dev->int_ep;
ep->driver_data = cdev; /* claim */
- exit:
+ return 0;
+
+ err_disable_out_ep:
+ usb_ep_disable(dev->out_ep);
+
+ err_free_in_req:
+ free_ep_req(dev->in_ep, dev->in_req);
+ dev->in_req = NULL;
+
+ err_disable_in_ep:
+ usb_ep_disable(dev->in_ep);
+
+ err:
return result;
}
diff --git a/drivers/usb/host/xhci-rcar.c b/drivers/usb/host/xhci-rcar.c
index a837afc483..f2e91ef0fe 100644
--- a/drivers/usb/host/xhci-rcar.c
+++ b/drivers/usb/host/xhci-rcar.c
@@ -117,12 +117,15 @@ err_clk:
static int xhci_rcar_deregister(struct udevice *dev)
{
+ int ret;
struct rcar_xhci_platdata *plat = dev_get_platdata(dev);
+ ret = xhci_deregister(dev);
+
clk_disable(&plat->clk);
clk_free(&plat->clk);
- return xhci_deregister(dev);
+ return ret;
}
static int xhci_rcar_ofdata_to_platdata(struct udevice *dev)
diff --git a/drivers/usb/host/xhci-rockchip.c b/drivers/usb/host/xhci-rockchip.c
index 060a6c4309..f19bea3a91 100644
--- a/drivers/usb/host/xhci-rockchip.c
+++ b/drivers/usb/host/xhci-rockchip.c
@@ -17,7 +17,6 @@
struct rockchip_xhci_platdata {
fdt_addr_t hcd_base;
- fdt_addr_t phy_base;
struct udevice *vbus_supply;
};
@@ -35,7 +34,6 @@ struct rockchip_xhci {
static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
{
struct rockchip_xhci_platdata *plat = dev_get_platdata(dev);
- struct udevice *child;
int ret = 0;
/*
@@ -47,20 +45,6 @@ static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
return -ENXIO;
}
- /* Get the base address for usbphy from the device node */
- for (device_find_first_child(dev, &child); child;
- device_find_next_child(&child)) {
- if (!device_is_compatible(child, "rockchip,rk3399-usb3-phy"))
- continue;
- plat->phy_base = devfdt_get_addr(child);
- break;
- }
-
- if (plat->phy_base == FDT_ADDR_T_NONE) {
- pr_err("Can't get the usbphy register address\n");
- return -ENXIO;
- }
-
/* Vbus regulator */
ret = device_get_supply_regulator(dev, "vbus-supply",
&plat->vbus_supply);
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 3adb0028f2..9ded14cc3c 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -536,7 +536,7 @@ static int xhci_set_configuration(struct usb_device *udev)
/* slot context */
xhci_slot_copy(ctrl, in_ctx, out_ctx);
slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
- slot_ctx->dev_info &= ~(LAST_CTX_MASK);
+ slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
@@ -1424,7 +1424,7 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
/* Initialize the input context control */
- ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
+ ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
ctrl_ctx->drop_flags = 0;
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -1435,8 +1435,15 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
/* Update hub related fields */
slot_ctx->dev_info |= cpu_to_le32(DEV_HUB);
- if (hub->tt.multi && udev->speed == USB_SPEED_HIGH)
+ /*
+ * refer to section 6.2.2: MTT should be 0 for full speed hub,
+ * but it may be already set to 1 when setup an xHCI virtual
+ * device, so clear it anyway.
+ */
+ if (hub->tt.multi)
slot_ctx->dev_info |= cpu_to_le32(DEV_MTT);
+ else if (udev->speed == USB_SPEED_FULL)
+ slot_ctx->dev_info &= cpu_to_le32(~DEV_MTT);
slot_ctx->dev_info2 |= cpu_to_le32(XHCI_MAX_PORTS(udev->maxchild));
/*
* Set TT think time - convert from ns to FS bit times.
@@ -1452,6 +1459,7 @@ static int xhci_update_hub_device(struct udevice *dev, struct usb_device *udev)
think_time = (think_time / 666) - 1;
if (udev->speed == USB_SPEED_HIGH)
slot_ctx->tt_info |= cpu_to_le32(TT_THINK_TIME(think_time));
+ slot_ctx->dev_state = 0;
return xhci_configure_endpoints(udev, false);
}
diff --git a/fs/fs.c b/fs/fs.c
index 94cdc37deb..33808d549e 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -265,6 +265,19 @@ static struct fstype_info *fs_get_info(int fstype)
return info;
}
+/**
+ * fs_get_type_name() - Get type of current filesystem
+ *
+ * Return: Pointer to filesystem name
+ *
+ * Returns a string describing the current filesystem, or the sentinel
+ * "unsupported" for any unrecognised filesystem.
+ */
+const char *fs_get_type_name(void)
+{
+ return fs_get_info(fs_type)->name;
+}
+
int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)
{
struct fstype_info *info;
diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h
new file mode 100644
index 0000000000..bf2f2b3c89
--- /dev/null
+++ b/include/fastboot-internal.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _FASTBOOT_INTERNAL_H_
+#define _FASTBOOT_INTERNAL_H_
+
+/**
+ * fastboot_buf_addr - base address of the fastboot download buffer
+ */
+extern void *fastboot_buf_addr;
+
+/**
+ * fastboot_buf_size - size of the fastboot download buffer
+ */
+extern u32 fastboot_buf_size;
+
+/**
+ * fastboot_progress_callback - callback executed during long operations
+ */
+extern void (*fastboot_progress_callback)(const char *msg);
+
+/**
+ * fastboot_getvar() - Writes variable indicated by cmd_parameter to response.
+ *
+ * @cmd_parameter: Pointer to command parameter
+ * @response: Pointer to fastboot response buffer
+ *
+ * Look up cmd_parameter first as an environment variable of the form
+ * fastboot.<cmd_parameter>, if that exists return use its value to set
+ * response.
+ *
+ * Otherwise lookup the name of variable and execute the appropriate
+ * function to return the requested value.
+ */
+void fastboot_getvar(char *cmd_parameter, char *response);
+
+#endif
diff --git a/include/fastboot.h b/include/fastboot.h
index 009f1a72e1..1933b1d98e 100644
--- a/include/fastboot.h
+++ b/include/fastboot.h
@@ -12,10 +12,143 @@
#ifndef _FASTBOOT_H_
#define _FASTBOOT_H_
+#define FASTBOOT_VERSION "0.4"
+
/* The 64 defined bytes plus \0 */
+#define FASTBOOT_COMMAND_LEN (64 + 1)
#define FASTBOOT_RESPONSE_LEN (64 + 1)
-void fastboot_fail(const char *reason);
-void fastboot_okay(const char *reason);
+/**
+ * All known commands to fastboot
+ */
+enum {
+ FASTBOOT_COMMAND_GETVAR = 0,
+ FASTBOOT_COMMAND_DOWNLOAD,
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+ FASTBOOT_COMMAND_FLASH,
+ FASTBOOT_COMMAND_ERASE,
+#endif
+ FASTBOOT_COMMAND_BOOT,
+ FASTBOOT_COMMAND_CONTINUE,
+ FASTBOOT_COMMAND_REBOOT,
+ FASTBOOT_COMMAND_REBOOT_BOOTLOADER,
+ FASTBOOT_COMMAND_SET_ACTIVE,
+#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_FORMAT)
+ FASTBOOT_COMMAND_OEM_FORMAT,
+#endif
+
+ FASTBOOT_COMMAND_COUNT
+};
+
+/**
+ * fastboot_response() - Writes a response of the form "$tag$reason".
+ *
+ * @tag: The first part of the response
+ * @response: Pointer to fastboot response buffer
+ * @format: printf style format string
+ */
+void fastboot_response(const char *tag, char *response,
+ const char *format, ...)
+ __attribute__ ((format (__printf__, 3, 4)));
+
+/**
+ * fastboot_fail() - Write a FAIL response of the form "FAIL$reason".
+ *
+ * @reason: Pointer to returned reason string
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_fail(const char *reason, char *response);
+
+/**
+ * fastboot_okay() - Write an OKAY response of the form "OKAY$reason".
+ *
+ * @reason: Pointer to returned reason string, or NULL to send a bare "OKAY"
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_okay(const char *reason, char *response);
+
+/**
+ * fastboot_set_reboot_flag() - Set flag to indicate reboot-bootloader
+ *
+ * Set flag which indicates that we should reboot into the bootloader
+ * following the reboot that fastboot executes after this function.
+ *
+ * This function should be overridden in your board file with one
+ * which sets whatever flag your board specific Android bootloader flow
+ * requires in order to re-enter the bootloader.
+ */
+int fastboot_set_reboot_flag(void);
+
+/**
+ * fastboot_set_progress_callback() - set progress callback
+ *
+ * @progress: Pointer to progress callback
+ *
+ * Set a callback which is invoked periodically during long running operations
+ * (flash and erase). This can be used (for example) by the UDP transport to
+ * send INFO responses to keep the client alive whilst those commands are
+ * executing.
+ */
+void fastboot_set_progress_callback(void (*progress)(const char *msg));
+
+/*
+ * fastboot_init() - initialise new fastboot protocol session
+ *
+ * @buf_addr: Pointer to download buffer, or NULL for default
+ * @buf_size: Size of download buffer, or zero for default
+ */
+void fastboot_init(void *buf_addr, u32 buf_size);
+
+/**
+ * fastboot_boot() - Execute fastboot boot command
+ *
+ * If ${fastboot_bootcmd} is set, run that command to execute the boot
+ * process, if that returns, then exit the fastboot server and return
+ * control to the caller.
+ *
+ * Otherwise execute "bootm <fastboot_buf_addr>", if that fails, reset
+ * the board.
+ */
+void fastboot_boot(void);
+
+/**
+ * fastboot_handle_command() - Handle fastboot command
+ *
+ * @cmd_string: Pointer to command string
+ * @response: Pointer to fastboot response buffer
+ *
+ * Return: Executed command, or -1 if not recognized
+ */
+int fastboot_handle_command(char *cmd_string, char *response);
+
+/**
+ * fastboot_data_remaining() - return bytes remaining in current transfer
+ *
+ * Return: Number of bytes left in the current download
+ */
+u32 fastboot_data_remaining(void);
+
+/**
+ * fastboot_data_download() - Copy image data to fastboot_buf_addr.
+ *
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @response: Pointer to fastboot response buffer
+ *
+ * Copies image data from fastboot_data to fastboot_buf_addr. Writes to
+ * response. fastboot_bytes_received is updated to indicate the number
+ * of bytes that have been transferred.
+ */
+void fastboot_data_download(const void *fastboot_data,
+ unsigned int fastboot_data_len, char *response);
+
+/**
+ * fastboot_data_complete() - Mark current transfer complete
+ *
+ * @response: Pointer to fastboot response buffer
+ *
+ * Set image_size and ${filesize} to the total size of the downloaded image.
+ */
+void fastboot_data_complete(char *response);
#endif /* _FASTBOOT_H_ */
diff --git a/include/fb_mmc.h b/include/fb_mmc.h
index a2d7c4895f..fd5db9eac8 100644
--- a/include/fb_mmc.h
+++ b/include/fb_mmc.h
@@ -3,6 +3,35 @@
* Copyright 2014 Broadcom Corporation.
*/
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes);
-void fb_mmc_erase(const char *cmd);
+#ifndef _FB_MMC_H_
+#define _FB_MMC_H_
+
+/**
+ * fastboot_mmc_get_part_info() - Lookup eMMC partion by name
+ *
+ * @part_name: Named partition to lookup
+ * @dev_desc: Pointer to returned blk_desc pointer
+ * @part_info: Pointer to returned disk_partition_t
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_mmc_get_part_info(char *part_name, struct blk_desc **dev_desc,
+ disk_partition_t *part_info, char *response);
+
+/**
+ * fastboot_mmc_flash_write() - Write image to eMMC for fastboot
+ *
+ * @cmd: Named partition to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_flash_write(const char *cmd, void *download_buffer,
+ u32 download_bytes, char *response);
+/**
+ * fastboot_mmc_flash_erase() - Erase eMMC for fastboot
+ *
+ * @cmd: Named partition to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_mmc_erase(const char *cmd, char *response);
+#endif
diff --git a/include/fb_nand.h b/include/fb_nand.h
index 3daae8c4ca..08ab0e28a6 100644
--- a/include/fb_nand.h
+++ b/include/fb_nand.h
@@ -4,6 +4,37 @@
* Copyright 2015 Free Electrons.
*/
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
- unsigned int download_bytes);
-void fb_nand_erase(const char *cmd);
+#ifndef _FB_NAND_H_
+#define _FB_NAND_H_
+
+#include <jffs2/load_kernel.h>
+
+/**
+ * fastboot_nand_get_part_info() - Lookup NAND partion by name
+ *
+ * @part_name: Named device to lookup
+ * @part_info: Pointer to returned part_info pointer
+ * @response: Pointer to fastboot response buffer
+ */
+int fastboot_nand_get_part_info(char *part_name, struct part_info **part_info,
+ char *response);
+
+/**
+ * fastboot_nand_flash_write() - Write image to NAND for fastboot
+ *
+ * @cmd: Named device to write image to
+ * @download_buffer: Pointer to image data
+ * @download_bytes: Size of image data
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_flash_write(const char *cmd, void *download_buffer,
+ u32 download_bytes, char *response);
+
+/**
+ * fastboot_nand_flash_erase() - Erase NAND for fastboot
+ *
+ * @cmd: Named device to erase
+ * @response: Pointer to fastboot response buffer
+ */
+void fastboot_nand_erase(const char *cmd, char *response);
+#endif
diff --git a/include/fs.h b/include/fs.h
index d703ed5027..163da103b4 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -37,6 +37,16 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype);
*/
int fs_set_blk_dev_with_part(struct blk_desc *desc, int part);
+/**
+ * fs_get_type_name() - Get type of current filesystem
+ *
+ * Return: Pointer to filesystem name
+ *
+ * Returns a string describing the current filesystem, or the sentinel
+ * "unsupported" for any unrecognised filesystem.
+ */
+const char *fs_get_type_name(void);
+
/*
* Print the list of files on the partition previously set by fs_set_blk_dev(),
* in directory "dirname".
diff --git a/include/image-sparse.h b/include/image-sparse.h
index f39dc16617..234c237b84 100644
--- a/include/image-sparse.h
+++ b/include/image-sparse.h
@@ -23,7 +23,7 @@ struct sparse_storage {
lbaint_t blk,
lbaint_t blkcnt);
- void (*mssg)(const char *str);
+ void (*mssg)(const char *str, char *response);
};
static inline int is_sparse_image(void *buf)
@@ -38,4 +38,4 @@ static inline int is_sparse_image(void *buf)
}
int write_sparse_image(struct sparse_storage *info, const char *part_name,
- void *data);
+ void *data, char *response);
diff --git a/include/net.h b/include/net.h
index 65f51d77a5..5760685556 100644
--- a/include/net.h
+++ b/include/net.h
@@ -535,7 +535,7 @@ extern int net_restart_wrap; /* Tried all network devices */
enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
- TFTPSRV, TFTPPUT, LINKLOCAL
+ TFTPSRV, TFTPPUT, LINKLOCAL, FASTBOOT
};
extern char net_boot_file_name[1024];/* Boot File name */
diff --git a/include/net/fastboot.h b/include/net/fastboot.h
new file mode 100644
index 0000000000..68602095d2
--- /dev/null
+++ b/include/net/fastboot.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#ifndef __NET_FASTBOOT_H__
+#define __NET_FASTBOOT_H__
+
+/**********************************************************************/
+/*
+ * Global functions and variables.
+ */
+
+/**
+ * Wait for incoming fastboot comands.
+ */
+void fastboot_start_server(void);
+
+/**********************************************************************/
+
+#endif /* __NET_FASTBOOT_H__ */
diff --git a/lib/Kconfig b/lib/Kconfig
index 1590f7afa4..15c6a52d4a 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -61,6 +61,17 @@ config SPL_STRTO
config TPL_STRTO
bool
+config IMAGE_SPARSE
+ bool
+
+config IMAGE_SPARSE_FILLBUF_SIZE
+ hex "Android sparse image CHUNK_TYPE_FILL buffer size"
+ default 0x80000
+ depends on IMAGE_SPARSE
+ help
+ Set the size of the fill buffer used when processing CHUNK_TYPE_FILL
+ chunks.
+
config USE_PRIVATE_LIBGCC
bool "Use private libgcc"
depends on HAVE_PRIVATE_LIBGCC
diff --git a/lib/Makefile b/lib/Makefile
index e6cb4afc23..c0511cbff8 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_FIT) += fdtdec_common.o
obj-$(CONFIG_TEST_FDTDEC) += fdtdec_test.o
obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
+obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
obj-y += initcall.o
obj-$(CONFIG_LMB) += lmb.o
obj-y += ldiv.o
diff --git a/common/image-sparse.c b/lib/image-sparse.c
index 9223b9a1b8..036062139b 100644
--- a/common/image-sparse.c
+++ b/lib/image-sparse.c
@@ -44,14 +44,10 @@
#include <linux/math64.h>
-#ifndef CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
-#define CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE (1024 * 512)
-#endif
-
-static void default_log(const char *ignored) {}
+static void default_log(const char *ignored, char *response) {}
int write_sparse_image(struct sparse_storage *info,
- const char *part_name, void *data)
+ const char *part_name, void *data, char *response)
{
lbaint_t blk;
lbaint_t blkcnt;
@@ -69,7 +65,7 @@ int write_sparse_image(struct sparse_storage *info,
int i;
int j;
- fill_buf_num_blks = CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE / info->blksz;
+ fill_buf_num_blks = CONFIG_IMAGE_SPARSE_FILLBUF_SIZE / info->blksz;
/* Read and skip over sparse image header */
sparse_header = (sparse_header_t *)data;
@@ -104,7 +100,7 @@ int write_sparse_image(struct sparse_storage *info,
if (offset) {
printf("%s: Sparse image block size issue [%u]\n",
__func__, sparse_header->blk_sz);
- info->mssg("sparse image block size issue");
+ info->mssg("sparse image block size issue", response);
return -1;
}
@@ -139,7 +135,8 @@ int write_sparse_image(struct sparse_storage *info,
case CHUNK_TYPE_RAW:
if (chunk_header->total_sz !=
(sparse_header->chunk_hdr_sz + chunk_data_sz)) {
- info->mssg("Bogus chunk size for chunk type Raw");
+ info->mssg("Bogus chunk size for chunk type Raw",
+ response);
return -1;
}
@@ -147,7 +144,8 @@ int write_sparse_image(struct sparse_storage *info,
printf(
"%s: Request would exceed partition size!\n",
__func__);
- info->mssg("Request would exceed partition size!");
+ info->mssg("Request would exceed partition size!",
+ response);
return -1;
}
@@ -157,7 +155,7 @@ int write_sparse_image(struct sparse_storage *info,
printf("%s: %s" LBAFU " [" LBAFU "]\n",
__func__, "Write failed, block #",
blk, blks);
- info->mssg("flash write failure");
+ info->mssg("flash write failure", response);
return -1;
}
blk += blks;
@@ -169,7 +167,7 @@ int write_sparse_image(struct sparse_storage *info,
case CHUNK_TYPE_FILL:
if (chunk_header->total_sz !=
(sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
- info->mssg("Bogus chunk size for chunk type FILL");
+ info->mssg("Bogus chunk size for chunk type FILL", response);
return -1;
}
@@ -179,7 +177,8 @@ int write_sparse_image(struct sparse_storage *info,
info->blksz * fill_buf_num_blks,
ARCH_DMA_MINALIGN));
if (!fill_buf) {
- info->mssg("Malloc failed for: CHUNK_TYPE_FILL");
+ info->mssg("Malloc failed for: CHUNK_TYPE_FILL",
+ response);
return -1;
}
@@ -196,7 +195,8 @@ int write_sparse_image(struct sparse_storage *info,
printf(
"%s: Request would exceed partition size!\n",
__func__);
- info->mssg("Request would exceed partition size!");
+ info->mssg("Request would exceed partition size!",
+ response);
return -1;
}
@@ -211,7 +211,8 @@ int write_sparse_image(struct sparse_storage *info,
__func__,
"Write failed, block #",
blk, j);
- info->mssg("flash write failure");
+ info->mssg("flash write failure",
+ response);
free(fill_buf);
return -1;
}
@@ -231,7 +232,8 @@ int write_sparse_image(struct sparse_storage *info,
case CHUNK_TYPE_CRC32:
if (chunk_header->total_sz !=
sparse_header->chunk_hdr_sz) {
- info->mssg("Bogus chunk size for chunk type Dont Care");
+ info->mssg("Bogus chunk size for chunk type Dont Care",
+ response);
return -1;
}
total_blocks += chunk_header->chunk_sz;
@@ -241,7 +243,7 @@ int write_sparse_image(struct sparse_storage *info,
default:
printf("%s: Unknown chunk type: %x\n", __func__,
chunk_header->chunk_type);
- info->mssg("Unknown chunk type");
+ info->mssg("Unknown chunk type", response);
return -1;
}
}
@@ -251,7 +253,7 @@ int write_sparse_image(struct sparse_storage *info,
printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
if (total_blocks != sparse_header->total_blks) {
- info->mssg("sparse image write failure");
+ info->mssg("sparse image write failure", response);
return -1;
}
diff --git a/net/Makefile b/net/Makefile
index d1e8e01f62..07466879f5 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_CMD_PING) += ping.o
obj-$(CONFIG_CMD_RARP) += rarp.o
obj-$(CONFIG_CMD_SNTP) += sntp.o
obj-$(CONFIG_CMD_TFTPBOOT) += tftp.o
+obj-$(CONFIG_UDP_FUNCTION_FASTBOOT) += fastboot.o
# Disable this warning as it is triggered by:
# sprintf(buf, index ? "foo%d" : "foo", index)
diff --git a/net/fastboot.c b/net/fastboot.c
new file mode 100644
index 0000000000..a9f7c0743d
--- /dev/null
+++ b/net/fastboot.c
@@ -0,0 +1,317 @@
+// SPDX-License-Identifier: BSD-2-Clause
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ */
+
+#include <common.h>
+#include <fastboot.h>
+#include <net.h>
+#include <net/fastboot.h>
+
+/* Fastboot port # defined in spec */
+#define WELL_KNOWN_PORT 5554
+
+enum {
+ FASTBOOT_ERROR = 0,
+ FASTBOOT_QUERY = 1,
+ FASTBOOT_INIT = 2,
+ FASTBOOT_FASTBOOT = 3,
+};
+
+struct __packed fastboot_header {
+ uchar id;
+ uchar flags;
+ unsigned short seq;
+};
+
+#define PACKET_SIZE 1024
+#define DATA_SIZE (PACKET_SIZE - sizeof(struct fastboot_header))
+
+/* Sequence number sent for every packet */
+static unsigned short sequence_number = 1;
+static const unsigned short packet_size = PACKET_SIZE;
+static const unsigned short udp_version = 1;
+
+/* Keep track of last packet for resubmission */
+static uchar last_packet[PACKET_SIZE];
+static unsigned int last_packet_len;
+
+static struct in_addr fastboot_remote_ip;
+/* The UDP port at their end */
+static int fastboot_remote_port;
+/* The UDP port at our end */
+static int fastboot_our_port;
+
+static void boot_downloaded_image(void);
+
+#if CONFIG_IS_ENABLED(FASTBOOT_FLASH)
+/**
+ * fastboot_udp_send_info() - Send an INFO packet during long commands.
+ *
+ * @msg: String describing the reason for waiting
+ */
+static void fastboot_udp_send_info(const char *msg)
+{
+ uchar *packet;
+ uchar *packet_base;
+ int len = 0;
+ char response[FASTBOOT_RESPONSE_LEN] = {0};
+
+ struct fastboot_header response_header = {
+ .id = FASTBOOT_FASTBOOT,
+ .flags = 0,
+ .seq = htons(sequence_number)
+ };
+ ++sequence_number;
+ packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
+ packet_base = packet;
+
+ /* Write headers */
+ memcpy(packet, &response_header, sizeof(response_header));
+ packet += sizeof(response_header);
+ /* Write response */
+ fastboot_response("INFO", response, "%s", msg);
+ memcpy(packet, response, strlen(response));
+ packet += strlen(response);
+
+ len = packet - packet_base;
+
+ /* Save packet for retransmitting */
+ last_packet_len = len;
+ memcpy(last_packet, packet_base, last_packet_len);
+
+ net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+ fastboot_remote_port, fastboot_our_port, len);
+}
+
+/**
+ * fastboot_timed_send_info() - Send INFO packet every 30 seconds
+ *
+ * @msg: String describing the reason for waiting
+ *
+ * Send an INFO packet during long commands based on timer. An INFO packet
+ * is sent if the time is 30 seconds after start. Else, noop.
+ */
+static void fastboot_timed_send_info(const char *msg)
+{
+ static ulong start;
+
+ /* Initialize timer */
+ if (start == 0)
+ start = get_timer(0);
+ ulong time = get_timer(start);
+ /* Send INFO packet to host every 30 seconds */
+ if (time >= 30000) {
+ start = get_timer(0);
+ fastboot_udp_send_info(msg);
+ }
+}
+#endif
+
+/**
+ * fastboot_send() - Sends a packet in response to received fastboot packet
+ *
+ * @header: Header for response packet
+ * @fastboot_data: Pointer to received fastboot data
+ * @fastboot_data_len: Length of received fastboot data
+ * @retransmit: Nonzero if sending last sent packet
+ */
+static void fastboot_send(struct fastboot_header header, char *fastboot_data,
+ unsigned int fastboot_data_len, uchar retransmit)
+{
+ uchar *packet;
+ uchar *packet_base;
+ int len = 0;
+ const char *error_msg = "An error occurred.";
+ short tmp;
+ struct fastboot_header response_header = header;
+ static char command[FASTBOOT_COMMAND_LEN];
+ static int cmd = -1;
+ static bool pending_command;
+ char response[FASTBOOT_RESPONSE_LEN] = {0};
+
+ /*
+ * We will always be sending some sort of packet, so
+ * cobble together the packet headers now.
+ */
+ packet = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
+ packet_base = packet;
+
+ /* Resend last packet */
+ if (retransmit) {
+ memcpy(packet, last_packet, last_packet_len);
+ net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+ fastboot_remote_port, fastboot_our_port,
+ last_packet_len);
+ return;
+ }
+
+ response_header.seq = htons(response_header.seq);
+ memcpy(packet, &response_header, sizeof(response_header));
+ packet += sizeof(response_header);
+
+ switch (header.id) {
+ case FASTBOOT_QUERY:
+ tmp = htons(sequence_number);
+ memcpy(packet, &tmp, sizeof(tmp));
+ packet += sizeof(tmp);
+ break;
+ case FASTBOOT_INIT:
+ tmp = htons(udp_version);
+ memcpy(packet, &tmp, sizeof(tmp));
+ packet += sizeof(tmp);
+ tmp = htons(packet_size);
+ memcpy(packet, &tmp, sizeof(tmp));
+ packet += sizeof(tmp);
+ break;
+ case FASTBOOT_ERROR:
+ memcpy(packet, error_msg, strlen(error_msg));
+ packet += strlen(error_msg);
+ break;
+ case FASTBOOT_FASTBOOT:
+ if (cmd == FASTBOOT_COMMAND_DOWNLOAD) {
+ if (!fastboot_data_len && !fastboot_data_remaining()) {
+ fastboot_data_complete(response);
+ } else {
+ fastboot_data_download(fastboot_data,
+ fastboot_data_len,
+ response);
+ }
+ } else if (!pending_command) {
+ strlcpy(command, fastboot_data,
+ min((size_t)fastboot_data_len + 1,
+ sizeof(command)));
+ pending_command = true;
+ } else {
+ cmd = fastboot_handle_command(command, response);
+ pending_command = false;
+ }
+ /*
+ * Sent some INFO packets, need to update sequence number in
+ * header
+ */
+ if (header.seq != sequence_number) {
+ response_header.seq = htons(sequence_number);
+ memcpy(packet_base, &response_header,
+ sizeof(response_header));
+ }
+ /* Write response to packet */
+ memcpy(packet, response, strlen(response));
+ packet += strlen(response);
+ break;
+ default:
+ pr_err("ID %d not implemented.\n", header.id);
+ return;
+ }
+
+ len = packet - packet_base;
+
+ /* Save packet for retransmitting */
+ last_packet_len = len;
+ memcpy(last_packet, packet_base, last_packet_len);
+
+ net_send_udp_packet(net_server_ethaddr, fastboot_remote_ip,
+ fastboot_remote_port, fastboot_our_port, len);
+
+ /* Continue boot process after sending response */
+ if (!strncmp("OKAY", response, 4)) {
+ switch (cmd) {
+ case FASTBOOT_COMMAND_BOOT:
+ boot_downloaded_image();
+ break;
+
+ case FASTBOOT_COMMAND_CONTINUE:
+ net_set_state(NETLOOP_SUCCESS);
+ break;
+
+ case FASTBOOT_COMMAND_REBOOT:
+ case FASTBOOT_COMMAND_REBOOT_BOOTLOADER:
+ do_reset(NULL, 0, 0, NULL);
+ break;
+ }
+ }
+
+ if (!strncmp("OKAY", response, 4) || !strncmp("FAIL", response, 4))
+ cmd = -1;
+}
+
+/**
+ * boot_downloaded_image() - Boots into downloaded image.
+ */
+static void boot_downloaded_image(void)
+{
+ fastboot_boot();
+ net_set_state(NETLOOP_SUCCESS);
+}
+
+/**
+ * fastboot_handler() - Incoming UDP packet handler.
+ *
+ * @packet: Pointer to incoming UDP packet
+ * @dport: Destination UDP port
+ * @sip: Source IP address
+ * @sport: Source UDP port
+ * @len: Packet length
+ */
+static void fastboot_handler(uchar *packet, unsigned int dport,
+ struct in_addr sip, unsigned int sport,
+ unsigned int len)
+{
+ struct fastboot_header header;
+ char fastboot_data[DATA_SIZE] = {0};
+ unsigned int fastboot_data_len = 0;
+
+ if (dport != fastboot_our_port)
+ return;
+
+ fastboot_remote_ip = sip;
+ fastboot_remote_port = sport;
+
+ if (len < sizeof(struct fastboot_header) || len > PACKET_SIZE)
+ return;
+ memcpy(&header, packet, sizeof(header));
+ header.flags = 0;
+ header.seq = ntohs(header.seq);
+ packet += sizeof(header);
+ len -= sizeof(header);
+
+ switch (header.id) {
+ case FASTBOOT_QUERY:
+ fastboot_send(header, fastboot_data, 0, 0);
+ break;
+ case FASTBOOT_INIT:
+ case FASTBOOT_FASTBOOT:
+ fastboot_data_len = len;
+ if (len > 0)
+ memcpy(fastboot_data, packet, len);
+ if (header.seq == sequence_number) {
+ fastboot_send(header, fastboot_data,
+ fastboot_data_len, 0);
+ sequence_number++;
+ } else if (header.seq == sequence_number - 1) {
+ /* Retransmit last sent packet */
+ fastboot_send(header, fastboot_data,
+ fastboot_data_len, 1);
+ }
+ break;
+ default:
+ pr_err("ID %d not implemented.\n", header.id);
+ header.id = FASTBOOT_ERROR;
+ fastboot_send(header, fastboot_data, 0, 0);
+ break;
+ }
+}
+
+void fastboot_start_server(void)
+{
+ printf("Using %s device\n", eth_get_name());
+ printf("Listening for fastboot command on %pI4\n", &net_ip);
+
+ fastboot_our_port = WELL_KNOWN_PORT;
+
+ fastboot_set_progress_callback(fastboot_timed_send_info);
+ net_set_udp_handler(fastboot_handler);
+
+ /* zero out server ether in case the server ip has changed */
+ memset(net_server_ethaddr, 0, 6);
+}
diff --git a/net/net.c b/net/net.c
index 7f85211442..a4932f46d9 100644
--- a/net/net.c
+++ b/net/net.c
@@ -87,6 +87,7 @@
#include <environment.h>
#include <errno.h>
#include <net.h>
+#include <net/fastboot.h>
#include <net/tftp.h>
#if defined(CONFIG_LED_STATUS)
#include <miiphy.h>
@@ -451,6 +452,11 @@ restart:
tftp_start_server();
break;
#endif
+#ifdef CONFIG_UDP_FUNCTION_FASTBOOT
+ case FASTBOOT:
+ fastboot_start_server();
+ break;
+#endif
#if defined(CONFIG_CMD_DHCP)
case DHCP:
bootp_reset();
@@ -1322,6 +1328,7 @@ common:
/* Fall through */
case NETCONS:
+ case FASTBOOT:
case TFTPSRV:
if (net_ip.s_addr == 0) {
puts("*** ERROR: `ipaddr' not set\n");
diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt
index aa6dec0c7b..d681937026 100644
--- a/scripts/config_whitelist.txt
+++ b/scripts/config_whitelist.txt
@@ -589,8 +589,6 @@ CONFIG_EXYNOS_RELOCATE_CODE_BASE
CONFIG_EXYNOS_SPL
CONFIG_EXYNOS_TMU
CONFIG_FACTORYSET
-CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
-CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
CONFIG_FAST_FLASH_BIT
CONFIG_FB_ADDR
CONFIG_FB_BACKLIGHT