flashprog.c: Let select_erase_functions() return byte count
Having the total byte count that will be erased helps to calculate
an overall progress state.
Change-Id: Ib4c326d1c98e97325b6ffd67363bbba4f9194678
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/74730
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/flashprog.c b/flashprog.c
index bca0b20..c1a1b2f 100644
--- a/flashprog.c
+++ b/flashprog.c
@@ -976,16 +976,18 @@
* @param findex index of the erase function
* @param block_num index of the block to erase according to the erase function index
* @param info current info from walking the regions
+ * @return number of bytes selected for erase
*/
-static void select_erase_functions_rec(const struct flashctx *flashctx, const struct erase_layout *layout,
- size_t findex, size_t block_num, const struct walk_info *info)
+static size_t select_erase_functions_rec(const struct flashctx *flashctx, const struct erase_layout *layout,
+ size_t findex, size_t block_num, const struct walk_info *info)
{
struct eraseblock_data *ll = &layout[findex].layout_list[block_num];
+ const size_t eraseblock_size = ll->end_addr - ll->start_addr + 1;
if (!findex) {
if (ll->start_addr <= info->region_end && ll->end_addr >= info->region_start) {
if (explicit_erase(info)) {
ll->selected = true;
- return;
+ return eraseblock_size;
}
const chipoff_t write_start = MAX(info->region_start, ll->start_addr);
const chipoff_t write_end = MIN(info->region_end, ll->end_addr);
@@ -994,36 +996,39 @@
ll->selected = need_erase(
info->curcontents + write_start, info->newcontents + write_start,
write_len, flashctx->chip->gran, erased_value);
+ if (ll->selected)
+ return eraseblock_size;
}
+ return 0;
} else {
- int count = 0;
const int sub_block_start = ll->first_sub_block_index;
const int sub_block_end = ll->last_sub_block_index;
+ size_t bytes = 0;
int j;
- for (j = sub_block_start; j <= sub_block_end; j++) {
- select_erase_functions_rec(flashctx, layout, findex - 1, j, info);
- if (layout[findex - 1].layout_list[j].selected)
- count++;
- }
+ for (j = sub_block_start; j <= sub_block_end; j++)
+ bytes += select_erase_functions_rec(flashctx, layout, findex - 1, j, info);
- const int total_blocks = sub_block_end - sub_block_start + 1;
- if (count && count > total_blocks/2) {
+ if (bytes > eraseblock_size / 2) {
if (ll->start_addr >= info->region_start && ll->end_addr <= info->region_end) {
for (j = sub_block_start; j <= sub_block_end; j++)
layout[findex - 1].layout_list[j].selected = false;
ll->selected = true;
+ bytes = eraseblock_size;
}
}
+ return bytes;
}
}
-static void select_erase_functions(const struct flashctx *flashctx, const struct erase_layout *layout,
- size_t erasefn_count, const struct walk_info *info)
+static size_t select_erase_functions(const struct flashctx *flashctx, const struct erase_layout *layout,
+ size_t erasefn_count, const struct walk_info *info)
{
+ size_t bytes = 0;
size_t block_num;
for (block_num = 0; block_num < layout[erasefn_count - 1].block_count; ++block_num)
- select_erase_functions_rec(flashctx, layout, erasefn_count - 1, block_num, info);
+ bytes += select_erase_functions_rec(flashctx, layout, erasefn_count - 1, block_num, info);
+ return bytes;
}
static int write_range(struct flashctx *const flashctx, const chipoff_t flash_offset,