fastboot: Move fastboot to drivers/fastboot
authorAlex Kiernan <alex.kiernan@gmail.com>
Tue, 29 May 2018 15:30:39 +0000 (15:30 +0000)
committerMarek Vasut <marex@denx.de>
Wed, 30 May 2018 09:59:21 +0000 (11:59 +0200)
Separate CMD_FASTBOOT from FASTBOOT and move code and configuration to
drivers/fastboot.

Switch dependencies on FASTBOOT to USB_FUNCTION_FASTBOOT as anyone who wants
FASTBOOT before this series wants USB_FUNCTION_FASTBOOT. Split
USB_FUNCTION_FASTBOOT from FASTBOOT so they retain their existing
behaviour.

Signed-off-by: Alex Kiernan <alex.kiernan@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
50 files changed:
arch/arm/Kconfig
board/ti/common/Kconfig
cmd/Kconfig
cmd/fastboot/Kconfig [deleted file]
common/Makefile
common/fb_mmc.c [deleted file]
common/fb_nand.c [deleted file]
configs/am335x_boneblack_defconfig
configs/am335x_boneblack_vboot_defconfig
configs/am335x_evm_defconfig
configs/am335x_evm_nor_defconfig
configs/am335x_evm_norboot_defconfig
configs/am335x_evm_spiboot_defconfig
configs/am335x_evm_usbspl_defconfig
configs/am57xx_evm_defconfig
configs/am57xx_hs_evm_defconfig
configs/bcm23550_w1d_defconfig
configs/bcm28155_ap_defconfig
configs/birdland_bav335a_defconfig
configs/birdland_bav335b_defconfig
configs/cgtqmx6eval_defconfig
configs/dra7xx_evm_defconfig
configs/dra7xx_hs_evm_defconfig
configs/imx6dl_mamoj_defconfig
configs/kc1_defconfig
configs/mx6qsabrelite_defconfig
configs/mx6sabresd_defconfig
configs/nitrogen6dl2g_defconfig
configs/nitrogen6dl_defconfig
configs/nitrogen6q2g_defconfig
configs/nitrogen6q_defconfig
configs/nitrogen6s1g_defconfig
configs/nitrogen6s_defconfig
configs/omap3_beagle_defconfig
configs/omap3_evm_defconfig
configs/omap3_logic_defconfig
configs/sniper_defconfig
configs/stih410-b2260_defconfig
configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
configs/xilinx_zynqmp_zcu102_revA_defconfig
configs/xilinx_zynqmp_zcu102_revB_defconfig
configs/xilinx_zynqmp_zcu106_revA_defconfig
drivers/Kconfig
drivers/Makefile
drivers/fastboot/Kconfig [new file with mode: 0644]
drivers/fastboot/Makefile [new file with mode: 0644]
drivers/fastboot/fb_mmc.c [new file with mode: 0644]
drivers/fastboot/fb_nand.c [new file with mode: 0644]

index 582e84cf4014555bd593459da994a17b65d7df7b..dde422bc5d53ce661747f86149fde1a33fe40bbd 100644 (file)
@@ -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
index c21eb8c2d2e39c9d17c8ec3616a1faa8c0fbf413..b1956b810035ab5e1ff64427942353453fcb0d05 100644 (file)
@@ -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
index d532c9fc41c05f8b43ee2553c2d441d43ebed211..9848c067daa96d9c5fcdd07e3c1ae560d9c46544 100644 (file)
@@ -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 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
diff --git a/cmd/fastboot/Kconfig b/cmd/fastboot/Kconfig
deleted file mode 100644 (file)
index 0d2c2f1..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-comment "FASTBOOT"
-
-menuconfig FASTBOOT
-       bool "Fastboot support"
-       depends on USB_GADGET
-       default y if ARCH_SUNXI && USB_MUSB_GADGET
-
-if FASTBOOT
-
-config USB_FUNCTION_FASTBOOT
-       bool "Enable USB fastboot gadget"
-       default y
-       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"
-       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.
-
-if USB_FUNCTION_FASTBOOT
-
-config FASTBOOT_BUF_ADDR
-       hex "Define FASTBOOT buffer address"
-       default 0x82000000 if MX6SX || MX6SL || MX6UL || MX6SLL
-       default 0x81000000 if ARCH_OMAP2PLUS
-       default 0x42000000 if ARCH_SUNXI && !MACH_SUN9I
-       default 0x22000000 if ARCH_SUNXI && MACH_SUN9I
-       default 0x60800800 if ROCKCHIP_RK3036 || ROCKCHIP_RK3188 || \
-                               ROCKCHIP_RK322X
-       default 0x800800 if ROCKCHIP_RK3288 || ROCKCHIP_RK3329 || \
-                               ROCKCHIP_RK3399
-       default 0x280000 if ROCKCHIP_RK3368
-       default 0x100000 if ARCH_ZYNQMP
-       help
-         The fastboot protocol requires a large memory buffer for
-         downloads. Define this to the starting RAM address to use for
-         downloaded images.
-
-config FASTBOOT_BUF_SIZE
-       hex "Define FASTBOOT buffer size"
-       default 0x8000000 if ARCH_ROCKCHIP
-       default 0x6000000 if ARCH_ZYNQMP
-       default 0x2000000 if ARCH_SUNXI
-       default 0x7000000
-       help
-         The fastboot protocol requires a large memory buffer for
-         downloads. This buffer should be as large as possible for a
-         platform. Define this to the size available RAM for fastboot.
-
-config FASTBOOT_USB_DEV
-       int "USB controller number"
-       default 0
-       help
-         Some boards have USB OTG controller other than 0. Define this
-         option so it can be used in compiled environment (e.g. in
-         CONFIG_BOOTCOMMAND).
-
-config FASTBOOT_FLASH
-       bool "Enable FASTBOOT FLASH command"
-       default y if ARCH_SUNXI
-       help
-         The fastboot protocol includes a "flash" command for writing
-         the downloaded image to a non-volatile storage device. Define
-         this to enable the "fastboot flash" command.
-
-choice
-       prompt "Flash provider for FASTBOOT"
-       depends on FASTBOOT_FLASH
-
-config FASTBOOT_FLASH_MMC
-       bool "FASTBOOT on MMC"
-       depends on MMC
-
-config FASTBOOT_FLASH_NAND
-       bool "FASTBOOT on NAND"
-       depends on NAND
-
-endchoice
-
-config FASTBOOT_FLASH_MMC_DEV
-       int "Define FASTBOOT MMC FLASH default device"
-       depends on FASTBOOT_FLASH_MMC
-       default 0 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1
-       default 1 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1
-       help
-         The fastboot "flash" command requires additional information
-         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"
-       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.
-
-config FASTBOOT_GPT_NAME
-       string "Target name for updating GPT"
-       depends on FASTBOOT_FLASH
-       default "gpt"
-       help
-         The fastboot "flash" command supports writing the downloaded
-         image to the Protective MBR and the Primary GUID Partition
-         Table. (Additionally, this downloaded image is post-processed
-         to generate and write the Backup GUID Partition Table.)
-         This occurs when the specified "partition name" on the
-         "fastboot flash" command line matches the value defined here.
-         The default target name for updating GPT is "gpt".
-
-config FASTBOOT_MBR_NAME
-       string "Target name for updating MBR"
-       depends on FASTBOOT_FLASH
-       default "mbr"
-       help
-         The fastboot "flash" command allows to write the downloaded image
-         to the Master Boot Record. This occurs when the "partition 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
-
-endif # FASTBOOT
index d0681c7dd96ac87f0636d6d18501a03164fee9bb..9ec40b9d272ce4b2f4a4d3a9a2f14477c5a037f2 100644 (file)
@@ -29,7 +29,7 @@ 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_FASTBOOT_FLASH) += image-sparse.o
 obj-$(CONFIG_MII) += miiphyutil.o
 obj-$(CONFIG_CMD_MII) += miiphyutil.o
 obj-$(CONFIG_PHYLIB) += miiphyutil.o
