Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-sh into next
[platform/kernel/u-boot.git] / cmd / sf.c
index bd102f5..11b9c25 100644 (file)
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -179,16 +179,18 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
                size_t len, const char *buf, char *cmp_buf, size_t *skipped)
 {
        char *ptr = (char *)buf;
+       u32 start_offset = offset % flash->sector_size;
+       u32 read_offset = offset - start_offset;
 
-       debug("offset=%#x, sector_size=%#x, len=%#zx\n",
-             offset, flash->sector_size, len);
+       debug("offset=%#x+%#x, sector_size=%#x, len=%#zx\n",
+             read_offset, start_offset, flash->sector_size, len);
        /* Read the entire sector so to allow for rewriting */
-       if (spi_flash_read(flash, offset, flash->sector_size, cmp_buf))
+       if (spi_flash_read(flash, read_offset, flash->sector_size, cmp_buf))
                return "read";
        /* Compare only what is meaningful (len) */
-       if (memcmp(cmp_buf, buf, len) == 0) {
-               debug("Skip region %x size %zx: no change\n",
-                     offset, len);
+       if (memcmp(cmp_buf + start_offset, buf, len) == 0) {
+               debug("Skip region %x+%x size %zx: no change\n",
+                     start_offset, read_offset, len);
                *skipped += len;
                return NULL;
        }
@@ -197,7 +199,7 @@ static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset,
                return "erase";
        /* If it's a partial sector, copy the data into the temp-buffer */
        if (len != flash->sector_size) {
-               memcpy(cmp_buf, buf, len);
+               memcpy(cmp_buf + start_offset, buf, len);
                ptr = cmp_buf;
        }
        /* Write one complete sector */
@@ -238,6 +240,8 @@ static int spi_flash_update(struct spi_flash *flash, u32 offset,
 
                for (; buf < end && !err_oper; buf += todo, offset += todo) {
                        todo = min_t(size_t, end - buf, flash->sector_size);
+                       todo = min_t(size_t, end - buf,
+                                    flash->sector_size - (offset % flash->sector_size));
                        if (get_timer(last_update) > 100) {
                                printf("   \rUpdating, %zu%% %lu B/s",
                                       100 - (end - buf) / scale,
@@ -277,33 +281,33 @@ static int do_spi_flash_read_write(int argc, char *const argv[])
        loff_t offset, len, maxsize;
 
        if (argc < 3)
-               return -1;
+               return CMD_RET_USAGE;
 
        addr = hextoul(argv[1], &endp);
        if (*argv[1] == 0 || *endp != 0)
-               return -1;
+               return CMD_RET_USAGE;
 
        if (mtd_arg_off_size(argc - 2, &argv[2], &dev, &offset, &len,
                             &maxsize, MTD_DEV_TYPE_NOR, flash->size))
-               return -1;
+               return CMD_RET_FAILURE;
 
        /* Consistency checking */
        if (offset + len > flash->size) {
                printf("ERROR: attempting %s past flash size (%#x)\n",
                       argv[0], flash->size);
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        if (strncmp(argv[0], "read", 4) != 0 && flash->flash_is_unlocked &&
            !flash->flash_is_unlocked(flash, offset, len)) {
                printf("ERROR: flash area is locked\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        buf = map_physmem(addr, len, MAP_WRBACK);
        if (!buf && addr) {
                puts("Failed to map physical memory\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        if (strcmp(argv[0], "update") == 0) {
@@ -328,7 +332,7 @@ static int do_spi_flash_read_write(int argc, char *const argv[])
 
        unmap_physmem(buf, len);
 
-       return ret == 0 ? 0 : 1;
+       return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
 
 static int do_spi_flash_erase(int argc, char *const argv[])
@@ -339,27 +343,27 @@ static int do_spi_flash_erase(int argc, char *const argv[])
        ulong size;
 
        if (argc < 3)
-               return -1;
+               return CMD_RET_USAGE;
 
        if (mtd_arg_off(argv[1], &dev, &offset, &len, &maxsize,
                        MTD_DEV_TYPE_NOR, flash->size))
-               return -1;
+               return CMD_RET_FAILURE;
 
        ret = sf_parse_len_arg(argv[2], &size);
        if (ret != 1)
-               return -1;
+               return CMD_RET_USAGE;
 
        /* Consistency checking */
        if (offset + size > flash->size) {
                printf("ERROR: attempting %s past flash size (%#x)\n",
                       argv[0], flash->size);
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        if (flash->flash_is_unlocked &&
            !flash->flash_is_unlocked(flash, offset, len)) {
                printf("ERROR: flash area is locked\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        ret = spi_flash_erase(flash, offset, size);
@@ -369,7 +373,7 @@ static int do_spi_flash_erase(int argc, char *const argv[])
        else
                printf("OK\n");
 
-       return ret == 0 ? 0 : 1;
+       return ret ? CMD_RET_FAILURE : CMD_RET_SUCCESS;
 }
 
 static int do_spi_protect(int argc, char *const argv[])
@@ -554,7 +558,7 @@ static int do_spi_flash_test(int argc, char *const argv[])
                return 1;
        }
 
-       from = map_sysmem(CONFIG_SYS_TEXT_BASE, 0);
+       from = map_sysmem(CONFIG_TEXT_BASE, 0);
        memcpy(buf, from, len);
        ret = spi_flash_test(flash, buf, len, offset, vbuf);
        free(vbuf);
@@ -575,21 +579,19 @@ static int do_spi_flash(struct cmd_tbl *cmdtp, int flag, int argc,
 
        /* need at least two arguments */
        if (argc < 2)
-               goto usage;
+               return CMD_RET_USAGE;
 
        cmd = argv[1];
        --argc;
        ++argv;
 
-       if (strcmp(cmd, "probe") == 0) {
-               ret = do_spi_flash_probe(argc, argv);
-               goto done;
-       }
+       if (strcmp(cmd, "probe") == 0)
+               return do_spi_flash_probe(argc, argv);
 
        /* The remaining commands require a selected device */
        if (!flash) {
                puts("No SPI flash selected. Please run `sf probe'\n");
-               return 1;
+               return CMD_RET_FAILURE;
        }
 
        if (strcmp(cmd, "read") == 0 || strcmp(cmd, "write") == 0 ||
@@ -602,14 +604,9 @@ static int do_spi_flash(struct cmd_tbl *cmdtp, int flag, int argc,
        else if (IS_ENABLED(CONFIG_CMD_SF_TEST) && !strcmp(cmd, "test"))
                ret = do_spi_flash_test(argc, argv);
        else
-               ret = -1;
-
-done:
-       if (ret != -1)
-               return ret;
+               ret = CMD_RET_USAGE;
 
-usage:
-       return CMD_RET_USAGE;
+       return ret;
 }
 
 #ifdef CONFIG_SYS_LONGHELP