flash_info and MEMGETREGIONCOUNT

Hinko Kocevar hinko.kocevar at cetrtapot.si
Thu Aug 7 03:55:45 EDT 2008


hartleys wrote:
> On Tuesday, August 05, 2008 8:06 AM, Hinko Kocevar wrote:
>> Hi,
>>
>> I would like to know some info about the flash chip present
>> on the board. I found flash_info utility and can't seem to
>> get information about the region count with MEMGETREGIONCOUNT.
>> # /flash_info /dev/mtd0
>> Device /dev/mtd0 has 0 erase regions
>> # /flash_info /dev/mtd1
>> Device /dev/mtd1 has 0 erase regions
>> # /flash_info /dev/mtd2
>> Device /dev/mtd2 has 0 erase regions
> 
> I get the same results on my system. I'm not sure what "flash_info" is
> actually meant for.
> 
> Try the mtd_debug utility instead and see if that information is more
> helpful. Here's a sample output from one of my mtd partitions:
> 
> / # mtd_debug info /dev/mtd0
> mtd.type = MTD_NORFLASH
> mtd.flags = MTD_WRITEABLE | MTD_BIT_WRITEABLE
> mtd.size = 262144 (256K)
> mtd.erasesize = 131072 (128K)
> mtd.writesize = 1
> mtd.oobsize = 0
> regions = 0
> 
> BTW, the regions = 0 is why the flash_info utility reports 0 erase
> regions.
> 

