[U-Boot] [PATCH v4] cmd_sf: add "update" subcommand to do smart SPI flash update

Simon Glass sjg at chromium.org
Sun Aug 21 12:27:16 CEST 2011


On Sat, Aug 20, 2011 at 4:35 PM, Mike Frysinger <vapier at gentoo.org> wrote:
> From: Simon Glass <sjg at chromium.org>
>
> This adds a new SPI flash command which only rewrites blocks if the contents
> need to change. This can speed up SPI flash programming when much of the
> data is unchanged from what is already there.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> Signed-off-by: Mike Frysinger <vapier at gentoo.org>
> ---
> v4
>        - tweak summary
>        - fix printf warnings with %d vs %zu
>        - fix help string and missing/extra newlines
>
> TODO: it'd be nice if we supported +len like we do with erase ...
...
> +static int spi_flash_update(struct spi_flash *flash, u32 offset,
> +               size_t len, const char *buf)
> +{
> +       const char *err_oper = NULL;
> +       char *cmp_buf;
> +       const char *end = buf + len;
> +       size_t todo;            /* number of bytes to do in this pass */
> +       size_t skipped;         /* statistics */
> +
> +       cmp_buf = malloc(flash->sector_size);
> +       if (cmp_buf) {
> +               for (skipped = 0; buf < end; buf += todo, offset += todo) {

Oops I got this wrong:

for (skipped = 0; buf < end && !err_oper; buf += todo, offset += todo) {

(or if (err_oper) break in the loop)

> +                       todo = min(end - buf, flash->sector_size);
> +                       err_oper = spi_flash_update_block(flash, offset, todo,
> +                                       buf, cmp_buf, &skipped);
> +               }
> +       } else {
> +               err_oper = "malloc";
> +       }
> +       free(cmp_buf);
> +       if (err_oper) {
> +               printf("SPI flash failed in %s step\n", err_oper);
> +               return 1;
> +       }
> +       printf("%zu bytes written, %zu bytes skipped\n", len - skipped, skipped);
> +       return 0;
> +}
> +
>  static int do_spi_flash_read_write(int argc, char * const argv[])
>  {
>        unsigned long addr;
> @@ -137,7 +210,9 @@ static int do_spi_flash_read_write(int argc, char * const argv[])
>                return 1;
>        }
>
> -       if (strcmp(argv[0], "read") == 0)
> +       if (strcmp(argv[0], "update") == 0)
> +               ret = spi_flash_update(flash, offset, len, buf);
> +       else if (strcmp(argv[0], "read") == 0)
>                ret = spi_flash_read(flash, offset, len, buf);
>        else
>                ret = spi_flash_write(flash, offset, len, buf);
> @@ -203,7 +278,8 @@ static int do_spi_flash(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
>                return 1;
>        }
>
> -       if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0)
> +       if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0 ||
> +           strcmp(cmd, "update") == 0)
>                ret = do_spi_flash_read_write(argc, argv);
>        else if (strcmp(cmd, "erase") == 0)
>                ret = do_spi_flash_erase(argc, argv);
> @@ -228,5 +304,7 @@ U_BOOT_CMD(
>        "sf write addr offset len       - write `len' bytes from memory\n"
>        "                                 at `addr' to flash at `offset'\n"
>        "sf erase offset [+]len         - erase `len' bytes from `offset'\n"
> -       "                                 `+len' round up `len' to block size"
> +       "                                 `+len' round up `len' to block size\n"
> +       "sf update addr offset len      - erase and write `len' bytes from memory\n"
> +       "                                 at `addr' to flash at `offset'"
>  );
> --
> 1.7.6
>
>


More information about the U-Boot mailing list