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.