[Just a side note, patch is inlined just for evaluation, yesterdays reply with attached patch didn't go through the MTD maintainer/mail server]

Same here...
# /mtd_debug info /dev/mtd0 
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size = 65536 (64K)
mtd.erasesize = 32768 (32K)
mtd.writesize = 1 
mtd.oobsize = 0 
regions = 0

# /mtd_debug info /dev/mtd1 
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size = 1179648 (1M)
mtd.erasesize = 65536 (64K)
mtd.writesize = 1 
mtd.oobsize = 0 
regions = 0

Looking at the code I see that cfi_amdstd_setup() sets the erase region parameters to detected values. The same info can be also dumped in my flash map driver.

My investigation lead to add_mtd_partitions() that creates slave partitions out of master mtd partition - and where erase regions are not set for each slave partition.

Attached is a *dirty* patch that makes each slave partition hold the erase region info in addition to just erasesize.
Patch is just a proof of concept and should be rewritten, thus any pointers on how to improve it are welcomed!

And here are some of the results (lines with [xxxx..] are from kernel log):
# ./flash_info /dev/mtd0
[42949395.891554] Nr erase regions 3
[42949395.894925] 0: offset=0x0,size=0x4000,blocks=1
[42949395.905162] 1: offset=0x4000,size=0x2000,blocks=2
[42949395.910202] 2: offset=0x8000,size=0x8000,blocks=1
Device /dev/mtd0 has 3 erase regions
Region 0 is at 0x0 with size 0x4000 and has 0x1 blocks
Region 1 is at 0x4000 with size 0x2000 and has 0x2 blocks
Region 2 is at 0x8000 with size 0x8000 and has 0x1 blocks

# ./mtd_debug info /dev/mtd0
[42949414.642758] Nr erase regions 3
[42949414.646124] 0: offset=0x0,size=0x4000,blocks=1
[42949414.656363] 1: offset=0x4000,size=0x2000,blocks=2
[42949414.661395] 2: offset=0x8000,size=0x8000,blocks=1
mtd.type = MTD_NORFLASH
mtd.flags = MTD_CAP_NORFLASH
mtd.size = 65536 (64K)
mtd.erasesize = 32768 (32K)
mtd.writesize = 1 
mtd.oobsize = 0 
regions = 3

region[0].offset = 0x00000000
region[0].erasesize = 16384 (16K)
region[0].numblocks = 1
region[0].regionindex = 0
region[1].offset = 0x00004000
region[1].erasesize = 8192 (8K)
region[1].numblocks = 2
region[1].regionindex = 0
region[2].offset = 0x00008000
region[2].erasesize = 32768 (32K)
region[2].numblocks = 1
region[2].regionindex = 0

# flash_erase /dev/mtd0 0 1
Erase Total 1 Units
[42949452.398375] Nr erase regions 3
[42949452.408603] 0: offset=0x0,size=0x4000,blocks=1
[42949452.413376] 1: offset=0x4000,size=0x2000,blocks=2
[42949452.423585] 2: offset=0x8000,size=0x8000,blocks=1
Region 0 is at 0 of 1 sector and with sector size 4000
Region 1 is at 16384 of 2 sector and with sector size 2000
Region 2 is at 32768 of 1 sector and with sector size 8000
Performing Flash Erase of length 16384 at offset 0x0
Moving to region 1
 done
# flash_erase /dev/mtd0 0 2
Erase Total 2 Units
[42949458.054011] Nr erase regions 3
[42949458.057376] 0: offset=0x0,size=0x4000,blocks=1
[42949458.062136] 1: offset=0x4000,size=0x2000,blocks=2
[42949458.072363] 2: offset=0x8000,size=0x8000,blocks=1
Region 0 is at 0 of 1 sector and with sector size 4000
Region 1 is at 16384 of 2 sector and with sector size 2000
Region 2 is at 32768 of 1 sector and with sector size 8000
Performing Flash Erase of length 16384 at offset 0x0
Moving to region 1
Performing Flash Erase of length 8192 at offset 0x4000 done
# flash_erase /dev/mtd0 0 3
Erase Total 3 Units
[42949465.054067] Nr erase regions 3
[42949465.057435] 0: offset=0x0,size=0x4000,blocks=1
[42949465.062193] 1: offset=0x4000,size=0x2000,blocks=2
[42949465.072413] 2: offset=0x8000,size=0x8000,blocks=1
Region 0 is at 0 of 1 sector and with sector size 4000
Region 1 is at 16384 of 2 sector and with sector size 2000
Region 2 is at 32768 of 1 sector and with sector size 8000
Performing Flash Erase of length 16384 at offset 0x0
Moving to region 1
Performing Flash Erase of length 8192 at offset 0x6000
Moving to region 2
 done
# flash_erase /dev/mtd0 0 4
Erase Total 4 Units
[42949474.454087] Nr erase regions 3
[42949474.457454] 0: offset=0x0,size=0x4000,blocks=1
[42949474.462212] 1: offset=0x4000,size=0x2000,blocks=2
[42949474.472429] 2: offset=0x8000,size=0x8000,blocks=1
Region 0 is at 0 of 1 sector and with sector size 4000
Region 1 is at 16384 of 2 sector and with sector size 2000
Region 2 is at 32768 of 1 sector and with sector size 8000
Performing Flash Erase of length 16384 at offset 0x0
Moving to region 1
Performing Flash Erase of length 8192 at offset 0x6000
Moving to region 2
Performing Flash Erase of length 32768 at offset 0x8000
Moving to region 3
 done

PATCH:
------
diff -urN linux-2.6.26-clean/drivers/mtd/mtdpart.c linux-2.6.26/drivers/mtd/mtdpart.c
--- linux-2.6.26-clean/drivers/mtd/mtdpart.c	2008-07-13 23:51:29.000000000 +0200
+++ linux-2.6.26/drivers/mtd/mtdpart.c	2008-08-06 10:27:33.000000000 +0200
@@ -339,6 +339,14 @@
 
 	printk (KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
 
+	printk("Nr master erase regions %d\n", master->numeraseregions);
+	for (i=0; i<master->numeraseregions;i++){
+		printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
+		       i,master->eraseregions[i].offset,
+		       master->eraseregions[i].erasesize,
+		       master->eraseregions[i].numblocks);
+	}
+
 	for (i = 0; i < nbparts; i++) {
 
 		/* allocate the partition structure */
@@ -443,6 +451,7 @@
 			printk ("mtd: partition \"%s\" extends beyond the end of device \"%s\" -- size truncated to %#x\n",
 				parts[i].name, master->name, slave->mtd.size);
 		}
+
 		if (master->numeraseregions>1) {
 			/* Deal with variable erase size stuff */
 			int i;
@@ -451,12 +460,31 @@
 			/* Find the first erase regions which is part of this partition. */
 			for (i=0; i < master->numeraseregions && slave->offset >= regions[i].offset; i++)
 				;
+			printk("first erase region %d for slave @ %d\n", i-1, slave->offset);
 
+			slave->mtd.eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) * 
+				4, GFP_KERNEL);
+			
+			int j = 0;
 			for (i--; i < master->numeraseregions && slave->offset + slave->mtd.size > regions[i].offset; i++) {
 				if (slave->mtd.erasesize < regions[i].erasesize) {
 					slave->mtd.erasesize = regions[i].erasesize;
 				}
+				slave->mtd.eraseregions[j].offset = regions[i].offset;
+				slave->mtd.eraseregions[j].erasesize = regions[i].erasesize;
+				slave->mtd.eraseregions[j].numblocks = regions[i].numblocks;
+				j++;
 			}
+			slave->mtd.numeraseregions = j;
+
+			printk("Nr slave erase regions %d\n", slave->mtd.numeraseregions);
+			for (i=0; i<slave->mtd.numeraseregions;i++){
+				printk("%d: offset=0x%x,size=0x%x,blocks=%d\n",
+				       i,slave->mtd.eraseregions[i].offset,
+				       slave->mtd.eraseregions[i].erasesize,
+				       slave->mtd.eraseregions[i].numblocks);
+			}
+
 		} else {
 			/* Single erase size */
 			slave->mtd.erasesize = master->erasesize;

------


Thanks,
Hinko
-- 
ČETRTA POT, d.o.o., Kranj
Planina 3
4000 Kranj
Slovenia, Europe
Tel. +386 (0) 4 280 66 03
E-mail: hinko.kocevar at cetrtapot.si
Http: www.cetrtapot.si






More information about the linux-mtd mailing list