diff options
author | Filip Brozovic <fbrozovic@gmail.com> | 2020-06-29 13:14:37 +0200 |
---|---|---|
committer | Marek Vasut <marex@denx.de> | 2020-09-01 14:47:43 +0200 |
commit | a17c0cb85e3abe8601efaadbb287116d1142fefd (patch) | |
tree | bc3db8e28e4492a464ac2697de90a949f93f2a9f /drivers | |
parent | 1468a1cc72afa210c35a4d0ed533de29110de648 (diff) |
fastboot: Support defining raw partitions without a partition table
Add support for defining raw fastboot partitions in eMMC by specifying
the offset and size in an environment variable. Optionally, the eMMC
hardware partition number may also be specified.
This makes it possible to e.g. update only part of the eMMC boot
partition, instead of having to write the entire partition.
Signed-off-by: Filip Brozovic <fbrozovic@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/fastboot/fb_mmc.c | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index b2f8932e1c..ae8e8e512f 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -50,6 +50,48 @@ static int part_get_info_by_name_or_alias(struct blk_desc *dev_desc, return ret; } +static int raw_part_get_info_by_name(struct blk_desc *dev_desc, + const char *name, struct disk_partition *info, int *mmcpart) +{ + /* strlen("fastboot_raw_partition_") + PART_NAME_LEN + 1 */ + char env_desc_name[23 + PART_NAME_LEN + 1]; + char *raw_part_desc; + const char *argv[2]; + const char **parg = argv; + + /* check for raw partition descriptor */ + strcpy(env_desc_name, "fastboot_raw_partition_"); + strncat(env_desc_name, name, PART_NAME_LEN); + raw_part_desc = strdup(env_get(env_desc_name)); + if (raw_part_desc == NULL) + return -ENODEV; + + /* + * parse partition descriptor + * + * <lba_start> <lba_size> [mmcpart <num>] + */ + for (; parg < argv + sizeof(argv) / sizeof(*argv); ++parg) { + *parg = strsep(&raw_part_desc, " "); + if (*parg == NULL) { + pr_err("Invalid number of arguments.\n"); + return -ENODEV; + } + } + + info->start = simple_strtoul(argv[0], NULL, 0); + info->size = simple_strtoul(argv[1], NULL, 0); + info->blksz = dev_desc->blksz; + strncpy((char *)info->name, name, PART_NAME_LEN); + + if (raw_part_desc) { + if (strcmp(strsep(&raw_part_desc, " "), "mmcpart") == 0) + *mmcpart = simple_strtoul(raw_part_desc, NULL, 0); + } + + return 0; +} + /** * fb_mmc_blk_write() - Write/erase MMC in chunks of FASTBOOT_MAX_BLK_WRITE * @@ -376,7 +418,8 @@ int fastboot_mmc_get_part_info(const char *part_name, struct blk_desc **dev_desc, struct disk_partition *part_info, char *response) { - int r; + int r = 0; + int mmcpart; *dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); if (!*dev_desc) { @@ -388,10 +431,12 @@ int fastboot_mmc_get_part_info(const char *part_name, return -ENOENT; } - r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info); - if (r < 0) { - fastboot_fail("partition not found", response); - return r; + if (raw_part_get_info_by_name(*dev_desc, part_name, part_info, &mmcpart) < 0) { + r = part_get_info_by_name_or_alias(*dev_desc, part_name, part_info); + if (r < 0) { + fastboot_fail("partition not found", response); + return r; + } } return r; @@ -410,6 +455,7 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, { struct blk_desc *dev_desc; struct disk_partition info; + int mmcpart = 0; dev_desc = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) { @@ -482,7 +528,13 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, } #endif - if (part_get_info_by_name_or_alias(dev_desc, cmd, &info) < 0) { + if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) { + if (blk_dselect_hwpart(dev_desc, mmcpart)) { + pr_err("Failed to select hwpart\n"); + fastboot_fail("Failed to select hwpart", response); + return; + } + } else 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", response); return; @@ -524,11 +576,11 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, */ void fastboot_mmc_erase(const char *cmd, char *response) { - int ret; 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); + int mmcpart = 0; if (mmc == NULL) { pr_err("invalid mmc device\n"); @@ -562,8 +614,13 @@ void fastboot_mmc_erase(const char *cmd, char *response) } #endif - ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info); - if (ret < 0) { + if (raw_part_get_info_by_name(dev_desc, cmd, &info, &mmcpart) == 0) { + if (blk_dselect_hwpart(dev_desc, mmcpart)) { + pr_err("Failed to select hwpart\n"); + fastboot_fail("Failed to select hwpart", response); + return; + } + } else 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", response); return; |