[Skiboot] [PATCH 14/17] external/pflash: Reinstate the progress bars
Cyril Bur
cyrilbur at gmail.com
Mon Jul 24 13:18:02 AEST 2017
On Fri, 2017-07-21 at 16:36 +1000, Cyril Bur wrote:
> Recent work did some optimising which unfortunately removed some of the
> progress bars in pflash.
>
> It turns out that there's only one thing people prefer to correctly
> programmed flash chips, it is the ability to watch little equals
> characters go across their screens for potentially minutes.
>
> Personally I don't understand the appeal but I have received strongly
> worded requests for the reinstatement of the progress bars in pflash and
> I fear for the stability of our society if pflash doesn't promptly regain
> its most unimportant feature.
>
> Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
> ---
> external/pflash/pflash.c | 77 ++++++++++++++++++++++++++++++++++++++----------
> 1 file changed, 62 insertions(+), 15 deletions(-)
>
> diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
> index 80675c85..65c23673 100644
> --- a/external/pflash/pflash.c
> +++ b/external/pflash/pflash.c
> @@ -254,10 +254,11 @@ static struct ffs_handle *lookup_partition_at_side(struct flash_details *flash,
> return lookup_partition_at_toc(flash, name, index);
> }
>
> -static int erase_chip(struct blocklevel_device *bl)
> +static int erase_chip(struct flash_details *flash)
> {
> bool confirm;
> int rc;
> + uint64_t pos;
>
> printf("About to erase chip !\n");
> confirm = check_confirm();
> @@ -272,20 +273,33 @@ static int erase_chip(struct blocklevel_device *bl)
> return 1;
> }
>
> - rc = arch_flash_erase_chip(bl);
> + /*
> + * We could use arch_flash_erase_chip() here BUT everyone really
> + * likes the progress bars.
> + * Lets do an erase block at a time erase then...
> + */
> + progress_init(flash->total_size);
> + for (pos = 0; pos < flash->total_size; pos += flash->erase_granule) {
> + rc = blocklevel_erase(flash->bl, pos, flash->erase_granule);
> + if (rc)
> + break;
> + progress_tick(pos);
This eventually overflows the progress tracking and causes the progress
bar to go back to zero and count upwards again.
I'll send a fix
> + }
> + progress_end();
> if (rc) {
> fprintf(stderr, "Error %d erasing chip\n", rc);
> - return 1;
> + return rc;
> }
>
> printf("done !\n");
> return 0;
> }
>
> -static int erase_range(struct blocklevel_device *bl,
> +static int erase_range(struct flash_details *flash,
> uint32_t start, uint32_t size, bool will_program,
> struct ffs_handle *ffsh, int ffs_index)
> {
> + uint32_t done = 0, erase_mask = flash->erase_granule - 1;
> bool confirm;
> int rc;
>
> @@ -300,12 +314,45 @@ static int erase_range(struct blocklevel_device *bl,
> }
>
> printf("Erasing...\n");
> - rc = blocklevel_smart_erase(bl, start, size);
> - if (rc) {
> - fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc);
> - return 1;
> + /*
> + * blocklevel_smart_erase() can do the entire thing in one call
> + * BUT everyone really likes progress bars so break stuff up
> + */
> + 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));
> + if (rc) {
> + fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc);
> + return 1;
> + }
> + start += flash->erase_granule - (start & erase_mask);
> + size -= flash->erase_granule - (start & erase_mask);
> + done = flash->erase_granule - (start & erase_mask);
> }
> -
> + progress_tick(done);
> + while (size & ~(erase_mask)) {
> + rc = blocklevel_smart_erase(flash->bl, start, flash->erase_granule);
> + if (rc) {
> + fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc);
> + return 1;
> + }
> + start += flash->erase_granule;
> + size -= flash->erase_granule;
> + done += flash->erase_granule;
> + progress_tick(done);
> + }
> + if (size) {
> + rc = blocklevel_smart_erase(flash->bl, start, size);
> + if (rc) {
> + fprintf(stderr, "Failed to blocklevel_smart_erase(): %d\n", rc);
> + return 1;
> + }
> + done += size;
> + progress_tick(done);
> + }
> + progress_end();
> /* If this is a flash partition, mark it empty if we aren't
> * going to program over it as well
> */
> @@ -316,7 +363,7 @@ static int erase_range(struct blocklevel_device *bl,
> return 0;
> }
>
> -static int set_ecc(struct blocklevel_device *bl, uint32_t start, uint32_t size)
> +static int set_ecc(struct flash_details *flash, uint32_t start, uint32_t size)
> {
> uint32_t i = start + 8;
> uint8_t ecc = 0;
> @@ -327,12 +374,12 @@ static int set_ecc(struct blocklevel_device *bl, uint32_t start, uint32_t size)
> if (!confirm)
> return 1;
>
> - erase_range(bl, start, size, true, NULL, 0);
> + erase_range(flash, start, size, true, NULL, 0);
>
> printf("Programming ECC bits...\n");
> progress_init(size);
> while (i < start + size) {
> - blocklevel_write(bl, i, &ecc, sizeof(ecc));
> + blocklevel_write(flash->bl, i, &ecc, sizeof(ecc));
> i += 9;
> progress_tick(i - start);
> }
> @@ -1060,15 +1107,15 @@ int main(int argc, char *argv[])
> if (do_read)
> rc = do_read_file(flash.bl, read_file, address, read_size);
> if (!rc && erase_all)
> - rc = erase_chip(flash.bl);
> + rc = erase_chip(&flash);
> else if (!rc && erase)
> - rc = erase_range(flash.bl, address, write_size,
> + rc = erase_range(&flash, address, write_size,
> program, ffsh, ffs_index);
> if (!rc && program)
> rc = program_file(flash.bl, write_file, address, write_size,
> ffsh, ffs_index);
> if (!rc && do_clear)
> - rc = set_ecc(flash.bl, address, write_size);
> + rc = set_ecc(&flash, address, write_size);
>
> close:
> if (flash.need_relock)
More information about the Skiboot
mailing list