diff options
Diffstat (limited to 'common/fb_nand.c')
-rw-r--r-- | common/fb_nand.c | 104 |
1 files changed, 60 insertions, 44 deletions
diff --git a/common/fb_nand.c b/common/fb_nand.c index ae34f48..c8c79e9 100644 --- a/common/fb_nand.c +++ b/common/fb_nand.c @@ -10,16 +10,13 @@ #include <fastboot.h> #include <image-sparse.h> -#include <sparse_format.h> #include <linux/mtd/mtd.h> #include <jffs2/jffs2.h> #include <nand.h> -static char *response_str; - struct fb_nand_sparse { - struct mtd_info *nand; + struct mtd_info *mtd; struct part_info *part; }; @@ -33,7 +30,7 @@ __weak int board_fastboot_write_partition_setup(char *name) return 0; } -static int fb_nand_lookup(const char *partname, char *response, +static int fb_nand_lookup(const char *partname, struct mtd_info **mtd, struct part_info **part) { @@ -44,21 +41,21 @@ static int fb_nand_lookup(const char *partname, char *response, ret = mtdparts_init(); if (ret) { error("Cannot initialize MTD partitions\n"); - fastboot_fail(response_str, "cannot init mtdparts"); + fastboot_fail("cannot init mtdparts"); return ret; } ret = find_dev_and_part(partname, &dev, &pnum, part); if (ret) { error("cannot find partition: '%s'", partname); - fastboot_fail(response_str, "cannot find partition"); + fastboot_fail("cannot find partition"); return ret; } if (dev->id->type != MTD_DEV_TYPE_NAND) { error("partition '%s' is not stored on a NAND device", partname); - fastboot_fail(response_str, "not a NAND device"); + fastboot_fail("not a NAND device"); return -EINVAL; } @@ -105,42 +102,60 @@ static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part, buffer, flags); } -static int fb_nand_sparse_write(struct sparse_storage *storage, - void *priv, - unsigned int offset, - unsigned int size, - char *data) +static lbaint_t fb_nand_sparse_write(struct sparse_storage *info, + lbaint_t blk, lbaint_t blkcnt, const void *buffer) { - struct fb_nand_sparse *sparse = priv; + struct fb_nand_sparse *sparse = info->priv; size_t written; int ret; - ret = _fb_nand_write(sparse->nand, sparse->part, data, - offset * storage->block_sz, - size * storage->block_sz, &written); + ret = _fb_nand_write(sparse->mtd, sparse->part, (void *)buffer, + blk * info->blksz, + blkcnt * info->blksz, &written); if (ret < 0) { printf("Failed to write sparse chunk\n"); return ret; } - return written / storage->block_sz; +/* TODO - verify that the value "written" includes the "bad-blocks" ... */ + + /* + * the return value must be 'blkcnt' ("good-blocks") plus the + * number of "bad-blocks" encountered within this space... + */ + return written / info->blksz; +} + +static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info, + lbaint_t blk, lbaint_t blkcnt) +{ + int bad_blocks = 0; + +/* + * TODO - implement a function to determine the total number + * of blocks which must be used in order to reserve the specified + * number ("blkcnt") of "good-blocks", starting at "blk"... + * ( possibly something like the "check_skip_len()" function ) + */ + + /* + * the return value must be 'blkcnt' ("good-blocks") plus the + * number of "bad-blocks" encountered within this space... + */ + return blkcnt + bad_blocks; } -void fb_nand_flash_write(const char *partname, unsigned int session_id, - void *download_buffer, unsigned int download_bytes, - char *response) +void fb_nand_flash_write(const char *cmd, void *download_buffer, + unsigned int download_bytes) { struct part_info *part; struct mtd_info *mtd = NULL; int ret; - /* initialize the response buffer */ - response_str = response; - - ret = fb_nand_lookup(partname, response, &mtd, &part); + ret = fb_nand_lookup(cmd, &mtd, &part); if (ret) { error("invalid NAND device"); - fastboot_fail(response_str, "invalid NAND device"); + fastboot_fail("invalid NAND device"); return; } @@ -150,19 +165,23 @@ void fb_nand_flash_write(const char *partname, unsigned int session_id, if (is_sparse_image(download_buffer)) { struct fb_nand_sparse sparse_priv; - sparse_storage_t sparse; + struct sparse_storage sparse; - sparse_priv.nand = mtd; + sparse_priv.mtd = mtd; sparse_priv.part = part; - sparse.block_sz = mtd->writesize; - sparse.start = part->offset / sparse.block_sz; - sparse.size = part->size / sparse.block_sz; - sparse.name = part->name; + sparse.blksz = mtd->writesize; + sparse.start = part->offset / sparse.blksz; + sparse.size = part->size / sparse.blksz; sparse.write = fb_nand_sparse_write; + sparse.reserve = fb_nand_sparse_reserve; + + printf("Flashing sparse image at offset " LBAFU "\n", + sparse.start); - ret = store_sparse_image(&sparse, &sparse_priv, session_id, - download_buffer); + sparse.priv = &sparse_priv; + write_sparse_image(&sparse, cmd, download_buffer, + download_bytes); } else { printf("Flashing raw image at offset 0x%llx\n", part->offset); @@ -175,26 +194,23 @@ void fb_nand_flash_write(const char *partname, unsigned int session_id, } if (ret) { - fastboot_fail(response_str, "error writing the image"); + fastboot_fail("error writing the image"); return; } - fastboot_okay(response_str, ""); + fastboot_okay(""); } -void fb_nand_erase(const char *partname, char *response) +void fb_nand_erase(const char *cmd) { struct part_info *part; struct mtd_info *mtd = NULL; int ret; - /* initialize the response buffer */ - response_str = response; - - ret = fb_nand_lookup(partname, response, &mtd, &part); + ret = fb_nand_lookup(cmd, &mtd, &part); if (ret) { error("invalid NAND device"); - fastboot_fail(response_str, "invalid NAND device"); + fastboot_fail("invalid NAND device"); return; } @@ -205,9 +221,9 @@ void fb_nand_erase(const char *partname, char *response) ret = _fb_nand_erase(mtd, part); if (ret) { error("failed erasing from device %s", mtd->name); - fastboot_fail(response_str, "failed erasing from device"); + fastboot_fail("failed erasing from device"); return; } - fastboot_okay(response_str, ""); + fastboot_okay(""); } |