@@ -109,19 +109,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/common/fb_mmc.c b/common/fb_mmc.c
deleted file mode 100644 (file)
index 46f0073..0000000
+++ /dev/null
@@ -1,406 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2014 Broadcom Corporation.
- */
-
-#include <config.h>
-#include <common.h>
-#include <blk.h>
-#include <fastboot.h>
-#include <fb_mmc.h>
-#include <image-sparse.h>
-#include <part.h>
-#include <mmc.h>
-#include <div64.h>
-#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 BOOT_PARTITION_NAME "boot"
-
-struct fb_mmc_sparse {
-       struct blk_desc *dev_desc;
-};
-
-static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
-               const char *name, disk_partition_t *info)
-{
-       int ret;
-
-       ret = part_get_info_by_name(dev_desc, name, info);
-       if (ret < 0) {
-               /* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
-               char env_alias_name[25 + 32 + 1];
-               char *aliased_part_name;
-
-               /* check for alias */
-               strcpy(env_alias_name, "fastboot_partition_alias_");
-               strncat(env_alias_name, name, 32);
-               aliased_part_name = env_get(env_alias_name);
-               if (aliased_part_name != NULL)
-                       ret = part_get_info_by_name(dev_desc,
-                                       aliased_part_name, info);
-       }
-       return ret;
-}
-
-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);
-}
-
-static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
-               lbaint_t blk, lbaint_t blkcnt)
-{
-       return blkcnt;
-}
-
-static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
-               const char *part_name, void *buffer,
-               unsigned int download_bytes)
-{
-       lbaint_t blkcnt;
-       lbaint_t blks;
-
-       /* determine number of blocks to write */
-       blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
-       blkcnt = lldiv(blkcnt, info->blksz);
-
-       if (blkcnt > info->size) {
-               pr_err("too large for partition: '%s'\n", part_name);
-               fastboot_fail("too large for partition");
-               return;
-       }
-
-       puts("Flashing Raw Image\n");
-
-       blks = blk_dwrite(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");
-               return;
-       }
-
-       printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
-              part_name);
-       fastboot_okay("");
-}
-
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-/**
- * Read Android boot image header from boot partition.
- *
- * @param[in] dev_desc MMC device descriptor
- * @param[in] info Boot partition info
- * @param[out] hdr Where to store read boot image header
- *
- * @return Boot image header sectors count or 0 on error
- */
-static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
-                                      disk_partition_t *info,
-                                      struct andr_img_hdr *hdr)
-{
-       ulong sector_size;              /* boot partition sector size */
-       lbaint_t hdr_sectors;           /* boot image header sectors count */
-       int res;
-
-       /* Calculate boot image sectors count */
-       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");
-               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");
-               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");
-               return 0;
-       }
-
-       return hdr_sectors;
-}
-
-/**
- * Write downloaded zImage to boot partition and repack it properly.
- *
- * @param dev_desc MMC device descriptor
- * @param download_buffer Address to fastboot buffer with zImage in it
- * @param download_bytes Size of fastboot buffer, in bytes
- *
- * @return 0 on success or -1 on error
- */
-static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
-                               void *download_buffer,
-                               unsigned int download_bytes)
-{
-       uintptr_t hdr_addr;                     /* boot image header address */
-       struct andr_img_hdr *hdr;               /* boot image header */
-       lbaint_t hdr_sectors;                   /* boot image header sectors */
-       u8 *ramdisk_buffer;
-       u32 ramdisk_sector_start;
-       u32 ramdisk_sectors;
-       u32 kernel_sector_start;
-       u32 kernel_sectors;
-       u32 sectors_per_page;
-       disk_partition_t info;
-       int res;
-
-       puts("Flashing zImage\n");
-
-       /* 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");
-               return -1;
-       }
-
-       /* Put boot image header in fastboot buffer after downloaded zImage */
-       hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
-       hdr = (struct andr_img_hdr *)hdr_addr;
-
-       /* Read boot image header */
-       hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
-       if (hdr_sectors == 0) {
-               pr_err("unable to read boot image header");
-               fastboot_fail("unable to read boot image header");
-               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");
-               return -1;
-       }
-
-       /* Extract ramdisk location */
-       sectors_per_page = hdr->page_size / info.blksz;
-       ramdisk_sector_start = info.start + sectors_per_page;
-       ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
-                                            sectors_per_page;
-       ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
-                                      sectors_per_page;
-
-       /* Read ramdisk and put it in fastboot buffer after boot image header */
-       ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
-       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");
-               return -1;
-       }
-
-       /* Write new kernel size to boot image header */
-       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");
-               return -1;
-       }
-
-       /* Write the new downloaded kernel */
-       kernel_sector_start = info.start + sectors_per_page;
-       kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
-                                     sectors_per_page;
-       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");
-               return -1;
-       }
-
-       /* Write the saved ramdisk back */
-       ramdisk_sector_start = info.start + sectors_per_page;
-       ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
-                                            sectors_per_page;
-       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");
-               return -1;
-       }
-
-       puts("........ zImage was updated in boot partition\n");
-       fastboot_okay("");
-       return 0;
-}
-#endif
-
-void fb_mmc_flash_write(const char *cmd, void *download_buffer,
-                       unsigned int download_bytes)
-{
-       struct blk_desc *dev_desc;
-       disk_partition_t info;
-
-       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");
-               return;
-       }
-
-#if CONFIG_IS_ENABLED(EFI_PARTITION)
-       if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
-               printf("%s: updating MBR, Primary and Backup GPT(s)\n",
-                      __func__);
-               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");
-                       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");
-                       return;
-               }
-               printf("........ success\n");
-               fastboot_okay("");
-               return;
-       }
-#endif
-
-#if CONFIG_IS_ENABLED(DOS_PARTITION)
-       if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
-               printf("%s: updating MBR\n", __func__);
-               if (is_valid_dos_buf(download_buffer)) {
-                       printf("%s: invalid MBR - refusing to write to flash\n",
-                              __func__);
-                       fastboot_fail("invalid MBR partition");
-                       return;
-               }
-               if (write_mbr_partition(dev_desc, download_buffer)) {
-                       printf("%s: writing MBR partition failed\n", __func__);
-                       fastboot_fail("writing MBR partition failed");
-                       return;
-               }
-               printf("........ success\n");
-               fastboot_okay("");
-               return;
-       }
-#endif
-
-#ifdef CONFIG_ANDROID_BOOT_IMAGE
-       if (strncasecmp(cmd, "zimage", 6) == 0) {
-               fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
-               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");
-               return;
-       }
-
-       if (is_sparse_image(download_buffer)) {
-               struct fb_mmc_sparse sparse_priv;
-               struct sparse_storage sparse;
-               int err;
-
-               sparse_priv.dev_desc = dev_desc;
-
-               sparse.blksz = info.blksz;
-               sparse.start = info.start;
-               sparse.size = info.size;
-               sparse.write = fb_mmc_sparse_write;
-               sparse.reserve = fb_mmc_sparse_reserve;
-               sparse.mssg = fastboot_fail;
-
-               printf("Flashing sparse image at offset " LBAFU "\n",
-                      sparse.start);
-
-               sparse.priv = &sparse_priv;
-               err = write_sparse_image(&sparse, cmd, download_buffer);
-               if (!err)
-                       fastboot_okay("");
-       } else {
-               write_raw_image(dev_desc, &info, cmd, download_buffer,
-                               download_bytes);
-       }
-}
-
-void fb_mmc_erase(const char *cmd)
-{
-       int ret;
-       struct blk_desc *dev_desc;
-       disk_partition_t info;
-       lbaint_t blks, blks_start, blks_size, grp_size;
-       struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
-
-       if (mmc == NULL) {
-               pr_err("invalid mmc device");
-               fastboot_fail("invalid mmc device");
-               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");
-               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");
-               return;
-       }
-
-       /* Align blocks to erase group size to avoid erasing other partitions */
-       grp_size = mmc->erase_grp_size;
-       blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
-       if (info.size >= grp_size)
-               blks_size = (info.size - (blks_start - info.start)) &
-                               (~(grp_size - 1));
-       else
-               blks_size = 0;
-
-       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);
-       if (blks != blks_size) {
-               pr_err("failed erasing from device %d", dev_desc->devnum);
-               fastboot_fail("failed erasing from device");
-               return;
-       }
-
-       printf("........ erased " LBAFU " bytes from '%s'\n",
-              blks_size * info.blksz, cmd);
-       fastboot_okay("");
-}
diff --git a/common/fb_nand.c b/common/fb_nand.c
deleted file mode 100644 (file)
index c07655e..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright 2014 Broadcom Corporation.
- * Copyright 2015 Free Electrons.
- */
-
-#include <config.h>
-#include <common.h>
-
-#include <fastboot.h>
-#include <image-sparse.h>
-
-#include <linux/mtd/mtd.h>
-#include <jffs2/jffs2.h>
-#include <nand.h>
-
-struct fb_nand_sparse {
-       struct mtd_info         *mtd;
-       struct part_info        *part;
-};
-
-__weak int board_fastboot_erase_partition_setup(char *name)
-{
-       return 0;
-}
-
-__weak int board_fastboot_write_partition_setup(char *name)
-{
-       return 0;
-}
-
-static int fb_nand_lookup(const char *partname,
-                         struct mtd_info **mtd,
-                         struct part_info **part)
-{
-       struct mtd_device *dev;
-       int ret;
-       u8 pnum;
-
-       ret = mtdparts_init();
-       if (ret) {
-               pr_err("Cannot initialize MTD partitions\n");
-               fastboot_fail("cannot init mtdparts");
-               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");
-               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");
-               return -EINVAL;
-       }
-
-       *mtd = get_nand_dev_by_index(dev->id->num);
-
-       return 0;
-}
-
-static int _fb_nand_erase(struct mtd_info *mtd, struct part_info *part)
-{
-       nand_erase_options_t opts;
-       int ret;
-
-       memset(&opts, 0, sizeof(opts));
-       opts.offset = part->offset;
-       opts.length = part->size;
-       opts.quiet = 1;
-
-       printf("Erasing blocks 0x%llx to 0x%llx\n",
-              part->offset, part->offset + part->size);
-
-       ret = nand_erase_opts(mtd, &opts);
-       if (ret)
-               return ret;
-
-       printf("........ erased 0x%llx bytes from '%s'\n",
-              part->size, part->name);
-
-       return 0;
-}
-
-static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
-                         void *buffer, unsigned int offset,
-                         unsigned int length, size_t *written)
-{
-       int flags = WITH_WR_VERIFY;
-
-#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
-       flags |= WITH_DROP_FFS;
-#endif
-
-       return nand_write_skip_bad(mtd, offset, &length, written,
-                                  part->size - (offset - part->offset),
-                                  buffer, flags);
-}
-
-static lbaint_t fb_nand_sparse_write(struct sparse_storage *info,
-               lbaint_t blk, lbaint_t blkcnt, const void *buffer)
-{
-       struct fb_nand_sparse *sparse = info->priv;
-       size_t written;
-       int ret;
-
-       ret = _fb_nand_write(sparse->mtd, sparse->part, (void *)buffer,
-                            blk * info->blksz,
-                            blkcnt * info->blksz, &written);
-       if (ret < 0) {
-               printf("Failed to write sparse chunk\n");
-               return ret;
-       }
-
-/* TODO - verify that the value "written" includes the "bad-blocks" ... */
-
-       /*
-        * the return value must be 'blkcnt' ("good-blocks") plus the
-        * number of "bad-blocks" encountered within this space...
-        */
-       return written / info->blksz;
-}
-
-static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info,
-               lbaint_t blk, lbaint_t blkcnt)
-{
-       int bad_blocks = 0;
-
-/*
- * TODO - implement a function to determine the total number
- * of blocks which must be used in order to reserve the specified
- * number ("blkcnt") of "good-blocks", starting at "blk"...
- * ( possibly something like the "check_skip_len()" function )
- */
-
-       /*
-        * the return value must be 'blkcnt' ("good-blocks") plus the
-        * number of "bad-blocks" encountered within this space...
-        */
-       return blkcnt + bad_blocks;
-}
-
-void fb_nand_flash_write(const char *cmd, void *download_buffer,
-                        unsigned int download_bytes)
-{
-       struct part_info *part;
-       struct mtd_info *mtd = NULL;
-       int ret;
-
-       ret = fb_nand_lookup(cmd, &mtd, &part);
-       if (ret) {
-               pr_err("invalid NAND device");
-               fastboot_fail("invalid NAND device");
-               return;
-       }
-
-       ret = board_fastboot_write_partition_setup(part->name);
-       if (ret)
-               return;
-
-       if (is_sparse_image(download_buffer)) {
-               struct fb_nand_sparse sparse_priv;
-               struct sparse_storage sparse;
-
-               sparse_priv.mtd = mtd;
-               sparse_priv.part = part;
-
-               sparse.blksz = mtd->writesize;
-               sparse.start = part->offset / sparse.blksz;
-               sparse.size = part->size / sparse.blksz;
-               sparse.write = fb_nand_sparse_write;
-               sparse.reserve = fb_nand_sparse_reserve;
-               sparse.mssg = fastboot_fail;
-
-               printf("Flashing sparse image at offset " LBAFU "\n",
-                      sparse.start);
-
-               sparse.priv = &sparse_priv;
-               ret = write_sparse_image(&sparse, cmd, download_buffer);
-               if (!ret)
-                       fastboot_okay("");
-       } else {
-               printf("Flashing raw image at offset 0x%llx\n",
-                      part->offset);
-
-               ret = _fb_nand_write(mtd, part, download_buffer, part->offset,
-                                    download_bytes, NULL);
-
-               printf("........ wrote %u bytes to '%s'\n",
-                      download_bytes, part->name);
-       }
-
-       if (ret) {
-               fastboot_fail("error writing the image");
-               return;
-       }
-
-       fastboot_okay("");
-}
-
-void fb_nand_erase(const char *cmd)
-{
-       struct part_info *part;
-       struct mtd_info *mtd = NULL;
-       int ret;
-
-       ret = fb_nand_lookup(cmd, &mtd, &part);
-       if (ret) {
-               pr_err("invalid NAND device");
-               fastboot_fail("invalid NAND device");
-               return;
-       }
-
-       ret = board_fastboot_erase_partition_setup(part->name);
-       if (ret)
-               return;
-
-       ret = _fb_nand_erase(mtd, part);
-       if (ret) {
-               pr_err("failed erasing from device %s", mtd->name);
-               fastboot_fail("failed erasing from device");
-               return;
-       }
-
-       fastboot_okay("");
-}
index 5c01b20dff188ebd6249547ec804b100c7126801..bd3a37427df84fa18442b478cedb57334e51a847 100644 (file)
@@ -16,7 +16,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_FASTBOOT_FLASH=y
 CONFIG_FASTBOOT_FLASH_MMC_DEV=1
 CONFIG_CMD_SPL=y
