]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - common/image-sparse.c
Merge branch 'rmobile-mx' of git://git.denx.de/u-boot-sh
[people/ms/u-boot.git] / common / image-sparse.c
index 924cc63797e9239c0ddfbd4626b806f5aae53d6b..ddf5772cf825ca6ae2f74542491b5e0ae9e76235 100644 (file)
 
 #include <linux/math64.h>
 
+#ifndef CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE
+#define CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE (1024 * 512)
+#endif
+
 void write_sparse_image(
                struct sparse_storage *info, const char *part_name,
-               void *data, unsigned sz, char *response_str)
+               void *data, unsigned sz)
 {
        lbaint_t blk;
        lbaint_t blkcnt;
@@ -61,7 +65,11 @@ void write_sparse_image(
        sparse_header_t *sparse_header;
        chunk_header_t *chunk_header;
        uint32_t total_blocks = 0;
+       int fill_buf_num_blks;
        int i;
+       int j;
+
+       fill_buf_num_blks = CONFIG_FASTBOOT_FLASH_FILLBUF_SIZE / info->blksz;
 
        /* Read and skip over sparse image header */
        sparse_header = (sparse_header_t *)data;
@@ -93,7 +101,7 @@ void write_sparse_image(
        if (offset) {
                printf("%s: Sparse image block size issue [%u]\n",
                       __func__, sparse_header->blk_sz);
-               fastboot_fail(response_str, "sparse image block size issue");
+               fastboot_fail("sparse image block size issue");
                return;
        }
 
@@ -128,7 +136,7 @@ void write_sparse_image(
                case CHUNK_TYPE_RAW:
                        if (chunk_header->total_sz !=
                            (sparse_header->chunk_hdr_sz + chunk_data_sz)) {
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                        "Bogus chunk size for chunk type Raw");
                                return;
                        }
@@ -137,7 +145,7 @@ void write_sparse_image(
                                printf(
                                    "%s: Request would exceed partition size!\n",
                                    __func__);
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                    "Request would exceed partition size!");
                                return;
                        }
@@ -148,7 +156,7 @@ void write_sparse_image(
                                printf("%s: %s" LBAFU " [" LBAFU "]\n",
                                       __func__, "Write failed, block #",
                                       blk, blks);
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                              "flash write failure");
                                return;
                        }
@@ -161,17 +169,18 @@ void write_sparse_image(
                case CHUNK_TYPE_FILL:
                        if (chunk_header->total_sz !=
                            (sparse_header->chunk_hdr_sz + sizeof(uint32_t))) {
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                        "Bogus chunk size for chunk type FILL");
                                return;
                        }
 
                        fill_buf = (uint32_t *)
                                   memalign(ARCH_DMA_MINALIGN,
-                                           ROUNDUP(info->blksz,
-                                                   ARCH_DMA_MINALIGN));
+                                           ROUNDUP(
+                                               info->blksz * fill_buf_num_blks,
+                                               ARCH_DMA_MINALIGN));
                        if (!fill_buf) {
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                        "Malloc failed for: CHUNK_TYPE_FILL");
                                return;
                        }
@@ -179,30 +188,39 @@ void write_sparse_image(
                        fill_val = *(uint32_t *)data;
                        data = (char *)data + sizeof(uint32_t);
 
-                       for (i = 0; i < (info->blksz / sizeof(fill_val)); i++)
+                       for (i = 0;
+                            i < (info->blksz * fill_buf_num_blks /
+                                 sizeof(fill_val));
+                            i++)
                                fill_buf[i] = fill_val;
 
                        if (blk + blkcnt > info->start + info->size) {
                                printf(
                                    "%s: Request would exceed partition size!\n",
                                    __func__);
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                    "Request would exceed partition size!");
                                return;
                        }
 
-                       for (i = 0; i < blkcnt; i++) {
-                               blks = info->write(info, blk, 1, fill_buf);
-                               /* blks might be > 1 (eg. NAND bad-blocks) */
-                               if (blks < 1) {
-                                       printf("%s: %s, block # " LBAFU "\n",
-                                              __func__, "Write failed", blk);
-                                       fastboot_fail(response_str,
+                       for (i = 0; i < blkcnt;) {
+                               j = blkcnt - i;
+                               if (j > fill_buf_num_blks)
+                                       j = fill_buf_num_blks;
+                               blks = info->write(info, blk, j, fill_buf);
+                               /* blks might be > j (eg. NAND bad-blocks) */
+                               if (blks < j) {
+                                       printf("%s: %s " LBAFU " [%d]\n",
+                                              __func__,
+                                              "Write failed, block #",
+                                              blk, j);
+                                       fastboot_fail(
                                                      "flash write failure");
                                        free(fill_buf);
                                        return;
                                }
                                blk += blks;
+                               i += j;
                        }
                        bytes_written += blkcnt * info->blksz;
                        total_blocks += chunk_data_sz / sparse_header->blk_sz;
@@ -210,16 +228,14 @@ void write_sparse_image(
                        break;
 
                case CHUNK_TYPE_DONT_CARE:
-#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
-                       blk += blkcnt;
+                       blk += info->reserve(info, blk, blkcnt);
                        total_blocks += chunk_header->chunk_sz;
-#endif
                        break;
 
                case CHUNK_TYPE_CRC32:
                        if (chunk_header->total_sz !=
                            sparse_header->chunk_hdr_sz) {
-                               fastboot_fail(response_str,
+                               fastboot_fail(
                                        "Bogus chunk size for chunk type Dont Care");
                                return;
                        }
@@ -230,7 +246,7 @@ void write_sparse_image(
                default:
                        printf("%s: Unknown chunk type: %x\n", __func__,
                               chunk_header->chunk_type);
-                       fastboot_fail(response_str, "Unknown chunk type");
+                       fastboot_fail("Unknown chunk type");
                        return;
                }
        }
@@ -240,9 +256,9 @@ void write_sparse_image(
        printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name);
 
        if (total_blocks != sparse_header->total_blks)
-               fastboot_fail(response_str, "sparse image write failure");
+               fastboot_fail("sparse image write failure");
        else
-               fastboot_okay(response_str, "");
+               fastboot_okay("");
 
        return;
 }