[Yaffs-archive] Re:[YAFFS] Latest CVS ==> Interaction with mtd

Thomas Gleixner tglx@linutronix.de
Sat, 23 Nov 2002 10:00:44 +0100


Charles, 

On Friday 22 November 2002 22:04, Charles Manning wrote:
> One thing I have realised (and this might be a Good Thing for mtd too) is
> that some options are best not compiled in, but run-time selected. With
> YAFFS2, I intend to allow both YAFFS1 and YAFFS2 in a single system with
> YAFFS1 or YAFFS2 being runtime selected (as well as other attributes such
> as internal caching, chunk size etc which are now compile time selected).
> The reason for this is that a smaller partition (eg boot partition) might
> be more suited to YAFFS1 and a larger partition to YAFFS2.
>
> In mtd, for example, is it perfectly reasonable to think that an mtd in a
> single system might need to run JFFS, YAFFS and some other fs
> (??FAT/SmartMedia??) all with different feature requirements (eg. ECC,
> placement of ECC data). Would it not be better to control these on a
> per-parftition basis?

In the current code the ECC-placement and ECC-calculation selection is runtime 
selectable. You can also supply oob-data from your filesystem driver and 
readback the oob-data together with the data from the main area.
This implies, that you can use different filesystems on the partitions of a 
chip. 

static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
			   size_t * retlen, const u_char * buf, u_char * eccbuf, int oobsel)

If you supply an eccbuf, the driver writes those data into the oobarea. The 
buffer length should be equal to oobsize * number of blocks to write. If you 
do not supply a buffer there (NULL), then no fs-specific data is written into 
the spare area and the nand driver builds a buffer, which is filled with 
0xff.

The oobsel argument selects the filesystem dependent placement of ECC data. If 
you select NAND_NONE_OOB, no ECC calculation is done and no ECC data is 
placed in the spare area. This applies to the current YAFFS code.
If you select one of the defined placements (NAND_JFFS2_OOB, NAND_YAFFS_OOB)
the ECC calculation you selected for this chip is done and the ECC data is 
placed on the appropriate byte positions either in the sparearea buffer, 
which was supplied by the fs driver, or in the buffer, which was filled with 
0xff by the nand driver.

The oobsel argument is either NAND_OOB_NONE; if you supply ECC in your spare 
buffer alreday, or NAND_OOB_YAFFS, if you want to utilize the nand-driver ECC 
functionality as selected for your chip. 

The nand_read_ecc function is analogous.

IMHO it makes no sense to select different ECC-modes for different partitions 
on the same chip, except the NONE variant where the fs-driver supplies all 
oob data including ECC. 

__________________________________________________________________

The current yaffs-mtd interface can be run on top of the current mtd-cvs 
_WITHOUT_ any modifications of nand.c, as it defaults to NAND_NONE_OOB for 
mtd->write and mtd->read. So it skips all ECC related calculations. I run it 
together with a jffs2 partition on the same chip. The jffs2 partition uses  
software ECC and selects NAND_JFFS2_OOB for read_ecc and write_ecc.
I copied and moved files around the two partitions without any problem. 
Due to the fact, that nand.c uses the fs-buffer for page aligned read / write 
and some other critizied speed problems are resolved, there should be no or 
only a minimal speed penalty compared to a yaffs optimized driver.

I made following changes to yaffs_mtdif.c and improved the performance, due to 
the fact, that data and oob area are read and written in one go, without 
(de)selecting the chip again. 

RCS file: /home/aleph1/cvs/yaffs/yaffs_mtdif.c,v
retrieving revision 1.2
diff -u -r1.2 yaffs_mtdif.c
--- yaffs_mtdif.c	27 Aug 2002 03:31:38 -0000	1.2
+++ yaffs_mtdif.c	23 Nov 2002 07:54:21 -0000
@@ -32,11 +32,12 @@
 	
 	__u8 *spareAsBytes = (__u8 *)spare;
 	
-	if(data)
+	if(data && !spare)
 		mtd->write(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
-	if(spare)
+	if(!data && spare)
 		mtd->write_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
-
+	if(data && spare)
+		
mtd->write_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_OOB_NONE);
 	return YAFFS_OK;
 }
 
@@ -50,10 +51,12 @@
 	
 	__u8 *spareAsBytes = (__u8 *)spare;
 	
-	if(data)
+	if(data && !spare)
 		mtd->read(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data);
-	if(spare)
+	if(!data && spare)
 		mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes);
+	if(data && spare)
+		
mtd->read_ecc(mtd,addr,YAFFS_BYTES_PER_CHUNK,&dummy,data,spareAsBytes,NAND_OOB_NONE);
 
 	return YAFFS_OK;
 }

I think it would be easy to modify YAFFS code to use the ECC functionality of 
nand.c, which includes software ECC and various hardware ECC modes. The 
hardware ECC functions have to be provided by the hardware dependend driver.
To use this, you only have to supply your sparearea buffer as now and select 
NAND_YAFFS_OOB. The ECC positions in the oobarea should be defined correctly 
for Yaffs already. 
Further improvement could be done by using the multiblock read/write, which is 
possible with read/write_ecc.

One further suggestion: I tried to mount yaffs on an already JFFS2 formatted 
partition. Yaffs mounts, but tells the that the fs is 100% full. JFFS2 checks 
the partition, if it's empty, JFFS2 formatted or formatted for a different 
filesystem. In the later case it refuses to mount. This would be a reasonable 
feature for YAFFS too.

-- 
Thomas
____________________________________________________
linutronix - competence in embedded & realtime linux
http://www.linutronix.de
mail: tglx@linutronix.de


---------------------------------------------------------------------------------------
This mailing list is hosted by Toby Churchill open software (www.toby-churchill.org).
If mailing list membership is no longer wanted you can remove yourself from the list by 
sending an email to yaffs-request@toby-churchill.org with the text "unsubscribe" 
(without the quotes) as the subject.