index abbacdc77ec4b1657141fa51acdd38295c101d9e..baaae36d288c5a9822e5dadefc0644859049deff 100644 (file)
@@ -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
index 6732013b03f5bf4a0beec22f36ec7e31f9febcb1..cc556d1c3d7b01e46889ac990058d51373619d6e 100644 (file)
@@ -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
index bbde07fb1d64da69e73a5d6cf4a1ce7acef8eaa8..41a5c79604d6c746e7e3edf7dc6a58d25558cec1 100644 (file)
@@ -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
index 3ddcf649423c48a3665dd12052773f68c3d8655e..75d0793f2d2c7ee01e032d071ff26f81e2c463c8 100644 (file)
@@ -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"
index 10eb0fe1ee8cbf7914129ec033373fbd46c67e56..b2678875ecab6e9b9b838bafa650cfd6cee3273e 100644 (file)
@@ -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
index dc9ac216c215a2d215f6de72007e6bf9605bf546..44012919a366c741dcac5575d2763a2bd7beda75 100644 (file)
@@ -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
index 0e992684412ce8bf6b5d8d171234ab3693aaaffa..3b83b69e5f41b6e070199e09fca924cd57150e41 100644 (file)
@@ -24,7 +24,7 @@ CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
 CONFIG_FASTBOOT_USB_DEV=1
