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 ae34f4891b6..c8c79e92383 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("");  } | 
