diff options
| author | Tom Rini <[email protected]> | 2025-12-04 08:35:41 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-12-04 08:35:41 -0600 |
| commit | 2d08dfc1dc4fc159b13d54535fdca4566b5808d1 (patch) | |
| tree | 6682c52efde5e39c0857e06d8a635872c7fb4edd /drivers | |
| parent | d300702c5be5a846032834abe4f01dcd3f50b3a8 (diff) | |
| parent | 769c6cbbb53074025c3af53d8df5571ae18d74c3 (diff) | |
Merge tag 'u-boot-dfu-next-20251203' of https://source.denx.de/u-boot/custodians/u-boot-dfu into next
u-boot-dfu-next-20251203:
CI: https://source.denx.de/u-boot/custodians/u-boot-dfu/-/pipelines/28617
Fastboot:
- Add generic flashing support using BLK
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/fastboot/Kconfig | 32 | ||||
| -rw-r--r-- | drivers/fastboot/Makefile | 4 | ||||
| -rw-r--r-- | drivers/fastboot/fb_block.c | 322 | ||||
| -rw-r--r-- | drivers/fastboot/fb_command.c | 8 | ||||
| -rw-r--r-- | drivers/fastboot/fb_common.c | 22 | ||||
| -rw-r--r-- | drivers/fastboot/fb_getvar.c | 8 | ||||
| -rw-r--r-- | drivers/fastboot/fb_mmc.c | 210 |
7 files changed, 400 insertions, 206 deletions
diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 843171902ae..576c3ef8a45 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -90,8 +90,9 @@ config FASTBOOT_USB_DEV config FASTBOOT_FLASH bool "Enable FASTBOOT FLASH command" - default y if ARCH_SUNXI || ARCH_ROCKCHIP - depends on MMC || (MTD_RAW_NAND && CMD_MTDPARTS) || DM_SPI_FLASH + default y if ARCH_SUNXI && ( MMC || MTD_RAW_NAND ) + default y if ARCH_ROCKCHIP && MMC + depends on MMC || (MTD_RAW_NAND && CMD_MTDPARTS) || DM_SPI_FLASH || BLK select IMAGE_SPARSE help The fastboot protocol includes a "flash" command for writing @@ -123,6 +124,10 @@ config FASTBOOT_FLASH_SPI bool "FASTBOOT on SPI flash" depends on DM_SPI_FLASH +config FASTBOOT_FLASH_BLOCK + bool "FASTBOOT on block device" + depends on BLK + endchoice config FASTBOOT_FLASH_MMC_DEV @@ -197,6 +202,29 @@ config FASTBOOT_MMC_USER_NAME defined here. The default target name for erasing EMMC_USER is "mmc0". +config FASTBOOT_FLASH_BLOCK_INTERFACE_NAME + string "Define FASTBOOT block interface name" + depends on FASTBOOT_FLASH_BLOCK + help + The fastboot "flash" and "erase" commands support operations + on any Block device, this should specify the block device name + like ide, scsi, usb, sata, nvme, virtio, blkmap, mtd... + The mmc block device type can be used but most of the features + available in the FASTBOOT_MMC will be missing. + Consider using FASTBOOT_MMC on a MMC block device until all + features are migrated. + +config FASTBOOT_FLASH_BLOCK_DEVICE_ID + int "Define FASTBOOT block device identifier" + depends on FASTBOOT_FLASH_BLOCK + default 0 + help + The fastboot "flash" and "erase" commands support operations + on any Block device, this should specify the block device + identifier on the system, as a number. + Device identifiers are numbered starting from 0 and the most + common case is to use the first controller on the system. + config FASTBOOT_GPT_NAME string "Target name for updating GPT" depends on FASTBOOT_FLASH_MMC && EFI_PARTITION diff --git a/drivers/fastboot/Makefile b/drivers/fastboot/Makefile index adedba0bf24..a341af076d1 100644 --- a/drivers/fastboot/Makefile +++ b/drivers/fastboot/Makefile @@ -3,6 +3,8 @@ 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_BLOCK) += fb_block.o +# MMC reuses block implementation +obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fb_block.o fb_mmc.o obj-$(CONFIG_FASTBOOT_FLASH_NAND) += fb_nand.o obj-$(CONFIG_FASTBOOT_FLASH_SPI) += fb_spi_flash.o diff --git a/drivers/fastboot/fb_block.c b/drivers/fastboot/fb_block.c new file mode 100644 index 00000000000..2a7e47992f8 --- /dev/null +++ b/drivers/fastboot/fb_block.c @@ -0,0 +1,322 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2024 The Android Open Source Project + */ + +#include <blk.h> +#include <div64.h> +#include <fastboot.h> +#include <fastboot-internal.h> +#include <fb_block.h> +#include <image-sparse.h> +#include <malloc.h> +#include <part.h> + +/** + * FASTBOOT_MAX_BLOCKS_ERASE - maximum blocks to erase per derase call + * + * in the ERASE case we can have much larger buffer size since + * we're not transferring an actual buffer + */ +#define FASTBOOT_MAX_BLOCKS_ERASE 1048576 +/** + * FASTBOOT_MAX_BLOCKS_SOFT_ERASE - maximum blocks to software erase at once + */ +#define FASTBOOT_MAX_BLOCKS_SOFT_ERASE 4096 +/** + * FASTBOOT_MAX_BLOCKS_WRITE - maximum blocks to write per dwrite call + */ +#define FASTBOOT_MAX_BLOCKS_WRITE 65536 + +struct fb_block_sparse { + struct blk_desc *dev_desc; +}; + +/* Write 0s instead of using erase operation, inefficient but functional */ +static lbaint_t fb_block_soft_erase(struct blk_desc *block_dev, lbaint_t blk, + lbaint_t cur_blkcnt, lbaint_t erase_buf_blks, + void *erase_buffer) +{ + lbaint_t blks_written = 0; + lbaint_t j; + + memset(erase_buffer, 0, erase_buf_blks * block_dev->blksz); + + for (j = 0; j < cur_blkcnt; j += erase_buf_blks) { + lbaint_t remain = min(cur_blkcnt - j, erase_buf_blks); + + blks_written += blk_dwrite(block_dev, blk + j, + remain, erase_buffer); + printf("."); + } + + return blks_written; +} + +static lbaint_t fb_block_write(struct blk_desc *block_dev, lbaint_t start, + lbaint_t blkcnt, const void *buffer) +{ + lbaint_t blk = start; + lbaint_t blks_written = 0; + lbaint_t blks = 0; + void *erase_buf = NULL; + int erase_buf_blks = 0; + lbaint_t step = buffer ? FASTBOOT_MAX_BLOCKS_WRITE : FASTBOOT_MAX_BLOCKS_ERASE; + lbaint_t i; + + for (i = 0; i < blkcnt; i += step) { + lbaint_t cur_blkcnt = min(blkcnt - i, step); + + 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"); + + if (!erase_buf) { + blks_written = blk_derase(block_dev, blk, cur_blkcnt); + + /* Allocate erase buffer if erase is not implemented */ + if ((long)blks_written == -ENOSYS) { + erase_buf_blks = min_t(long, blkcnt, + FASTBOOT_MAX_BLOCKS_SOFT_ERASE); + erase_buf = malloc(erase_buf_blks * block_dev->blksz); + + printf("Slowly writing empty buffers due to missing erase operation\n"); + } + } + + if (erase_buf) + blks_written = fb_block_soft_erase(block_dev, blk, cur_blkcnt, + erase_buf_blks, erase_buf); + } + blk += blks_written; + blks += blks_written; + } + + if (erase_buf) + free(erase_buf); + + return blks; +} + +static lbaint_t fb_block_sparse_write(struct sparse_storage *info, + lbaint_t blk, lbaint_t blkcnt, + const void *buffer) +{ + struct fb_block_sparse *sparse = info->priv; + struct blk_desc *dev_desc = sparse->dev_desc; + + return fb_block_write(dev_desc, blk, blkcnt, buffer); +} + +static lbaint_t fb_block_sparse_reserve(struct sparse_storage *info, + lbaint_t blk, lbaint_t blkcnt) +{ + return blkcnt; +} + +int fastboot_block_get_part_info(const char *part_name, + struct blk_desc **dev_desc, + struct disk_partition *part_info, + char *response) +{ + int ret; + const char *interface = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK, + CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME, + NULL); + const int device = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK, + CONFIG_FASTBOOT_FLASH_BLOCK_DEVICE_ID, -1); + + if (!part_name || !strcmp(part_name, "")) { + fastboot_fail("partition not given", response); + return -ENOENT; + } + if (!interface || !strcmp(interface, "")) { + fastboot_fail("block interface isn't provided", response); + return -EINVAL; + } + + *dev_desc = blk_get_dev(interface, device); + if (!dev_desc) { + fastboot_fail("no such device", response); + return -ENODEV; + } + + ret = part_get_info_by_name(*dev_desc, part_name, part_info); + if (ret < 0) + fastboot_fail("failed to get partition info", response); + + return ret; +} + +void fastboot_block_raw_erase_disk(struct blk_desc *dev_desc, const char *disk_name, + char *response) +{ + lbaint_t written; + + debug("Start Erasing %s...\n", disk_name); + + written = fb_block_write(dev_desc, 0, dev_desc->lba, NULL); + if (written != dev_desc->lba) { + pr_err("Failed to erase %s\n", disk_name); + fastboot_response("FAIL", response, "Failed to erase %s", disk_name); + return; + } + + printf("........ erased " LBAFU " bytes from '%s'\n", + dev_desc->lba * dev_desc->blksz, disk_name); + fastboot_okay(NULL, response); +} + +void fastboot_block_raw_erase(struct blk_desc *dev_desc, struct disk_partition *info, + const char *part_name, uint alignment, char *response) +{ + lbaint_t written, blks_start, blks_size; + + if (alignment) { + blks_start = (info->start + alignment - 1) & ~(alignment - 1); + if (info->size >= alignment) + blks_size = (info->size - (blks_start - info->start)) & + (~(alignment - 1)); + else + blks_size = 0; + + printf("Erasing blocks " LBAFU " to " LBAFU " due to alignment\n", + blks_start, blks_start + blks_size); + } else { + blks_start = info->start; + blks_size = info->size; + } + + written = fb_block_write(dev_desc, blks_start, blks_size, NULL); + if (written != blks_size) { + fastboot_fail("failed to erase partition", response); + return; + } + + printf("........ erased " LBAFU " bytes from '%s'\n", + blks_size * info->blksz, part_name); + fastboot_okay(NULL, response); +} + +void fastboot_block_erase(const char *part_name, char *response) +{ + struct blk_desc *dev_desc; + struct disk_partition part_info; + + if (fastboot_block_get_part_info(part_name, &dev_desc, &part_info, response) < 0) + return; + + fastboot_block_raw_erase(dev_desc, &part_info, part_name, 0, response); +} + +void fastboot_block_write_raw_disk(struct blk_desc *dev_desc, const char *disk_name, + void *buffer, u32 download_bytes, char *response) +{ + lbaint_t blkcnt; + lbaint_t blks; + + /* determine number of blocks to write */ + blkcnt = ((download_bytes + (dev_desc->blksz - 1)) & ~(dev_desc->blksz - 1)); + blkcnt = lldiv(blkcnt, dev_desc->blksz); + + if (blkcnt > dev_desc->lba) { + pr_err("too large for disk: '%s'\n", disk_name); + fastboot_fail("too large for disk", response); + return; + } + + printf("Flashing Raw Image\n"); + + blks = fb_block_write(dev_desc, 0, blkcnt, buffer); + + if (blks != blkcnt) { + pr_err("failed writing to %s\n", disk_name); + fastboot_fail("failed writing to device", response); + return; + } + + printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * dev_desc->blksz, + disk_name); + fastboot_okay(NULL, response); +} + +void fastboot_block_write_raw_image(struct blk_desc *dev_desc, + struct disk_partition *info, const char *part_name, + void *buffer, u32 download_bytes, char *response) +{ + 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", response); + return; + } + + printf("Flashing Raw Image\n"); + + blks = fb_block_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", response); + return; + } + + printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz, + part_name); + fastboot_okay(NULL, response); +} + +void fastboot_block_write_sparse_image(struct blk_desc *dev_desc, struct disk_partition *info, + const char *part_name, void *buffer, char *response) +{ + struct fb_block_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_block_sparse_write; + sparse.reserve = fb_block_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, part_name, buffer, + response); + if (!err) + fastboot_okay(NULL, response); +} + +void fastboot_block_flash_write(const char *part_name, void *download_buffer, + u32 download_bytes, char *response) +{ + struct blk_desc *dev_desc; + struct disk_partition part_info; + + if (fastboot_block_get_part_info(part_name, &dev_desc, &part_info, response) < 0) + return; + + if (is_sparse_image(download_buffer)) { + fastboot_block_write_sparse_image(dev_desc, &part_info, part_name, + download_buffer, response); + } else { + fastboot_block_write_raw_image(dev_desc, &part_info, part_name, + download_buffer, download_bytes, response); + } +} diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 791088bc094..18d86988f4c 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -8,6 +8,7 @@ #include <env.h> #include <fastboot.h> #include <fastboot-internal.h> +#include <fb_block.h> #include <fb_mmc.h> #include <fb_nand.h> #include <fb_spi_flash.h> @@ -338,6 +339,10 @@ void fastboot_data_complete(char *response) */ static void __maybe_unused flash(char *cmd_parameter, char *response) { + if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK)) + fastboot_block_flash_write(cmd_parameter, fastboot_buf_addr, + image_size, response); + if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) fastboot_mmc_flash_write(cmd_parameter, fastboot_buf_addr, image_size, response); @@ -362,6 +367,9 @@ static void __maybe_unused flash(char *cmd_parameter, char *response) */ static void __maybe_unused erase(char *cmd_parameter, char *response) { + if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK)) + fastboot_block_erase(cmd_parameter, response); + if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) fastboot_mmc_erase(cmd_parameter, response); diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index 68f92c4b887..dac5528f809 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -97,16 +97,24 @@ int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) [FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot", [FASTBOOT_REBOOT_REASON_RECOVERY] = "boot-recovery" }; - const int mmc_dev = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC, - CONFIG_FASTBOOT_FLASH_MMC_DEV, -1); - if (!IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) + int device = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK, + CONFIG_FASTBOOT_FLASH_BLOCK_DEVICE_ID, -1); + if (device == -1) { + device = config_opt_enabled(CONFIG_FASTBOOT_FLASH_MMC, + CONFIG_FASTBOOT_FLASH_MMC_DEV, -1); + } + const char *bcb_iface = config_opt_enabled(CONFIG_FASTBOOT_FLASH_BLOCK, + CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME, + "mmc"); + + if (device == -1) return -EINVAL; if (reason >= FASTBOOT_REBOOT_REASONS_COUNT) return -EINVAL; - ret = bcb_find_partition_and_load("mmc", mmc_dev, "misc"); + ret = bcb_find_partition_and_load(bcb_iface, device, "misc"); if (ret) goto out; @@ -226,8 +234,14 @@ void fastboot_set_progress_callback(void (*progress)(const char *msg)) */ void fastboot_init(void *buf_addr, u32 buf_size) { +#if IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK) + if (!strcmp(CONFIG_FASTBOOT_FLASH_BLOCK_INTERFACE_NAME, "mmc")) + printf("Warning: the fastboot block backend features are limited, consider using the MMC backend\n"); +#endif + 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 index 6775ea397ab..e8aa0e09aa6 100644 --- a/drivers/fastboot/fb_getvar.c +++ b/drivers/fastboot/fb_getvar.c @@ -7,6 +7,7 @@ #include <fastboot.h> #include <fastboot-internal.h> #include <fb_mmc.h> +#include <fb_block.h> #include <fb_nand.h> #include <fb_spi_flash.h> #include <fs.h> @@ -115,7 +116,12 @@ static int getvar_get_part_info(const char *part_name, char *response, struct disk_partition disk_part; struct part_info *part_info; - if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) { + if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_BLOCK)) { + r = fastboot_block_get_part_info(part_name, &dev_desc, &disk_part, + response); + if (r >= 0 && size) + *size = disk_part.size * disk_part.blksz; + } else if (IS_ENABLED(CONFIG_FASTBOOT_FLASH_MMC)) { r = fastboot_mmc_get_part_info(part_name, &dev_desc, &disk_part, response); if (r >= 0 && size) diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index dca7c222f35..11d9c8e8460 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -8,6 +8,7 @@ #include <env.h> #include <fastboot.h> #include <fastboot-internal.h> +#include <fb_block.h> #include <fb_mmc.h> #include <image-sparse.h> #include <image.h> @@ -20,10 +21,6 @@ #define BOOT_PARTITION_NAME "boot" -struct fb_mmc_sparse { - struct blk_desc *dev_desc; -}; - static int raw_part_get_info_by_name(struct blk_desc *dev_desc, const char *name, struct disk_partition *info) @@ -114,118 +111,10 @@ static int part_get_info_by_name_or_alias(struct blk_desc **dev_desc, return do_get_part_info(dev_desc, name, info); } -/** - * 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 fb_mmc_blk_write(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, - struct disk_partition *info, const char *part_name, - void *buffer, u32 download_bytes, char *response) -{ - 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", response); - return; - } - - puts("Flashing Raw Image\n"); - - 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", response); - return; - } - - printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz, - part_name); - fastboot_okay(NULL, response); -} - -#if defined(CONFIG_FASTBOOT_MMC_BOOT_SUPPORT) || \ - defined(CONFIG_FASTBOOT_MMC_USER_SUPPORT) -static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc) -{ - lbaint_t blks; - - debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart); - - blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL); - - if (blks != dev_desc->lba) { - pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart); - return 1; - } - - printf("........ erased %llu bytes from mmc hwpart[%u]\n", - (u64)(dev_desc->lba * dev_desc->blksz), dev_desc->hwpart); - - return 0; -} -#endif - #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer, int hwpart, u32 buff_sz, char *response) { - lbaint_t blkcnt; - lbaint_t blks; - unsigned long blksz; - // To operate on EMMC_BOOT1/2 (mmc0boot0/1) we first change the hwpart if (blk_dselect_hwpart(dev_desc, hwpart)) { pr_err("Failed to select hwpart\n"); @@ -233,42 +122,11 @@ static void fb_mmc_boot_ops(struct blk_desc *dev_desc, void *buffer, return; } - if (buffer) { /* flash */ - - /* determine number of blocks to write */ - blksz = dev_desc->blksz; - blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1)); - blkcnt = lldiv(blkcnt, blksz); - - if (blkcnt > dev_desc->lba) { - pr_err("Image size too large\n"); - fastboot_fail("Image size too large", response); - return; - } - - debug("Start Flashing Image to EMMC_BOOT%d...\n", hwpart); - - blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer); - - if (blks != blkcnt) { - pr_err("Failed to write EMMC_BOOT%d\n", hwpart); - fastboot_fail("Failed to write EMMC_BOOT part", - response); - return; - } - - printf("........ wrote %llu bytes to EMMC_BOOT%d\n", - (u64)(blkcnt * blksz), hwpart); - } else { /* erase */ - if (fb_mmc_erase_mmc_hwpart(dev_desc)) { - pr_err("Failed to erase EMMC_BOOT%d\n", hwpart); - fastboot_fail("Failed to erase EMMC_BOOT part", - response); - return; - } - } - - fastboot_okay(NULL, response); + if (buffer) /* flash */ + fastboot_block_write_raw_disk(dev_desc, "EMMC_BOOT", + buffer, buff_sz, response); + else /* erase */ + fastboot_block_raw_erase_disk(dev_desc, "EMMC_BOOT", response); } #endif @@ -609,30 +467,11 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, 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, - response); - if (!err) - fastboot_okay(NULL, response); + fastboot_block_write_sparse_image(dev_desc, &info, cmd, + download_buffer, response); } else { - write_raw_image(dev_desc, &info, cmd, download_buffer, - download_bytes, response); + fastboot_block_write_raw_image(dev_desc, &info, cmd, download_buffer, + download_bytes, response); } } @@ -646,7 +485,6 @@ void fastboot_mmc_erase(const char *cmd, char *response) { struct blk_desc *dev_desc; struct disk_partition info; - lbaint_t blks, blks_start, blks_size, grp_size; struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV); #ifdef CONFIG_FASTBOOT_MMC_BOOT_SUPPORT @@ -673,10 +511,7 @@ void fastboot_mmc_erase(const char *cmd, char *response) if (!dev_desc) return; - if (fb_mmc_erase_mmc_hwpart(dev_desc)) - fastboot_fail("Failed to erase EMMC_USER", response); - else - fastboot_okay(NULL, response); + fastboot_block_raw_erase_disk(dev_desc, "EMMC_USER", response); return; } #endif @@ -685,26 +520,5 @@ void fastboot_mmc_erase(const char *cmd, char *response) 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 = fb_mmc_blk_write(dev_desc, blks_start, blks_size, NULL); - - if (blks != blks_size) { - 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(NULL, response); + fastboot_block_raw_erase(dev_desc, &info, cmd, mmc->erase_grp_size, response); } |