index 165c2a40ba084fa65a773bedfef459c3daca953c..9c2aef482f7ff757fb8b85bc0c0a118f887a07c5 100644 (file)
@@ -29,7 +29,7 @@ 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_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
 CONFIG_FASTBOOT_USB_DEV=1
index 9a986ca9ae8a8500ae75bb340e59e84c3ce3b4b8..de4fa60df7c9cc5bf336302a47cf8d285d0f27fc 100644 (file)
@@ -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
index d26cde5b0ed0954f063dbe71fb2808e2d37e255c..4f7a58e362a85c12b8eaa4ea487f527e11f462c4 100644 (file)
@@ -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
index 51b3e6b4e1a1bbe9b9e5bfeef1fdb59bb8c41f84..3efd5669a74924c101bc01e844756eafd8b6d42a 100644 (file)
@@ -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
index 29b223a58062382f8fe96910427c81cda294cec2..2f981168734959abd53c06f8bfca747fdb2e307f 100644 (file)
@@ -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
index d4204aa7122067231fd256383894aa4192188ff5..241e9582a5a255a8a4263d2f964d98f7100f4730 100644 (file)
@@ -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
index 9b81b0cc7168c1e27388efd1d7ad9654fea08b83..b766ba27cda0c39ba0489342f48385a396dd552c 100644 (file)
@@ -25,7 +25,7 @@ CONFIG_SPL_SEPARATE_BSS=y
 CONFIG_SPL_DMA_SUPPORT=y
 CONFIG_SPL_OS_BOOT=y
 CONFIG_SPL_SPI_LOAD=y
