mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH 1/2] mtd: partition: Fix multi eraseregion chips
@ 2014-06-10 11:55 Sascha Hauer
  2014-06-10 11:55 ` [PATCH 2/2] mtd: partition: implement lock/unlock Sascha Hauer
  0 siblings, 1 reply; 2+ messages in thread
From: Sascha Hauer @ 2014-06-10 11:55 UTC (permalink / raw)
  To: barebox

The current code counts the eraseregions a new partition spans and
sets the partitions number of eraseregions accordingly, but the code
forgets to allocate and fill in the eraseregions for the partition
mtd device. This makes the erase operation crash with a NULL pointer
exception.
This patch fixes this with the same approach the kernel uses: Set
the number of eraseregions to 1 unconditionally and the eraseregion
size to the maximum of the eraseregions found in the partition.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/partition.c | 41 ++++++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 17 deletions(-)

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index 7c19766..52d0c94 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -76,7 +76,6 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 		uint64_t size, unsigned long flags, const char *name)
 {
 	struct mtd_info *part;
-	int start = 0, end = 0, i;
 
 	part = xzalloc(sizeof(*part));
 
@@ -93,24 +92,32 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 	part->ecc_strength = mtd->ecc_strength;
 	part->subpage_sft = mtd->subpage_sft;
 
-	/*
-	 * find the number of eraseregions the partition includes.
-	 * Do not bother to create the mtd_erase_region_infos as
-	 * ubi is only interested in its number. UBI does not
-	 * yet support multiple erase regions.
-	 */
-	for (i = mtd->numeraseregions - 1; i >= 0; i--) {
-		struct mtd_erase_region_info *region = &mtd->eraseregions[i];
-		if (offset >= region->offset &&
-		    offset < region->offset + region->erasesize * region->numblocks)
-			start = i;
-		if (offset + size >= region->offset &&
-		    offset + size <= region->offset + region->erasesize * region->numblocks)
-			end = i;
+	if (mtd->numeraseregions > 1) {
+		/* Deal with variable erase size stuff */
+		int i, max = mtd->numeraseregions;
+		u64 end = offset + size;
+		struct mtd_erase_region_info *regions = mtd->eraseregions;
+
+		/* Find the first erase regions which is part of this
+		 * partition. */
+		for (i = 0; i < max && regions[i].offset <= offset; i++)
+			;
+		/* The loop searched for the region _behind_ the first one */
+		if (i > 0)
+			i--;
+
+		/* Pick biggest erasesize */
+		for (; i < max && regions[i].offset < end; i++) {
+			if (part->erasesize < regions[i].erasesize) {
+				part->erasesize = regions[i].erasesize;
+			}
+		}
+		BUG_ON(part->erasesize == 0);
+	} else {
+		/* Single erase size */
+		part->erasesize = mtd->erasesize;
 	}
 
-	part->numeraseregions = end - start;
-
 	part->read = mtd_part_read;
 	if (IS_ENABLED(CONFIG_MTD_WRITE)) {
 		part->write = mtd_part_write;
-- 
2.0.0.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [PATCH 2/2] mtd: partition: implement lock/unlock
  2014-06-10 11:55 [PATCH 1/2] mtd: partition: Fix multi eraseregion chips Sascha Hauer
@ 2014-06-10 11:55 ` Sascha Hauer
  0 siblings, 0 replies; 2+ messages in thread
From: Sascha Hauer @ 2014-06-10 11:55 UTC (permalink / raw)
  To: barebox

CFI Nor flashes need lock/unlock which is not implemented for partitions.
Fix this.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/partition.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/drivers/mtd/partition.c b/drivers/mtd/partition.c
index 52d0c94..5c0d46f 100644
--- a/drivers/mtd/partition.c
+++ b/drivers/mtd/partition.c
@@ -49,6 +49,32 @@ static int mtd_part_erase(struct mtd_info *mtd, struct erase_info *instr)
 	return ret;
 }
 
+static int mtd_part_lock(struct mtd_info *mtd, loff_t offset, size_t len)
+{
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+
+	if (offset + len > mtd->size)
+		return -EINVAL;
+
+	offset += mtd->master_offset;
+
+	return mtd->master->lock(mtd->master, offset, len);
+}
+
+static int mtd_part_unlock(struct mtd_info *mtd, loff_t offset, size_t len)
+{
+	if (!(mtd->flags & MTD_WRITEABLE))
+		return -EROFS;
+
+	if (offset + len > mtd->size)
+		return -EINVAL;
+
+	offset += mtd->master_offset;
+
+	return mtd->master->unlock(mtd->master, offset, len);
+}
+
 static int mtd_part_block_isbad(struct mtd_info *mtd, loff_t ofs)
 {
 	if (ofs >= mtd->size)
@@ -122,6 +148,8 @@ struct mtd_info *mtd_add_partition(struct mtd_info *mtd, off_t offset,
 	if (IS_ENABLED(CONFIG_MTD_WRITE)) {
 		part->write = mtd_part_write;
 		part->erase = mtd_part_erase;
+		part->lock = mtd_part_lock;
+		part->unlock = mtd_part_unlock;
 		part->block_markbad = mtd->block_markbad ? mtd_part_block_markbad : NULL;
 	}
 
-- 
2.0.0.rc2


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-06-10 11:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-10 11:55 [PATCH 1/2] mtd: partition: Fix multi eraseregion chips Sascha Hauer
2014-06-10 11:55 ` [PATCH 2/2] mtd: partition: implement lock/unlock Sascha Hauer

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox