[Yaffs-archive] YAFFS code repartitioning for YAFFS2 etc

Top Page
Attachments:
Message as email
+ (text/plain)
+ YAFFS_code_repartitioning.html (text/html)
Delete this message
Reply to this message
Author: Charles Manning
Date:  
To: yaffs
Subject: [Yaffs-archive] YAFFS code repartitioning for YAFFS2 etc
One of the things that is needed to align the YAFFS codebase for YAFFS2 is to
make a cleaner division between the YAFFS guts and device specific routines.
There are already some uglinesses in yaffs_guts to support hw ecc etc., so
this repartitioning should help to make the system integrator's job easier
too.

Herewith a repartitioning proposal. I'd like people to give this a read
(particularly anyone who has dabbled with the yaffs_mtd interface or
equivalent) and comment.

Thanx

-- Charles



    
    YAFFS code repartitioning
    
    
    
    
    
    
    
    


YAFFS code repartitioning proposal


Currently the YAFFS code has the
following basic structure.
Yaffs_fs.c (or similar): YAFFS file
system interface to hook up YAFFS to the OS. Eg, Under Linux this
implements the VFS interface.
Yaffs_guts.c: The file system "guts".
This is the (portable) code that implements the YAFFS file sytem
algorithms.

Yaffs_mtdif.c (or equivalent): Routines
to access the NAND flash.
Yaffc_ecc.c: ECC algorithms.


Currently, yaffs_guts "knows
about" ECC, spare (out of band) regions, bad block algorithms
and such low-level NAND actions. This means that yaffs_guts gets a
bit messy when dealing devices where these algorithms need to be
changed. For instance:

    Devices with different bad block
    marking strategies.

    Devices with hardware ECC.
    Devices where the spare data
    layout is different.

    Dealing with different chunk
    sizes, particularly the different ECC sizes for YAFFS2.

    Dealing with write verification.



This discussion proposes a
re-partitioning of the interface between the yaffs_guts. And
yaffs_mtd.c to clean up these issues, thus making it easier (and
cleaner) to deal with these differences.


The current interface comprises 4
functions:


int
WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND, const __u8 *data,
yaffs_Spare *spare);
int
ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data,
yaffs_Spare *spare);
int
EraseBlockInNAND(yaffs_Device *dev,int blockInNAND);
int
InitialiseNAND(yaffs_Device *dev);


As listed above, of the 4 major
partitioning issues, three are related to dealing with the spare area
(and it's ECC side-kick). The spare area is used to hold ECC info,
bad block markers, and tags. Of these, the ECC and bad block markers
are device dependent. The mixing of device dependent and "logical"
entities (ie the tags) through the one interface makes the interface
rather messy. What I propose is that this interface be re-structured
to deal with the logical entities (tags) only.


Also, I propose that the bad block
handling algorithm be partitioned off so that it may be easily
changed to support different devices.


Ie. the new proposed interface is:
int
WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND, const __u8 *data,
yaffs_Spare *spare);
int
ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data,
yaffs_Spare *spare);
int
EraseBlockInNAND(yaffs_Device *dev,int blockInNAND);
int
InitialiseNAND(yaffs_Device *dev);
int
CheckBlockBad(yaffs_Device *dev,int blockInNAND);
int
MarkBlockBad(yaffs_Device *dev,int blockInNAND);


Now, the nand interface layer (eg.
yaffs_mtdif.c) becomes responsible for handling all ECC, spare to
tags mapping and the bad block handling.


For the most part (for existing code
and devices), this just means shifting code around rather than
writing new code. Once this is done, the code changes to support
various devices (as well as future changes to mtd etc) can be better
maintained without impacting on yaffs_guts.c. This should make it far
easier for both me (the yaffs_guts maintainer) since I won't need to
worry about conditional code for various devices and the messiness
that causes. It also makes life easier easier for system integrators
since they need not go deep into yaffs_guts to make changes.


More details on the functions


int WriteChunkToNAND(yaffs_Device
*dev,int chunkInNAND, const __u8 *data, const yaffs_Tags *tags);


When called, data might be NULL, but
tags should never be.
Writing can fail due to:
Write error
Verification failure
int ReadChunkFromNAND(yaffs_Device
*dev,int chunkInNAND, __u8 *data, yaffs_Tags *tags);


Data or tags might be NULL in which
case these are not written/read.
The function performs all ECC etc, but
returns the following results.Data OK.
ECC corrected

ECC not corrected
Tags OK
Tags corrected
Tags not corrected


int EraseBlockInNAND(yaffs_Device
*dev,int blockInNAND);
Erase can return an error if the
erasure failed.


int CheckBlockBad(yaffs_Device
*dev,int blockInNAND);
Returns a Boolean result as to whether
the block is bad or not.


int MarkBlockBad(yaffs_Device
*dev,int blockInNAND);
Marks a block as a bad block.


int InitialiseNAND(yaffs_Device *dev);
A call YAFFS makes to the NAND layer
during its initialisation (before it uses the other NAND functions).
This call can modify some of yaffs_Device structure members.