-CONFIG_FASTBOOT=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
 CONFIG_FASTBOOT_FLASH=y
index 536946eb29007db39d6f247660f850308c4983a0..39a6801216f927ac8d9b42db971b2941601cd3f5 100644 (file)
@@ -30,7 +30,7 @@ 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_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x82000000
 CONFIG_FASTBOOT_BUF_SIZE=0x2F000000
 CONFIG_FASTBOOT_FLASH=y
index 0001457f5d08f702f34d963dd2b1bb21693be4df..40a128b8cbcc5032b1bfa6534870553b1c2836b3 100644 (file)
@@ -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
index 534d60484a078196137e796ff3f499304073bdd0..ce71e37011aeeef66af2d9900ed04f7930b3dd57 100644 (file)
@@ -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
index 966e823b40d7901c6248e0cfaa9714846bf97168..a4740d49cf428d240688b91313a96d3bbc4711d5 100644 (file)
@@ -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
index ca37d8bef80ec8164f9ab6fbfc4a6ed9a53500a4..5c8e9de0819ffb91f27266e34d522bc5097d0abe 100644 (file)
@@ -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
index 6ef4226db910a23d84dbc3fad26e8fc27539577b..cfb2ed8889d238d8445e2fba0d8f2789cbcc927c 100644 (file)
@@ -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
index b9784a2d23fed3698b6845392c4b41a1b49c386c..9cb7ac22d5441bccda5a75448b6dc02ef7d59f3f 100644 (file)
@@ -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
index 61688ba49e48fdf6b45291f3a4d9074c94ead62f..e31521a0609a685193725cc8dbff37a362978933 100644 (file)
@@ -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
index cfee7ba88916972ae84a0613e5d23232dda35ec7..85c352c6f0030acd00fcfb091bfc5bab78be4f13 100644 (file)
@@ -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
index 0f29a56c4646e6d3ce039ff29d9a64b7eb4d0ace..1f3732019da77e27028cafc55c92e2d3460006f7 100644 (file)
@@ -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
index 7ad1584af27fecab669e219899cc628d41e1283a..0696f09d5e68c3b8d834fc6b43819962071d1c98 100644 (file)
@@ -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
index 7b81b039c9fd94a0cd6bb0b6af1ad80fb0123ad9..05dc73755f326f00ec54418be620a35f6cf3c0a0 100644 (file)
@@ -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
index 20795c3170fdd5492eacd439e039964c13f894e1..52285cc1651f82e64322c41d80ac517d321628df 100644 (file)
@@ -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
index 5a31e46dbaf5b00836aceaa06675ffe9914b2996..953980c95c962583be9f66593371bbf7ef9fdf9b 100644 (file)
@@ -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
index ad22a1cbe2ff1f683479dc5c1773a41f5f9b8de5..70e485fab27c865376e46149ef488d12fbaac288 100644 (file)
@@ -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
index 67391bdfdf73e2e5c5e3d6ded08f027f9ac0d311..7d990f9a34f338b1d07f676e3d292a30a4f4dbf2 100644 (file)
@@ -10,7 +10,7 @@ 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_USB_FUNCTION_FASTBOOT=y
 CONFIG_FASTBOOT_BUF_ADDR=0x40000000
 CONFIG_FASTBOOT_BUF_SIZE=0x3DF00000
 CONFIG_FASTBOOT_FLASH=y
index f5a33342fa64164836c1e42f1479123d367c35a4..9e4886d0647ed5b56220150ba193f208e6971001 100644 (file)
@@ -19,7 +19,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_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
index 7f7ee558ee7ef25d14e8d826004ec263c142581d..9d9216f5fe75d1e106234e66c12393921efce206 100644 (file)
@@ -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
index 4cb3959f3626b655e1baddcfb64009839187b403..29743bdb1e65386be632022506da2be9a8365053 100644 (file)
@@ -19,7 +19,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_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
index e989d1635c3092ee361f97811ce8a7c7161d59dd..cc4118230e65d4654edd6f0222f729dceac74652 100644 (file)
@@ -19,7 +19,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_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
index bd67df904a2df1b7371896af379a3e72f7f8101a..ae791c356781d8aa2b357df10674afa344e6350e 100644 (file)
@@ -19,7 +19,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_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
index a5fa33e366aec95201cca465f6271366cd92cf8c..34e3c857e2169ed0106e47e69118f8508161a071 100644 (file)
@@ -18,7 +18,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_FASTBOOT_FLASH_MMC_DEV=0
 CONFIG_CMD_THOR_DOWNLOAD=y
index c2e813f5adf73762743245a95fd833991ed5cc64..8424898dbdc6226c645a2436c10c90c8370fe455 100644 (file)
@@ -28,6 +28,8 @@ source "drivers/dfu/Kconfig"
 
 source "drivers/dma/Kconfig"
 
+source "drivers/fastboot/Kconfig"
+
 source "drivers/firmware/Kconfig"
 
 source "drivers/fpga/Kconfig"
index b3f1b600a558cef08d1f750c1b42b27a6bb9ad51..a79ff2e6b0065953d8a307a605793fbee6271512 100644 (file)
@@ -71,6 +71,9 @@ obj-y += block/
 obj-$(CONFIG_BOOTCOUNT_LIMIT) += bootcount/
 obj-$(CONFIG_CPU) += cpu/
 obj-y += crypto/
