diff options
author | Cyril Bur <cyril.bur@au1.ibm.com> | 2017-11-17 11:02:45 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-11-20 20:36:08 -0600 |
commit | ba540e0be90f1055fd9d40b0a6858f96aff6b180 (patch) | |
tree | b5f0db99ae6db605bed69d9cebf7979b199b977a /external | |
parent | d665e102ef3760d590a35b9051a8941062e22df5 (diff) | |
download | skiboot-ba540e0be90f1055fd9d40b0a6858f96aff6b180.zip skiboot-ba540e0be90f1055fd9d40b0a6858f96aff6b180.tar.gz skiboot-ba540e0be90f1055fd9d40b0a6858f96aff6b180.tar.bz2 |
external/pflash: Fix erasing within a single erase block
It is possible to erase within a single erase block. Currently the
pflash code assumes that if the erase starts part way into an erase
block it is because it needs to be aligned up to the boundary with the
next erase block.
Doing an erase smaller than a single erase block will cause underflows
and looping forever on erase.
Fixes: ae6cb86c2 ("external/pflash: Reinstate the progress bars")
Signed-off-by: Cyril Bur <cyril.bur@au1.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external')
-rw-r--r-- | external/pflash/pflash.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c index d6b2b8e..381df24 100644 --- a/external/pflash/pflash.c +++ b/external/pflash/pflash.c @@ -325,16 +325,20 @@ static int erase_range(struct flash_details *flash, */ progress_init(size); if (start & erase_mask) { - /* Align to next erase block */ - rc = blocklevel_smart_erase(flash->bl, start, - flash->erase_granule - (start & erase_mask)); + /* + * Align to next erase block, or just do the entire + * thing if we fit within one erase block + */ + uint32_t first_size = MIN(size, (flash->erase_granule - (start & erase_mask))); + + rc = blocklevel_smart_erase(flash->bl, start, first_size); if (rc) { fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc); return 1; } - size -= flash->erase_granule - (start & erase_mask); - done = flash->erase_granule - (start & erase_mask); - start += flash->erase_granule - (start & erase_mask); + size -= first_size; + done = first_size; + start += first_size; } progress_tick(done); while (size & ~(erase_mask)) { |