kernel: make bcm47xxpart work with TRX flashed at bad block(s)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 48061
This commit is contained in:
		| @@ -22,7 +22,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|   |   | ||||||
|  #include <uapi/linux/magic.h> |  #include <uapi/linux/magic.h> | ||||||
|   |   | ||||||
| @@ -131,6 +132,17 @@ static int bcm47xxpart_parse(struct mtd_ | @@ -159,6 +160,17 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  			break; |  			break; | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
|   | |||||||
| @@ -12,7 +12,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  |  | ||||||
| --- a/drivers/mtd/bcm47xxpart.c | --- a/drivers/mtd/bcm47xxpart.c | ||||||
| +++ b/drivers/mtd/bcm47xxpart.c | +++ b/drivers/mtd/bcm47xxpart.c | ||||||
| @@ -66,19 +66,22 @@ static void bcm47xxpart_add_part(struct | @@ -94,19 +94,22 @@ static size_t bcm47xxpart_real_offset(st | ||||||
|  static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, |  static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, | ||||||
|  						  size_t offset) |  						  size_t offset) | ||||||
|  { |  { | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|   |   | ||||||
|  #include <uapi/linux/magic.h> |  #include <uapi/linux/magic.h> | ||||||
|   |   | ||||||
| @@ -131,6 +132,17 @@ static int bcm47xxpart_parse(struct mtd_ | @@ -159,6 +160,17 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  			break; |  			break; | ||||||
|  		} |  		} | ||||||
|   |   | ||||||
|   | |||||||
| @@ -0,0 +1,100 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> | ||||||
|  | Date: Sat, 2 Jan 2016 01:04:52 +0100 | ||||||
|  | Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating | ||||||
|  |  offsets | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- | ||||||
|  |  1 file changed, 40 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/bcm47xxpart.c | ||||||
|  | +++ b/drivers/mtd/bcm47xxpart.c | ||||||
|  | @@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, | ||||||
|  |  	part->mask_flags = mask_flags; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* | ||||||
|  | + * Calculate real end offset (address) for a given amount of data. It checks | ||||||
|  | + * all blocks skipping bad ones. | ||||||
|  | + */ | ||||||
|  | +static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset, | ||||||
|  | +				      size_t bytes) | ||||||
|  | +{ | ||||||
|  | +	size_t real_offset = offset; | ||||||
|  | + | ||||||
|  | +	if (mtd_block_isbad(master, real_offset)) | ||||||
|  | +		pr_warn("Base offset shouldn't be at bad block"); | ||||||
|  | + | ||||||
|  | +	while (bytes >= master->erasesize) { | ||||||
|  | +		bytes -= master->erasesize; | ||||||
|  | +		real_offset += master->erasesize; | ||||||
|  | +		while (mtd_block_isbad(master, real_offset)) { | ||||||
|  | +			real_offset += master->erasesize; | ||||||
|  | + | ||||||
|  | +			if (real_offset >= master->size) | ||||||
|  | +				return real_offset - master->erasesize; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	real_offset += bytes; | ||||||
|  | + | ||||||
|  | +	return real_offset; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, | ||||||
|  |  						  size_t offset) | ||||||
|  |  { | ||||||
|  | @@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |   | ||||||
|  |  		/* TRX */ | ||||||
|  |  		if (buf[0x000 / 4] == TRX_MAGIC) { | ||||||
|  | +			uint32_t tmp; | ||||||
|  | + | ||||||
|  |  			if (BCM47XXPART_MAX_PARTS - curr_part < 4) { | ||||||
|  |  				pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); | ||||||
|  |  				break; | ||||||
|  | @@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			i = 0; | ||||||
|  |  			/* We have LZMA loader if offset[2] points to sth */ | ||||||
|  |  			if (trx->offset[2]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "loader", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "loader", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "linux", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "linux", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  | @@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  |  				const char *name; | ||||||
|  |   | ||||||
|  | -				name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  | +				name = bcm47xxpart_trx_data_part_name(master, tmp); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     name, | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     name, tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
| @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  #define ML_MAGIC1			0x39685a42 |  #define ML_MAGIC1			0x39685a42 | ||||||
|  #define ML_MAGIC2			0x26594131 |  #define ML_MAGIC2			0x26594131 | ||||||
|  #define TRX_MAGIC			0x30524448 |  #define TRX_MAGIC			0x30524448 | ||||||
| @@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ | @@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  					     MTD_WRITEABLE); |  					     MTD_WRITEABLE); | ||||||
|  			continue; |  			continue; | ||||||
|  		} |  		} | ||||||
|   | |||||||
| @@ -0,0 +1,100 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> | ||||||
|  | Date: Sat, 2 Jan 2016 01:04:52 +0100 | ||||||
|  | Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating | ||||||
|  |  offsets | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- | ||||||
|  |  1 file changed, 40 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/bcm47xxpart.c | ||||||
|  | +++ b/drivers/mtd/bcm47xxpart.c | ||||||
|  | @@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, | ||||||
|  |  	part->mask_flags = mask_flags; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* | ||||||
|  | + * Calculate real end offset (address) for a given amount of data. It checks | ||||||
|  | + * all blocks skipping bad ones. | ||||||
|  | + */ | ||||||
|  | +static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset, | ||||||
|  | +				      size_t bytes) | ||||||
|  | +{ | ||||||
|  | +	size_t real_offset = offset; | ||||||
|  | + | ||||||
|  | +	if (mtd_block_isbad(master, real_offset)) | ||||||
|  | +		pr_warn("Base offset shouldn't be at bad block"); | ||||||
|  | + | ||||||
|  | +	while (bytes >= master->erasesize) { | ||||||
|  | +		bytes -= master->erasesize; | ||||||
|  | +		real_offset += master->erasesize; | ||||||
|  | +		while (mtd_block_isbad(master, real_offset)) { | ||||||
|  | +			real_offset += master->erasesize; | ||||||
|  | + | ||||||
|  | +			if (real_offset >= master->size) | ||||||
|  | +				return real_offset - master->erasesize; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	real_offset += bytes; | ||||||
|  | + | ||||||
|  | +	return real_offset; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, | ||||||
|  |  						  size_t offset) | ||||||
|  |  { | ||||||
|  | @@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |   | ||||||
|  |  		/* TRX */ | ||||||
|  |  		if (buf[0x000 / 4] == TRX_MAGIC) { | ||||||
|  | +			uint32_t tmp; | ||||||
|  | + | ||||||
|  |  			if (BCM47XXPART_MAX_PARTS - curr_part < 4) { | ||||||
|  |  				pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); | ||||||
|  |  				break; | ||||||
|  | @@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			i = 0; | ||||||
|  |  			/* We have LZMA loader if offset[2] points to sth */ | ||||||
|  |  			if (trx->offset[2]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "loader", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "loader", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "linux", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "linux", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  | @@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  |  				const char *name; | ||||||
|  |   | ||||||
|  | -				name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  | +				name = bcm47xxpart_trx_data_part_name(master, tmp); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     name, | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     name, tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
| @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  #define ML_MAGIC1			0x39685a42 |  #define ML_MAGIC1			0x39685a42 | ||||||
|  #define ML_MAGIC2			0x26594131 |  #define ML_MAGIC2			0x26594131 | ||||||
|  #define TRX_MAGIC			0x30524448 |  #define TRX_MAGIC			0x30524448 | ||||||
| @@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ | @@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  					     MTD_WRITEABLE); |  					     MTD_WRITEABLE); | ||||||
|  			continue; |  			continue; | ||||||
|  		} |  		} | ||||||
|   | |||||||
| @@ -0,0 +1,100 @@ | |||||||
|  | From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com> | ||||||
|  | Date: Sat, 2 Jan 2016 01:04:52 +0100 | ||||||
|  | Subject: [PATCH] mtd: bcm47xxpart: check for bad blocks when calculating | ||||||
|  |  offsets | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | ||||||
|  | --- | ||||||
|  |  drivers/mtd/bcm47xxpart.c | 50 +++++++++++++++++++++++++++++++++++++---------- | ||||||
|  |  1 file changed, 40 insertions(+), 10 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/drivers/mtd/bcm47xxpart.c | ||||||
|  | +++ b/drivers/mtd/bcm47xxpart.c | ||||||
|  | @@ -61,6 +61,34 @@ static void bcm47xxpart_add_part(struct mtd_partition *part, const char *name, | ||||||
|  |  	part->mask_flags = mask_flags; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +/* | ||||||
|  | + * Calculate real end offset (address) for a given amount of data. It checks | ||||||
|  | + * all blocks skipping bad ones. | ||||||
|  | + */ | ||||||
|  | +static size_t bcm47xxpart_real_offset(struct mtd_info *master, size_t offset, | ||||||
|  | +				      size_t bytes) | ||||||
|  | +{ | ||||||
|  | +	size_t real_offset = offset; | ||||||
|  | + | ||||||
|  | +	if (mtd_block_isbad(master, real_offset)) | ||||||
|  | +		pr_warn("Base offset shouldn't be at bad block"); | ||||||
|  | + | ||||||
|  | +	while (bytes >= master->erasesize) { | ||||||
|  | +		bytes -= master->erasesize; | ||||||
|  | +		real_offset += master->erasesize; | ||||||
|  | +		while (mtd_block_isbad(master, real_offset)) { | ||||||
|  | +			real_offset += master->erasesize; | ||||||
|  | + | ||||||
|  | +			if (real_offset >= master->size) | ||||||
|  | +				return real_offset - master->erasesize; | ||||||
|  | +		} | ||||||
|  | +	} | ||||||
|  | + | ||||||
|  | +	real_offset += bytes; | ||||||
|  | + | ||||||
|  | +	return real_offset; | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  static const char *bcm47xxpart_trx_data_part_name(struct mtd_info *master, | ||||||
|  |  						  size_t offset) | ||||||
|  |  { | ||||||
|  | @@ -182,6 +210,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |   | ||||||
|  |  		/* TRX */ | ||||||
|  |  		if (buf[0x000 / 4] == TRX_MAGIC) { | ||||||
|  | +			uint32_t tmp; | ||||||
|  | + | ||||||
|  |  			if (BCM47XXPART_MAX_PARTS - curr_part < 4) { | ||||||
|  |  				pr_warn("Not enough partitions left to register trx, scanning stopped!\n"); | ||||||
|  |  				break; | ||||||
|  | @@ -196,18 +226,18 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			i = 0; | ||||||
|  |  			/* We have LZMA loader if offset[2] points to sth */ | ||||||
|  |  			if (trx->offset[2]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "loader", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "loader", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     "linux", | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     "linux", tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
|  | @@ -219,11 +249,11 @@ static int bcm47xxpart_parse(struct mtd_info *master, | ||||||
|  |  			if (trx->offset[i]) { | ||||||
|  |  				const char *name; | ||||||
|  |   | ||||||
|  | -				name = bcm47xxpart_trx_data_part_name(master, offset + trx->offset[i]); | ||||||
|  | +				tmp = bcm47xxpart_real_offset(master, offset, | ||||||
|  | +							      trx->offset[i]); | ||||||
|  | +				name = bcm47xxpart_trx_data_part_name(master, tmp); | ||||||
|  |  				bcm47xxpart_add_part(&parts[curr_part++], | ||||||
|  | -						     name, | ||||||
|  | -						     offset + trx->offset[i], | ||||||
|  | -						     0); | ||||||
|  | +						     name, tmp, 0); | ||||||
|  |  				i++; | ||||||
|  |  			} | ||||||
|  |   | ||||||
| @@ -24,7 +24,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com> | |||||||
|  #define ML_MAGIC1			0x39685a42 |  #define ML_MAGIC1			0x39685a42 | ||||||
|  #define ML_MAGIC2			0x26594131 |  #define ML_MAGIC2			0x26594131 | ||||||
|  #define TRX_MAGIC			0x30524448 |  #define TRX_MAGIC			0x30524448 | ||||||
| @@ -179,6 +180,15 @@ static int bcm47xxpart_parse(struct mtd_ | @@ -207,6 +208,15 @@ static int bcm47xxpart_parse(struct mtd_ | ||||||
|  					     MTD_WRITEABLE); |  					     MTD_WRITEABLE); | ||||||
|  			continue; |  			continue; | ||||||
|  		} |  		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Rafał Miłecki
					Rafał Miłecki