+ifneq ($(CONFIG_FASTBOOT_FLASH_MMC_DEV)$(CONFIG_FASTBOOT_FLASH_NAND_DEV),)
+obj-y += fastboot/
+endif
 obj-y += firmware/
 obj-$(CONFIG_FPGA) += fpga/
 obj-y += misc/
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig
new file mode 100644 (file)
index 0000000..93a8ac6
--- /dev/null
@@ -0,0 +1,123 @@
+menu "Fastboot support"
+
+config FASTBOOT
+       bool
+       imply ANDROID_BOOT_IMAGE
+       imply CMD_FASTBOOT
+
+config USB_FUNCTION_FASTBOOT
+       bool "Enable USB fastboot gadget"
+       depends on USB_GADGET
+       default y if ARCH_SUNXI && USB_MUSB_GADGET
+       select FASTBOOT
+       select USB_GADGET_DOWNLOAD
+       help
+         This enables the USB part of the fastboot gadget.
+
+if FASTBOOT
+
+config FASTBOOT_BUF_ADDR
+       hex "Define FASTBOOT buffer address"
+       default 0x82000000 if MX6SX || MX6SL || MX6UL || MX6SLL
+       default 0x81000000 if ARCH_OMAP2PLUS
+       default 0x42000000 if ARCH_SUNXI && !MACH_SUN9I
+       default 0x22000000 if ARCH_SUNXI && MACH_SUN9I
+       default 0x60800800 if ROCKCHIP_RK3036 || ROCKCHIP_RK3188 || \
+                               ROCKCHIP_RK322X
+       default 0x800800 if ROCKCHIP_RK3288 || ROCKCHIP_RK3329 || \
+                               ROCKCHIP_RK3399
+       default 0x280000 if ROCKCHIP_RK3368
+       default 0x100000 if ARCH_ZYNQMP
+       help
+         The fastboot protocol requires a large memory buffer for
+         downloads. Define this to the starting RAM address to use for
+         downloaded images.
+
+config FASTBOOT_BUF_SIZE
+       hex "Define FASTBOOT buffer size"
+       default 0x8000000 if ARCH_ROCKCHIP
+       default 0x6000000 if ARCH_ZYNQMP
+       default 0x2000000 if ARCH_SUNXI
+       default 0x7000000
+       help
+         The fastboot protocol requires a large memory buffer for
+         downloads. This buffer should be as large as possible for a
+         platform. Define this to the size available RAM for fastboot.
+
+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
+         option so it can be used in compiled environment (e.g. in
+         CONFIG_BOOTCOMMAND).
+
+config FASTBOOT_FLASH
+       bool "Enable FASTBOOT FLASH command"
+       default y if ARCH_SUNXI
+       help
+         The fastboot protocol includes a "flash" command for writing
+         the downloaded image to a non-volatile storage device. Define
+         this to enable the "fastboot flash" command.
+
+choice
+       prompt "Flash provider for FASTBOOT"
+       depends on FASTBOOT_FLASH
+
+config FASTBOOT_FLASH_MMC
+       bool "FASTBOOT on MMC"
+       depends on MMC
+
+config FASTBOOT_FLASH_NAND
+       bool "FASTBOOT on NAND"
+       depends on NAND
+
+endchoice
+
+config FASTBOOT_FLASH_MMC_DEV
+       int "Define FASTBOOT MMC FLASH default device"
+       depends on FASTBOOT_FLASH_MMC
+       default 0 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA = -1
+       default 1 if ARCH_SUNXI && MMC_SUNXI_SLOT_EXTRA != -1
+       help
+         The fastboot "flash" command requires additional information
+         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"
+       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.
+
+config FASTBOOT_GPT_NAME
+       string "Target name for updating GPT"
+       depends on FASTBOOT_FLASH
+       default "gpt"
+       help
+         The fastboot "flash" command supports writing the downloaded
+         image to the Protective MBR and the Primary GUID Partition
+         Table. (Additionally, this downloaded image is post-processed
+         to generate and write the Backup GUID Partition Table.)
+         This occurs when the specified "partition name" on the
+         "fastboot flash" command line matches the value defined here.
+         The default target name for updating GPT is "gpt".
+
+config FASTBOOT_MBR_NAME
+       string "Target name for updating MBR"
+       depends on FASTBOOT_FLASH
+       default "mbr"
+       help
+         The fastboot "flash" command allows to write the downloaded image
+         to the Master Boot Record. This occurs when the "partition name"
+         specified on the "fastboot flash" command line matches the value
+         defined here. The default target name for updating MBR is "mbr".
+
+endif # FASTBOOT
+
+endmenu
diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile
new file mode 100644 (file)
index 0000000..651fbf0
--- /dev/null
@@ -0,0 +1,8 @@
+# SPDX-License-Identifier:      GPL-2.0+
+
+ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
+obj-y += fb_mmc.o
+endif
+ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
+obj-y += fb_nand.o
+endif
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c
new file mode 100644 (file)
index 0000000..46f0073
--- /dev/null
@@ -0,0 +1,406 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <blk.h>
+#include <fastboot.h>
+#include <fb_mmc.h>
+#include <image-sparse.h>
+#include <part.h>
+#include <mmc.h>
+#include <div64.h>
+#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 BOOT_PARTITION_NAME "boot"
+
+struct fb_mmc_sparse {
+       struct blk_desc *dev_desc;
+};
+
+static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc,
+               const char *name, disk_partition_t *info)
+{
+       int ret;
+
+       ret = part_get_info_by_name(dev_desc, name, info);
+       if (ret < 0) {
+               /* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
+               char env_alias_name[25 + 32 + 1];
+               char *aliased_part_name;
+
+               /* check for alias */
+               strcpy(env_alias_name, "fastboot_partition_alias_");
+               strncat(env_alias_name, name, 32);
+               aliased_part_name = env_get(env_alias_name);
+               if (aliased_part_name != NULL)
+                       ret = part_get_info_by_name(dev_desc,
+                                       aliased_part_name, info);
+       }
+       return ret;
+}
+
+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);
+}
+
+static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
+               lbaint_t blk, lbaint_t blkcnt)
+{
+       return blkcnt;
+}
+
+static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info,
+               const char *part_name, void *buffer,
+               unsigned int download_bytes)
+{
+       lbaint_t blkcnt;
+       lbaint_t blks;
+
+       /* determine number of blocks to write */
+       blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
+       blkcnt = lldiv(blkcnt, info->blksz);
+
+       if (blkcnt > info->size) {
+               pr_err("too large for partition: '%s'\n", part_name);
+               fastboot_fail("too large for partition");
+               return;
+       }
+
+       puts("Flashing Raw Image\n");
+
+       blks = blk_dwrite(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");
+               return;
+       }
+
+       printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
+              part_name);
+       fastboot_okay("");
+}
+
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+/**
+ * Read Android boot image header from boot partition.
+ *
+ * @param[in] dev_desc MMC device descriptor
+ * @param[in] info Boot partition info
+ * @param[out] hdr Where to store read boot image header
+ *
+ * @return Boot image header sectors count or 0 on error
+ */
+static lbaint_t fb_mmc_get_boot_header(struct blk_desc *dev_desc,
+                                      disk_partition_t *info,
+                                      struct andr_img_hdr *hdr)
+{
+       ulong sector_size;              /* boot partition sector size */
+       lbaint_t hdr_sectors;           /* boot image header sectors count */
+       int res;
+
+       /* Calculate boot image sectors count */
+       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");
+               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");
+               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");
+               return 0;
+       }
+
+       return hdr_sectors;
+}
+
+/**
+ * Write downloaded zImage to boot partition and repack it properly.
+ *
+ * @param dev_desc MMC device descriptor
+ * @param download_buffer Address to fastboot buffer with zImage in it
+ * @param download_bytes Size of fastboot buffer, in bytes
+ *
+ * @return 0 on success or -1 on error
+ */
+static int fb_mmc_update_zimage(struct blk_desc *dev_desc,
+                               void *download_buffer,
+                               unsigned int download_bytes)
+{
+       uintptr_t hdr_addr;                     /* boot image header address */
+       struct andr_img_hdr *hdr;               /* boot image header */
+       lbaint_t hdr_sectors;                   /* boot image header sectors */
+       u8 *ramdisk_buffer;
+       u32 ramdisk_sector_start;
+       u32 ramdisk_sectors;
+       u32 kernel_sector_start;
+       u32 kernel_sectors;
+       u32 sectors_per_page;
+       disk_partition_t info;
+       int res;
+
+       puts("Flashing zImage\n");
+
+       /* 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");
+               return -1;
+       }
+
+       /* Put boot image header in fastboot buffer after downloaded zImage */
+       hdr_addr = (uintptr_t)download_buffer + ALIGN(download_bytes, PAGE_SIZE);
+       hdr = (struct andr_img_hdr *)hdr_addr;
+
+       /* Read boot image header */
+       hdr_sectors = fb_mmc_get_boot_header(dev_desc, &info, hdr);
+       if (hdr_sectors == 0) {
+               pr_err("unable to read boot image header");
+               fastboot_fail("unable to read boot image header");
+               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");
+               return -1;
+       }
+
+       /* Extract ramdisk location */
+       sectors_per_page = hdr->page_size / info.blksz;
+       ramdisk_sector_start = info.start + sectors_per_page;
+       ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+                                            sectors_per_page;
+       ramdisk_sectors = DIV_ROUND_UP(hdr->ramdisk_size, hdr->page_size) *
+                                      sectors_per_page;
+
+       /* Read ramdisk and put it in fastboot buffer after boot image header */
+       ramdisk_buffer = (u8 *)hdr + (hdr_sectors * info.blksz);
+       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");
+               return -1;
+       }
+
+       /* Write new kernel size to boot image header */
+       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");
+               return -1;
+       }
+
+       /* Write the new downloaded kernel */
+       kernel_sector_start = info.start + sectors_per_page;
+       kernel_sectors = DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+                                     sectors_per_page;
+       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");
+               return -1;
+       }
+
+       /* Write the saved ramdisk back */
+       ramdisk_sector_start = info.start + sectors_per_page;
+       ramdisk_sector_start += DIV_ROUND_UP(hdr->kernel_size, hdr->page_size) *
+                                            sectors_per_page;
+       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");
+               return -1;
+       }
+
+       puts("........ zImage was updated in boot partition\n");
+       fastboot_okay("");
+       return 0;
+}
+#endif
+
+void fb_mmc_flash_write(const char *cmd, void *download_buffer,
+                       unsigned int download_bytes)
+{
+       struct blk_desc *dev_desc;
+       disk_partition_t info;
+
+       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");
+               return;
+       }
+
+#if CONFIG_IS_ENABLED(EFI_PARTITION)
+       if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
+               printf("%s: updating MBR, Primary and Backup GPT(s)\n",
+                      __func__);
+               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");
+                       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");
+                       return;
+               }
+               printf("........ success\n");
+               fastboot_okay("");
+               return;
+       }
+#endif
+
+#if CONFIG_IS_ENABLED(DOS_PARTITION)
+       if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
+               printf("%s: updating MBR\n", __func__);
+               if (is_valid_dos_buf(download_buffer)) {
+                       printf("%s: invalid MBR - refusing to write to flash\n",
+                              __func__);
+                       fastboot_fail("invalid MBR partition");
+                       return;
+               }
+               if (write_mbr_partition(dev_desc, download_buffer)) {
+                       printf("%s: writing MBR partition failed\n", __func__);
+                       fastboot_fail("writing MBR partition failed");
+                       return;
+               }
+               printf("........ success\n");
+               fastboot_okay("");
+               return;
+       }
+#endif
+
+#ifdef CONFIG_ANDROID_BOOT_IMAGE
+       if (strncasecmp(cmd, "zimage", 6) == 0) {
+               fb_mmc_update_zimage(dev_desc, download_buffer, download_bytes);
+               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");
+               return;
+       }
+
+       if (is_sparse_image(download_buffer)) {
+               struct fb_mmc_sparse sparse_priv;
+               struct sparse_storage sparse;
+               int err;
+
+               sparse_priv.dev_desc = dev_desc;
+
+               sparse.blksz = info.blksz;
+               sparse.start = info.start;
+               sparse.size = info.size;
+               sparse.write = fb_mmc_sparse_write;
+               sparse.reserve = fb_mmc_sparse_reserve;
+               sparse.mssg = fastboot_fail;
+
+               printf("Flashing sparse image at offset " LBAFU "\n",
+                      sparse.start);
+
+               sparse.priv = &sparse_priv;
+               err = write_sparse_image(&sparse, cmd, download_buffer);
+               if (!err)
+                       fastboot_okay("");
+       } else {
+               write_raw_image(dev_desc, &info, cmd, download_buffer,
+                               download_bytes);
+       }
+}
+
+void fb_mmc_erase(const char *cmd)
+{
+       int ret;
+       struct blk_desc *dev_desc;
+       disk_partition_t info;
+       lbaint_t blks, blks_start, blks_size, grp_size;
+       struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);
+
+       if (mmc == NULL) {
+               pr_err("invalid mmc device");
+               fastboot_fail("invalid mmc device");
+               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");
+               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");
+               return;
+       }
+
+       /* Align blocks to erase group size to avoid erasing other partitions */
+       grp_size = mmc->erase_grp_size;
+       blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
+       if (info.size >= grp_size)
+               blks_size = (info.size - (blks_start - info.start)) &
+                               (~(grp_size - 1));
+       else
+               blks_size = 0;
+
+       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);
+       if (blks != blks_size) {
+               pr_err("failed erasing from device %d", dev_desc->devnum);
+               fastboot_fail("failed erasing from device");
+               return;
+       }
+
+       printf("........ erased " LBAFU " bytes from '%s'\n",
+              blks_size * info.blksz, cmd);
+       fastboot_okay("");
+}
diff --git a/drivers/fastboot/fb_nand.c b/drivers/fastboot/fb_nand.c
new file mode 100644 (file)
index 0000000..c07655e
--- /dev/null
@@ -0,0 +1,230 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2014 Broadcom Corporation.
+ * Copyright 2015 Free Electrons.
+ */
+
+#include <config.h>
+#include <common.h>
+
+#include <fastboot.h>
+#include <image-sparse.h>
+
+#include <linux/mtd/mtd.h>
+#include <jffs2/jffs2.h>
+#include <nand.h>
+
+struct fb_nand_sparse {
+       struct mtd_info         *mtd;
+       struct part_info        *part;
+};
+
+__weak int board_fastboot_erase_partition_setup(char *name)
+{
+       return 0;
+}
+
+__weak int board_fastboot_write_partition_setup(char *name)
+{
+       return 0;
+}
+
+static int fb_nand_lookup(const char *partname,
+                         struct mtd_info **mtd,
+                         struct part_info **part)
+{
+       struct mtd_device *dev;
+       int ret;
+       u8 pnum;
+
+       ret = mtdparts_init();
+       if (ret) {
+               pr_err("Cannot initialize MTD partitions\n");
+               fastboot_fail("cannot init mtdparts");
+               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");
+               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");
+               return -EINVAL;
+       }
+
+       *mtd = get_nand_dev_by_index(dev->id->num);
+
+       return 0;
+}
+
+static int _fb_nand_erase(struct mtd_info *mtd, struct part_info *part)
+{
+       nand_erase_options_t opts;
+       int ret;
+
+       memset(&opts, 0, sizeof(opts));
+       opts.offset = part->offset;
+       opts.length = part->size;
+       opts.quiet = 1;
+
+       printf("Erasing blocks 0x%llx to 0x%llx\n",
+              part->offset, part->offset + part->size);
+
+       ret = nand_erase_opts(mtd, &opts);
+       if (ret)
+               return ret;
+
+       printf("........ erased 0x%llx bytes from '%s'\n",
+              part->size, part->name);
+
+       return 0;
+}
+
+static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
+                         void *buffer, unsigned int offset,
+                         unsigned int length, size_t *written)
+{
+       int flags = WITH_WR_VERIFY;
+
+#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
+       flags |= WITH_DROP_FFS;
+#endif
+
+       return nand_write_skip_bad(mtd, offset, &length, written,
+                                  part->size - (offset - part->offset),
+                                  buffer, flags);
+}
+
+static lbaint_t fb_nand_sparse_write(struct sparse_storage *info,
+               lbaint_t blk, lbaint_t blkcnt, const void *buffer)
+{
+       struct fb_nand_sparse *sparse = info->priv;
+       size_t written;
+       int ret;
+
+       ret = _fb_nand_write(sparse->mtd, sparse->part, (void *)buffer,
+                            blk * info->blksz,
+                            blkcnt * info->blksz, &written);
+       if (ret < 0) {
+               printf("Failed to write sparse chunk\n");
+               return ret;
+       }
+
+/* TODO - verify that the value "written" includes the "bad-blocks" ... */
+
+       /*
+        * the return value must be 'blkcnt' ("good-blocks") plus the
+        * number of "bad-blocks" encountered within this space...
+        */
+       return written / info->blksz;
+}
+
+static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info,
+               lbaint_t blk, lbaint_t blkcnt)
+{
+       int bad_blocks = 0;
+
+/*
+ * TODO - implement a function to determine the total number
+ * of blocks which must be used in order to reserve the specified
+ * number ("blkcnt") of "good-blocks", starting at "blk"...
+ * ( possibly something like the "check_skip_len()" function )
+ */
+
+       /*
+        * the return value must be 'blkcnt' ("good-blocks") plus the
+        * number of "bad-blocks" encountered within this space...
+        */
+       return blkcnt + bad_blocks;
+}
+
+void fb_nand_flash_write(const char *cmd, void *download_buffer,
+                        unsigned int download_bytes)
+{
+       struct part_info *part;
+       struct mtd_info *mtd = NULL;
+       int ret;
+
+       ret = fb_nand_lookup(cmd, &mtd, &part);
+       if (ret) {
+               pr_err("invalid NAND device");
+               fastboot_fail("invalid NAND device");
+               return;
+       }
+
+       ret = board_fastboot_write_partition_setup(part->name);
+       if (ret)
+               return;
+
+       if (is_sparse_image(download_buffer)) {
+               struct fb_nand_sparse sparse_priv;
+               struct sparse_storage sparse;
+
+               sparse_priv.mtd = mtd;
+               sparse_priv.part = part;
+
+               sparse.blksz = mtd->writesize;
+               sparse.start = part->offset / sparse.blksz;
+               sparse.size = part->size / sparse.blksz;
+               sparse.write = fb_nand_sparse_write;
+               sparse.reserve = fb_nand_sparse_reserve;
+               sparse.mssg = fastboot_fail;
+
+               printf("Flashing sparse image at offset " LBAFU "\n",
+                      sparse.start);
+
+               sparse.priv = &sparse_priv;
+               ret = write_sparse_image(&sparse, cmd, download_buffer);
+               if (!ret)
+                       fastboot_okay("");
+       } else {
+               printf("Flashing raw image at offset 0x%llx\n",
+                      part->offset);
+
+               ret = _fb_nand_write(mtd, part, download_buffer, part->offset,
+                                    download_bytes, NULL);
+
+               printf("........ wrote %u bytes to '%s'\n",
+                      download_bytes, part->name);
+       }
+
+       if (ret) {
+               fastboot_fail("error writing the image");
+               return;
+       }
+
+       fastboot_okay("");
+}
+
+void fb_nand_erase(const char *cmd)
+{
+       struct part_info *part;
+       struct mtd_info *mtd = NULL;
+       int ret;
+
+       ret = fb_nand_lookup(cmd, &mtd, &part);
+       if (ret) {
+               pr_err("invalid NAND device");
+               fastboot_fail("invalid NAND device");
+               return;
+       }
+
+       ret = board_fastboot_erase_partition_setup(part->name);
+       if (ret)
+               return;
+
+       ret = _fb_nand_erase(mtd, part);
+       if (ret) {
+               pr_err("failed erasing from device %s", mtd->name);
+               fastboot_fail("failed erasing from device");
+               return;
+       }
+
+       fastboot_okay("");
+}