X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=common%2Ffb_nand.c;h=c8c79e92383762138294f1124c58ade2cb329902;hb=fa72de10452c51ee32f8278cdfabd38a6aafc7f8;hp=9ca8602a73ecbab5abdbf86cb6cd1dc1ec2b334e;hpb=bc80109b117abe4ed2cd4d12c8dc188561bc298e;p=u-boot diff --git a/common/fb_nand.c b/common/fb_nand.c index 9ca8602a73..c8c79e9238 100644 --- a/common/fb_nand.c +++ b/common/fb_nand.c @@ -10,16 +10,13 @@ #include #include -#include #include #include #include -static char *response_str; - struct fb_nand_sparse { - nand_info_t *nand; + struct mtd_info *mtd; struct part_info *part; }; @@ -33,8 +30,8 @@ __weak int board_fastboot_write_partition_setup(char *name) return 0; } -static int fb_nand_lookup(const char *partname, char *response, - nand_info_t **nand, +static int fb_nand_lookup(const char *partname, + struct mtd_info **mtd, struct part_info **part) { struct mtd_device *dev; @@ -44,30 +41,30 @@ 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; } - *nand = &nand_info[dev->id->num]; + *mtd = nand_info[dev->id->num]; return 0; } -static int _fb_nand_erase(nand_info_t *nand, struct part_info *part) +static int _fb_nand_erase(struct mtd_info *mtd, struct part_info *part) { nand_erase_options_t opts; int ret; @@ -80,7 +77,7 @@ static int _fb_nand_erase(nand_info_t *nand, struct part_info *part) printf("Erasing blocks 0x%llx to 0x%llx\n", part->offset, part->offset + part->size); - ret = nand_erase_opts(nand, &opts); + ret = nand_erase_opts(mtd, &opts); if (ret) return ret; @@ -90,7 +87,7 @@ static int _fb_nand_erase(nand_info_t *nand, struct part_info *part) return 0; } -static int _fb_nand_write(nand_info_t *nand, struct part_info *part, +static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part, void *buffer, unsigned int offset, unsigned int length, size_t *written) { @@ -100,47 +97,65 @@ static int _fb_nand_write(nand_info_t *nand, struct part_info *part, flags |= WITH_DROP_FFS; #endif - return nand_write_skip_bad(nand, offset, &length, written, + return nand_write_skip_bad(mtd, offset, &length, written, part->size - (offset - part->offset), 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; - nand_info_t *nand = NULL; + struct mtd_info *mtd = NULL; int ret; - /* initialize the response buffer */ - response_str = response; - - ret = fb_nand_lookup(partname, response, &nand, &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,24 +165,28 @@ 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 = nand; + sparse_priv.mtd = mtd; sparse_priv.part = part; - sparse.block_sz = nand->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); - ret = _fb_nand_write(nand, part, download_buffer, part->offset, + ret = _fb_nand_write(mtd, part, download_buffer, part->offset, download_bytes, NULL); printf("........ wrote %u bytes to '%s'\n", @@ -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; - nand_info_t *nand = NULL; + struct mtd_info *mtd = NULL; int ret; - /* initialize the response buffer */ - response_str = response; - - ret = fb_nand_lookup(partname, response, &nand, &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; } @@ -202,12 +218,12 @@ void fb_nand_erase(const char *partname, char *response) if (ret) return; - ret = _fb_nand_erase(nand, part); + ret = _fb_nand_erase(mtd, part); if (ret) { - error("failed erasing from device %s", nand->name); - fastboot_fail(response_str, "failed erasing from device"); + error("failed erasing from device %s", mtd->name); + fastboot_fail("failed erasing from device"); return; } - fastboot_okay(response_str, ""); + fastboot_okay(""); }