Skip to contentSkip to conversation

CFI numblocks incorrect?

U-Boot New Ladislav Michl 2 participants 3 messages Jan 27, 2010 – Feb 2, 2010 Memory technology devices (MTD)

lore
Share & tools
lore
#0 lore raw

it seems CFI flash support is somehow broken. mtd->eraseregions is filled as bellow:

erase size      blocks  correct blocks
00004000        01      01
00002000        01      02
00008000        00      01
00010000        0f      0f

'blocks' is actual numblocks field value while 'correct blocks' is expected value. flinfo gives correct results (it is AM29LV800BB). It seems to be related to cfi_mtd_set_erasesize function, but I'm too tired to debug it further. Just reporting in case anyone has time to look at it. Otherwise I'll do so at Friday.

Best regards,
ladis

#1 lore raw

PATCH 1/1 CFI: fix eraseregions numblocks

From: Ladislav Michl <[email protected]>

eraseregions numblocks was sometimes one less than actual, possibly producing erase regions with zero blocks. As MTD code touches eraseregions only if numeraseregions is greater that zero, allocate eraseregions only for non uniform erase size flash.

---
 cfi_mtd.c |   35 ++++++++++++++++++-----------------
 1 file changed, 18 insertions(+), 17 deletions(-)
drivers/mtd/cfi_mtd.c +18 -17
index 34748dd..6a0cab3 100644
@@ -161,8 +161,8 @@ static int cfi_mtd_set_erasesize(struct mtd_info *mtd, flash_info_t *fi)
 	int sect;
 	int regions = 0;
 	int numblocks = 0;
-	ulong offset = 0;
-	ulong base_addr = fi->start[0];
+	ulong offset;
+	ulong base_addr;
 
 	/*
 	 * First detect the number of eraseregions so that we can allocate
@@ -174,29 +174,35 @@ static int cfi_mtd_set_erasesize(struct mtd_info *mtd, flash_info_t *fi)
 		sect_size_old = flash_sector_size(fi, sect);
 	}
 
+	switch (regions) {
+	case 0:
+		return 1;
+	case 1:	/* flash has uniform erase size */
+		mtd->numeraseregions = 0;
+		mtd->erasesize = sect_size_old;
+		return 0;
+	}
+
+	mtd->numeraseregions = regions;
 	mtd->eraseregions = malloc(sizeof(struct mtd_erase_region_info) * regions);
 
 	/*
 	 * Now detect the largest sector and fill the eraseregions
 	 */
-	sect_size_old = 0;
 	regions = 0;
+	base_addr = offset = fi->start[0];
+	sect_size_old = flash_sector_size(fi, 0);
 	for (sect = 0; sect < fi->sector_count; sect++) {
-		if ((sect_size_old != flash_sector_size(fi, sect)) &&
-		    (sect_size_old != 0)) {
+		if (sect_size_old != flash_sector_size(fi, sect)) {
 			mtd->eraseregions[regions].offset = offset - base_addr;
 			mtd->eraseregions[regions].erasesize = sect_size_old;
 			mtd->eraseregions[regions].numblocks = numblocks;
-
 			/* Now start counting the next eraseregions */
 			numblocks = 0;
 			regions++;
-		} else {
-			numblocks++;
-		}
-
-		if (sect_size_old != flash_sector_size(fi, sect))
 			offset = fi->start[sect];
+		}
+		numblocks++;
 
 		/*
 		 * Select the largest sector size as erasesize (e.g. for UBI)
@@ -212,12 +218,7 @@ static int cfi_mtd_set_erasesize(struct mtd_info *mtd, flash_info_t *fi)
 	 */
 	mtd->eraseregions[regions].offset = offset - base_addr;
 	mtd->eraseregions[regions].erasesize = sect_size_old;
-	mtd->eraseregions[regions].numblocks = numblocks + 1;
-
-	if (regions)
-		mtd->numeraseregions = regions + 1;
-	else
-		mtd->numeraseregions = 0;
+	mtd->eraseregions[regions].numblocks = numblocks;
 
 	mtd->erasesize = sect_size;
 
#2 lore raw

PATCH 1/1 CFI: fix eraseregions numblocks

Quoted 6 lines · On Thursday 28 January 2010 12:27:14 Ladislav Michl wrote:

From: Ladislav Michl <[email protected]>

eraseregions numblocks was sometimes one less than actual, possibly
producing erase regions with zero blocks. As MTD code touches eraseregions only if numeraseregions is greater that zero, allocate eraseregions only for non uniform erase size flash.

Applied to u-boot-cfi-flash/master. Thanks.

Cheers,
Stefan

--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-0 Fax: (+49)-8142-66989-80 Email: office at denx.de