From nick@cecomputing.co.uk Fri Oct 1 10:56:10 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Fri, 1 Oct 2004 10:56:10 +0100 Subject: [Yaffs] yaffs on 2.4.26 In-Reply-To: Message-ID: This is a multi-part message in MIME format. ------=_NextPart_000_0102_01C4A7A5.42DD2C50 Content-Type: text/plain; charset="gb2312" Content-Transfer-Encoding: 7bit It might be that the mtd snapshot is upsetting the yaffs interface somehow. I have never seen this kind of behaviour and I have done a lot of ports. If you use the 2.4.25 in husaberg.toby-churchill.com/balloon you should be ok. Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Dick Chen Sent: 29 September 2004 10:37 To: yaffs@stoneboat.aleph1.co.uk Subject: [Yaffs] yaffs on 2.4.26 Hi: I am trying to get yaffs working on my board. The Configure is: CPU: Samsung S3C44B0X ( ARM ) OS: uClinux with kernel 2.4.26 MTD: mtd-snapshot-20040912 yaffs: downloaded from aleph1 CVS 20040928 NAND Chip: Samsung K9K1G08U0M ( 128 MByte ) The problem is: I can not copy large file to the yaffs( e.g about 320k ) when I config yaffs as CONFIG_YAFFS_USE_GENERIC_RW, and smaller files is ok. However, if i don't use the CONFIG_YAFFS_USE_GENERIC_RW option, lager file is ok, but if i launch other program when operating yaffs( e.g. cp test.wav /mnt/yaffs & ls ) the console shows "BINFMT_FLAT:reloc outside program 0xce20ce2(0-0x20294/0x19500), killing ls!" can anyone help me? Regards Dich Chen ------=_NextPart_000_0102_01C4A7A5.42DD2C50 Content-Type: text/html; charset="gb2312" Content-Transfer-Encoding: quoted-printable
It=20 might be that the mtd snapshot is upsetting the yaffs interface=20 somehow.
 
I have=20 never seen this kind of behaviour and I have done a lot of=20 ports.
 
If you=20 use the 2.4.25 in husaberg.toby-churchill.com/balloon you should be=20 ok.
 
Nick
-----Original Message-----
From:=20 yaffs-admin@stoneboat.aleph1.co.uk=20 [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Dick=20 Chen
Sent: 29 September 2004 10:37
To:=20 yaffs@stoneboat.aleph1.co.uk
Subject: [Yaffs] yaffs on=20 2.4.26

Hi:
    I am trying to get yaffs = working on my=20 board.
 
    The Configure is:
    CPU: Samsung S3C44B0X ( ARM=20 )
    OS: uClinux with kernel=20 2.4.26
    MTD: = mtd-snapshot-20040912
    yaffs: downloaded from aleph1 = CVS=20 20040928
    NAND Chip: Samsung K9K1G08U0M ( = 128 MByte=20 )
 
    The problem is: I can not copy = large file=20 to the yaffs( e.g about 320k ) when I config = yaffs as=20 CONFIG_YAFFS_USE_GENERIC_RW, and smaller files is ok. However, if = i don't=20 use the CONFIG_YAFFS_USE_GENERIC_RW option, lager file is ok, = but if=20 i launch other program when operating yaffs( e.g.
cp test.wav /mnt/yaffs &
ls
) the console shows "BINFMT_FLAT:reloc outside = program=20 0xce20ce2(0-0x20294/0x19500), killing ls!"
 
    can anyone help = me?
 
Regards
Dich Chen
 
 
------=_NextPart_000_0102_01C4A7A5.42DD2C50-- From manningc2@actrix.gen.nz Sat Oct 2 02:36:34 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Sat, 2 Oct 2004 13:36:34 +1200 Subject: [Yaffs] step0 In-Reply-To: References: Message-ID: <20041002013340.019DF195DE@desire.actrix.co.nz> On Wednesday 29 September 2004 03:16, lp4u@inwind.it wrote: > Hi, > > how to compile a kernel 2.6.x (p.e. 2.6.9) with yaffs. > I haven't the file Config.in in [linux]/fs. > > Thanks, > Lorenzo YAFFS, as it stands in CVS, is really a seperate module build. To build as part of Linux, I suggest you read: http://www.aleph1.co.uk/yaffs/yaffs-rootfs-howto.html -- Charles From lorenzo.parisi@st.com Mon Oct 4 11:12:19 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Mon, 4 Oct 2004 12:12:19 +0200 Subject: [Yaffs] YAFFS on kernel 2.6.x Message-ID: <53d7e0cc.89f0f174.8223900@mail1.agr.st.com> Hi, howto include yaffs on kernel 2.6.x? Thanks. From lorenzo.parisi@st.com Mon Oct 4 11:31:07 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Mon, 4 Oct 2004 12:31:07 +0200 Subject: [Yaffs] Errors Message-ID: <97176254.89f2aa2c.81aa100@mail1.agr.st.com> Hi, whi compiling yaffs_guts.c there are errors, with command: #ifdefined KERNEL... there are more one error. Thanks. From nick@cecomputing.co.uk Mon Oct 4 11:38:56 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Mon, 4 Oct 2004 11:38:56 +0100 Subject: [Yaffs] YAFFS on kernel 2.6.x In-Reply-To: <53d7e0cc.89f0f174.8223900@mail1.agr.st.com> Message-ID: See http://husaberg.toby-churchill/balloon Nick > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Lorenzo PARISI > Sent: 04 October 2004 11:12 > To: YAFFS mailing list > Subject: [Yaffs] YAFFS on kernel 2.6.x >=20 >=20 > Hi, >=20 > howto include yaffs on kernel 2.6.x? >=20 > Thanks. >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From nick@cecomputing.co.uk Mon Oct 4 13:48:12 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Mon, 4 Oct 2004 13:48:12 +0100 Subject: [Yaffs] Errors In-Reply-To: <97176254.89f2aa2c.81aa100@mail1.agr.st.com> Message-ID: >=20 > Hi, >=20 > whi compiling yaffs_guts.c there are errors, with command: >=20 > #ifdefined KERNEL... >=20 >=20 > there are more one error. >=20 Thats not enough detail to be helpful. Can you give line numbers etc > Thanks. >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From jdub@us.ibm.com Mon Oct 4 13:40:50 2004 From: jdub@us.ibm.com (Josh Boyer) Date: Mon, 04 Oct 2004 07:40:50 -0500 Subject: [Yaffs] Re: Errors In-Reply-To: <97176254.89f2aa2c.81aa100@mail1.agr.st.com> References: <97176254.89f2aa2c.81aa100@mail1.agr.st.com> Message-ID: <1096893650.22034.11.camel@weaponx.rchland.ibm.com> On Mon, 2004-10-04 at 05:31, Lorenzo PARISI wrote: > Hi, > > whi compiling yaffs_guts.c there are errors, with command: > > #ifdefined KERNEL... > > > there are more one error. Maybe your questions could be answered on the yaffs mailing list. linux-mtd doesn't do the yaffs development. http://www.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs josh From jdub@us.ibm.com Mon Oct 4 13:56:59 2004 From: jdub@us.ibm.com (Josh Boyer) Date: Mon, 04 Oct 2004 07:56:59 -0500 Subject: [Yaffs] Re: Errors In-Reply-To: <1096893650.22034.11.camel@weaponx.rchland.ibm.com> References: <97176254.89f2aa2c.81aa100@mail1.agr.st.com> <1096893650.22034.11.camel@weaponx.rchland.ibm.com> Message-ID: <1096894619.22034.17.camel@weaponx.rchland.ibm.com> On Mon, 2004-10-04 at 07:40, Josh Boyer wrote: > On Mon, 2004-10-04 at 05:31, Lorenzo PARISI wrote: > > Hi, > > > > whi compiling yaffs_guts.c there are errors, with command: > > > > #ifdefined KERNEL... > > > > > > there are more one error. > > Maybe your questions could be answered on the yaffs mailing list. > linux-mtd doesn't do the yaffs development. Oops, you did ask that mailing list. Sorry, I should have looked at the CC line first. josh From bbeveridge@bluewatersys.com Mon Oct 4 22:51:12 2004 From: bbeveridge@bluewatersys.com (Brad Beveridge) Date: Tue, 05 Oct 2004 10:51:12 +1300 Subject: [Yaffs] Trivial yportenv.h patch Message-ID: <4161C5D0.6070906@bluewatersys.com> To get the LINUX_VERSION_CODE macro (when building yaffs as a module) I needed to apply the following trivial patch. I think yportenv is the correct place to put it. Cheers Brad Index: yportenv.h =================================================================== RCS file: /home/aleph1/cvs/yaffs/yportenv.h,v retrieving revision 1.11 diff -r1.11 yportenv.h 38a39 > #include "linux/version.h" From manningc2@actrix.gen.nz Tue Oct 5 01:29:21 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Tue, 5 Oct 2004 13:29:21 +1300 Subject: [Yaffs] Trivial yportenv.h patch In-Reply-To: <4161C5D0.6070906@bluewatersys.com> References: <4161C5D0.6070906@bluewatersys.com> Message-ID: <20041004232624.557CE5420@blood.actrix.co.nz> Thanx Brad I have put this into CVS. Maybe this is required by recent kernels. My current build (based on olde= r=20 stuff) did not. -- CHarles On Tuesday 05 October 2004 10:51, Brad Beveridge wrote: > To get the LINUX_VERSION_CODE macro (when building yaffs as a module) I > needed to apply the following trivial patch. I think yportenv is the > correct place to put it. > > Cheers > Brad > > Index: yportenv.h > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > RCS file: /home/aleph1/cvs/yaffs/yportenv.h,v > retrieving revision 1.11 > diff -r1.11 yportenv.h > 38a39 > > > #include "linux/version.h" > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From PesceG@gea-automotive.com Tue Oct 5 09:55:54 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Tue, 5 Oct 2004 10:55:54 +0200 Subject: [Yaffs] yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AAB9.1F122110 Content-Type: text/plain; charset="iso-8859-1" Hi , I am using an ARM machine with 2.4.18 kernel I want to use yaffs , the file system is mounted , but when I try to do any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1 Any help will be appreciated -------------------------------------------------------------- GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. Via Renata Bianchi 40 - 16152 GENOVA (ITALY) Tel.: +39 010 65966.1 Fax: +39 010 65966.311 http://www.gea-automotive.com; E-mail: mailbox@gea-automotive.com Ing. Gianfranco Pesce APPLICATION DEVELOPMENT DEPT. Project Engineer Tel. +39.010.659.66.507 E-mail: pesceg@gea-automotive.com -------------------------------------------------------------- ------_=_NextPart_001_01C4AAB9.1F122110 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable yaffs - file system on ARM


Hi ,

I am using an ARM machine with 2.4.18 = kernel
I want to use yaffs , the file system = is mounted , but when I try to do any operation , as mkdir or cp , I = get the message

"cannot allocate memory" and = the command df says 100% used for /dev/mtdblock/1

Any help will be appreciated


---------------------------------------------------------= -----
GENERALE = ELETTRONICA e AUTOMAZIONE S.r.l.
Via Renata Bianchi 40 - 16152 GENOVA = (ITALY)
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION = DEVELOPMENT DEPT.
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
---------------------------------------------------------= -----


------_=_NextPart_001_01C4AAB9.1F122110-- From PesceG@gea-automotive.com Tue Oct 5 10:00:34 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Tue, 5 Oct 2004 11:00:34 +0200 Subject: [Yaffs] I: yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AAB9.C66CD770 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Sorry , more informations I am using a NAND flash Samsung K9D1208V0M > -----Messaggio originale----- > Da: Pesce Gianfranco =20 > Inviato: marted=EC 5 ottobre 2004 10.56 > A: 'yaffs@stoneboat.aleph1.co.uk' > Oggetto: yaffs - file system on ARM >=20 >=20 >=20 >=20 > Hi , >=20 > I am using an ARM machine with 2.4.18 kernel > I want to use yaffs , the file system is mounted , but when I try to = do > any operation , as mkdir or cp , I get the message > "cannot allocate memory" and the command df says 100% used for > /dev/mtdblock/1 >=20 > Any help will be appreciated >=20 >=20 > --------------------------------------------------------------=20 > GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. > Via Renata Bianchi 40 - 16152 GENOVA (ITALY) > Tel.: +39 010 65966.1 > Fax: +39 010 65966.311 > http://www.gea-automotive.com; > E-mail: mailbox@gea-automotive.com >=20 >=20 > Ing. Gianfranco Pesce > APPLICATION DEVELOPMENT DEPT. > Project Engineer > Tel. +39.010.659.66.507 > E-mail: pesceg@gea-automotive.com > -------------------------------------------------------------- >=20 >=20 ------_=_NextPart_001_01C4AAB9.C66CD770 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I: yaffs - file system on ARM

        Sorry , more informations

        I am using a NAND flash Samsung = K9D1208V0M

 -----Messaggio originale-----
Da:     = Pesce Gianfranco 
Inviato:        marted=EC 5 ottobre 2004 = 10.56
A:      'yaffs@stoneboat.aleph1.co.uk'
Oggetto:        yaffs - file system on ARM




Hi ,

I am using an ARM machine with 2.4.18 = kernel
I want to use yaffs , the file system = is mounted , but when I try to do any operation , as mkdir or cp , I = get the message

"cannot allocate memory" and = the command df says 100% used for /dev/mtdblock/1

Any help will be appreciated


---------------------------------------------------------= -----
GENERALE = ELETTRONICA e AUTOMAZIONE S.r.l.
Via Renata Bianchi 40 - 16152 GENOVA = (ITALY)
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION = DEVELOPMENT DEPT.
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
---------------------------------------------------------= -----


------_=_NextPart_001_01C4AAB9.C66CD770-- From nick@cecomputing.co.uk Tue Oct 5 10:31:11 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Tue, 5 Oct 2004 10:31:11 +0100 Subject: [Yaffs] I: yaffs - file system on ARM In-Reply-To: Message-ID: This is a multi-part message in MIME format. ------=_NextPart_000_0002_01C4AAC6.70648960 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit I: yaffs - file system on ARMPesce Could you use plain text? It makes replying much easier. what does /proc/yaffs say? If its all used it may be that it isn't all erased ot being accessed correctly. How big is the mtd partition in the boot messages? Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce Gianfranco Sent: 05 October 2004 10:01 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] I: yaffs - file system on ARM Sorry , more informations I am using a NAND flash Samsung K9D1208V0M -----Messaggio originale----- Da: Pesce Gianfranco Inviato: marted́ 5 ottobre 2004 10.56 A: 'yaffs@stoneboat.aleph1.co.uk' Oggetto: yaffs - file system on ARM Hi , I am using an ARM machine with 2.4.18 kernel I want to use yaffs , the file system is mounted , but when I try to do any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1 Any help will be appreciated -------------------------------------------------------------- GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. Via Renata Bianchi 40 - 16152 GENOVA (ITALY) Tel.: +39 010 65966.1 Fax: +39 010 65966.311 http://www.gea-automotive.com; E-mail: mailbox@gea-automotive.com Ing. Gianfranco Pesce APPLICATION DEVELOPMENT DEPT. Project Engineer Tel. +39.010.659.66.507 E-mail: pesceg@gea-automotive.com -------------------------------------------------------------- --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.772 / Virus Database: 519 - Release Date: 01/10/2004 ------=_NextPart_000_0002_01C4AAC6.70648960 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I: yaffs - file system on ARM
Pesce
 
Could=20 you use plain text? It makes replying much easier.
 
what=20 does /proc/yaffs say?
If its=20 all used it may be that it isn't all erased ot being accessed=20 correctly.
How=20 big is the mtd partition in the boot messages?
 
Nick
-----Original Message-----
From:=20 yaffs-admin@stoneboat.aleph1.co.uk=20 [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce=20 Gianfranco
Sent: 05 October 2004 10:01
To:=20 'yaffs@stoneboat.aleph1.co.uk'
Subject: [Yaffs] I: yaffs - = file=20 system on ARM


        Sorry , more informations

        I am using a NAND flash Samsung K9D1208V0M

 -----Messaggio=20 originale-----
Da:=20     Pesce = Gianfranco =20
Inviato:        = marted=EC 5 ottobre 2004 10.56
=
A:     
= 'yaffs@stoneboat.aleph1.co.uk' =
Oggetto:        = yaffs - file system on ARM =




Hi ,

I am using an ARM machine with 2.4.18 = kernel=20
I want to use yaffs , the file system = is mounted ,=20 but when I try to do any operation , as mkdir or cp , I get the=20 message

"cannot allocate memory" and the = command df says=20 100% used for /dev/mtdblock/1

Any help will be appreciated =


--------------------------------------------------------------
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. =
Via Renata Bianchi 40 - 16152 GENOVA = (ITALY)=20
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: = mailbox@gea-automotive.com =


Ing. Gianfranco Pesce =
APPLICATION DEVELOPMENT = DEPT.=20
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------=20


------=_NextPart_000_0002_01C4AAC6.70648960-- From PesceG@gea-automotive.com Tue Oct 5 10:40:25 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Tue, 5 Oct 2004 11:40:25 +0200 Subject: I: [Yaffs] I: yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AABF.579E63D0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable =20 -----Messaggio originale----- Da: Pesce Gianfranco=20 Inviato: marted=EC 5 ottobre 2004 11.39 A: 'Nick Bane' Cc: 'yaffs@stoneboat.aleph1.co.uk' Oggetto: R: [Yaffs] I: yaffs - file system on ARM to Nick =20 =20 >Could you use plain text? It makes replying much easier. =20 Sorry ,what does means plain text ? =20 >what does /proc/yaffs say?=20 =20 this is the output of my /proc/yaffs =20 # cat /proc/yaffs YAFFS built:Oct 5 2004 10:04:10 $Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $ $Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $ =20 Device yaffs startBlock......... 1 endBlock........... 2174 chunkGroupBits..... 1 chunkGroupSize..... 2 nErasedBlocks...... 6 nTnodesCreated..... 0 nFreeTnodes........ 0 nObjectsCreated.... 100 nFreeObjects....... 97 nFreeChunks........ 192 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 6 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 1 # =20 >How big is the mtd partition in the boot messages? =20 # cat /proc/mtd dev: size erasesize name mtd0: 04000000 00004000 "BON" mtd1: 021fc000 00004000 "mtd" =20 =20 Thanks =20 =20 -----Messaggio originale----- Da: Nick Bane [mailto:nick@cecomputing.co.uk] Inviato: marted=EC 5 ottobre 2004 11.31 A: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk Oggetto: RE: [Yaffs] I: yaffs - file system on ARM Pesce =20 Could you use plain text? It makes replying much easier. =20 what does /proc/yaffs say?=20 If its all used it may be that it isn't all erased ot being accessed correctly. How big is the mtd partition in the boot messages? =20 Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce = Gianfranco Sent: 05 October 2004 10:01 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] I: yaffs - file system on ARM Sorry , more informations=20 I am using a NAND flash Samsung K9D1208V0M=20 -----Messaggio originale-----=20 Da: Pesce Gianfranco =20 Inviato: marted=EC 5 ottobre 2004 10.56=20 A: 'yaffs@stoneboat.aleph1.co.uk'=20 Oggetto: yaffs - file system on ARM=20 Hi ,=20 I am using an ARM machine with 2.4.18 kernel=20 I want to use yaffs , the file system is mounted , but when I try to do = any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1=20 Any help will be appreciated=20 --------------------------------------------------------------=20 GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.=20 Via Renata Bianchi 40 - 16152 GENOVA (ITALY)=20 Tel.: +39 010 65966.1=20 Fax: +39 010 65966.311=20 http://www.gea-automotive.com ;=20 E-mail: mailbox@gea-automotive.com=20 Ing. Gianfranco Pesce=20 APPLICATION DEVELOPMENT DEPT.=20 Project Engineer=20 Tel. +39.010.659.66.507=20 E-mail: pesceg@gea-automotive.com=20 --------------------------------------------------------------=20 ------_=_NextPart_001_01C4AABF.579E63D0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I: yaffs - file system on ARM
 
-----Messaggio originale-----
Da: Pesce Gianfranco=20
Inviato: marted=EC 5 ottobre 2004 11.39
A: 'Nick=20 Bane'
Cc: 'yaffs@stoneboat.aleph1.co.uk'
Oggetto: = R: [Yaffs]=20 I: yaffs - file system on ARM

    to Nick =20
 
>Could you use plain text? It = makes replying=20 much easier.
 
Sorry ,what does means plain text = ?
 
>what does /proc/yaffs say?=20
 
this is the output of my /proc/yaffs
 
# = cat=20 /proc/yaffs
YAFFS built:Oct  5 2004 10:04:10
$Id: = yaffs_fs.c,v 1.32=20 2003/10/29 20:42:34 charles Exp $
$Id: yaffs_guts.c,v 1.34 = 2004/06/08=20 08:47:55 charles Exp $
 
Device=20 yaffs
startBlock......... 1
endBlock...........=20 2174
chunkGroupBits..... 1
chunkGroupSize..... = 2
nErasedBlocks......=20 6
nTnodesCreated..... 0
nFreeTnodes........ = 0
nObjectsCreated....=20 100
nFreeObjects....... 97
nFreeChunks........ = 192
nPageWrites........=20 0
nPageReads......... 0
nBlockErasures..... = 0
nGCCopies..........=20 0
garbageCollections. 0
passiveGCs......... = 0
nRetriedWrites.....=20 0
nRetireBlocks...... 0
eccFixed........... = 0
eccUnfixed.........=20 0
tagsEccFixed....... 0
tagsEccUnfixed..... = 6
cacheHits..........=20 0
nDeletedFiles...... 0
nUnlinkedFiles..... = 0
nBackgroudDeletions=20 0
useNANDECC......... 1
#
 
>How big is the mtd partition in = the boot=20 messages?
 
# cat=20 /proc/mtd
dev:    size   erasesize =20 name
mtd0: 04000000 00004000 "BON"
mtd1: 021fc000 00004000=20 "mtd"
 
 
    Thanks
 
 
-----Messaggio originale-----
Da: Nick Bane=20 [mailto:nick@cecomputing.co.uk]
Inviato: marted=EC 5 = ottobre 2004=20 11.31
A: Pesce Gianfranco;=20 yaffs@stoneboat.aleph1.co.uk
Oggetto: RE: [Yaffs] I: yaffs = - file=20 system on ARM

Pesce
 
Could you use=20 plain text? It makes replying much easier.
 
what does=20 /proc/yaffs say?
If = its all used it=20 may be that it isn't all erased ot being accessed=20 correctly.
How = big is the mtd=20 partition in the boot messages?
 
Nick
-----Original Message-----
From:=20 yaffs-admin@stoneboat.aleph1.co.uk=20 [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of = Pesce=20 Gianfranco
Sent: 05 October 2004 10:01
To:=20 'yaffs@stoneboat.aleph1.co.uk'
Subject: [Yaffs] I: yaffs = - file=20 system on ARM


        Sorry=20 , more informations

        I am=20 using a NAND flash Samsung K9D1208V0M

 -----Messaggio=20 originale-----
Da:=20     Pesce=20 Gianfranco 
Inviato:        = marted=EC 5 ottobre 2004 10.56 =
A:      = 'yaffs@stoneboat.aleph1.co.uk' =
Oggetto:        = yaffs - file system on ARM =




Hi ,

I am using an ARM machine with = 2.4.18=20 kernel
I want to use yaffs , = the file=20 system is mounted , but when I try to do any operation , as mkdir = or cp , I=20 get the message

"cannot allocate memory" and the = command df says=20 100% used for /dev/mtdblock/1

Any help will be appreciated =


--------------------------------------------------------------<= /FONT>
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. =
Via Renata Bianchi 40 - 16152 GENOVA = (ITALY)=20
Tel.: +39 010 65966.1 =
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: = mailbox@gea-automotive.com=20


Ing. Gianfranco Pesce =
APPLICATION DEVELOPMENT = DEPT.=20
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------<= /FONT>=20


------_=_NextPart_001_01C4AABF.579E63D0-- From PesceG@gea-automotive.com Tue Oct 5 10:54:07 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Tue, 5 Oct 2004 11:54:07 +0200 Subject: R: [Yaffs] I: yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AAC1.419FAC90 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable =20 to Nick =20 =20 >Could you use plain text? It makes replying much easier. =20 Sorry ,what does means plain text ? =20 >what does /proc/yaffs say?=20 =20 this is the output of my /proc/yaffs =20 # cat /proc/yaffs YAFFS built:Oct 5 2004 10:04:10 $Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $ $Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $ =20 Device yaffs startBlock......... 1 endBlock........... 2174 chunkGroupBits..... 1 chunkGroupSize..... 2 nErasedBlocks...... 6 nTnodesCreated..... 0 nFreeTnodes........ 0 nObjectsCreated.... 100 nFreeObjects....... 97 nFreeChunks........ 192 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 6 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 1 # =20 >How big is the mtd partition in the boot messages? =20 # cat /proc/mtd dev: size erasesize name mtd0: 04000000 00004000 "BON" mtd1: 021fc000 00004000 "mtd" =20 =20 Thanks =20 =20 =20 -----Messaggio originale----- Da: Nick Bane [mailto:nick@cecomputing.co.uk] Inviato: marted=EC 5 ottobre 2004 11.31 A: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk Oggetto: RE: [Yaffs] I: yaffs - file system on ARM Pesce =20 Could you use plain text? It makes replying much easier. =20 what does /proc/yaffs say?=20 If its all used it may be that it isn't all erased ot being accessed correctly. How big is the mtd partition in the boot messages? =20 Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce = Gianfranco Sent: 05 October 2004 10:01 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] I: yaffs - file system on ARM Sorry , more informations=20 I am using a NAND flash Samsung K9D1208V0M=20 -----Messaggio originale-----=20 Da: Pesce Gianfranco =20 Inviato: marted=EC 5 ottobre 2004 10.56=20 A: 'yaffs@stoneboat.aleph1.co.uk'=20 Oggetto: yaffs - file system on ARM=20 Hi ,=20 I am using an ARM machine with 2.4.18 kernel=20 I want to use yaffs , the file system is mounted , but when I try to do = any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1=20 Any help will be appreciated=20 --------------------------------------------------------------=20 GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.=20 Via Renata Bianchi 40 - 16152 GENOVA (ITALY)=20 Tel.: +39 010 65966.1=20 Fax: +39 010 65966.311=20 http://www.gea-automotive.com ;=20 E-mail: mailbox@gea-automotive.com=20 Ing. Gianfranco Pesce=20 APPLICATION DEVELOPMENT DEPT.=20 Project Engineer=20 Tel. +39.010.659.66.507=20 E-mail: pesceg@gea-automotive.com=20 --------------------------------------------------------------=20 ------_=_NextPart_001_01C4AAC1.419FAC90 Content-Type: text/html; charset="iso-8859-1" I: yaffs - file system on ARM  
    to Nick 
 
>Could you use plain text? It makes replying much easier.
 
Sorry ,what does means plain text ?
 
>what does /proc/yaffs say?
 
this is the output of my /proc/yaffs
 
# cat /proc/yaffs
YAFFS built:Oct  5 2004 10:04:10
$Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $
$Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $
 
Device yaffs
startBlock......... 1
endBlock........... 2174
chunkGroupBits..... 1
chunkGroupSize..... 2
nErasedBlocks...... 6
nTnodesCreated..... 0
nFreeTnodes........ 0
nObjectsCreated.... 100
nFreeObjects....... 97
nFreeChunks........ 192
nPageWrites........ 0
nPageReads......... 0
nBlockErasures..... 0
nGCCopies.......... 0
garbageCollections. 0
passiveGCs......... 0
nRetriedWrites..... 0
nRetireBlocks...... 0
eccFixed........... 0
eccUnfixed......... 0
tagsEccFixed....... 0
tagsEccUnfixed..... 6
cacheHits.......... 0
nDeletedFiles...... 0
nUnlinkedFiles..... 0
nBackgroudDeletions 0
useNANDECC......... 1
#
 
>How big is the mtd partition in the boot messages?
 
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 04000000 00004000 "BON"
mtd1: 021fc000 00004000 "mtd"
 
 
    Thanks
 
 
 
-----Messaggio originale-----
Da: Nick Bane [mailto:nick@cecomputing.co.uk]
Inviato: marted́ 5 ottobre 2004 11.31
A: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk
Oggetto: RE: [Yaffs] I: yaffs - file system on ARM

Pesce
 
Could you use plain text? It makes replying much easier.
 
what does /proc/yaffs say?
If its all used it may be that it isn't all erased ot being accessed correctly.
How big is the mtd partition in the boot messages?
 
Nick
-----Original Message-----
From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce Gianfranco
Sent: 05 October 2004 10:01
To: 'yaffs@stoneboat.aleph1.co.uk'
Subject: [Yaffs] I: yaffs - file system on ARM


        Sorry , more informations

        I am using a NAND flash Samsung K9D1208V0M

 -----Messaggio originale-----
Da:     Pesce Gianfranco 
Inviato:        marted́ 5 ottobre 2004 10.56
A:      'yaffs@stoneboat.aleph1.co.uk'
Oggetto:        yaffs - file system on ARM




Hi ,

I am using an ARM machine with 2.4.18 kernel
I want to use yaffs , the file system is mounted , but when I try to do any operation , as mkdir or cp , I get the message

"cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1

Any help will be appreciated


--------------------------------------------------------------
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.
Via Renata Bianchi 40 - 16152 GENOVA (ITALY)
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION DEVELOPMENT DEPT.
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------


------_=_NextPart_001_01C4AAC1.419FAC90-- From wookey@aleph1.co.uk Tue Oct 5 11:07:21 2004 From: wookey@aleph1.co.uk (Wookey) Date: Tue, 5 Oct 2004 11:07:21 +0100 Subject: I: [Yaffs] I: yaffs - file system on ARM In-Reply-To: References: Message-ID: <20041005100721.GJ3447@xios> +++ Pesce Gianfranco [04-10-05 11:40 +0200]: > > -----Messaggio originale----- > Da: Pesce Gianfranco > Inviato: marted́ 5 ottobre 2004 11.39 > A: 'Nick Bane' > Cc: 'yaffs@stoneboat.aleph1.co.uk' > Oggetto: R: [Yaffs] I: yaffs - file system on ARM > > > to Nick > > >Could you use plain text? It makes replying much easier. > > Sorry ,what does means plain text ? It means messages which are text (like this one), not HTML. But in fact your original message was both text and HTML, so why nick chose to read the HTML version rather than the text I don't know :-) HTML email is evil and should simply be turned off, particularly to aid in avoiding phishing scams.. And I'm afraid I'mnot sure what's wrong with your YAFFS - I don't have a working one to hand to compare with. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From PesceG@gea-automotive.com Tue Oct 5 11:14:20 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Tue, 5 Oct 2004 12:14:20 +0200 Subject: [Yaffs] I: yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AAC4.14815A30 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable =20 =20 =20 to Nick =20 =20 >what does /proc/yaffs say?=20 =20 this is the output of my /proc/yaffs =20 # cat /proc/yaffs YAFFS built:Oct 5 2004 10:04:10 $Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $ $Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $ =20 Device yaffs startBlock......... 1 endBlock........... 2174 chunkGroupBits..... 1 chunkGroupSize..... 2 nErasedBlocks...... 6 nTnodesCreated..... 0 nFreeTnodes........ 0 nObjectsCreated.... 100 nFreeObjects....... 97 nFreeChunks........ 192 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 6 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 1 # =20 >How big is the mtd partition in the boot messages? =20 # cat /proc/mtd dev: size erasesize name mtd0: 04000000 00004000 "BON" mtd1: 021fc000 00004000 "mtd" =20 =20 Thanks =20 =20 =20 -----Original Message----- From: Nick Bane [mailto:nick@cecomputing.co.uk] Sent: Tuesday, October 05, 2004 11:31 AM To: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk Subject: RE: [Yaffs] I: yaffs - file system on ARM Pesce =20 Could you use plain text? It makes replying much easier. =20 what does /proc/yaffs say?=20 If its all used it may be that it isn't all erased ot being accessed correctly. How big is the mtd partition in the boot messages? =20 Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce = Gianfranco Sent: 05 October 2004 10:01 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] I: yaffs - file system on ARM Sorry , more informations=20 I am using a NAND flash Samsung K9D1208V0M=20 -----Messaggio originale-----=20 Da: Pesce Gianfranco =20 Inviato: marted=EC 5 ottobre 2004 10.56=20 A: 'yaffs@stoneboat.aleph1.co.uk'=20 Oggetto: yaffs - file system on ARM=20 Hi ,=20 I am using an ARM machine with 2.4.18 kernel=20 I want to use yaffs , the file system is mounted , but when I try to do = any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1=20 Any help will be appreciated=20 --------------------------------------------------------------=20 GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.=20 Via Renata Bianchi 40 - 16152 GENOVA (ITALY)=20 Tel.: +39 010 65966.1=20 Fax: +39 010 65966.311=20 http://www.gea-automotive.com ;=20 E-mail: mailbox@gea-automotive.com=20 Ing. Gianfranco Pesce=20 APPLICATION DEVELOPMENT DEPT.=20 Project Engineer=20 Tel. +39.010.659.66.507=20 E-mail: pesceg@gea-automotive.com=20 --------------------------------------------------------------=20 ------_=_NextPart_001_01C4AAC4.14815A30 Content-Type: text/html; charset="iso-8859-1" I: yaffs - file system on ARM
 
 
 
    to Nick 
 
>what does /proc/yaffs say?
 
this is the output of my /proc/yaffs
 
# cat /proc/yaffs
YAFFS built:Oct  5 2004 10:04:10
$Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $
$Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $
 
Device yaffs
startBlock......... 1
endBlock........... 2174
chunkGroupBits..... 1
chunkGroupSize..... 2
nErasedBlocks...... 6
nTnodesCreated..... 0
nFreeTnodes........ 0
nObjectsCreated.... 100
nFreeObjects....... 97
nFreeChunks........ 192
nPageWrites........ 0
nPageReads......... 0
nBlockErasures..... 0
nGCCopies.......... 0
garbageCollections. 0
passiveGCs......... 0
nRetriedWrites..... 0
nRetireBlocks...... 0
eccFixed........... 0
eccUnfixed......... 0
tagsEccFixed....... 0
tagsEccUnfixed..... 6
cacheHits.......... 0
nDeletedFiles...... 0
nUnlinkedFiles..... 0
nBackgroudDeletions 0
useNANDECC......... 1
#
 
>How big is the mtd partition in the boot messages?
 
# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 04000000 00004000 "BON"
mtd1: 021fc000 00004000 "mtd"
 
 
    Thanks
 
 
 
-----Original Message-----
From: Nick Bane [mailto:nick@cecomputing.co.uk]
Sent: Tuesday, October 05, 2004 11:31 AM
To: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk
Subject: RE: [Yaffs] I: yaffs - file system on ARM

Pesce
 
Could you use plain text? It makes replying much easier.
 
what does /proc/yaffs say?
If its all used it may be that it isn't all erased ot being accessed correctly.
How big is the mtd partition in the boot messages?
 
Nick
-----Original Message-----
From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce Gianfranco
Sent: 05 October 2004 10:01
To: 'yaffs@stoneboat.aleph1.co.uk'
Subject: [Yaffs] I: yaffs - file system on ARM


        Sorry , more informations

        I am using a NAND flash Samsung K9D1208V0M

 -----Messaggio originale-----
Da:     Pesce Gianfranco 
Inviato:        marted́ 5 ottobre 2004 10.56
A:      'yaffs@stoneboat.aleph1.co.uk'
Oggetto:        yaffs - file system on ARM




Hi ,

I am using an ARM machine with 2.4.18 kernel
I want to use yaffs , the file system is mounted , but when I try to do any operation , as mkdir or cp , I get the message

"cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1

Any help will be appreciated


--------------------------------------------------------------
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.
Via Renata Bianchi 40 - 16152 GENOVA (ITALY)
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION DEVELOPMENT DEPT.
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------


------_=_NextPart_001_01C4AAC4.14815A30-- From nick@cecomputing.co.uk Tue Oct 5 11:54:08 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Tue, 5 Oct 2004 11:54:08 +0100 Subject: [Yaffs] I: yaffs - file system on ARM In-Reply-To: Message-ID: This is a multi-part message in MIME format. ------=_NextPart_000_000B_01C4AAD2.056892D0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit I: yaffs - file system on ARM -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce Gianfranco Sent: 05 October 2004 10:54 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: R: [Yaffs] I: yaffs - file system on ARM to Nick >Could you use plain text? It makes replying much easier. Sorry ,what does means plain text ? You are emailing html intead of text. Some Windowsy client I guess. Note the blue text and vertical blue bars. I have seen exchange server seem to add html as a wrapper. There is a move to bounce all html emails by zealots. >what does /proc/yaffs say? this is the output of my /proc/yaffs # cat /proc/yaffs YAFFS built:Oct 5 2004 10:04:10 $Id: yaffs_fs.c,v 1.32 2003/10/29 20:42:34 charles Exp $ $Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles Exp $ Device yaffs startBlock......... 1 endBlock........... 2174 chunkGroupBits..... 1 chunkGroupSize..... 2 nErasedBlocks...... 6 nTnodesCreated..... 0 nFreeTnodes........ 0 nObjectsCreated.... 100 nFreeObjects....... 97 nFreeChunks........ 192 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 6 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 1 # >How big is the mtd partition in the boot messages? # cat /proc/mtd dev: size erasesize name mtd0: 04000000 00004000 "BON" mtd1: 021fc000 00004000 "mtd" 2 mtd blocks. Are both yaffs? I am not clear which block /proc/yaffs is referring to but it looks like /mtdblock/1 as 21fc000 bytes is 2175 16k blocks. Is there data in the nand partition? Is it sane? I have seem this before on systems which had a mismatch in the ecc encoding or which had had a lot of erase/resumes. My problem was a mismatch in the ecc calculations used to write the yaffs image (using bootldr) to nans and that used by linux. Reading was fine, writing was a mess. You could enable mtd debugging and it should tell you where it finds pain. Thanks -----Messaggio originale----- Da: Nick Bane [mailto:nick@cecomputing.co.uk] Inviato: marted́ 5 ottobre 2004 11.31 A: Pesce Gianfranco; yaffs@stoneboat.aleph1.co.uk Oggetto: RE: [Yaffs] I: yaffs - file system on ARM Pesce Could you use plain text? It makes replying much easier. what does /proc/yaffs say? If its all used it may be that it isn't all erased ot being accessed correctly. How big is the mtd partition in the boot messages? Nick -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce Gianfranco Sent: 05 October 2004 10:01 To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] I: yaffs - file system on ARM Sorry , more informations I am using a NAND flash Samsung K9D1208V0M -----Messaggio originale----- Da: Pesce Gianfranco Inviato: marted́ 5 ottobre 2004 10.56 A: 'yaffs@stoneboat.aleph1.co.uk' Oggetto: yaffs - file system on ARM Hi , I am using an ARM machine with 2.4.18 kernel I want to use yaffs , the file system is mounted , but when I try to do any operation , as mkdir or cp , I get the message "cannot allocate memory" and the command df says 100% used for /dev/mtdblock/1 Any help will be appreciated -------------------------------------------------------------- GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. Via Renata Bianchi 40 - 16152 GENOVA (ITALY) Tel.: +39 010 65966.1 Fax: +39 010 65966.311 http://www.gea-automotive.com; E-mail: mailbox@gea-automotive.com Ing. Gianfranco Pesce APPLICATION DEVELOPMENT DEPT. Project Engineer Tel. +39.010.659.66.507 E-mail: pesceg@gea-automotive.com -------------------------------------------------------------- --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.772 / Virus Database: 519 - Release Date: 01/10/2004 ------=_NextPart_000_000B_01C4AAD2.056892D0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I: yaffs - file system on ARM
 
-----Original=20 Message-----
From: yaffs-admin@stoneboat.aleph1.co.uk=20 [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Pesce=20 Gianfranco
Sent: 05 October 2004 10:54
To:=20 'yaffs@stoneboat.aleph1.co.uk'
Subject: R: [Yaffs] I: yaffs = - file=20 system on ARM

 =20
    to Nick =20
 
>Could you use plain text? It = makes=20 replying much easier.
 
Sorry ,what does means plain text = ?
 
You are emailing html = intead of text.=20 Some Windowsy client I guess. Note the blue text and vertical blue=20 bars. I have seen exchange server seem to add html as a = wrapper. There=20 is a move to bounce all html emails by = zealots.
 
>what does /proc/yaffs say?=20
 
this is the output = of my=20 /proc/yaffs
 
# cat = /proc/yaffs
YAFFS=20 built:Oct  5 2004 10:04:10
$Id: yaffs_fs.c,v 1.32 2003/10/29 = 20:42:34=20 charles Exp $
$Id: yaffs_guts.c,v 1.34 2004/06/08 08:47:55 charles = Exp=20 $
 
Device=20 yaffs
startBlock......... 1
endBlock...........=20 2174
chunkGroupBits..... 1
chunkGroupSize..... = 2
nErasedBlocks......=20 6
nTnodesCreated..... 0
nFreeTnodes........ = 0
nObjectsCreated....=20 100
nFreeObjects....... 97
nFreeChunks........=20 192
nPageWrites........ 0
nPageReads......... = 0
nBlockErasures.....=20 0
nGCCopies.......... 0
garbageCollections. = 0
passiveGCs.........=20 0
nRetriedWrites..... 0
nRetireBlocks...... = 0
eccFixed...........=20 0
eccUnfixed......... 0
tagsEccFixed....... = 0
tagsEccUnfixed.....=20 6
cacheHits.......... 0
nDeletedFiles...... = 0
nUnlinkedFiles.....=20 0
nBackgroudDeletions 0
useNANDECC......... = 1
#
 
>How big is the mtd partition in = the boot=20 messages?
 
# cat=20 /proc/mtd
dev:    size   erasesize =20 name
mtd0: 04000000 00004000 "BON"
mtd1: 021fc000 00004000=20 "mtd"
 
2 = mtd blocks. Are=20 both yaffs? I am not clear which block /proc/yaffs is referring to but = it looks=20 like /mtdblock/1 as 21fc000 bytes is 2175 16k blocks. Is there data in = the nand=20 partition? Is it sane?
 
I = have seem this=20 before on systems which had a mismatch in the ecc encoding or which had = had a=20 lot of erase/resumes.
My problem was = a mismatch in=20 the ecc calculations used to write the yaffs image (using bootldr) to = nans and=20 that used by linux. Reading was fine, writing was a=20 mess.
 
You could enable=20 mtd debugging and it should tell you where it finds=20 pain.
 
 
    Thanks
 
 
 
-----Messaggio originale-----
Da: Nick Bane=20 [mailto:nick@cecomputing.co.uk]
Inviato: marted=EC 5 = ottobre 2004=20 11.31
A: Pesce Gianfranco;=20 yaffs@stoneboat.aleph1.co.uk
Oggetto: RE: [Yaffs] I: yaffs = - file=20 system on ARM

Pesce
 
Could you use plain text? It makes replying much=20 easier.
 
what does /proc/yaffs say?
If=20 its all used it may be that it isn't all erased ot being accessed=20 correctly.
How big is the mtd partition in the boot=20 messages?
 
Nick
-----Original Message-----
From:=20 yaffs-admin@stoneboat.aleph1.co.uk=20 [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of = Pesce=20 Gianfranco
Sent: 05 October 2004 10:01
To:=20 'yaffs@stoneboat.aleph1.co.uk'
Subject: [Yaffs] I: yaffs = - file=20 system on ARM


        Sorry , more informations

        I am using a NAND flash Samsung = K9D1208V0M=20

 -----Messaggio=20 originale-----
Da:=20     Pesce=20 Gianfranco 
Inviato:        = marted=EC 5 ottobre 2004 10.56 =
A:      = 'yaffs@stoneboat.aleph1.co.uk' =
Oggetto:        = yaffs - file system on ARM =




Hi ,

I am using an ARM machine with = 2.4.18=20 kernel
I want to use yaffs = , the file=20 system is mounted , but when I try to do any operation , as mkdir = or cp ,=20 I get the message

"cannot allocate memory" and the = command df=20 says 100% used for /dev/mtdblock/1

Any help will be appreciated =


--------------------------------------------------------------
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. =
Via Renata Bianchi 40 - 16152 GENOVA = (ITALY)=20
Tel.: +39 010 65966.1 =
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com=20


Ing. Gianfranco Pesce =
APPLICATION = DEVELOPMENT=20 DEPT.
Project = Engineer=20
Tel. +39.010.659.66.507 =
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------=20


------=_NextPart_000_000B_01C4AAD2.056892D0-- From lorenzo.parisi@st.com Tue Oct 5 13:18:48 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Tue, 5 Oct 2004 14:18:48 +0200 Subject: [Yaffs] /proc Message-ID: <35c66fec.8a805a46.81a3300@mail1.agr.st.com> Hi, I've a s3c2410 board with BAST architecture. On board, I've a kernel 2.6.9-rc2-bk13. I've compiled the kernel with CONFIG_PROC_FS = YES; but the directory /proc is empty, why? Thus, I don't see mtd information. Thanks. From robbie@rubin.hu Tue Oct 5 14:13:40 2004 From: robbie@rubin.hu (Robert Szabo) Date: Tue, 05 Oct 2004 15:13:40 +0200 Subject: [Yaffs] /proc In-Reply-To: <35c66fec.8a805a46.81a3300@mail1.agr.st.com> References: <35c66fec.8a805a46.81a3300@mail1.agr.st.com> Message-ID: <41629E04.3000405@rubin.hu> Lorenzo PARISI wrote: >Hi, > >I've a s3c2410 board with BAST architecture. >On board, I've a kernel 2.6.9-rc2-bk13. >I've compiled the kernel with CONFIG_PROC_FS = YES; >but the directory /proc is empty, why? >Thus, I don't see mtd information. > >Thanks. > >_______________________________________________ >yaffs mailing list >yaffs@stoneboat.aleph1.co.uk >http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > Try mount it with: mount -t proc / /proc regards, Robbie From rpjday@mindspring.com Tue Oct 5 16:45:36 2004 From: rpjday@mindspring.com (Robert P. J. Day) Date: Tue, 5 Oct 2004 11:45:36 -0400 (EDT) Subject: [Yaffs] Re: /proc In-Reply-To: <35c66fec.8a805a46.81a3300@mail1.agr.st.com> References: <35c66fec.8a805a46.81a3300@mail1.agr.st.com> Message-ID: On Tue, 5 Oct 2004, Lorenzo PARISI wrote: > Hi, > > I've a s3c2410 board with BAST architecture. > On board, I've a kernel 2.6.9-rc2-bk13. > I've compiled the kernel with CONFIG_PROC_FS = YES; > but the directory /proc is empty, why? > Thus, I don't see mtd information. i think you still have to mount it at boot time. rday From PesceG@gea-automotive.com Wed Oct 6 11:17:02 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Wed, 6 Oct 2004 12:17:02 +0200 Subject: [Yaffs] I: yaffs - file system on ARM Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4AB8D.9F7C2BF0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable ciao Adamo , grazie per la risposta > -----Original Message----- > From: Reggiani, Adamo [mailto:areggiani@ferrari.it] > Sent: Tuesday, October 05, 2004 3:57 PM > To: Pesce Gianfranco > Subject: RE: [Yaffs] I: yaffs - file system on ARM >=20 >=20 >=20 > Ciao Gianfranco, > =E8 probabile che tu stia usando un client di posta per windows=20 > tipo outlook. > Per settare la modalit=E0 testuale prova a creare una nuova=20 > mail e vai sulla voce del men=F9 Formato->Testo Normale (o=20 > qualcosa del genere a seconda della versione di outlook).=20 >=20 > Tutte le mailing list relative a software OpenSource sono=20 > molto critiche nei riguardi del software microsoft, in=20 > particolare delle feature pericolose quali le mail html. > Ti consiglio d'ora in avanti di utilizzare solo la modalit=E0=20 > testuale ;) >=20 spero che questo formato sia corretto > Per quanto riguarda il tuo problema, hai provato ad eseguire=20 > un mkfs.yaffs ? >=20 si=20 abilitando il debug di mtd si vede che sbaglia l'ECC =09 smc_read_ecc_512: ECC [59a667 : 65a967] nand_read_ecc: Failed ECC read, page 0x00006fb0 >=20 >=20 > --------------------------------------------------------------=20 > GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.=20 > Via Renata Bianchi 40 - 16152 GENOVA (ITALY)=20 > Tel.: +39 010 65966.1=20 > Fax: +39 010 65966.311=20 > http://www.gea-automotive.com;=20 > E-mail: mailbox@gea-automotive.com=20 >=20 >=20 > Ing. Gianfranco Pesce=20 > APPLICATION DEVELOPMENT DEPT.=20 > Project Engineer=20 > Tel. +39.010.659.66.507=20 > E-mail: pesceg@gea-automotive.com=20 > --------------------------------------------------------------=20 >=20 ------_=_NextPart_001_01C4AB8D.9F7C2BF0 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable RE: [Yaffs] I: yaffs - file system on ARM

        ciao Adamo = , grazie per la risposta

> -----Original Message-----
> From: Reggiani, Adamo [mailto:areggiani@ferrari.it]
> Sent: Tuesday, October 05, 2004 3:57 PM
> To: Pesce Gianfranco
> Subject: RE: [Yaffs] I: yaffs - file system on = ARM
>
>
>
> Ciao Gianfranco,
> =E8 probabile che tu stia usando un client di = posta per windows
> tipo outlook.
> Per settare la modalit=E0 testuale prova a = creare una nuova
> mail e vai sulla voce del men=F9 = Formato->Testo Normale (o
> qualcosa del genere a seconda della versione di = outlook).
>
> Tutte le mailing list relative  a software = OpenSource sono
> molto critiche nei riguardi del software = microsoft, in
> particolare delle feature pericolose quali le = mail html.
> Ti consiglio d'ora in avanti di utilizzare solo = la modalit=E0
> testuale ;)
>

        spero che = questo formato sia corretto

> Per quanto riguarda il tuo problema, hai provato = ad eseguire
> un mkfs.yaffs ?
>
        si =

        abilitando = il debug di mtd si vede che sbaglia l'ECC
       =20
smc_read_ecc_512: ECC [59a667 : 65a967]

nand_read_ecc: Failed ECC read, page = 0x00006fb0



>
>
> = --------------------------------------------------------------
> GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. =
> Via Renata Bianchi 40 - 16152 GENOVA (ITALY) =
> Tel.: +39 010 65966.1
> Fax: +39 010 65966.311
> http://www.gea-automotive.com;
> E-mail: mailbox@gea-automotive.com
>
>
> Ing. Gianfranco Pesce
> APPLICATION DEVELOPMENT DEPT.
> Project Engineer
> Tel. +39.010.659.66.507
> E-mail: pesceg@gea-automotive.com
> = --------------------------------------------------------------
>

------_=_NextPart_001_01C4AB8D.9F7C2BF0-- From lorenzo.parisi@st.com Thu Oct 7 13:53:32 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Thu, 7 Oct 2004 14:53:32 +0200 Subject: [Yaffs] benchmark Message-ID: Hi, I've a s3c2410 board and I want testing my NAND, but I don't know any benchmark that run under ARM architecture and i386 architecture, so. Do you know someone? I work with jffs2 and yaffs. Thanks From lorenzo.parisi@st.com Thu Oct 7 14:14:34 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Thu, 7 Oct 2004 15:14:34 +0200 Subject: [Yaffs] use yaffs Message-ID: <38783f98.8b8d1e85.8199800@mail1.agr.st.com> Hi, I've a s3c2410 board and I mount on NAND yaffs fs, with this operation: mkyaffs /dev/mtdN mount -t yaffs /dev/mtdblockN /mnt/yaffs with N: number of device. Is it corretct? For benchmarking NAND, I use bonnie++. When I use bonnie++ on NAND with YAFFS, it return this errors: can't putc() - disk full? nand_write_oob: Failed write verify, page 0x0001ffc0 nand_write_oob: Failed write verify, page 0x0001ffc1 But, when I'm writing on NAND I don't receive any errors. Why? Thanks. From areggiani@ferrari.it Thu Oct 7 14:44:08 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Thu, 7 Oct 2004 15:44:08 +0200 Subject: [Yaffs] benchmark Message-ID: What do you mean for "testing your nand"? If you need a speed comparison on unix it's easy to do with: time dd if=3D/mnt/yaffs/file1 of=3D/dev/null bs=3D4096 count=3D1024 (read performance on yaffs for 4Mbyte) or time dd if=3D/dev/null of=3D/mnt/yaffs/file2 bs=3D4096 count=3D1024 (write performance on yaffs for 4Mbyte) Or you can write a simple apps that do the same, creating/deleting = files, depending on your needs. It would take no more than a few minutes. There're also some OpenSource benchmark like bonnie that you can = download from inet. Regards Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Lorenzo PARISI > Sent: gioved=EC 7 ottobre 2004 14.54 > To: MTD mailing list; YAFFS mailing list > Subject: [Yaffs] benchmark >=20 >=20 > Hi, >=20 > I've a s3c2410 board and I want testing my NAND, but I don't=20 > know any benchmark that run under ARM architecture and i386=20 > architecture, so. >=20 > Do you know someone? I work with jffs2 and yaffs. >=20 > Thanks >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From lorenzo.parisi@st.com Thu Oct 7 14:53:19 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Thu, 7 Oct 2004 15:53:19 +0200 Subject: [Yaffs] benchmark Message-ID: I want measure the performance of the NAND. I don't know how to build a simple benchmark. I like build a simple benchmark that write, read, create and delete some files on NAND. Thanks. From daniel.gustafsson@space.se Thu Oct 7 16:03:21 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Thu, 7 Oct 2004 17:03:21 +0200 Subject: [Yaffs] Problems when making yaffs direct Message-ID: <200410071458.i97EwNrB027327@space.se> I am trying to use yaffs direct. Having problems when making the direct directory. If anyone how have tried the direct approach can give me some tips I would be extreamly greateful. //Daniel From areggiani@ferrari.it Fri Oct 8 08:31:57 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Fri, 8 Oct 2004 09:31:57 +0200 Subject: [Yaffs] Problems when making yaffs direct Message-ID: Hi Daniel, could you be more precise? What you mean for "problems when making the direct directory"? What kind of problem you have? Regards Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel > Gustafsson > Sent: gioved=EC 7 ottobre 2004 17.03 > To: yaffs@stoneboat.aleph1.co.uk > Subject: [Yaffs] Problems when making yaffs direct >=20 >=20 > I am trying to use yaffs direct. Having problems when making=20 > the direct > directory. If anyone how have tried the direct approach can=20 > give me some > tips I would be extreamly greateful. >=20 > //Daniel >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From areggiani@ferrari.it Fri Oct 8 08:42:43 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Fri, 8 Oct 2004 09:42:43 +0200 Subject: [Yaffs] use yaffs Message-ID: Hi, have you tried Bonnie instead of Bonnie++ ? On your error, are pages 0x0001ffc0-0x0001ffc1 always the same over = different tests or do they change? You can find other usefull test&benchmarking sources on http://www.acnc.com/benchmark.html cu Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Lorenzo PARISI > Sent: gioved=EC 7 ottobre 2004 15.15 > To: YAFFS mailing list > Subject: [Yaffs] use yaffs >=20 >=20 > Hi, >=20 > I've a s3c2410 board and I mount on NAND yaffs fs, with this=20 > operation: >=20 > mkyaffs /dev/mtdN > mount -t yaffs /dev/mtdblockN /mnt/yaffs >=20 > with N: number of device. >=20 > Is it corretct? >=20 > For benchmarking NAND, I use bonnie++. When I use bonnie++=20 > on NAND with YAFFS, it return this errors: >=20 > can't putc() - disk full? > nand_write_oob: Failed write verify, page 0x0001ffc0 > nand_write_oob: Failed write verify, page 0x0001ffc1 >=20 > But, when I'm writing on NAND I don't receive any errors. > Why? >=20 > Thanks. >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From areggiani@ferrari.it Fri Oct 8 10:24:25 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Fri, 8 Oct 2004 11:24:25 +0200 Subject: [Yaffs] Problems when making yaffs direct Message-ID: My approach to yaffs_direct was a little bit different. AFAIK yaffs_direct is made to be compiled inside your apps/os, instead = of using the standard yaffs kernel module. I've tested it last year with a small rtos (named TargetOS) and i've = done this steps: - make a new directory with this files: devextras.h dtest.c yaffs_ecc.c = yaffs_ecc.h yaffs_flashif.c yaffs_flashif.h yaffs_guts.c yaffs_guts.h = yaffs_ramdisk.c yaffs_ramdisk.h yaffscfg.c yaffscfg.h yaffsfs.c = yaffsfs.h yaffsinterface.h yportenv.h - puts file reference in your makefile/project environment (this depend = on the toolchain, etc.) - modify the yaffscfg.c and yaffscfg.h to fit your environment; this = normally means to define a way to lock/unlock yaffs access (through = semaphore, mutex, etc.), and eventually your customized init - call somewhere in your app some test function (cache_read_test, = long_test, ...) - compile it That's all, and works well for me. Note that in the reported file list i've mentioned yaffs_ramdisk.c, this = because i've tested yaffs in ram. I suggest to do the same the first time, it's simpler than using nand = drivers. After you've set up correctly your environment you can switch to = nand/mtd or whatever. Regards Adamo > -----Original Message----- > From: Daniel Gustafsson [mailto:daniel.gustafsson@space.se] > Sent: venerd=EC 8 ottobre 2004 09.47 > To: Reggiani, Adamo; yaffs@stoneboat.aleph1.co.uk > Subject: RE: [Yaffs] Problems when making yaffs direct >=20 >=20 > =20 > I want to test yaffs using the direct approach. When=20 > downloading yaffs and > extracting the tarball I get several directorys and files(of=20 > course). When > reading on the yaffs homepage they explain how to make and=20 > mount yaffs. > Everything works fine when running the Makefile in the yaffs=20 > dir. If I want > to compile and run with "yaffs/direct" instead I assume that=20 > I should use > the Makefile in yaffs/direct. When doing so I get some=20 > strange errors that I > dont understand and see a solution to.=20 >=20 > An minor example of the errors: >=20 > [gustad@tuxsrv1 work]$ make clean > rm -f dtest.o yaffscfg.o yaffsfs.o yaffs_ramdisk.o core > [gustad@tuxsrv1 work]$ make > gcc -c -Wall -DCONFIG_YAFFS_DIRECT=20 > -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g > dtest.c -o dtest.o > In file included from yaffscfg.h:12, > from yaffsfs.h:10, > from dtest.c:9: > yaffs_guts.h:204: warning: no semicolon at end of struct or union > yaffs_guts.h:204: parse error before '.' token > yaffs_guts.h:205: parse error before '.' token > yaffs_guts.h:206: parse error before '.' token > yaffs_guts.h:229: parse error before '}' token > yaffs_guts.h:229: warning: type defaults to `int' in declaration of > `yaffs_ObjectHeader' > yaffs_guts.h:229: warning: data definition has no type or=20 > storage class > yaffs_guts.h:353: warning: no semicolon at end of struct or union > yaffs_guts.h:353: parse error before '.' token > yaffs_guts.h:354: parse error before '.' token > yaffs_guts.h:355: parse error before '.' token > yaffs_guts.h:372: parse error before '}' token >=20 >=20 > I have not modified any of the files. >=20 > What is wrong??? >=20 >=20 > >-----Original Message----- > >From: Reggiani, Adamo [mailto:areggiani@ferrari.it]=20 > >Sent: Friday, October 08, 2004 9:32 AM > >To: Daniel Gustafsson; yaffs@stoneboat.aleph1.co.uk > >Subject: RE: [Yaffs] Problems when making yaffs direct > > > > > >Hi Daniel, > >could you be more precise? > >What you mean for "problems when making the direct directory"? > >What kind of problem you have? > > > >Regards > >Adamo > > > > > >> -----Original Message----- > >> From: yaffs-admin@stoneboat.aleph1.co.uk > >> [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel > >> Gustafsson > >> Sent: gioved=EC 7 ottobre 2004 17.03 > >> To: yaffs@stoneboat.aleph1.co.uk > >> Subject: [Yaffs] Problems when making yaffs direct > >>=20 > >>=20 > >> I am trying to use yaffs direct. Having problems when making=20 > >> the direct > >> directory. If anyone how have tried the direct approach can=20 > >> give me some > >> tips I would be extreamly greateful. > >>=20 > >> //Daniel > >>=20 > >>=20 > >> _______________________________________________ > >> yaffs mailing list > >> yaffs@stoneboat.aleph1.co.uk > >> http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > >>=20 > > > > >=20 >=20 From lorenzo.parisi@st.com Fri Oct 8 10:52:23 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Fri, 8 Oct 2004 11:52:23 +0200 Subject: [Yaffs] Benchmark errors Message-ID: <83197f15.8bfe70e2.81c1800@mail1.agr.st.com> Hi all, when I benchmark the NAND with Bonnie++, I receive many errors: nand_write_oob: Failed write verify, page 0x0.... : : : : : : and Bonnie++ end with this messages: Bonnie: drastic I/O error (rmdir): Directory not empty Cleaning up test directory after error Bonnie: drastic I/O error (rmdir): No such file or directory Initially, I thinked that a problem of Bonnie++, but if I run Bonnie++ on a NAND with JFFS2, I don't receive any errors. Why? Thanks. From tglx@linutronix.de Fri Oct 8 11:00:57 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 08 Oct 2004 12:00:57 +0200 Subject: [Yaffs] Re: Benchmark errors In-Reply-To: <83197f15.8bfe70e2.81c1800@mail1.agr.st.com> References: <83197f15.8bfe70e2.81c1800@mail1.agr.st.com> Message-ID: <1097229657.11402.1440.camel@thomas> On Fri, 2004-10-08 at 11:52, Lorenzo PARISI wrote: > Hi all, > nand_write_oob: Failed write verify, page 0x0.... So it works with JFFS2 and it fails on YAFFS. The MTD internal interface was reworked some time ago and it might be that the write verify does not work with YAFFS anymore, as YAFFS is using a legacy variant of the interface. Can you please switch of the write verify and test again ? tglx From a.hawkins@cabletime.com Fri Oct 8 11:31:30 2004 From: a.hawkins@cabletime.com (Andy Hawkins) Date: Fri, 8 Oct 2004 11:31:30 +0100 Subject: [Yaffs] YAFFS2 Status Message-ID: <000c01c4ad21$f9f7f740$153335bf@cabletime.com> Hi, Can anyone provide me with a brief summary of progress on YAFFS2? We are currently working on a device that contains a number (currently 15 I think) 128MB NAND chips, that we would like to treat as a single filesystem. This doesn't currently work with JFFS2, and we would like to try it with YAFFS2 when it becomes available. Thanks Andy From tglx@linutronix.de Fri Oct 8 11:27:44 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 08 Oct 2004 12:27:44 +0200 Subject: [Yaffs] Re: Benchmark errors In-Reply-To: <1097229657.11402.1440.camel@thomas> References: <83197f15.8bfe70e2.81c1800@mail1.agr.st.com> <1097229657.11402.1440.camel@thomas> Message-ID: <1097231263.11402.1449.camel@thomas> --=-aHQQwQ/k4c2xqyLjos7P Content-Type: text/plain Content-Transfer-Encoding: 7bit On Fri, 2004-10-08 at 12:00, Thomas Gleixner wrote: > On Fri, 2004-10-08 at 11:52, Lorenzo PARISI wrote: > > Hi all, > > nand_write_oob: Failed write verify, page 0x0.... > > So it works with JFFS2 and it fails on YAFFS. The MTD internal interface > was reworked some time ago and it might be that the write verify does > not work with YAFFS anymore, as YAFFS is using a legacy variant of the > interface. Can you please switch of the write verify and test again ? > Can you please figure out, where the verify exactly fails ? Please apply the attached patch to nand_base.c tglx --=-aHQQwQ/k4c2xqyLjos7P Content-Disposition: attachment; filename=nand_base.diff Content-Type: text/x-patch; name=nand_base.diff; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 7bit diff -u -r1.121 nand_base.c --- nand_base.c 6 Oct 2004 19:53:11 -0000 1.121 +++ nand_base.c 8 Oct 2004 10:34:39 -0000 @@ -310,11 +310,17 @@ { int i; struct nand_chip *this = mtd->priv; + u_char tmp; - for (i=0; iIO_ADDR_R)) + for (i=0; iIO_ADDR_R); + if (buf[i] != tmp) { + DEBUG (MTD_DEBUG_LEVEL0, + "Verify failed: 0x%02x instead of 0x%02x at offset %d\n", + tmp, buf[i], i); return -EFAULT; - + } + } return 0; } @@ -955,7 +961,7 @@ */ if (oobmode) { if (this->verify_buf(mtd, &oob_buf[oobofs], mtd->oobsize - hweccbytes * eccsteps)) { - DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page); + DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify oob, page 0x%08x ", __FUNCTION__, page); goto out; } } else { --=-aHQQwQ/k4c2xqyLjos7P-- From daniel.gustafsson@space.se Fri Oct 8 08:47:10 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Fri, 8 Oct 2004 09:47:10 +0200 Subject: [Yaffs] Problems when making yaffs direct In-Reply-To: Message-ID: <200410080742.i987gBrB024381@space.se> =20 I want to test yaffs using the direct approach. When downloading yaffs = and extracting the tarball I get several directorys and files(of course). = When reading on the yaffs homepage they explain how to make and mount yaffs. Everything works fine when running the Makefile in the yaffs dir. If I = want to compile and run with "yaffs/direct" instead I assume that I should = use the Makefile in yaffs/direct. When doing so I get some strange errors = that I dont understand and see a solution to.=20 An minor example of the errors: [gustad@tuxsrv1 work]$ make clean rm -f dtest.o yaffscfg.o yaffsfs.o yaffs_ramdisk.o core [gustad@tuxsrv1 work]$ make gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g dtest.c -o dtest.o In file included from yaffscfg.h:12, from yaffsfs.h:10, from dtest.c:9: yaffs_guts.h:204: warning: no semicolon at end of struct or union yaffs_guts.h:204: parse error before '.' token yaffs_guts.h:205: parse error before '.' token yaffs_guts.h:206: parse error before '.' token yaffs_guts.h:229: parse error before '}' token yaffs_guts.h:229: warning: type defaults to `int' in declaration of `yaffs_ObjectHeader' yaffs_guts.h:229: warning: data definition has no type or storage class yaffs_guts.h:353: warning: no semicolon at end of struct or union yaffs_guts.h:353: parse error before '.' token yaffs_guts.h:354: parse error before '.' token yaffs_guts.h:355: parse error before '.' token yaffs_guts.h:372: parse error before '}' token I have not modified any of the files. What is wrong??? >-----Original Message----- >From: Reggiani, Adamo [mailto:areggiani@ferrari.it]=20 >Sent: Friday, October 08, 2004 9:32 AM >To: Daniel Gustafsson; yaffs@stoneboat.aleph1.co.uk >Subject: RE: [Yaffs] Problems when making yaffs direct > > >Hi Daniel, >could you be more precise? >What you mean for "problems when making the direct directory"? >What kind of problem you have? > >Regards >Adamo > > >> -----Original Message----- >> From: yaffs-admin@stoneboat.aleph1.co.uk >> [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel >> Gustafsson >> Sent: gioved=EC 7 ottobre 2004 17.03 >> To: yaffs@stoneboat.aleph1.co.uk >> Subject: [Yaffs] Problems when making yaffs direct >>=20 >>=20 >> I am trying to use yaffs direct. Having problems when making=20 >> the direct >> directory. If anyone how have tried the direct approach can=20 >> give me some >> tips I would be extreamly greateful. >>=20 >> //Daniel >>=20 >>=20 >> _______________________________________________ >> yaffs mailing list >> yaffs@stoneboat.aleph1.co.uk >> http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >>=20 > > From nick@cecomputing.co.uk Fri Oct 8 12:34:37 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Fri, 8 Oct 2004 12:34:37 +0100 Subject: [Yaffs] YAFFS2 Status In-Reply-To: <000c01c4ad21$f9f7f740$153335bf@cabletime.com> Message-ID: > We are currently working on a device that contains a number=20 > (currently 15 I > think) 128MB NAND chips, that we would like to treat as a single=20 > filesystem. > This doesn't currently work with JFFS2, and we would like to try it = with > YAFFS2 when it becomes available. >=20 I currently use the newest mtd (2.6.8.1 and later) to run 3 nand chips = as a single mtd device using yaffs (not yaffs2) so you could do that. = The latest mtd may allow jffs2 to do that too of course. Nick --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.773 / Virus Database: 520 - Release Date: 05/10/2004 From fischi@epygi.de Fri Oct 8 12:54:47 2004 From: fischi@epygi.de (Michael Fischer) Date: Fri, 8 Oct 2004 13:54:47 +0200 Subject: [Yaffs] problem with object (file) creation Message-ID: Hello everyone, i am new to the list as well as to the linux vfs/fs stuff and i am looking for any help/comments on the following: In some cases when copying a big number of files i got complains from the cp command that a newly created file was a directory thus not beeing able to write data into it. The following steps would reproduce the behavior: - delete a directory with many files and subdirs recursively. - have some process which still has a reference to the dir or some file open (e.g. cd /test; rm -rf /test) - move or copy back the deleted dir-tree from some backup location. Debuging it further i found that the yaffs layer deletes objects which due to references still exist in the inode cache of the vfs layer. Looking into the code i found that yaffs_fs.c/yaffs_mknod => __yaffs_mknod => yaffs_FindNiceObjectBucket returns the object id . Depending on YAFFS_NOBJECT_BUCKETS you probably get an id of a recently deleted object. When afterwards calling yaffs_get_inode(iget4) you get an possibly allready existing inode (inode reference count > 1). This inode doesnt get initialized so attributes like directory are still valid and cause the described behavior. so a small patch (read: fast dirty hack) of yaffs_mknod (see below) does solve the problem in my case: doitagain: obj = __yaffs_mknod ( parent, dentry, mode, rdev); if(obj) { inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count))); if (atomic_read(&inode->i_count) > 1) { iput(inode); yaffs_DeleteFile(obj); goto doitagain; } d_instantiate(dentry, inode); error = 0; } else { ok, as mentioned before i am new to all this therefore i am of cause unsure if i havnt overseen something or this is fixed in later versions or how a clean patch could look like. Thanks a lot for any comments and best regards, Michael From lorenzo.parisi@st.com Fri Oct 8 13:15:50 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Fri, 8 Oct 2004 14:15:50 +0200 Subject: [Yaffs] Re: Benchmark errors Message-ID: <841a061c.8c0b92e4.81a3300@mail1.agr.st.com> I've used YAFFS, and I receive this errors with all NAND that try the benchmark. Moreover, I've make a script that write and remove 4000 files. My script return nand_write_oob errors, so. From lorenzo.parisi@st.com Fri Oct 8 13:19:40 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Fri, 8 Oct 2004 14:19:40 +0200 Subject: [Yaffs] Re: Benchmark errors Message-ID: <91d0fa5f.8c0becc6.81a3300@mail1.agr.st.com> I'm trying, but I receive same errors. From areggiani@ferrari.it Fri Oct 8 13:30:08 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Fri, 8 Oct 2004 14:30:08 +0200 Subject: [Yaffs] Re: Benchmark errors Message-ID: Please Lorenzo, could you left some text of the previous mail? It's difficult to follow the argument without it. Thanx Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Lorenzo PARISI > Sent: venerd=EC 8 ottobre 2004 14.20 > To: tglx@linutronix.de; Lorenzo PARISI > Cc: YAFFS mailing list; MTD mailing list > Subject: [Yaffs] Re: Benchmark errors >=20 >=20 > I'm trying, but I receive same errors. >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From a.hawkins@cabletime.com Fri Oct 8 13:53:54 2004 From: a.hawkins@cabletime.com (Andy Hawkins) Date: Fri, 8 Oct 2004 13:53:54 +0100 Subject: [Yaffs] YAFFS2 Status In-Reply-To: Message-ID: <001701c4ad35$df165070$153335bf@cabletime.com> Hi, > I currently use the newest mtd (2.6.8.1 and later) to run 3 > nand chips as a single mtd device using yaffs (not yaffs2) so > you could do that. The latest mtd may allow jffs2 to do that > too of course. We can manage three chips with JFFS2. Any more than that and it starts to complain and fails to mount. Andy From tglx@linutronix.de Fri Oct 8 14:00:39 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 08 Oct 2004 15:00:39 +0200 Subject: [Yaffs] YAFFS2 Status In-Reply-To: <001701c4ad35$df165070$153335bf@cabletime.com> References: <001701c4ad35$df165070$153335bf@cabletime.com> Message-ID: <1097240438.11402.1485.camel@thomas> On Fri, 2004-10-08 at 14:53, Andy Hawkins wrote: > We can manage three chips with JFFS2. Any more than that and it starts to > complain and fails to mount. Why ? What are the error messages ? Which kernel version ? Which mtd code ? tglx From daniel.gustafsson@space.se Fri Oct 8 14:28:35 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Fri, 8 Oct 2004 15:28:35 +0200 Subject: [Yaffs] Compile error when using yaffs/direct Message-ID: <200410081323.i98DNYrB007655@space.se> When i try to compile yaffs/direct I get strange errrors. I am running the original Makefile in yaffs/direct on Linux. Some of the errors: [gustad@tuxsrv1 work]$ make gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g dtest.c -o dtest.o In file included from yaffscfg.h:12, from yaffsfs.h:10, from dtest.c:9: yaffs_guts.h:204: warning: no semicolon at end of struct or union yaffs_guts.h:204: parse error before '.' token yaffs_guts.h:205: parse error before '.' token yaffs_guts.h:206: parse error before '.' token yaffs_guts.h:229: parse error before '}' token yaffs_guts.h:229: warning: type defaults to `int' in declaration of `yaffs_ObjectHeader' yaffs_guts.h:229: warning: data definition has no type or storage class yaffs_guts.h:353: warning: no semicolon at end of struct or union yaffs_guts.h:353: parse error before '.' token yaffs_guts.h:354: parse error before '.' token yaffs_guts.h:355: parse error before '.' token yaffs_guts.h:372: parse error before '}' token This rows plus some more concerning the same variables is the problem. __u32 st_atime; /* time of last access */ __u32 st_mtime; /* time of last modification */ __u32 st_ctime; /* time of last change */ Can somebody help me? //Daniel From wookey@aleph1.co.uk Fri Oct 8 14:37:24 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 8 Oct 2004 14:37:24 +0100 Subject: [Yaffs] Re: YAFFS2 Status In-Reply-To: <000c01c4ad21$f9f7f740$153335bf@cabletime.com> References: <000c01c4ad21$f9f7f740$153335bf@cabletime.com> Message-ID: <20041008133724.GK5737@xios> +++ Andy Hawkins [04-10-08 11:31 +0100]: > Hi, > > Can anyone provide me with a brief summary of progress on YAFFS2? It is progressing after something of a hiatus. Charles is the one who can give best info but my impression from what's he said to date is that it's 'about half done', and we might expect to see something useful in a few weeks. There is increasing interest in the 2K/16bit chips and this helps generate activity... Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From lorenzo.parisi@st.com Fri Oct 8 15:15:34 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Fri, 8 Oct 2004 16:15:34 +0200 Subject: [Yaffs] Re: Benchmark errors Message-ID: <304d07d9.8c168923.8424e00@mail1.agr.st.com> I applied the patch, but I receive same errors. From tglx@linutronix.de Fri Oct 8 15:35:32 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 08 Oct 2004 16:35:32 +0200 Subject: [Yaffs] Re: Benchmark errors In-Reply-To: <304d07d9.8c168923.8424e00@mail1.agr.st.com> References: <304d07d9.8c168923.8424e00@mail1.agr.st.com> Message-ID: <1097246132.11402.1496.camel@thomas> Please keep some text of the original mail ! On Fri, 2004-10-08 at 16:15, Lorenzo PARISI wrote: > I applied the patch, but I receive same errors. > That's expected, but the error messages are defenitely not the same. They contain more information and I could tell you more, if you would provide those extended messages tglx From dwmw2@infradead.org Fri Oct 8 15:55:36 2004 From: dwmw2@infradead.org (David Woodhouse) Date: Fri, 08 Oct 2004 15:55:36 +0100 Subject: [Yaffs] Re: Benchmark errors In-Reply-To: <1097246132.11402.1496.camel@thomas> References: <304d07d9.8c168923.8424e00@mail1.agr.st.com> <1097246132.11402.1496.camel@thomas> Message-ID: <1097247336.318.136.camel@hades.cambridge.redhat.com> On Fri, 2004-10-08 at 16:35 +0200, Thomas Gleixner wrote: > Please keep some text of the original mail ! Why? A mail has 'References:' headers, which give the Message-ID of the message to which you're replying. Most mail programs can then display a 'threaded' view where it's trivial to find the 'parent' message. Some mailers even show the References: header with hyperlinks so you can just click and be taken there. That's the theory according to RFC2822, anyway. Actually, Lorenzo's mail program is broken and didn't include the References: header as it should have done. That's why it was rejected by the mailing list. -- dwmw2 From beatit@hotmail.com Sat Oct 9 02:28:02 2004 From: beatit@hotmail.com (Wangfeng Ai) Date: Sat, 09 Oct 2004 09:28:02 +0800 Subject: [Yaffs] Compile error when using yaffs/direct In-Reply-To: <200410081323.i98DNYrB007655@space.se> References: <200410081323.i98DNYrB007655@space.se> Message-ID: <41673EA2.9000604@hotmail.com> I had the same case as you. It's very strange. I got the same error messages when I was compiling yaffs/utils. But it can be cross-compiled with armv4l-redhat-linux-gcc from mizi. Daniel Gustafsson wrote: > When i try to compile yaffs/direct I get strange errrors. I am running the > original Makefile in yaffs/direct on Linux. > > Some of the errors: > > [gustad@tuxsrv1 work]$ make > gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g > dtest.c -o dtest.o > In file included from yaffscfg.h:12, > from yaffsfs.h:10, > from dtest.c:9: > yaffs_guts.h:204: warning: no semicolon at end of struct or union > yaffs_guts.h:204: parse error before '.' token > yaffs_guts.h:205: parse error before '.' token > yaffs_guts.h:206: parse error before '.' token > yaffs_guts.h:229: parse error before '}' token > yaffs_guts.h:229: warning: type defaults to `int' in declaration of > `yaffs_ObjectHeader' > yaffs_guts.h:229: warning: data definition has no type or storage class > yaffs_guts.h:353: warning: no semicolon at end of struct or union > yaffs_guts.h:353: parse error before '.' token > yaffs_guts.h:354: parse error before '.' token > yaffs_guts.h:355: parse error before '.' token > yaffs_guts.h:372: parse error before '}' token > > > This rows plus some more concerning the same variables is the problem. > > __u32 st_atime; /* time of last access */ > __u32 st_mtime; /* time of last modification */ > __u32 st_ctime; /* time of last change */ > > Can somebody help me? > > //Daniel > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > . > From manningc2@actrix.gen.nz Sun Oct 10 08:23:24 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Sun, 10 Oct 2004 20:23:24 +1300 Subject: [Yaffs] Compile error when using yaffs/direct In-Reply-To: <200410081323.i98DNYrB007655@space.se> References: <200410081323.i98DNYrB007655@space.se> Message-ID: <20041010072036.CED845CED@blood.actrix.co.nz> I think this got messed up when I changed the=20 kernel version stuff for Linux as follows: //#if defined(CONFIG_KERNEL_2_5) #if defined(__KERNEL__) && (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) I thought the if defined(__KERNEL__) stuff would have prevented the rest = from=20 executing but it looks like I was wrong. For a quick fix, you could undo these changes. I will fix these properly = ASAP -- Charles On Saturday 09 October 2004 02:28, Daniel Gustafsson wrote: > When i try to compile yaffs/direct I get strange errrors. I am running = the > original Makefile in yaffs/direct on Linux. > > Some of the errors: > > [gustad@tuxsrv1 work]$ make > gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g > dtest.c -o dtest.o > In file included from yaffscfg.h:12, > from yaffsfs.h:10, > from dtest.c:9: > yaffs_guts.h:204: warning: no semicolon at end of struct or union > yaffs_guts.h:204: parse error before '.' token > yaffs_guts.h:205: parse error before '.' token > yaffs_guts.h:206: parse error before '.' token > yaffs_guts.h:229: parse error before '}' token > yaffs_guts.h:229: warning: type defaults to `int' in declaration of > `yaffs_ObjectHeader' > yaffs_guts.h:229: warning: data definition has no type or storage class > yaffs_guts.h:353: warning: no semicolon at end of struct or union > yaffs_guts.h:353: parse error before '.' token > yaffs_guts.h:354: parse error before '.' token > yaffs_guts.h:355: parse error before '.' token > yaffs_guts.h:372: parse error before '}' token > > > This rows plus some more concerning the same variables is the problem. > > __u32 st_atime; /* time of last access */ > __u32 st_mtime; /* time of last modification */ > __u32 st_ctime; /* time of last change */ > > Can somebody help me? > > //Daniel > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Sun Oct 10 19:14:53 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 11 Oct 2004 07:14:53 +1300 Subject: [Yaffs] Recent compile problems Message-ID: <20041010181144.BBE2C154D2@desire.actrix.co.nz> I recently fiddled around with things in an effort to get the code ready = for=20 inclusion in the Linux mainstream. I did two main things: 1) Pulled the WINCE and Direct stuff out of yportenv.h into their own=20 sub-includes. 2) Replaced the YAFFS_CONFIG_KERNEL_2_5 with "proper" Linux version macro= s. Unfortunately I did not test the changes sufficiently for non-kernel case= s. I've straightened things out and now get good compiles for kernel, utils,= =20 direct. I have not yet tried WinCE. All the Linux version specific stuff (relating to CURRENT_TIME) has been=20 puilled out of yaffs_guts.c and has been put into the appropriate yporten= v.h=20 section. The include dependencies have been straightened out. If there are still problems please yell. -- CHarles From manningc2@actrix.gen.nz Sun Oct 10 19:26:27 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 11 Oct 2004 07:26:27 +1300 Subject: [Yaffs] problem with object (file) creation In-Reply-To: References: Message-ID: <20041010182318.CAD555277@blood.actrix.co.nz> Michael Thank you very much for this. I too have struggled to sometimes get my he= ad=20 around the vfs and how it works and the input from various people has bee= m=20 very useful. I will be investigating this ASAP. Can you tell me what version of Linux you're using here? Some of these th= ings=20 might be version specific. Thanx -- CHarles On Saturday 09 October 2004 00:54, Michael Fischer wrote: > Hello everyone, > i am new to the list as well as to the linux vfs/fs stuff and i am look= ing > for any help/comments on the following: > In some cases when copying a big number of files i got complains from t= he > cp command that a newly created file was a directory thus not beeing ab= le > to write data into it. The following steps would reproduce the behavior= : - > delete a directory with many files and subdirs recursively. > - have some process which still has a reference to the dir or some file > open (e.g. cd /test; rm -rf /test) > - move or copy back the deleted dir-tree from some backup location. > > Debuging it further i found that the yaffs layer deletes objects which = due > to references still exist in the inode cache of the vfs layer. Looking = into > the code i found that yaffs_fs.c/yaffs_mknod =3D> __yaffs_mknod =3D> > yaffs_FindNiceObjectBucket returns the object id . Depending on > YAFFS_NOBJECT_BUCKETS you probably get an id of a recently deleted obje= ct. > When afterwards calling yaffs_get_inode(iget4) you get an possibly allr= eady > existing inode (inode reference count > 1). This inode doesnt get > initialized so attributes like directory are still valid and cause the > described behavior. > > so a small patch (read: fast dirty hack) of yaffs_mknod (see below) doe= s > solve the problem in my case: > > doitagain: > obj =3D __yaffs_mknod ( parent, dentry, mode, rdev); > if(obj) > { > inode =3D yaffs_get_inode(dir->i_sb, mode, rdev, obj); > T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count =3D > %d\n",obj->objectId,atomic_read(&inode->i_count))); > if (atomic_read(&inode->i_count) > 1) { > iput(inode); > yaffs_DeleteFile(obj); > goto doitagain; > } > d_instantiate(dentry, inode); > error =3D 0; > } > else > { > > ok, as mentioned before i am new to all this therefore i am of cause un= sure > if i havnt overseen something or this is fixed in later versions or how= a > clean patch could look like. > > Thanks a lot for any comments and best regards, > Michael > > > > > > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From fischi@epygi.de Mon Oct 11 10:20:18 2004 From: fischi@epygi.de (Michael Fischer) Date: Mon, 11 Oct 2004 11:20:18 +0200 Subject: [Yaffs] problem with object (file) creation In-Reply-To: <20041010182318.CAD555277@blood.actrix.co.nz> Message-ID: Hello, > Can you tell me what version of Linux you're using here? Some of > these things might be version specific. sure, we use a 2.4.18 kernel on a ppc 8xx platform. Best regards, Michael From daniel.gustafsson@space.se Mon Oct 11 13:46:45 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Mon, 11 Oct 2004 14:46:45 +0200 Subject: [Yaffs] Optimizing the number of reads and writes to flash Message-ID: <200410111241.i9BCfcrB027306@space.se> I am using yaffs/direct and I want to reduce the reads and writes towards the flash to an absolute minimum. I do not want any verifications of flash etc. I don not want to use ECC. I would greatly appreatiate any tips regarding the above issue but also how to reduce the footprint in RAM and size. Further more I am interested in some documetation what happens (reads/writes to flash) when performing some simple fs operations like read/write/open etc. I hope someone have the answers I am looking for, Best Regards Daniel Gustavsson From areggiani@ferrari.it Mon Oct 11 14:24:42 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Mon, 11 Oct 2004 15:24:42 +0200 Subject: [Yaffs] Optimizing the number of reads and writes to flash Message-ID: Hi Daniel, uncomment the define of this two labels in the makefile: CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK CONFIG_YAFFS_DISABLE_WRITE_VERIFY In this way you avoid to re-read every chunk before write (to control if = it's blank) and to re-read after a succesfull write. I've also made a little modification of the yaffs_WriteNewChunkToNAND, = to completely avoid chunks read after write (the original code avoids = yaffs_VerifyCompare only). Check the following code against cvs one. static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, = const __u8 *data, yaffs_Spare *spare,int useReserve) { int chunk; int writeOk =3D 1; int attempts =3D 0; do{ chunk =3D yaffs_AllocateChunk(dev,useReserve); if(chunk >=3D 0) { // First check this chunk is erased... #ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK writeOk =3D yaffs_CheckChunkErased(dev,chunk); #endif if(!writeOk) { T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d was not erased" = TENDSTR),chunk)); } else { writeOk =3D yaffs_WriteChunkToNAND(dev,chunk,data,spare); } attempts++; #ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY if(writeOk) { unsigned char rbData[YAFFS_BYTES_PER_CHUNK]; yaffs_Spare rbSpare; // Readback & verify // If verify fails, then delete this chunk and try again // To verify we compare everything except the block and // page status bytes. // NB We check a raw read without ECC correction applied yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0); if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare)) { // Didn't verify T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write verify failed on chunk = %d" TENDSTR), chunk)); writeOk =3D 0; } } #endif if(writeOk) { // Copy the data into the write buffer. // NB We do this at the end to prevent duplicates in the case of a = write error. //Todo yaffs_HandleWriteChunkOk(dev,chunk,data,spare); } else { yaffs_HandleWriteChunkError(dev,chunk); } } } while(chunk >=3D 0 && ! writeOk); if(attempts > 1) { T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write required %d attempts" = TENDSTR),attempts)); dev->nRetriedWrites+=3D (attempts - 1); } return chunk; } To reduce writes I think you must wait (or aid ;) for Yaffs2, which will = use a zero page rewrites to spare area and will have generally better = performance over Yaffs. Look at www.aleph1.co.uk/yaffs/yaffs2.html Regards Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel > Gustafsson > Sent: luned=EC 11 ottobre 2004 14.47 > To: yaffs@stoneboat.aleph1.co.uk > Subject: [Yaffs] Optimizing the number of reads and writes to flash >=20 >=20 >=20 >=20 > I am using yaffs/direct and I want to reduce the reads and=20 > writes towards > the flash to an absolute minimum. I do not want any=20 > verifications of flash > etc. I don not want to use ECC. >=20 > I would greatly appreatiate any tips regarding the above=20 > issue but also how > to reduce the footprint in RAM and size.=20 >=20 > Further more I am interested in some documetation what=20 > happens (reads/writes > to flash) when performing some simple fs operations like=20 > read/write/open > etc. >=20 >=20 > I hope someone have the answers I am looking for, >=20 > Best Regards > Daniel Gustavsson >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From daniel.gustafsson@space.se Mon Oct 11 15:14:24 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Mon, 11 Oct 2004 16:14:24 +0200 Subject: [Yaffs] Optimizing the number of reads and writes to flash In-Reply-To: Message-ID: <200410111409.i9BE9HrB009321@space.se> =20 Thanks.=20 I had already fixed the defines. The problem that confused me was that = the CONFIG_YAFFS_DISABLE_WRITE_VERIFY didn't optimize the reads. With the movement of the #ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY like = in your code the problem was solved. I believe that this is how the define CONFIG_YAFFS_DISABLE_WRITE_VERIFY is meant to work. //Daniel >-----Original Message----- >From: Reggiani, Adamo [mailto:areggiani@ferrari.it]=20 >Sent: Monday, October 11, 2004 3:25 PM >To: Daniel Gustafsson; yaffs@stoneboat.aleph1.co.uk >Subject: RE: [Yaffs] Optimizing the number of reads and writes to flash > >Hi Daniel, >uncomment the define of this two labels in the makefile: >CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK >CONFIG_YAFFS_DISABLE_WRITE_VERIFY > >In this way you avoid to re-read every chunk before write (to=20 >control if it's blank) and to re-read after a succesfull write. >I've also made a little modification of the=20 >yaffs_WriteNewChunkToNAND, to completely avoid chunks read=20 >after write (the original code avoids yaffs_VerifyCompare only). >Check the following code against cvs one. > > >static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct=20 >*dev, const __u8 *data, yaffs_Spare *spare,int useReserve) >{ > int chunk; > > int writeOk =3D 1; > int attempts =3D 0; > > do{ > chunk =3D yaffs_AllocateChunk(dev,useReserve); > > if(chunk >=3D 0) > { > > // First check this chunk is erased... >#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK > writeOk =3D yaffs_CheckChunkErased(dev,chunk); >#endif > if(!writeOk) > { > T(YAFFS_TRACE_ERROR,(TSTR("**>>=20 >yaffs chunk %d was not erased" TENDSTR),chunk)); > } > else > { > writeOk =3D =20 >yaffs_WriteChunkToNAND(dev,chunk,data,spare); > } > attempts++; >#ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY > if(writeOk) > { > unsigned char=20 >rbData[YAFFS_BYTES_PER_CHUNK]; > yaffs_Spare rbSpare; > > // Readback & verify > // If verify fails, then delete=20 >this chunk and try again > // To verify we compare=20 >everything except the block and > // page status bytes. > // NB We check a raw read=20 >without ECC correction applied > > =09 >yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0); > > =09 >if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare)) > { > // Didn't verify > =09 >T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write verify failed on=20 >chunk %d" TENDSTR), chunk)); > > writeOk =3D 0; > } > > } >#endif > if(writeOk) > { > // Copy the data into the write buffer. > // NB We do this at the end to=20 >prevent duplicates in the case of a write error. > //Todo > =09 >yaffs_HandleWriteChunkOk(dev,chunk,data,spare); > } > else > { > yaffs_HandleWriteChunkError(dev,chunk); > } > } > > } while(chunk >=3D 0 && ! writeOk); > > if(attempts > 1) > { > T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write=20 >required %d attempts" TENDSTR),attempts)); > dev->nRetriedWrites+=3D (attempts - 1); > } > > return chunk; >} > > >To reduce writes I think you must wait (or aid ;) for Yaffs2,=20 >which will use a zero page rewrites to spare area and will=20 >have generally better performance over Yaffs. >Look at www.aleph1.co.uk/yaffs/yaffs2.html > > >Regards >Adamo > > > >> -----Original Message----- >> From: yaffs-admin@stoneboat.aleph1.co.uk >> [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel >> Gustafsson >> Sent: luned=EC 11 ottobre 2004 14.47 >> To: yaffs@stoneboat.aleph1.co.uk >> Subject: [Yaffs] Optimizing the number of reads and writes to flash >>=20 >>=20 >>=20 >>=20 >> I am using yaffs/direct and I want to reduce the reads and=20 >> writes towards >> the flash to an absolute minimum. I do not want any=20 >> verifications of flash >> etc. I don not want to use ECC. >>=20 >> I would greatly appreatiate any tips regarding the above=20 >> issue but also how >> to reduce the footprint in RAM and size.=20 >>=20 >> Further more I am interested in some documetation what=20 >> happens (reads/writes >> to flash) when performing some simple fs operations like=20 >> read/write/open >> etc. >>=20 >>=20 >> I hope someone have the answers I am looking for, >>=20 >> Best Regards >> Daniel Gustavsson >>=20 >>=20 >> _______________________________________________ >> yaffs mailing list >> yaffs@stoneboat.aleph1.co.uk >> http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >>=20 > > From daniel.gustafsson@space.se Mon Oct 11 16:13:32 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Mon, 11 Oct 2004 17:13:32 +0200 Subject: [Yaffs] Reducing footprint in RAM Message-ID: <200410111508.i9BF8PrB016369@space.se> I am using yaffs/direct. I need to reduce the footprint in RAM a lot (maybe by not storing the complete tnode-list in RAM and increasing pagesize etc.). Any suggestions how to do that??? If you restart the system and you have a flash memory of 1GB, does the file system then have to read the whole memory to create the original state??? I need as much information as possible to establish a good starting point before trying to optimize. Regards Daniel Gustavsson From nick@cecomputing.co.uk Mon Oct 11 16:36:22 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Mon, 11 Oct 2004 16:36:22 +0100 Subject: [Yaffs] Reducing footprint in RAM In-Reply-To: <200410111508.i9BF8PrB016369@space.se> Message-ID: > I am using yaffs/direct. >=20 > I need to reduce the footprint in RAM a lot (maybe by not storing the > complete tnode-list in RAM and increasing pagesize etc.). Any = suggestions > how to do that??? >=20 > If you restart the system and you have a flash memory of 1GB,=20 > does the file > system then have to read the whole memory to create the original = state??? >=20 > I need as much information as possible to establish a good starting = point > before trying to optimize. >=20 In my variant on bootldr, I use a small yaffs partition to house a linux = zImage. This has a very rapid mount time and low ram footprint. This = could be a way of lightening the initial ram burden if you are using = yaffs-direct before booting an os. If you are severely ram cramped and/or not booting an os then I guess = you could split the nand up into small partitions and mount/unmount each = one as needed. Its a bit clumsy but its an option. Nick --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.773 / Virus Database: 520 - Release Date: 05/10/2004 From areggiani@ferrari.it Mon Oct 11 16:48:00 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Mon, 11 Oct 2004 17:48:00 +0200 Subject: [Yaffs] Reducing footprint in RAM Message-ID: Hi Daniel, > I need to reduce the footprint in RAM a lot (maybe by not storing the > complete tnode-list in RAM and increasing pagesize etc.). Any=20 > suggestions > how to do that??? has reported on the Yaffs2 document page = www.aleph1.co.uk/yaffs/yaffs2.html , there's a work in progress to be = able to arrange multiple pages in one chunk. In this way you don't have to keep track of each page, but only of = pages/pages_in_chunk reducing the ram footprint of the same factor. I really don't know the state of the art of this work, but I think it = could be done with some tricks to the current yaffs code. > If you restart the system and you have a flash memory of 1GB,=20 > does the file > system then have to read the whole memory to create the=20 > original state??? No, you need to access only the spare area of each page/chunk. The less the chunks are, the faster is the yaffs_Scan function. Hope to be helpfull cu Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Daniel > Gustafsson > Sent: luned=EC 11 ottobre 2004 17.14 > To: yaffs@stoneboat.aleph1.co.uk > Subject: [Yaffs] Reducing footprint in RAM >=20 >=20 >=20 >=20 > I am using yaffs/direct. >=20 > I need to reduce the footprint in RAM a lot (maybe by not storing the > complete tnode-list in RAM and increasing pagesize etc.). Any=20 > suggestions > how to do that??? >=20 > If you restart the system and you have a flash memory of 1GB,=20 > does the file > system then have to read the whole memory to create the=20 > original state??? >=20 > I need as much information as possible to establish a good=20 > starting point > before trying to optimize. >=20 > Regards > Daniel Gustavsson >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From manningc2@actrix.gen.nz Mon Oct 11 23:16:05 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Tue, 12 Oct 2004 11:16:05 +1300 Subject: [Yaffs] Reducing footprint in RAM In-Reply-To: <200410111508.i9BF8PrB016369@space.se> References: <200410111508.i9BF8PrB016369@space.se> Message-ID: <20041011221254.F1C395F0A@blood.actrix.co.nz> On Tuesday 12 October 2004 04:13, Daniel Gustafsson wrote: > I am using yaffs/direct. > > I need to reduce the footprint in RAM a lot (maybe by not storing the > complete tnode-list in RAM and increasing pagesize etc.). Any suggestio= ns > how to do that??? > > If you restart the system and you have a flash memory of 1GB, does the = file > system then have to read the whole memory to create the original state?= ?? > > I need as much information as possible to establish a good starting poi= nt > before trying to optimize. > When I designed YAFFS I tried to keep the footprint as low as I could. I=20 believe that YAFFS uses less RAM than any comparable file system.=20 At present yaffs uses a bit over 4kbytes per 1Mbytes of flash. When you g= et=20 into hundreds of MBytes of NAND, this can add up to quite a lot. Most of the RAM is used by the Tnode tree. Each "leaf" on the tree is a U= 16=20 for each "chunk" (ie.512 bytes) of NAND that is currently in a file.=20 YAFFS2 (in late development) allows you to use larger chunks. So if you u= se,=20 say, 4kbyte chunks then you only need approx one eighth of the RAM since=20 there will be one eighth the number of chunks for the same flash size. If you can think of useful ways to reduce RAM footprint, I would be more = than=20 willing to listen. When the file system is mounted, the whole NAND is scanned to build up th= e=20 state. This scanning reads just the spare areas in NAND where all the tag= s=20 are kept. Empty blocks do not need to be scanned. This takes some time, b= ut=20 again I believe this to be faster than any other comparable file system. It is possible to do some sort of "checkpointing" scheme that would save = away=20 the information so that it could be retrieved on remount without having = to=20 scan the whole NAND. However, that's going to require some development :-= ). -- Charles From manningc2@actrix.gen.nz Tue Oct 12 05:36:45 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Tue, 12 Oct 2004 17:36:45 +1300 Subject: [Yaffs] problem with object (file) creation In-Reply-To: <20041010182318.CAD555277@blood.actrix.co.nz> References: <20041010182318.CAD555277@blood.actrix.co.nz> Message-ID: <20041012043526.DED5564DD@blood.actrix.co.nz> A quick follow up... To summarise what seems to be going on, the problem is occuring because t= here=20 is an inode in the cache for an obect that no longer exists in YAFFS. Whe= n=20 asked to create a new object, YAFFS choses an objectId (same as an inode=20 number) that is the same as the one in cache. This means that when iget()= is=20 called, no callback happens to yaffs_read_inode and the new object's info= is=20 not associated with the inode in the cache and we get an inconsistency. This happens very infrequently because the bucket size is relatively larg= e=20 (256), though Michael has made a useful test case below. It occurs to me= =20 that by changing the bucket size to a smaller power of 2 (say 4), it will= =20 become easier to force the issue. Michael has also provided a patch that would seem to get around the probl= em=20 by aborting an object creation when the inode refernce count is too high=20 (which means that this problem would have occurred). While this hack woul= d=20 seem to work, I think it is, as Michael says, a "dirty hack" and cause ex= tra=20 writes to flash etc. I would prefer to do one of the following: 1) At the time of generating the objectId (inode number) for a new object= ,=20 first check that the object does not relate to an existing inode in the c= ache=20 and don't allocate that number if there is a conflict. 2)Don't just rely on the callback to yaffs_read_inode to fill out the ino= de=20 details. Also fill them out for other cases. The problem with this is th= at=20 we then end up with the thing in the cache being revalidated and cross-li= nked=20 to a differnt object which seems rather unhealthy to me! So I don't think= =20 this will work. 3) Stop trying to reuse object ids. Instead of just always trying to reus= e=20 the lowest value objectId in any bucket, we can rather keep allocating=20 upwards and wrap around when the objectId space is depleated (18 bits =3D= =3D=20 0x40000). While this would not absolutely guarantee we don't get reuse, i= t=20 would reduce the odds by a significant amount. 4) When we delete an object keep the object id for that object "in use" u= ntil=20 the last iput releases it from the cache. While (3) will likely work very well it does leave a bitter taste in the=20 mouth. I'd prefer (4) and (1) in that order. I don't trust (2), so dismis= s=20 that immediately. Comments/thoughts more than welcome. -- Charles On Monday 11 October 2004 07:26, Charles Manning wrote: > Michael > > Thank you very much for this. I too have struggled to sometimes get my = head > around the vfs and how it works and the input from various people has b= eem > very useful. > > I will be investigating this ASAP. > > Can you tell me what version of Linux you're using here? Some of these > things might be version specific. > > Thanx > > -- CHarles > > On Saturday 09 October 2004 00:54, Michael Fischer wrote: > > Hello everyone, > > i am new to the list as well as to the linux vfs/fs stuff and i am > > looking for any help/comments on the following: > > In some cases when copying a big number of files i got complains from= the > > cp command that a newly created file was a directory thus not beeing = able > > to write data into it. The following steps would reproduce the behavi= or: > > - delete a directory with many files and subdirs recursively. > > - have some process which still has a reference to the dir or some fi= le > > open (e.g. cd /test; rm -rf /test) > > - move or copy back the deleted dir-tree from some backup location. > > > > Debuging it further i found that the yaffs layer deletes objects whic= h > > due to references still exist in the inode cache of the vfs layer. > > Looking into the code i found that yaffs_fs.c/yaffs_mknod =3D> > > __yaffs_mknod =3D> yaffs_FindNiceObjectBucket returns the object id . > > Depending on > > YAFFS_NOBJECT_BUCKETS you probably get an id of a recently deleted > > object. When afterwards calling yaffs_get_inode(iget4) you get an > > possibly allready existing inode (inode reference count > 1). This in= ode > > doesnt get initialized so attributes like directory are still valid a= nd > > cause the described behavior. > > > > so a small patch (read: fast dirty hack) of yaffs_mknod (see below) d= oes > > solve the problem in my case: > > > > doitagain: > > obj =3D __yaffs_mknod ( parent, dentry, mode, rdev); > > if(obj) > > { > > inode =3D yaffs_get_inode(dir->i_sb, mode, rdev, obj); > > T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count =3D > > %d\n",obj->objectId,atomic_read(&inode->i_count))); > > if (atomic_read(&inode->i_count) > 1) { > > iput(inode); > > yaffs_DeleteFile(obj); > > goto doitagain; > > } > > d_instantiate(dentry, inode); > > error =3D 0; > > } > > else > > { > > > > ok, as mentioned before i am new to all this therefore i am of cause > > unsure if i havnt overseen something or this is fixed in later versio= ns > > or how a clean patch could look like. > > > > Thanks a lot for any comments and best regards, > > Michael > > > > > > > > > > > > > > > > _______________________________________________ > > yaffs mailing list > > yaffs@stoneboat.aleph1.co.uk > > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From domenico.di-tullio@st.com Tue Oct 12 09:44:12 2004 From: domenico.di-tullio@st.com (Domenico DI TULLIO) Date: Tue, 12 Oct 2004 10:44:12 +0200 Subject: [Yaffs] Porting YAFFS on Linux Message-ID: <002601c4b037$a729c980$a83682a4@nap.st.com> Dear All, I would know the file that works as interface between Linux OS and API = function of YAFFS. Can you help me, please? Thank you very much, Domenico From nick@cecomputing.co.uk Tue Oct 12 09:47:37 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Tue, 12 Oct 2004 09:47:37 +0100 Subject: [Yaffs] problem with object (file) creation In-Reply-To: <20041012043526.DED5564DD@blood.actrix.co.nz> Message-ID: > A quick follow up... >=20 > To summarise what seems to be going on, the problem is occuring=20 > because there=20 > is an inode in the cache for an obect that no longer exists in=20 > YAFFS. When=20 > asked to create a new object, YAFFS choses an objectId (same as an = inode=20 > number) that is the same as the one in cache. This means that=20 > when iget() is=20 > called, no callback happens to yaffs_read_inode and the new=20 > object's info is=20 > not associated with the inode in the cache and we get an = inconsistency. >=20 > This happens very infrequently because the bucket size is=20 > relatively large=20 > (256), though Michael has made a useful test case below. It occurs to = me=20 > that by changing the bucket size to a smaller power of 2 (say 4), it = will=20 > become easier to force the issue. >=20 > Michael has also provided a patch that would seem to get around=20 > the problem=20 > by aborting an object creation when the inode refernce count is too = high=20 > (which means that this problem would have occurred). While this=20 > hack would=20 > seem to work, I think it is, as Michael says, a "dirty hack" and=20 > cause extra=20 > writes to flash etc. >=20 > I would prefer to do one of the following: > 1) At the time of generating the objectId (inode number) for a=20 > new object,=20 > first check that the object does not relate to an existing inode=20 > in the cache=20 > and don't allocate that number if there is a conflict. > 2)Don't just rely on the callback to yaffs_read_inode to fill out=20 > the inode=20 > details. Also fill them out for other cases. The problem with=20 > this is that=20 > we then end up with the thing in the cache being revalidated and=20 > cross-linked=20 > to a differnt object which seems rather unhealthy to me! So I don't = think=20 > this will work. > 3) Stop trying to reuse object ids. Instead of just always trying=20 > to reuse=20 > the lowest value objectId in any bucket, we can rather keep allocating = > upwards and wrap around when the objectId space is depleated (18 bits = =3D=3D=20 > 0x40000). While this would not absolutely guarantee we don't get=20 > reuse, it=20 > would reduce the odds by a significant amount. > 4) When we delete an object keep the object id for that object=20 > "in use" until=20 > the last iput releases it from the cache. >=20 > While (3) will likely work very well it does leave a bitter taste in = the=20 > mouth. I'd prefer (4) and (1) in that order. I don't trust (2),=20 > so dismiss=20 > that immediately. >=20 > Comments/thoughts more than welcome. >=20 > -- Charles I entirely agree with Charles.=20 One (possibly dim) query. Why is the reference count not zero anyway = once the object is deleted? Does the vfs hold an additional reference? = As you say (4), unless it is zero then it should not be considered not = to be in use. (3) is just not good enough especially for TCL who are using yaffs in = the medical/assistive market. It will also mean that any errors/failures = of a system will leave a "what if its that yaffs bug again?" uncertainty = lurking. (1) is ok. Reading/writing NAND is the bottleneck so a cache search = won't add anything too noticeable I guess. Nick From daniel.gustafsson@space.se Tue Oct 12 09:54:35 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Tue, 12 Oct 2004 10:54:35 +0200 Subject: [Yaffs] ECC error with ECC turned off Message-ID: <200410120849.i9C8nQx9025690@space.se> When I run yaffs/direct and create, write, closes a file I always get an ECC error (**>>eec error fix performed on chunk XXX; Block 1 marked for retirement) regardless if I have the ECC turned off. Why??? How does the reserved blocks in the device work? Which blocks are reserved? Some simple explanation how the reserved and startblock work would be nice. //Daniel From nick@cecomputing.co.uk Tue Oct 12 10:12:17 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Tue, 12 Oct 2004 10:12:17 +0100 Subject: [Yaffs] Porting YAFFS on Linux In-Reply-To: <002601c4b037$a729c980$a83682a4@nap.st.com> Message-ID: >=20 > Dear All, >=20 > I would know the file that works as interface between Linux OS=20 > and API function of YAFFS. >=20 see http://husaberg.toby-churchill.com/ballon for several examples. > Can you help me, please? >=20 > Thank you very much, > Domenico >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From daniel.gustafsson@space.se Tue Oct 12 15:48:21 2004 From: daniel.gustafsson@space.se (Daniel Gustafsson) Date: Tue, 12 Oct 2004 16:48:21 +0200 Subject: [Yaffs] Strange ECC Error Message-ID: <200410121443.i9CEhAx9017016@space.se> Can somebody please explain the functions below. I am using yaffs/direct, ECC turned off. When scanning the emfile during a mount there are ecc errors. void yaffs_CalcTagsECC(yaffs_Tags *tags) { // Calculate an ecc unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; unsigned i,j; unsigned ecc = 0; unsigned bit = 0; tags->ecc = 0; for(i = 0; i < 8; i++) { for(j = 1; j &0xff; j<<=1) { bit++; if(b[i] & j) { ecc ^= bit; } } } tags->ecc = ecc; %%%I always get a high value on ecc approx 64 } int yaffs_CheckECCOnTags(yaffs_Tags *tags) { unsigned ecc = tags->ecc; yaffs_CalcTagsECC(tags); ecc ^= tags->ecc; %% Now my ecc increases to approx 4096. if(ecc && ecc <= 64) { // TODO: Handle the failure better. Retire? unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; ecc--; b[ecc / 8] ^= (1 << (ecc & 7)); // Now recvalc the ecc yaffs_CalcTagsECC(tags); return 1; // recovered error } else if(ecc) { // Wierd ecc failure value %%%% I always end up here. // TODO Need to do somethiong here return -1; //unrecovered error } return 0; } //Daniel From manningc2@actrix.gen.nz Tue Oct 12 21:48:56 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 13 Oct 2004 09:48:56 +1300 Subject: [Yaffs] ECC error with ECC turned off In-Reply-To: <200410120849.i9C8nQx9025690@space.se> References: <200410120849.i9C8nQx9025690@space.se> Message-ID: <20041012204544.3B022197EB@desire.actrix.co.nz> On Tuesday 12 October 2004 21:54, Daniel Gustafsson wrote: > When I run yaffs/direct and create, write, closes a file I always get a= n > ECC error (**>>eec error fix performed on chunk XXX; Block 1 marked for > retirement) regardless if I have the ECC turned off. Why??? What do you mean by "ECC turned off"? In YAFFS you can say "USE NAND ECC" which means that YAFFS assumes the NA= ND=20 does (or the mtd driver) does its own ECC andYAFFS does not have to.=20 Otherwise, YAFFS does its own ECC calculations and will give you these er= rors=20 if the ECC does not work. If you're using YAFFS in a situation where you don't want ECC then say "U= SE=20 NAND ECC" which means that YAFFS won't do the ECC. > > How does the reserved blocks in the device work? Which blocks are reser= ved? > Some simple explanation how the reserved and startblock work would be n= ice. You cannot use block 0 of a NAND device. the start block is the first block of the device available to YAFFS. The endBlock is the last block available to YAFFS. Typically you'd use startBlock=3D1 and enbBlock =3D devices_size_in-block= -1, but=20 frequently people do things like running two yaffs partitions by doing partiton 0 start=3D1 end=3Dn partion 1 start =3D n+1 end =3D size -1 The ReservedBlocks does not reserve any particular blocks. What it says i= s=20 that yaffs should reserve this number of blocks. The reserved space serve= s=20 three purposes: * it keeps some blocks as backup in case blocks fail. * it keeps space spare to handle inflight cached data. * it keeps spare space for garbage collection. YAFFS will not mount with less than 2 reserved free. How many you want to= =20 have depends on the degree of robustness you want against serial block=20 failures. As a guideline 5 to 10 should be enough. Hope that helps -- Charles From manningc2@actrix.gen.nz Tue Oct 12 21:54:45 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 13 Oct 2004 09:54:45 +1300 Subject: [Yaffs] Strange ECC Error In-Reply-To: <200410121443.i9CEhAx9017016@space.se> References: <200410121443.i9CEhAx9017016@space.se> Message-ID: <20041012205132.9CAFB1693A@desire.actrix.co.nz> Are you getting the errors when scanning empty chunks/pages? If so, these= can=20 be safely ignored.=20 The "ECC turned off" does not apply to the tags ECC calculation, only to = the=20 data ECC calculation. -- Charles On Wednesday 13 October 2004 03:48, Daniel Gustafsson wrote: > Can somebody please explain the functions below. I am using yaffs/direc= t, > ECC turned off. > > When scanning the emfile during a mount there are ecc errors. > > > > void yaffs_CalcTagsECC(yaffs_Tags *tags) > { > // Calculate an ecc > > unsigned char *b =3D ((yaffs_TagsUnion *)tags)->asBytes; > unsigned i,j; > unsigned ecc =3D 0; > unsigned bit =3D 0; > tags->ecc =3D 0; > > for(i =3D 0; i < 8; i++) > { > for(j =3D 1; j &0xff; j<<=3D1) > { > bit++; > if(b[i] & j) > { > ecc ^=3D bit; > } > } > } > > tags->ecc =3D ecc; %%%I always > get a high value on ecc approx 64 > > > } > > int yaffs_CheckECCOnTags(yaffs_Tags *tags) > { > unsigned ecc =3D tags->ecc; > > yaffs_CalcTagsECC(tags); > > ecc ^=3D tags->ecc; %% Now my > ecc increases to approx 4096. > > if(ecc && ecc <=3D 64) > { > // TODO: Handle the failure better. Retire? > unsigned char *b =3D ((yaffs_TagsUnion *)tags)->asBytes; > > ecc--; > > b[ecc / 8] ^=3D (1 << (ecc & 7)); > > // Now recvalc the ecc > yaffs_CalcTagsECC(tags); > > return 1; // recovered error > } > else if(ecc) > { > // Wierd ecc failure value > %%%% I always end up here. > // TODO Need to do somethiong here > return -1; //unrecovered error > } > > return 0; > } > > > > //Daniel > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Tue Oct 12 22:28:23 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 13 Oct 2004 10:28:23 +1300 Subject: [Yaffs] Optimizing the number of reads and writes to flash In-Reply-To: <200410111241.i9BCfcrB027306@space.se> References: <200410111241.i9BCfcrB027306@space.se> Message-ID: <20041012224551.905ED16351@desire.actrix.co.nz> I think some of your questions might not have been answered properly. On Tuesday 12 October 2004 01:46, Daniel Gustafsson wrote: > I am using yaffs/direct and I want to reduce the reads and writes towar= ds > the flash to an absolute minimum. I do not want any verifications of fl= ash > etc. I don not want to use ECC. If you do not want to use ECC, then set useNANDECC. This means that YAFFS= =20 will not do the ECC checks on data and will rely on the media doing any E= CC=20 checks itself. This can be used in situations where you want to avoid ECC= =20 completely (eg. the ram-disk in int yaffscfg.c:yaffs_StartUp(void)) > Further more I am interested in some documetation what happens > (reads/writes to flash) when performing some simple fs operations like > read/write/open etc. The biggest number of reads is on mount to scan the media. Otherwise here's a brief run-down: open(): Reads/writes nothing unless this is a file creation. If it is a = file=20 creeation then write a new object header. flush()/close(): If the file is modified then writes an object header. Al= so=20 flushes data in cache. If this is an overwrite, then needs to read and=20 overwrite old data. read(): Reads data unless it is already in cache. write(): Small writes (sub-page) go into cache otherwise go to flash. unlink()/delete(): writes an object header to say that the object has be= en=20 deleted. Data is cleaned up by garbage collection. Garbage collection: Reads data in block being collected. Writes useful stuff back to flash. E= rase=20 flash (2ms). -- Charles From areggiani@ferrari.it Wed Oct 13 10:03:46 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Wed, 13 Oct 2004 11:03:46 +0200 Subject: [Yaffs] Porting YAFFS on Linux Message-ID: DQpBcyBhIGtlcm5lbCBtb2R1bGUgeWFmZnMgaW50ZXJmYWNlIHRvIExpbnV4IHRocm91Z2ggdGhl IGZpbGUgeWFmZnNfZnMuYywgd2hpY2ggZ2x1ZSB0aGUgeWFmZnMgY29kZSAobWFpbmx5IHlhZmZz X2d1dHMuYy9oKSB0byB0aGUgZmlsZXN5c3RlbSBBUEkuDQoNClRoZSBvdGhlciBvcHRpb24gaXMg dG8gdXNlIGRpcmVjdC95YWZmc19mcy5jIHdoaWNoIGlzIGludGVuZGVkIGZvciBlbWJlZGRlZCBz eXN0ZW1zIHdpdGhvdXQgYSBMaW51eCBrZXJuZWw7IHRoaXMgb25lIGlzbid0IGEga2VybmVsIG1v ZHVsZSBidXQgaW1wbGVtZW50IGEgeWFmZnMgQVBJIHN1aXRhYmxlIGZvciBzbWFsbCBlbnZpcm9u bWVudHMuDQpXaXRoIGl0IHlvdSBjYW4gYWxzbyB0ZXN0IHlhZmZzIGZlYXR1cmVzIGluIHRoZSBs aW51eCB1c2VyIHNwYWNlLCBieSBlbWJlZGRpbmcgaXQgaW4gYSBub3JtYWwgcHJvZ3JhbS4NCg0K Tm90ZSB0aGF0LCBhcyBpbmRpY2F0ZWQgYnkgeW91ciBzdWJqZWN0LCB5b3UgZG9uJ3QgbmVlZCBh bnkgZWZmb3J0IHRvIHBvcnQgeWFmZnMgdG8gbGludXgsIHNpbmNlIGl0IGlzIGl0cyBuYXRpdmUg ZW52aXJvbm1lbnQuDQoNClJlZ2FyZHMNCkFkYW1vDQoNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3Nh Z2UtLS0tLQ0KPiBGcm9tOiB5YWZmcy1hZG1pbkBzdG9uZWJvYXQuYWxlcGgxLmNvLnVrDQo+IFtt YWlsdG86eWFmZnMtYWRtaW5Ac3RvbmVib2F0LmFsZXBoMS5jby51a11PbiBCZWhhbGYgT2YgRG9t ZW5pY28gREkNCj4gVFVMTElPDQo+IFNlbnQ6IG1hcnRlZMOsIDEyIG90dG9icmUgMjAwNCAxMC40 NA0KPiBUbzogJ1lBRkZTIG1haWxpbmcgbGlzdCcNCj4gU3ViamVjdDogW1lhZmZzXSBQb3J0aW5n IFlBRkZTIG9uIExpbnV4DQo+IA0KPiANCj4gRGVhciBBbGwsDQo+IA0KPiBJIHdvdWxkIGtub3cg dGhlIGZpbGUgdGhhdCB3b3JrcyBhcyBpbnRlcmZhY2UgYmV0d2VlbiBMaW51eCANCj4gT1MgYW5k IEFQSSBmdW5jdGlvbiBvZiBZQUZGUy4NCj4gDQo+IENhbiB5b3UgaGVscCBtZSwgcGxlYXNlPw0K PiANCj4gVGhhbmsgeW91IHZlcnkgbXVjaCwNCj4gRG9tZW5pY28NCj4gDQo+IA0KPiBfX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXw0KPiB5YWZmcyBtYWlsaW5n IGxpc3QNCj4geWFmZnNAc3RvbmVib2F0LmFsZXBoMS5jby51aw0KPiBodHRwOi8vc3RvbmVib2F0 LmFsZXBoMS5jby51ay9jZ2ktYmluL21haWxtYW4vbGlzdGluZm8veWFmZnMNCj4gDQo= From lorenzo.parisi@st.com Wed Oct 13 12:02:22 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Wed, 13 Oct 2004 13:02:22 +0200 Subject: [Yaffs] mkyaffs Message-ID: <118dc393.8e98005a.81a3a00@mail1.agr.st.com> Hi, how to use in correct mode the utility mkyaffs? I write mkyaffs /dev/mtd8. Can I mount YAFFS on NAND without use mkyaffs? Thanks From areggiani@ferrari.it Wed Oct 13 12:34:04 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Wed, 13 Oct 2004 13:34:04 +0200 Subject: [Yaffs] Porting YAFFS on Linux Message-ID: I apologize for my last mail. Laurie said me that was almonst unreadable on most clients. Sorry again folks. > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of=20 > Reggiani, Adamo > Sent: mercoled=EC 13 ottobre 2004 11.04 > To: Domenico DI TULLIO; YAFFS mailing list > Subject: RE: [Yaffs] Porting YAFFS on Linux >=20 >=20 >=20 > As a kernel module yaffs interface to Linux through the file=20 > yaffs_fs.c, which glue the yaffs code (mainly yaffs_guts.c/h)=20 > to the filesystem API. >=20 > The other option is to use direct/yaffs_fs.c which is=20 > intended for embedded systems without a Linux kernel; this=20 > one isn't a kernel module but implement a yaffs API suitable=20 > for small environments. > With it you can also test yaffs features in the linux user=20 > space, by embedding it in a normal program. >=20 > Note that, as indicated by your subject, you don't need any=20 > effort to port yaffs to linux, since it is its native environment. >=20 > Regards > Adamo >=20 >=20 > > -----Original Message----- > > From: yaffs-admin@stoneboat.aleph1.co.uk > > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Domenico DI > > TULLIO > > Sent: marted=EC 12 ottobre 2004 10.44 > > To: 'YAFFS mailing list' > > Subject: [Yaffs] Porting YAFFS on Linux > >=20 > >=20 > > Dear All, > >=20 > > I would know the file that works as interface between Linux=20 > > OS and API function of YAFFS. > >=20 > > Can you help me, please? > >=20 > > Thank you very much, > > Domenico > >=20 > >=20 From lorenzo.parisi@st.com Wed Oct 13 13:55:26 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Wed, 13 Oct 2004 14:55:26 +0200 Subject: [Yaffs] Build utility mkyaffs Message-ID: Hi, how to build the utility mkyaffs for kernel 2.6.9? When I run make under dir /yaffs/utils, I receive some errors. Thanks. From wookey@aleph1.co.uk Wed Oct 13 14:17:55 2004 From: wookey@aleph1.co.uk (Wookey) Date: Wed, 13 Oct 2004 14:17:55 +0100 Subject: [Yaffs] Re: Build utility mkyaffs In-Reply-To: References: Message-ID: <20041013131755.GE25877@xios> +++ Lorenzo PARISI [04-10-13 14:55 +0200]: > Hi, > > how to build the utility mkyaffs for kernel 2.6.9? > > When I run make under dir /yaffs/utils, I receive some > errors. Charles posted a fix for this a couple of days ago to this list I think. He probably checked it into CVS - have you tried updating? If that doesn't work, then this should do the trick: ------- I recently fiddled around with things in an effort to get the code ready for inclusion in the Linux mainstream. I did two main things: 1) Pulled the WINCE and Direct stuff out of yportenv.h into their own sub-includes. 2) Replaced the YAFFS_CONFIG_KERNEL_2_5 with "proper" Linux version macros. Unfortunately I did not test the changes sufficiently for non-kernel cases. I've straightened things out and now get good compiles for kernel, utils, direct. I have not yet tried WinCE. All the Linux version specific stuff (relating to CURRENT_TIME) has been puilled out of yaffs_guts.c and has been put into the appropriate yportenv.h section. The include dependencies have been straightened out. If there are still problems please yell. -- CHarles Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From Charles.Manning@trimble.co.nz Wed Oct 13 18:23:39 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Thu, 14 Oct 2004 06:23:39 +1300 Subject: [Yaffs] mkyaffs Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01548F8B@nzc-ap-xch-01.ap.trimblecorp.net> mkyaffs "formats" the NAND for yaffs and optionally installs an image file. To format a NAND for yaffs, all you need to do is to erase all the blocks (except bad blocks). Thus, if the NAND is known to be erased then there is no need to run mkyaffs. -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Lorenzo PARISI Sent: Thursday, 14 October 2004 12:02 a.m. To: YAFFS mailing list Subject: [Yaffs] mkyaffs Hi, how to use in correct mode the utility mkyaffs? I write mkyaffs /dev/mtd8. Can I mount YAFFS on NAND without use mkyaffs? Thanks _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Wed Oct 13 19:24:17 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Thu, 14 Oct 2004 07:24:17 +1300 Subject: [Yaffs] problem with object (file) creation In-Reply-To: <20041010182318.CAD555277@blood.actrix.co.nz> References: <20041010182318.CAD555277@blood.actrix.co.nz> Message-ID: <20041013182103.B8B9F1683D@desire.actrix.co.nz> A quick update: OK, I've worked through the reasoning as to what is going on. It is as=20 Michael says, YAFFS is forgetting about objects with cached inodes and th= is=20 causes things to get out of whack. I've been over to the linux-fsdevel folks and have received some advice. One of the possible solutions involves the use of ilookup(). I am loath t= o=20 use this as it is not available in older kernels (eg.2.4.18). I am acute= ly=20 aware that many embedded application use older kernels and it is unrealis= tic=20 to say "just upgrade". The solution I'm working on (ready in the next few days) does not use=20 ilookup(), but rather extends the code in yaffs_delete_inode. In the meantime, if you're being help up by things, try the patchlette th= at=20 Michael gives. -- Charles=20 On Monday 11 October 2004 07:26, Charles Manning wrote: > Michael > > Thank you very much for this. I too have struggled to sometimes get my = head > around the vfs and how it works and the input from various people has b= eem > very useful. > > I will be investigating this ASAP. > > Can you tell me what version of Linux you're using here? Some of these > things might be version specific. > > Thanx > > -- CHarles > > On Saturday 09 October 2004 00:54, Michael Fischer wrote: > > Hello everyone, > > i am new to the list as well as to the linux vfs/fs stuff and i am > > looking for any help/comments on the following: > > In some cases when copying a big number of files i got complains from= the > > cp command that a newly created file was a directory thus not beeing = able > > to write data into it. The following steps would reproduce the behavi= or: > > - delete a directory with many files and subdirs recursively. > > - have some process which still has a reference to the dir or some fi= le > > open (e.g. cd /test; rm -rf /test) > > - move or copy back the deleted dir-tree from some backup location. > > > > Debuging it further i found that the yaffs layer deletes objects whic= h > > due to references still exist in the inode cache of the vfs layer. > > Looking into the code i found that yaffs_fs.c/yaffs_mknod =3D> > > __yaffs_mknod =3D> yaffs_FindNiceObjectBucket returns the object id . > > Depending on > > YAFFS_NOBJECT_BUCKETS you probably get an id of a recently deleted > > object. When afterwards calling yaffs_get_inode(iget4) you get an > > possibly allready existing inode (inode reference count > 1). This in= ode > > doesnt get initialized so attributes like directory are still valid a= nd > > cause the described behavior. > > > > so a small patch (read: fast dirty hack) of yaffs_mknod (see below) d= oes > > solve the problem in my case: > > > > doitagain: > > obj =3D __yaffs_mknod ( parent, dentry, mode, rdev); > > if(obj) > > { > > inode =3D yaffs_get_inode(dir->i_sb, mode, rdev, obj); > > T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count =3D > > %d\n",obj->objectId,atomic_read(&inode->i_count))); > > if (atomic_read(&inode->i_count) > 1) { > > iput(inode); > > yaffs_DeleteFile(obj); > > goto doitagain; > > } > > d_instantiate(dentry, inode); > > error =3D 0; > > } > > else > > { > > > > ok, as mentioned before i am new to all this therefore i am of cause > > unsure if i havnt overseen something or this is fixed in later versio= ns > > or how a clean patch could look like. > > > > Thanks a lot for any comments and best regards, > > Michael > > > > > > > > > > > > > > > > _______________________________________________ > > yaffs mailing list > > yaffs@stoneboat.aleph1.co.uk > > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From ulla@bluewatersys.com Wed Oct 13 23:39:39 2004 From: ulla@bluewatersys.com (Ulla) Date: Thu, 14 Oct 2004 10:39:39 +1200 Subject: [Yaffs] CONFIG_YAFFS_USE_GENERIC_RW Message-ID: <200410141139.39627.ulla@bluewatersys.com> Hi, I am using yaffs (CVS) (linux 2.6.8.1, mtd-snapshot: 20041005), and I am ab= le=20 to mount the device properly, to write to the flash and erase from the flas= h.=20 But with CONFIG_YAFFS_USE_GENERIC_RW disabled copying back (or cat) doesn't= =20 work, it is running in an endless loop. For example, catting a simple text= =20 file will endlessly repeat the contents of that file. Copying a file will= =20 not end & create a huge file at the destination. By enabling=20 CONFIG_YAFFS_USE_GENERIC_RW everything is ok. Can someone explain what are= =20 the benefits of disabling CONFIG_YAFFS_USE_GENERIC_RW (like it is in the=20 default Makefile) and what are the exact differences between generic_rw and= =20 yaffs_rw? Thanks a lot Ulla =2D-=20 Bluewater Systems Ltd - ARM Technology Solution Centre =A0 =A0 =A0 =A0 Ulrike Eisenmann=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 Bluewater Systems Ltd Phone: +64 3 3779127 (Aus +1 800 148 751) =A0 =A0 =A0 Level 17, 119 Armagh = St =46ax: =A0 +64 3 3779135 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0PO Box 13889 Email: ulla@bluewatersys.com =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0Christchu= rch Web: =A0 http://www.bluewatersys.com =A0 =A0 =A0 =A0 =A0 =A0 =A0New Zealand From Charles.Manning@trimble.co.nz Thu Oct 14 00:12:36 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Thu, 14 Oct 2004 12:12:36 +1300 Subject: [Yaffs] CONFIG_YAFFS_USE_GENERIC_RW Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01548F96@nzc-ap-xch-01.ap.trimblecorp.net> This is a historic thing. USE_GENERIC_RW uses the Linux page cache for read/write. This means that = the Linux generic_read and generic_write functions are used which and = YAFFS supplies the read_page write_page calls. Not defining USE_GENERIC_RW directly implements read/write without using = the page cache. The direct read/write stuff was iimplemented first, and I followed it by = generic read/write when memory mapping was implemented. During the = transition both options worked. Things have now moved on and not = defining USE_GENERIC_RW is broken, with no real motivation to fix it.=20 Ie. You should always define USE_GENERIC_RW.=20 This comes up every couple of months on the list. I guess I should pull = it out. -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk = [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Ulla Sent: Thursday, 14 October 2004 11:40 a.m. To: yaffs@stoneboat.aleph1.co.uk Subject: [Yaffs] CONFIG_YAFFS_USE_GENERIC_RW Hi, I am using yaffs (CVS) (linux 2.6.8.1, mtd-snapshot: 20041005), and I am = able=20 to mount the device properly, to write to the flash and erase from the = flash.=20 But with CONFIG_YAFFS_USE_GENERIC_RW disabled copying back (or cat) = doesn't=20 work, it is running in an endless loop. For example, catting a simple = text=20 file will endlessly repeat the contents of that file. Copying a file = will=20 not end & create a huge file at the destination. By enabling=20 CONFIG_YAFFS_USE_GENERIC_RW everything is ok. Can someone explain what = are=20 the benefits of disabling CONFIG_YAFFS_USE_GENERIC_RW (like it is in the = default Makefile) and what are the exact differences between generic_rw = and=20 yaffs_rw? Thanks a lot Ulla --=20 Bluewater Systems Ltd - ARM Technology Solution Centre =A0 =A0 =A0 =A0 Ulrike Eisenmann=A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 Bluewater Systems Ltd Phone: +64 3 3779127 (Aus +1 800 148 751) =A0 =A0 =A0 Level 17, 119 = Armagh St Fax: =A0 +64 3 3779135 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0PO Box 13889 Email: ulla@bluewatersys.com =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0Christchurch Web: =A0 http://www.bluewatersys.com =A0 =A0 =A0 =A0 =A0 =A0 =A0New = Zealand _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk = http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From abhishek.b@lgsoftindia.com Thu Oct 14 07:52:36 2004 From: abhishek.b@lgsoftindia.com (Abhishek Bhattacharya) Date: Thu, 14 Oct 2004 12:22:36 +0530 Subject: [Yaffs] [Yaffs]bad sector control Message-ID: This is a multi-part message in MIME format. ------_=_NextPart_001_01C4B1BA.6462DA4B Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hello everyone I am new to yaffs! just going through the code, I wanted to know , how = do you take care of bad sector management? The garbage collection aspect = is pretty straight forward, but not quite clear about bad sector? Any = info please? By the way, I am going through yaffs direct source code. regards abhishek ------_=_NextPart_001_01C4B1BA.6462DA4B Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable [Yaffs]bad sector control

Hello everyone

I am new to yaffs! just going through = the code, I wanted to know , how do you take care of bad sector = management? The garbage collection aspect is pretty straight forward, = but not quite clear about bad sector? Any info please?

By the way, I am going through yaffs = direct source code.
regards
abhishek

------_=_NextPart_001_01C4B1BA.6462DA4B-- From fischi@epygi.de Thu Oct 14 09:52:23 2004 From: fischi@epygi.de (Michael Fischer) Date: Thu, 14 Oct 2004 10:52:23 +0200 Subject: [Yaffs] problem with object (file) creation In-Reply-To: <20041013182103.B8B9F1683D@desire.actrix.co.nz> Message-ID: Hello Charles, > > OK, I've worked through the reasoning as to what is going on. It is as > Michael says, YAFFS is forgetting about objects with cached > inodes and this causes things to get out of whack. > > I've been over to the linux-fsdevel folks and have received some advice. > > One of the possible solutions involves the use of ilookup(). I am > loath to use this as it is not available in older kernels (eg.2.4.18). I > am acutely aware that many embedded application use older kernels and it is > unrealistic to say "just upgrade". > > The solution I'm working on (ready in the next few days) does not use > ilookup(), but rather extends the code in yaffs_delete_inode. thanks a lot for your digging into this. Let me know if i can be of any help in testing your fixes in the environment i have here. > > In the meantime, if you're being help up by things, try the > patchlette that Michael gives. if its more convenient and someone is interessted please contact me for a "real patch" instead of the code sniplet i posted. Best regards, Michael From timm@ipi.ac.ru Thu Oct 14 14:05:44 2004 From: timm@ipi.ac.ru (Timofey V. Bondarenko) Date: Thu, 14 Oct 2004 17:05:44 +0400 Subject: [Yaffs] Busy inodes and memry leak Message-ID: <416E79A8.9080906@ipi.ac.ru> Hello. Help me please. I've pulled yaffs into uclinux 2.6.8 kernel. It works, but there is 2 strange thing: 1st: mount -t yaffs /dev/mtdblock1 /mnt yaffs: dev is 32505857 name is "mtdblock1" ls /mnt #or make another access umount /mnt VFS: Busy inodes after umount. Self-destruct in 5 seconds. Have a nice day... The last line bother me, though nothing bad happened, i can mount/use/umount the flash several times. 2nd problem is more serious. I loose memory when i'm working on mounted yaffs. After each run of a command such as 'cp' or 'cmp' the /proc/meminfo shows the 'MemFree' is decremented and 'Cached' is incremented by a roughly filesize of copyed/compared file. It happened even when i do 'cp the-same-file /dev/null' several times. The memory is never freed, even after umount. Finally, i can't run a new processes due to insufficient memory. Note, the uclinux is a no-MMU platform, so there is no virtual memory. I'm not sure at all is it a yaffs' bug. I'm just don't know where to dig and how is fs cahe controlled. May anyone point me a direction? Regards. Timofei. From manningc2@actrix.gen.nz Thu Oct 14 21:45:05 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 15 Oct 2004 09:45:05 +1300 Subject: [Yaffs] [Yaffs]bad sector control In-Reply-To: References: Message-ID: <20041014204201.00B587899@blood.actrix.co.nz> YAFFS tracks bad blocks by scanning for bad block markers at boot time. T= hese=20 blocks are then not used. Any errors on blocks that occur during runtime are flagged. When the bloc= k is=20 garbage collected, the data is copied off and instead of erasing and=20 recycling the block it is marked bad and never used again. -- CHarles On Thursday 14 October 2004 19:52, Abhishek Bhattacharya wrote: > Hello everyone > > I am new to yaffs! just going through the code, I wanted to know , how = do > you take care of bad sector management? The garbage collection aspect i= s > pretty straight forward, but not quite clear about bad sector? Any info > please? By the way, I am going through yaffs direct source code. > regards > abhishek From jsudeep@yahoo.co.in Fri Oct 15 00:43:39 2004 From: jsudeep@yahoo.co.in (Sudeep Jain) Date: Thu, 14 Oct 2004 16:43:39 -0700 (PDT) Subject: [Yaffs] YAFFS, DOC - newbie questions In-Reply-To: <20041014204201.00B587899@blood.actrix.co.nz> Message-ID: <20041014234339.14092.qmail@web8505.mail.in.yahoo.com> hello, As part of my masters project, I am planning to implement a new flash file system that shall be log structured in nature. The goal is not to have a production quality file system, but something that allows me to demonstrate and contribute one or two key ideas, and get results about optimizing writes/reads/erases etc. As Ive never done any kernel hacking before, neither have I worked with flash memory, so I have no idea as to how difficult/easy this job is going to be. >From the hardware aspect, I need a flash memory package that a) has multiple flash chips within. (I need at least 3, preferably 4) b) which hooks up into a standard interface (say IDE/USB) c) allows me access to write data on whichever (chip, block, page) I want to. d) Has all the lower level drivers in a pretty stable condition. >From these requirements, it appears that the M-Systems Disk on Chip devices are the best, as they are supported by MTD (are they ?), they hook up into a standard IDE interface, dont emulate a hard disk, and hopefuly (at least the larger disk sizes) have multiple flash chips inside which I can then access in parallel. Questions 1) Can the DOC devices be changed to allow access by the host system at a (chip, block, page) level ? 2) Do the MTD drivers work with DOC devices, and can they provide this level of access ? 3) Do the MTD devices have multiple NAND chips inside ? How do I find how many there are ? Thanks Sudeep __________________________________ Do you Yahoo!? Take Yahoo! Mail with you! Get it on your mobile phone. http://mobile.yahoo.com/maildemo From manningc2@actrix.gen.nz Fri Oct 15 01:19:12 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 15 Oct 2004 13:19:12 +1300 Subject: [Yaffs] YAFFS, DOC - newbie questions In-Reply-To: <20041014234339.14092.qmail@web8505.mail.in.yahoo.com> References: <20041014234339.14092.qmail@web8505.mail.in.yahoo.com> Message-ID: <20041015001554.06AF4470F@blood.actrix.co.nz> Hey Sandeep This sounds like an interesting project. I will be interested in hearing=20 about your results. Any useful things you come up with will be appreciate= d. The questions you ask below are mtd questions more than YAFFS ones, but I= =20 will give some answers below. If you're really interested in the filesystem algorithms themselves, then= I=20 suggest you try build the file system in userspace (like I have with yaff= s=20 direct). This is far easier/faster to debug and develop than in kernel sp= ace.=20 It also means you don't spend most of your time trying to figure outhow t= o=20 hook up with the Linux VFS. I do all the algorithmic (ie yaffs_guts.c) development using yaffs direct= and=20 a nand-on-disk emulation or nand-on-ram emulation. See yaffs/direct/filee= m.c In kernel space I also use yaffsram which uses a ram emulation to allow y= ou=20 to play with YAFFS in the kernel without having to worry about NAND suppo= rt.=20 THis makes it very easy to use it on a PC. On Friday 15 October 2004 12:43, Sudeep Jain wrote: > hello, > > As part of my masters project, I am planning to > implement a new flash file system that shall be log > structured in nature. The goal is not to have a > production quality file system, but something that > allows me to demonstrate and contribute one or two key > ideas, and get results about optimizing > writes/reads/erases etc. As Ive never done any kernel > hacking before, neither have I worked with flash > memory, so I have no idea as to how difficult/easy > this job is going to be. > > From the hardware aspect, I need a flash memory > package that > > a) has multiple flash chips within. (I need at least > 3, preferably 4) > b) which hooks up into a standard interface (say > IDE/USB) > c) allows me access to write data on whichever (chip, > block, page) I want to. > d) Has all the lower level drivers in a pretty stable > condition. > > From these requirements, it appears that the M-Systems > Disk on Chip devices are the best, as they are > supported by MTD (are they ?), they hook up into a > standard IDE interface, dont emulate a hard disk, and > hopefuly (at least the larger disk sizes) have > multiple flash chips inside which I can then access in > parallel. Some/most DOC devices are suypported by MTD. You can also use SmartMedia or XD devices. These are just packaged NAND c= hips. > > Questions > 1) Can the DOC devices be changed to allow access by > the host system at a (chip, block, page) level ? > 2) Do the MTD drivers work with DOC devices, and can > they provide this level of access ? Yes, DOC can be accessed as NAND. > 3) Do the MTD devices have multiple NAND chips inside > ? How do I find how many there are ? MTD can support multiple devices. It has two very nifty peices of softwar= e: mtdconcat: allows multiple devices to be concatenated to look like one de= vice. mtdpart: allows a single device to be split up into multiple logical devi= ces. I hope some of that helps. -- Charles From wookey@aleph1.co.uk Fri Oct 15 01:40:32 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 15 Oct 2004 01:40:32 +0100 Subject: [Yaffs] Re: YAFFS, DOC - newbie questions In-Reply-To: <20041014234339.14092.qmail@web8505.mail.in.yahoo.com> References: <20041014204201.00B587899@blood.actrix.co.nz> <20041014234339.14092.qmail@web8505.mail.in.yahoo.com> Message-ID: <20041015004032.GI20194@xios> +++ Sudeep Jain [04-10-14 16:43 -0700]: > hello, > > >From these requirements, it appears that the M-Systems > Disk on Chip devices are the best, as they are > supported by MTD (are they ?), they hook up into a > standard IDE interface, dont emulate a hard disk, and > hopefuly (at least the larger disk sizes) have > multiple flash chips inside which I can then access in > parallel. But all DOC devices contain a controller so you are not talking directly to the flash, but to a controller, which, if I understand correctly, runs M-system's TrueFFS filesystem on the flash. So you can't use your own filesystem on these devices. I may be confused about this, but that's the impression I got from an M-systems rep I talked to today. > Questions > 1) Can the DOC devices be changed to allow access by > the host system at a (chip, block, page) level ? I don't think so. > 2) Do the MTD drivers work with DOC devices, and can > they provide this level of access ? I think there is MTD support for DOC, but I don't understand how this fits with my understanding that you have to use TrueFFS. > 3) Do the MTD devices have multiple NAND chips inside Some DOCs will have multiple devices, as do some CF cards. MTD supports multiple devices which can be accesed individually or as a merged device. As Charles says you will get more accurate answers on the linux-mtd list (@infradead.org) Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From wookey@aleph1.co.uk Fri Oct 15 01:45:32 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 15 Oct 2004 01:45:32 +0100 Subject: [Yaffs] Re: CONFIG_YAFFS_USE_GENERIC_RW In-Reply-To: <8285CB7241FCFC4BB721A6F953F9B35E01548F96@nzc-ap-xch-01.ap.trimblecorp.net> References: <8285CB7241FCFC4BB721A6F953F9B35E01548F96@nzc-ap-xch-01.ap.trimblecorp.net> Message-ID: <20041015004532.GJ20194@xios> +++ Charles Manning [04-10-14 12:12 +1300]: > This is a historic thing. > USE_GENERIC_RW uses the Linux page cache for read/write. This means that the Linux generic_read and generic_write functions are used which and YAFFS supplies the read_page write_page calls. > > Not defining USE_GENERIC_RW directly implements read/write without using the page cache. > > The direct read/write stuff was iimplemented first, and I followed it by generic read/write when memory mapping was implemented. During the transition both options worked. Things have now moved on and not defining USE_GENERIC_RW is broken, with no real motivation to fix it. > > Ie. You should always define USE_GENERIC_RW. > > This comes up every couple of months on the list. I guess I should pull it out. We did find one person who found that it was useful to avoid the cache as it gave them a significant speedup in their fairly pathological use-case, as I recall. Maybe what we need is some better docs about what the various defines do and when you would want to use them.... There has been a lot of useful info on this list in the last couple of weeks - it just needs collecting together and putting on the web/in the docs. I've been meaning to updatethe docs for a while - but if anyone else feels enthused.... Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From manningc2@actrix.gen.nz Fri Oct 15 04:17:35 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 15 Oct 2004 16:17:35 +1300 Subject: [Yaffs] Re: CONFIG_YAFFS_USE_GENERIC_RW ==> caching In-Reply-To: <20041015004532.GJ20194@xios> References: <8285CB7241FCFC4BB721A6F953F9B35E01548F96@nzc-ap-xch-01.ap.trimblecorp.net> <20041015004532.GJ20194@xios> Message-ID: <20041015031415.19A5F1630F@desire.actrix.co.nz> Perhaps you're getting confused between the Linux cache and the cache ins= ide=20 YAFFS. The Linux page cache is pretty efficient for both read and write. Howeve= r,=20 it is a "write through" cache, not a "write into" cache. This means that = any=20 writes get written all the way through to the file system, so the code for(i =3D 0; i < 500; i++) write(f,"a",1);=20 will do 500 writes into YAFFS. YAFFS has an internal "write into" "short op" cache. This cache only oper= ates=20 on read/writes that are smaller than a NAND page .=20 Thus the above code will just write into the cache. The cache only writes= to=20 NAND when: * the file flushes or closes * the cache "spills" ie. gets full and some space must be retrieved. The caching code was originally written for WinCE reading (since WinCE do= es=20 not have a page cache like linix does) and writing was added shortly=20 thereafter. Since Linux has the page cache, and I thought it was a "write= =20 into" cache, I didn't enable the cache for Linux. However, some time late= r=20 someone was using code like the above and complained. I turned on caching= for=20 Linux and everything went much faster. One happy camper saying lots of ni= ce=20 things on the list! Perhaps that is the discussion you recall? Using YAFFS under Linux without generic_rw has been broken for a while=20 (broke during/around the addition of the softdelete speedups a year or mo= re =20 ago). I have not heard complaints as such, only comments when people have= had=20 a play and YAFFS bit back (like this thread from Ulla). -- Charles On Friday 15 October 2004 13:45, Wookey wrote: > +++ Charles Manning [04-10-14 12:12 +1300]: > > This is a historic thing. > > USE_GENERIC_RW uses the Linux page cache for read/write. This means t= hat > > the Linux generic_read and generic_write functions are used which and > > YAFFS supplies the read_page write_page calls. > > > > Not defining USE_GENERIC_RW directly implements read/write without us= ing > > the page cache. > > > > The direct read/write stuff was iimplemented first, and I followed it= by > > generic read/write when memory mapping was implemented. During the > > transition both options worked. Things have now moved on and not defi= ning > > USE_GENERIC_RW is broken, with no real motivation to fix it. > > > > Ie. You should always define USE_GENERIC_RW. > > > > This comes up every couple of months on the list. I guess I should pu= ll > > it out. > > We did find one person who found that it was useful to avoid the cache = as > it gave them a significant speedup in their fairly pathological use-cas= e, > as I recall. > > Maybe what we need is some better docs about what the various defines d= o > and when you would want to use them.... > > There has been a lot of useful info on this list in the last couple of > weeks - it just needs collecting together and putting on the web/in the > docs. > > I've been meaning to updatethe docs for a while - but if anyone else fe= els > enthused.... > > Wookey From wookey@aleph1.co.uk Fri Oct 15 10:55:59 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 15 Oct 2004 10:55:59 +0100 Subject: [Yaffs] Re: CONFIG_YAFFS_USE_GENERIC_RW ==> caching In-Reply-To: <20041015031415.19A5F1630F@desire.actrix.co.nz> References: <8285CB7241FCFC4BB721A6F953F9B35E01548F96@nzc-ap-xch-01.ap.trimblecorp.net> <20041015004532.GJ20194@xios> <20041015031415.19A5F1630F@desire.actrix.co.nz> Message-ID: <20041015095558.GM20194@xios> +++ Charles Manning [04-10-15 16:17 +1300]: > Perhaps you're getting confused between the Linux cache and the cache inside > YAFFS. > > Perhaps that is the discussion you recall? Probably > Using YAFFS under Linux without generic_rw has been broken for a while > (broke during/around the addition of the softdelete speedups a year or more > ago). In which case sound like you are right and this option should be binned. I wonder if we should do an 'official' 1.1 release sometime soon. Just so there is something more than 'what's in CVS today'. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From dave-gnus@bfnet.com Sat Oct 16 01:06:53 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Fri, 15 Oct 2004 17:06:53 -0700 Subject: [Yaffs] mounting yaffs.dat loopback? Message-ID: Is this supposed to work: mkyaffsimage /path/to/some/directory yaffs.dat "" >/dev/null losetup /dev/mtd/3 yaffs.dat mount /dev/mtd/3 /tmp/yaffs From abhishek.b@lgsoftindia.com Mon Oct 18 11:30:55 2004 From: abhishek.b@lgsoftindia.com (Abhishek Bhattacharya) Date: Mon, 18 Oct 2004 16:00:55 +0530 Subject: [Yaffs] yaffs 2.0 Message-ID: This is a multi-part message in MIME format. ------_=_NextPart_001_01C4B4FD.8D44A2E1 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hello All Is yaffs 2.0 ready ? can it be replaced with yaffs first version? Regards Abhishek ------_=_NextPart_001_01C4B4FD.8D44A2E1 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable yaffs 2.0

Hello All

Is yaffs 2.0 ready ? can  it be = replaced with yaffs first version?

Regards

Abhishek

------_=_NextPart_001_01C4B4FD.8D44A2E1-- From wookey@aleph1.co.uk Mon Oct 18 12:23:27 2004 From: wookey@aleph1.co.uk (Wookey) Date: Mon, 18 Oct 2004 12:23:27 +0100 Subject: [Yaffs] Re: yaffs 2.0 In-Reply-To: References: Message-ID: <20041018112327.GR21799@court.aleph1.co.uk> +++ Abhishek Bhattacharya [04-10-18 16:00 +0530]: > Hello All > > Is yaffs 2.0 ready ? No, not yet. Reasonable progress is being made and we are hopeful of having something to test before the end of the year. > can it be replaced with yaffs first version? I'm not sure I understand. Do you mean 'Can YAFFS2 replace YAFFS1 in a device'? OR do you really mean 'can YAFFS2 replace YAFFS1'? They are essentially interchangeable, although only YAFFS2 will support newer hardware (2k page size, no page rewriting). Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From a16157@motorola.com Mon Oct 18 13:33:59 2004 From: a16157@motorola.com (Li Xin-a16157) Date: Mon, 18 Oct 2004 20:33:59 +0800 Subject: [Yaffs] Re: yaffs 2.0 Message-ID: <01139FC052A0D411900B00508B9535FC18B7D628@ZCH07EXM04.corp.mot.com> They are essentially interchangeable, although only YAFFS2 will support newer hardware (2k page size, no page rewriting). ----------------------------------------------------- Does this mean the current YAFFS doesn't support 2K page size Nand flash? Li Xin Best Regards. From manningc2@actrix.gen.nz Tue Oct 19 03:08:24 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Tue, 19 Oct 2004 15:08:24 +1300 Subject: [Yaffs] Re: yaffs 2.0 In-Reply-To: <01139FC052A0D411900B00508B9535FC18B7D628@ZCH07EXM04.corp.mot.com> References: <01139FC052A0D411900B00508B9535FC18B7D628@ZCH07EXM04.corp.mot.com> Message-ID: <20041019020453.55EDC3FA6@blood.actrix.co.nz> The major difference in YAFFS2 is the support for flash parts with zero=20 rewrite. YAFFS1 keeps track of what data, files etc are deleted by the us= e of=20 deletion markers. Writing the deletion marker has two down-sides: 1) Some flash parts do not tolerate any rewrites. 2) Obviously more writes =3D=3D slower. YAFFS2 supports page sizes > 512bytes. You could hack YAFFS1 (ie. incre= ase=20 chunk size to 2k) to do this too, but YAFFS2 does straight off. Bigger chunks means less chunks per MB which means less RAM footprint. -- CHarles On Tuesday 19 October 2004 01:33, Li Xin-a16157 wrote: > They are essentially interchangeable, although only YAFFS2 will support > newer hardware (2k page size, no page rewriting). > ----------------------------------------------------- > > Does this mean the current YAFFS doesn't support 2K page size Nand flas= h? > > Li Xin > Best Regards. > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From a16157@motorola.com Tue Oct 19 09:21:53 2004 From: a16157@motorola.com (Li Xin-a16157) Date: Tue, 19 Oct 2004 16:21:53 +0800 Subject: [Yaffs] Re: yaffs 2.0 Message-ID: <01139FC052A0D411900B00508B9535FC18BF7A95@ZCH07EXM04.corp.mot.com> Hi Charles, I am quite new to YAFFS. The flash device on my board is Toshiba 128MB, = 3.3v, 8bit NAND flash. Its device ID is 0xF1 and has 2KB pages. My = objective is to run the current YAFFS on my NAND flash. Which files in = current YAFFS source should be modified to support 2KB page Nand? Will = this kind of modification to support 2KB page need a lot of effort?=20 Best Regards=20 Li Xin=20 -----Original Message----- From: Charles Manning [mailto:manningc2@actrix.gen.nz]=20 Sent: 2004=C4=EA10=D4=C219=C8=D5 10:08 To: Li Xin-a16157; Wookey; yaffs@stoneboat.aleph1.co.uk Cc: Li Xin-a16157 Subject: Re: [Yaffs] Re: yaffs 2.0 The major difference in YAFFS2 is the support for flash parts with zero = rewrite. YAFFS1 keeps track of what data, files etc are deleted by the = use of=20 deletion markers. Writing the deletion marker has two down-sides: 1) Some flash parts do not tolerate any rewrites. 2) Obviously more writes =3D=3D slower. YAFFS2 supports page sizes > 512bytes. You could hack YAFFS1 (ie. = increase=20 chunk size to 2k) to do this too, but YAFFS2 does straight off. Bigger chunks means less chunks per MB which means less RAM footprint. -- CHarles On Tuesday 19 October 2004 01:33, Li Xin-a16157 wrote: > They are essentially interchangeable, although only YAFFS2 will = support > newer hardware (2k page size, no page rewriting). > ----------------------------------------------------- > > Does this mean the current YAFFS doesn't support 2K page size Nand = flash? > > Li Xin > Best Regards. > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From lorenzo.parisi@st.com Wed Oct 20 12:05:42 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Wed, 20 Oct 2004 13:05:42 +0200 Subject: [Yaffs] Nand write errors Message-ID: Hi, when I write or remove a lot of file on my NAND with YAFFS, I receive many errors of that type: nand_write_oob: Failed write verify, page 0x0000ba81 Why? When I do same operations with JFFS2, I don't receive any errors. Why? Thanks. From manningc2@actrix.gen.nz Wed Oct 20 21:22:24 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Thu, 21 Oct 2004 09:22:24 +1300 Subject: [Yaffs] problem with object (file) creation ==> fix In-Reply-To: References: Message-ID: <20041020201846.28274583E@blood.actrix.co.nz> I have just checked in changes to yaffs_fs.c, yaffs_guts.c, yaffs_guts.h = to=20 fix this problem. Now yaffs Objects in the object look up hash table are not freed until th= e=20 coresponding inode is cleared. I did some tests with a smaller bucket size (8) and observed that the=20 recycling problem does not happen. Object numbers are now only recycled = when=20 the Linux cache tells us it is OK. This mechanism does not use any new kernel calls and should thus be good = with=20 older kernels. Thanx to Michael for his efforts in hunting down the problem. -- Charles From manningc2@actrix.gen.nz Wed Oct 20 21:32:25 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Thu, 21 Oct 2004 09:32:25 +1300 Subject: [Yaffs] Re: yaffs 2.0 In-Reply-To: <01139FC052A0D411900B00508B9535FC18BF7A95@ZCH07EXM04.corp.mot.com> References: <01139FC052A0D411900B00508B9535FC18BF7A95@ZCH07EXM04.corp.mot.com> Message-ID: <20041020202847.38349167C5@desire.actrix.co.nz> Hi Conceptually, making YAFFS1 work with 2k pages is straight forward, but t= here=20 are some subtle issues. YAFFS1 uses the stack for pages that it is workin= g=20 on. The Linux kernel stack is not large, so 2k pages might break. I would suggest that it makes more sense to wait for YAFFS2. At this stag= e=20 YAFFS2 is working in yaffs-direct mode on file emulation(that's how I dev= elop=20 file system algorithms). I still need to hook up the mtd code to have YA= FFS2=20 working with 2k pages in the kernel. I expect to have something in CVS wi= thin=20 2 weeks. There is also a compatability mode in YAFFS2 so that it will support YAFF= S1=20 format. The goal of this is that we move all development over to YAFFS2 a= nd=20 obsolete YAFFS1. Regards -- Charles On Tuesday 19 October 2004 21:21, Li Xin-a16157 wrote: > Hi Charles, > > I am quite new to YAFFS. The flash device on my board is Toshiba 128MB, > 3.3v, 8bit NAND flash. Its device ID is 0xF1 and has 2KB pages. My > objective is to run the current YAFFS on my NAND flash. Which files in > current YAFFS source should be modified to support 2KB page Nand? Will = this > kind of modification to support 2KB page need a lot of effort? > > Best Regards > Li Xin > > > -----Original Message----- > From: Charles Manning [mailto:manningc2@actrix.gen.nz] > Sent: 2004=C4=EA10=D4=C219=C8=D5 10:08 > To: Li Xin-a16157; Wookey; yaffs@stoneboat.aleph1.co.uk > Cc: Li Xin-a16157 > Subject: Re: [Yaffs] Re: yaffs 2.0 > > The major difference in YAFFS2 is the support for flash parts with zero > rewrite. YAFFS1 keeps track of what data, files etc are deleted by the = use > of deletion markers. Writing the deletion marker has two down-sides: 1= ) > Some flash parts do not tolerate any rewrites. > 2) Obviously more writes =3D=3D slower. > > YAFFS2 supports page sizes > 512bytes. You could hack YAFFS1 (ie.=20 > increase chunk size to 2k) to do this too, but YAFFS2 does straight off= . > > Bigger chunks means less chunks per MB which means less RAM footprint. > > -- CHarles > > On Tuesday 19 October 2004 01:33, Li Xin-a16157 wrote: > > They are essentially interchangeable, although only YAFFS2 will suppo= rt > > newer hardware (2k page size, no page rewriting). > > ----------------------------------------------------- > > > > Does this mean the current YAFFS doesn't support 2K page size Nand fl= ash? > > > > Li Xin > > Best Regards. > > > > _______________________________________________ > > yaffs mailing list > > yaffs@stoneboat.aleph1.co.uk > > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From dave-gnus@bfnet.com Wed Oct 20 23:23:23 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Wed, 20 Oct 2004 15:23:23 -0700 Subject: [Yaffs] YAFFS fs images not working the way I expect References: Message-ID: I'm trying to dump an image of a YAFFS partition so that I can reload it later. Things are not working the way I expect. Here is an example of where I'm unable to copy an image onto a partition and mount it. Any clues for sale? 1. create a new YAFFS filesystem on mtd partition 2 using a pregenerated yaffs.dat file, mount it, and verify that the etc and home directories are listed as expected: # cd /path/to/mounted/CF/card # /sbin/mkyaffs /dev/mtd/2 /yaffs.dat # /bin/mount -n /dev/mtdblock/2 /mnt/flash0 -t yaffs # ls /mnt/flash0 etc home lost+found # 2. unmount that and dump it to a file: # umount /mnt/flash0 # /sbin/mkyaffs /dev/mtd/2 /yaffs.dat argc 3 sh 0 optcnt 1 Erasing and programming NAND Erasing block at 0x080 Erasing block at 0x0810000 Erasing block at 0x08354000 OK # dd if=/dev/mtd/2 of=mtd2.img bs=16384 214+0 records in 214+0 records out # 3. copy zeros onto the partition and verify that we can't mount it anymore # dd if=/dev/zero of=/dev/mtd/2 bs=16384 count=214 214+0 records in 214+0 records out # mount -n /dev/mtdblock/2 /tmp/yaffs -t yaffs yaffs: dev is 7938 name is "1f:02" mount: Mounting /dev/mtdblock/2 on /tmp/yaffs failed: Not a directory # 4. copy the backup image onto the partition, try (and fail) to mount it, and wonder what I'm doing wrong: # dd if=mtd2.img of=/dev/mtd/2 bs=16384 214+0 records in 214+0 records out # /bin/mount -n /dev/mtdblock/2 /mnt/flash0 -t yaffs yaffs: dev is 7938 name is "1f:02" mount: Mounting /dev/mtdblock/2 on /tmp/yaffs failed: Not a directory # From manningc2@actrix.gen.nz Thu Oct 21 23:07:21 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 22 Oct 2004 11:07:21 +1300 Subject: [Yaffs] YAFFS fs images not working the way I expect In-Reply-To: References: Message-ID: <20041021220341.183BE197C0@desire.actrix.co.nz> Hi I think this is falling down on the "dd" commands. AFAIK, "dd" will be ignoring the OOB stuff which is required by YAFFS. Go look in the mtd tools, I think there are some nand specific tools like= =20 damddump or some such that will also extract the OOB info. -- Charles On Thursday 21 October 2004 11:23, you wrote: > I'm trying to dump an image of a YAFFS partition so that I can reload > it later. Things are not working the way I expect. Here is an > example of where I'm unable to copy an image onto a partition and > mount it. Any clues for sale? > > 1. create a new YAFFS filesystem on mtd partition 2 using a > pregenerated yaffs.dat file, mount it, and verify that the etc and > home directories are listed as expected: > > # cd /path/to/mounted/CF/card > # /sbin/mkyaffs /dev/mtd/2 /yaffs.dat > # /bin/mount -n /dev/mtdblock/2 /mnt/flash0 -t yaffs > # ls /mnt/flash0 > etc home lost+found > # > > 2. unmount that and dump it to a file: > > # umount /mnt/flash0 > # /sbin/mkyaffs /dev/mtd/2 /yaffs.dat > argc 3 sh 0 optcnt 1 > Erasing and programming NAND > Erasing block at 0x080 > Erasing block at 0x0810000 > > Erasing block at 0x08354000 > OK > # dd if=3D/dev/mtd/2 of=3Dmtd2.img bs=3D16384 > 214+0 records in > 214+0 records out > # > > 3. copy zeros onto the partition and verify that we can't mount it > anymore > > # dd if=3D/dev/zero of=3D/dev/mtd/2 bs=3D16384 count=3D214 > 214+0 records in > 214+0 records out > # mount -n /dev/mtdblock/2 /tmp/yaffs -t yaffs > yaffs: dev is 7938 name is "1f:02" > mount: Mounting /dev/mtdblock/2 on /tmp/yaffs failed: Not a directory > # > > 4. copy the backup image onto the partition, try (and fail) to mount > it, and wonder what I'm doing wrong: > > # dd if=3Dmtd2.img of=3D/dev/mtd/2 bs=3D16384 > 214+0 records in > 214+0 records out > # /bin/mount -n /dev/mtdblock/2 /mnt/flash0 -t yaffs > yaffs: dev is 7938 name is "1f:02" > mount: Mounting /dev/mtdblock/2 on /tmp/yaffs failed: Not a directory > # > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From PesceG@gea-automotive.com Fri Oct 22 07:32:23 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Fri, 22 Oct 2004 08:32:23 +0200 Subject: [Yaffs] yaffs seems do not work correctly Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4B800.E40A2F40 Content-Type: text/plain; charset="iso-8859-1" Hello , I am using an ARM machine with 2.4.18 kernel with a NAND flash Samsung K9D1208V0M I configured the kernel for yaffs I mounted this file system but if I create a file [ editing it by VI ] , the ls command don't list it if I do a cat , the file is printed correctly At the next boot the file disappear Any help will appreciated ------_=_NextPart_001_01C4B800.E40A2F40 Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable yaffs seems do not work correctly

        Hello = ,

        I am using = an ARM machine with 2.4.18 kernel with a NAND

        flash = Samsung K9D1208V0M

        I = configured the kernel for yaffs

        I mounted = this file system

        but if I = create a file [ editing it by VI ] , the ls command don't list = it

        if I do a = cat , the file is printed correctly

        At the = next boot the file disappear


        Any help = will appreciated



------_=_NextPart_001_01C4B800.E40A2F40-- From dave-gnus@bfnet.com Thu Oct 21 23:32:24 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Thu, 21 Oct 2004 15:32:24 -0700 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect References: <20041021220341.183BE197C0@desire.actrix.co.nz> Message-ID: Charles> I think this is falling down on the "dd" commands. AFAIK, Charles> "dd" will be ignoring the OOB stuff which is required by Charles> YAFFS. Go look in the mtd tools, I think there are some nand Charles> specific tools like damddump or some such that will also Charles> extract the OOB info. So are you saying that I won't be able to preload a YAFFS filesystem into my NAND flash unless my programmer can write OOB info??? From robbie@rubin.hu Fri Oct 22 08:33:19 2004 From: robbie@rubin.hu (Robert Szabo) Date: Fri, 22 Oct 2004 09:33:19 +0200 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> Message-ID: <4178B7BF.3060408@rubin.hu> Hi! Also, keep in mind that NAND Flashes are not error free and that they are at random places. Using dd (or other, OOB supported util) to preload an image on other NAND flash than it was dumped from is risky. Image might contain valid, live blocks where NAND has faults. regards, Robbie David Wuertele wrote: >Charles> I think this is falling down on the "dd" commands. AFAIK, >Charles> "dd" will be ignoring the OOB stuff which is required by >Charles> YAFFS. Go look in the mtd tools, I think there are some nand >Charles> specific tools like damddump or some such that will also >Charles> extract the OOB info. > >So are you saying that I won't be able to preload a YAFFS filesystem >into my NAND flash unless my programmer can write OOB info??? > > >_______________________________________________ >yaffs mailing list >yaffs@stoneboat.aleph1.co.uk >http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > > From tglx@linutronix.de Fri Oct 22 08:48:55 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 22 Oct 2004 09:48:55 +0200 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> Message-ID: <1098431334.8955.52.camel@thomas> On Fri, 2004-10-22 at 00:32, David Wuertele wrote: > Charles> I think this is falling down on the "dd" commands. AFAIK, > Charles> "dd" will be ignoring the OOB stuff which is required by > Charles> YAFFS. Go look in the mtd tools, I think there are some nand > Charles> specific tools like damddump or some such that will also > Charles> extract the OOB info. > > So are you saying that I won't be able to preload a YAFFS filesystem > into my NAND flash unless my programmer can write OOB info??? OOB info is part of the filesystem. ECC is part of error correction in the NAND layer. How should this work without ? nandwrite from MTD/utils programs images with OOB info, ECC and is bad block aware. tglx From dave-gnus@bfnet.com Fri Oct 22 19:33:08 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Fri, 22 Oct 2004 11:33:08 -0700 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect References: <20041021220341.183BE197C0@desire.actrix.co.nz> <4178B7BF.3060408@rubin.hu> Message-ID: Robert> Also, keep in mind that NAND Flashes are not error free and Robert> that they are at random places. Using dd (or other, OOB Robert> supported util) to preload an image on other NAND flash than Robert> it was dumped from is risky. Image might contain valid, live Robert> blocks where NAND has faults. Yes, I'm aware of that --- I am using dd for testing on my embedded system, but when I do the actual manufacturing I will be using a programmer which knows how to deal with bad blocks. And after I tried the dd test, I checked the partition for bad blocks and it has none. So I know that bad blocks aren't the reason the dd test didn't work. From dave-gnus@bfnet.com Fri Oct 22 19:35:49 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Fri, 22 Oct 2004 11:35:49 -0700 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect References: <20041021220341.183BE197C0@desire.actrix.co.nz> <1098431334.8955.52.camel@thomas> Message-ID: Thomas> OOB info is part of the filesystem. If it is, the designer made a boo-boo! It isn't called "out-of-band" for nothing! Thomas> ECC is part of error correction in the NAND layer. How should Thomas> this work without? 1. ECC is optional in the NAND layer 2. ECC should be a component of the NAND driver, not of the filesystem. Thomas> nandwrite from MTD/utils programs images with OOB info, ECC Thomas> and is bad block aware. But I need to pre-load my flash with a programmer. This is for the purposes of mass production, and there's no way to do it on a machine already running linux. How am I going to get my YAFFS partition onto the flash? From tglx@linutronix.de Fri Oct 22 23:03:14 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Sat, 23 Oct 2004 00:03:14 +0200 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> <4178B7BF.3060408@rubin.hu> Message-ID: <1098482594.3306.65.camel@thomas> On Fri, 2004-10-22 at 11:33 -0700, David Wuertele wrote: > Robert> Also, keep in mind that NAND Flashes are not error free and > Robert> that they are at random places. Using dd (or other, OOB > Robert> supported util) to preload an image on other NAND flash than > Robert> it was dumped from is risky. Image might contain valid, live > Robert> blocks where NAND has faults. > > Yes, I'm aware of that --- I am using dd for testing on my embedded > system, but when I do the actual manufacturing I will be using a > programmer which knows how to deal with bad blocks. > > And after I tried the dd test, I checked the partition for bad blocks > and it has none. So I know that bad blocks aren't the reason the dd > test didn't work. A lot of ppl pointed already out, why dd does not work. Read also http://www.linux-mtd.infradead.org/tech/nand.html It will never work the way you expect whether there are bad blocks or not. You _CANNOT_ use dd for testing on NAND. MTD/utils/nand.... _ARE_ NAND aware, dd is _NOT_ ! Plug the unplugged plug (http://www.bfnet.com) before arguing more about what you expect. tglx From tglx@linutronix.de Fri Oct 22 23:14:34 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Sat, 23 Oct 2004 00:14:34 +0200 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> <1098431334.8955.52.camel@thomas> Message-ID: <1098483274.3306.74.camel@thomas> On Fri, 2004-10-22 at 11:35 -0700, David Wuertele wrote: > Thomas> OOB info is part of the filesystem. > > If it is, the designer made a boo-boo! It isn't called "out-of-band" > for nothing! Yeah, I'm too stupid to understand how NAND works and you're the expert. Design your own filesystem, if you know to do it better. _ALL_ NAND aware filesystems, I'm aware of, use the OOB. And for the new 2K chips + Hardware ECC it is even neccecary to move parts of the fs into the OOb layer. > Thomas> ECC is part of error correction in the NAND layer. How should > Thomas> this work without? > > 1. ECC is optional in the NAND layer That's utter crap. It is not recommended to use NAND without ECC for a good reason > 2. ECC should be a component of the NAND driver, not of the > filesystem. It is part of the NAND driver, but dd and your programmer are not aware of that. Think about that for a second > Thomas> nandwrite from MTD/utils programs images with OOB info, ECC > Thomas> and is bad block aware. > > But I need to pre-load my flash with a programmer. This is for the > purposes of mass production, and there's no way to do it on a machine > already running linux. How am I going to get my YAFFS partition onto > the flash? Oh, your programmer does not support this. There are programmers available, which handle NAND including OOB programming. tglx From manningc2@actrix.gen.nz Sun Oct 24 04:22:16 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Sun, 24 Oct 2004 16:22:16 +1300 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> Message-ID: <20041024031833.12CAF6264@blood.actrix.co.nz> You won't be able to use any file system with NAND unless you can write t= he=20 OOB. All file systems I am aware of at the very least use OOB for storing ECC = etc. Have a look at the code for mkyaffs. This should give you a good kick-off= =20 point for programming YAFFS. I am aware of at least one smartphone=20 manufacturer pre-programming NAND chips directly with YAFFS. -- Charles On Friday 22 October 2004 11:32, David Wuertele wrote: > Charles> I think this is falling down on the "dd" commands. AFAIK, > Charles> "dd" will be ignoring the OOB stuff which is required by > Charles> YAFFS. Go look in the mtd tools, I think there are some nand > Charles> specific tools like damddump or some such that will also > Charles> extract the OOB info. > > So are you saying that I won't be able to preload a YAFFS filesystem > into my NAND flash unless my programmer can write OOB info??? > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Sun Oct 24 04:33:26 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Sun, 24 Oct 2004 16:33:26 +1300 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <1098431334.8955.52.camel@thomas> Message-ID: <20041024032941.F385C19DD4@desire.actrix.co.nz> On Saturday 23 October 2004 07:35, David Wuertele wrote: > Thomas> OOB info is part of the filesystem. > > If it is, the designer made a boo-boo! It isn't called "out-of-band" > for nothing! YAFFS uses the "OOB area" to store tags. I did this on purpose as a way t= o=20 improved the performance etc of YAFFS. I can asure you this was no booboo= . Hundreds of thousands of devices have been shipped with YAFFS, so I can=20 assure you it's working. It isn't really "out of band". That's really a pretty dopey name. All chi= p=20 vendors call it the "spare area". All block drivers use this area to stor= e=20 ECC and other info such as logical block number etc. YAFFS tages this one= =20 step further and uses the spare area to store file tags data. > > Thomas> ECC is part of error correction in the NAND layer. How should > Thomas> this work without? > > 1. ECC is optional in the NAND layer > > 2. ECC should be a component of the NAND driver, not of the > filesystem. > > Thomas> nandwrite from MTD/utils programs images with OOB info, ECC > Thomas> and is bad block aware. > > But I need to pre-load my flash with a programmer. This is for the > purposes of mass production, and there's no way to do it on a machine > already running linux. How am I going to get my YAFFS partition onto > the flash? I'm having a problem understanding what you can't do. Under Linux you can use mkyaffs to load a YAFFS image into a NAND partiti= on. If you're using a device programmer then have a look at the basic algorit= hm=20 in mkyaffs: Erase the device/partition, then write the info into the page and spare=20 areas, skipping over bad blocks. -- CHarles From PesceG@gea-automotive.com Mon Oct 25 14:33:35 2004 From: PesceG@gea-automotive.com (Pesce Gianfranco) Date: Mon, 25 Oct 2004 15:33:35 +0200 Subject: [Yaffs] yaffs source files Message-ID: This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_001_01C4BA97.3A52CEF0 Content-Type: text/plain; charset="iso-8859-1" Hello where can I find these files ? yaffs_fs.c,v 1.1.2.7 yaffs_guts.c,v 1.1.2.7 thanks -------------------------------------------------------------- GENERALE ELETTRONICA e AUTOMAZIONE S.r.l. Via Renata Bianchi 40 - 16152 GENOVA (ITALY) Tel.: +39 010 65966.1 Fax: +39 010 65966.311 http://www.gea-automotive.com; E-mail: mailbox@gea-automotive.com Ing. Gianfranco Pesce APPLICATION DEVELOPMENT DEPT. Project Engineer Tel. +39.010.659.66.507 E-mail: pesceg@gea-automotive.com -------------------------------------------------------------- ------_=_NextPart_001_01C4BA97.3A52CEF0 Content-Type: text/html; charset="iso-8859-1" yaffs source files

        Hello


        where can I find these files ?
                yaffs_fs.c,v 1.1.2.7
                yaffs_guts.c,v 1.1.2.7

       
        thanks


--------------------------------------------------------------
GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.
Via Renata Bianchi 40 - 16152 GENOVA (ITALY)
Tel.: +39 010 65966.1
Fax: +39 010 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION DEVELOPMENT DEPT.
Project Engineer
Tel. +39.010.659.66.507
E-mail: pesceg@gea-automotive.com
--------------------------------------------------------------

------_=_NextPart_001_01C4BA97.3A52CEF0-- From Charles.Manning@trimble.co.nz Mon Oct 25 21:35:56 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Tue, 26 Oct 2004 09:35:56 +1300 Subject: [Yaffs] yaffs source files Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01548FB6@nzc-ap-xch-01.ap.trimblecorp.net> This is a multi-part message in MIME format. ------=_NextPartTM-000-de2788aa-7fa9-4a97-ad7f-35c62225cdba Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C4BAD2.3ABAB3CA" ------_=_NextPart_001_01C4BAD2.3ABAB3CA Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Try browsing http://www.aleph1.co.uk/cgi-bin/viewcvs.cgi/yaffs/ =20 -- Charles =20 -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Pesce Gianfranco Sent: Tuesday, 26 October 2004 2:34 a.m. To: 'yaffs@stoneboat.aleph1.co.uk' Subject: [Yaffs] yaffs source files =09 =09 Hello=20 where can I find these files ?=20 yaffs_fs.c,v 1.1.2.7=20 yaffs_guts.c,v 1.1.2.7=20 =20 thanks=20 --------------------------------------------------------------=20 GENERALE ELETTRONICA e AUTOMAZIONE S.r.l.=20 Via Renata Bianchi 40 - 16152 GENOVA (ITALY)=20 Tel.: +39 010 65966.1=20 Fax: +39 010 65966.311=20 http://www.gea-automotive.com;=20 E-mail: mailbox@gea-automotive.com=20 Ing. Gianfranco Pesce=20 APPLICATION DEVELOPMENT DEPT.=20 Project Engineer=20 Tel. +39.010.659.66.507=20 E-mail: pesceg@gea-automotive.com=20 --------------------------------------------------------------=20 ------_=_NextPart_001_01C4BAD2.3ABAB3CA Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Message
Try=20 browsing http://www.al= eph1.co.uk/cgi-bin/viewcvs.cgi/yaffs/
 
--=20 Charles
 
-----Original Message-----
From:=20 yaffs-admin@stoneboat.aleph1.co.uk = [mailto:yaffs-admin@stoneboat.aleph1.co.uk]=20 On Behalf Of Pesce Gianfranco
Sent: Tuesday, 26 = October 2004=20 2:34 a.m.
To: = 'yaffs@stoneboat.aleph1.co.uk'
Subject:=20 [Yaffs] yaffs source files


        Hello=20


        where can = I find=20 these files ?
       =20         yaffs_fs.c,v = 1.1.2.7
       =20         yaffs_guts.c,v=20 1.1.2.7

       =20
        thanks=20


--------------------------------------------------------------=20
GENERALE ELETTRONICA e AUTOMAZIONE = S.r.l.=20
Via Renata Bianchi 40 - 16152 GENOVA (ITALY) =
Tel.: +39 010 65966.1

Fax: +39 010=20 65966.311
http://www.gea-automotive.com;
E-mail: mailbox@gea-automotive.com


Ing. Gianfranco Pesce
APPLICATION=20 DEVELOPMENT DEPT.
Project Engineer =
Tel. +39.010.659.66.507
E-mail:=20 pesceg@gea-automotive.com
--------------------------------------------------------------=20

=00 ------_=_NextPart_001_01C4BAD2.3ABAB3CA-- ------=_NextPartTM-000-de2788aa-7fa9-4a97-ad7f-35c62225cdba-- From abhishek.b@lgsoftindia.com Tue Oct 26 09:27:49 2004 From: abhishek.b@lgsoftindia.com (Abhishek Bhattacharya) Date: Tue, 26 Oct 2004 13:57:49 +0530 Subject: [Yaffs] yaffs BAD sector management queries! Message-ID: This is a multi-part message in MIME format. ------_=_NextPart_001_01C4BB35.AE47438B Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hello Charles =20 I have a doubt about BAD sector management. =20 Well, we do a scan for bad blocks at boot up, fine! In your last mail , = we came to know that, once you mark it DEAD we never use it again, but = if there is a situation where a block becomes BAD at run time, how = should we counter such a situation?=20 =20 Thanks Abhishek ------_=_NextPart_001_01C4BB35.AE47438B Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable
Hello=20 Charles
 
I have = a doubt=20 about BAD sector management.
 
Well, = we do a scan=20 for bad blocks at boot up, fine! In your last mail , we came to know = that, once=20 you mark it DEAD we never use it again, but if there is a situation = where a=20 block becomes BAD at run time, how should we counter such a situation?=20
 
Thanks
Abhishek
------_=_NextPart_001_01C4BB35.AE47438B-- From wookey@aleph1.co.uk Tue Oct 26 14:17:25 2004 From: wookey@aleph1.co.uk (Wookey) Date: Tue, 26 Oct 2004 14:17:25 +0100 Subject: [Yaffs] Re: yaffs BAD sector management queries! In-Reply-To: References: Message-ID: <20041026131725.GA24939@court.aleph1.co.uk> +++ Abhishek Bhattacharya [04-10-26 13:57 +0530]: > Hello Charles > > I have a doubt about BAD sector management. > Well, we do a scan for bad blocks at boot up, fine! In your last mail , we > came to know that, once you mark it DEAD we never use it again, but if there > is a situation where a block becomes BAD at run time, how should we counter > such a situation? YAFFS detects such runtime failures (by the errors it gets back from the OS) and marks any such blocks BAD so they are not used again. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From Charles.Manning@trimble.co.nz Wed Oct 27 01:10:40 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Wed, 27 Oct 2004 13:10:40 +1300 Subject: [Yaffs] yaffs BAD sector management queries! Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01548FBF@nzc-ap-xch-01.ap.trimblecorp.net> To expand on what Wookey wrote: YAFFS determines what blocks are bad at scan time (when mounting). If any further blocks go bad during the operation of the device (write errors detected etc), then these blocks are marked for retiring (blk->needsRetiring =3D 1). Then, when the block gets garbage collected (see yaffs_BlockBecameDirty()), instead of recycling the block (erase for furture use) we mark it dead. Apart from the blocks marked bad during manufacturing, blocks go bad very infrequently. In a recent 150GB write test I saw no blocks go bad. To test the bad block management I hack the NAND emulation layer in YAFFS direct to mimic block failures. If I didn't do this, the bad block handling would never have been tested. -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Abhishek Bhattacharya Sent: Tuesday, 26 October 2004 9:28 p.m. To: yaffs@stoneboat.aleph1.co.uk Subject: [Yaffs] yaffs BAD sector management queries! Hello Charles I have a doubt about BAD sector management. Well, we do a scan for bad blocks at boot up, fine! In your last mail , we came to know that, once you mark it DEAD we never use it again, but if there is a situation where a block becomes BAD at run time, how should we counter such a situation?=20 Thanks Abhishek From bandwidthcrunch Thu Oct 28 08:29:28 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Thu, 28 Oct 2004 12:59:28 +0530 Subject: [Yaffs] yaffs and 2.4.19 on a samsung NAND Message-ID: Hi All, I been working on a 2.4.19 kernel with a 2002 mtd snapshot(yes old but only one working with 2.4.19 for right now :( ) .I have a samsung k9F1208U0M nand chip on a custom pxa hardware. dmesg shows me that a mtd partition has been detected 0x00000000-0x00040000 : "Bootloader" 0x00040000-0x00140000 : "Kernel" 0x00140000-0x02000000 : "Filesystem" NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) Creating 1 MTD partitions on "Samsung K9D1208V0M": 0x00000000-0x02000000 : "Filesystem on nand" [root@manav /root]#cat /proc/mtd dev: size erasesize name mtd0: 00040000 00040000 "Bootloader" mtd1: 00100000 00040000 "Kernel" mtd2: 01ec0000 00040000 "Filesystem" mtd3: 02000000 00004000 "Filesystem on nand" but when i do a [root@manav /root]#cat /proc/yaffs YAFFS built:Oct 28 2004 11:35:04 $Id: yaffs_fs.c,v 1.35 2004/10/20 20:12:43 charles Exp $ $Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $ and thats it . mkyaffs /dev/mtd3 does try to format the device but ends up getting a nand_read_oob: from = 0x00444000, len = 16 nand_read_oob 1: col = 0, page=2220 Erasing block at 0x08444000 nand_read_oob: from = 0x00448000, len = 16 nand_read_oob 1: col = 0, page=2240 Block at 0x08448000 is damaged and is not being formatted and mkyaffs -e /dev/mtd3 sample.yaffs gives [root@manav /root]#./mkyaffs -e /dev/mtd3 root-balloon-base.yaffs Image not a multiple of 528 bytes Shouldnt my /proc/yaffs be showing some entries ?Any clues what is happening in here ? regards, band From bandwidthcrunch Fri Oct 29 08:07:47 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Fri, 29 Oct 2004 12:37:47 +0530 Subject: [Yaffs] yaffs chunk n was not erased Message-ID: Hi All, Have got yaffs running on a 2.6.8-1 kernel , It mounts perfectly but when i try to copy a file or write a file to the mounted partion it gives a lot of **>>yaffs chunk 1 was not erased ................... **>> yaffs chunk 32567 was not erased **>> yaffs chunk 32568 was not erased **>> yaffs chunk 32569 was not erased **>> yaffs chunk 32570 was not erased **>> yaffs chunk 32571 was not erased **>> yaffs chunk 32572 was not erased **>> yaffs chunk 32573 was not erased **>> yaffs chunk 32574 was not erased **>> yaffs chunk 32575 was not erased **>> Block 1017 retired **>> yaffs write required 32544 attempts cp: unable to open `/mnt/yaffs/startup': Cannot allocate memory and df will show me full usage Filesystem 1k-blocks Used Available Use% Mounted on rootfs 31488 8944 22544 28% / /dev/mtdblock2 31488 8944 22544 28% / /dev/mtdblock3 16368 16368 0 100% /mnt/yaffs after the failed attemp to copy. I have tried enabling and disabling both IGNORE_CHUNK_ERASED = -DCONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK in the Makefile but to no avail. I am erasing the nand device like this [root@manav /root]#./mkyaffs /dev/mtd3 Erasing and programming NAND Erasing block at 0x080 Block at 0x084000 is damaged and is not being formatted Erasingnand_erase: attempt to erase a bad block at page 0x00000060 block at 0x088000 Erasing block at 0x08c000 MTD Erase failure : Input/output error Any clues or suggestions are welcome ? regards, Manav From bandwidthcrunch Fri Oct 29 12:03:43 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Fri, 29 Oct 2004 16:33:43 +0530 Subject: [Yaffs] Re: yaffs chunk n was not erased In-Reply-To: References: Message-ID: My cat /proc/yaffs shows cat /proc/yaffs YAFFS built:Oct 29 2004 16:26:29 $Id: yaffs_fs.c,v 1.35 2004/10/20 20:12:43 charles Exp $ $Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $ Device yaffs startBlock......... 1 endBlock........... 1023 chunkGroupBits..... 0 chunkGroupSize..... 1 nErasedBlocks...... 1017 nTnodesCreated..... 100 nFreeTnodes........ 86 nObjectsCreated.... 100 nFreeObjects....... 91 nFreeChunks........ 32570 nPageWrites........ 4 nPageReads......... 4 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 1024 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 1 [root@manav yaffs]#cd / and a very weird erro message comes when we unmount the nand file system . umount /mnt/yaffs/ VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... ???? On Fri, 29 Oct 2004 12:37:47 +0530, bandwidthcrunch wrote: > Hi All, > Have got yaffs running on a 2.6.8-1 kernel , It mounts > perfectly but when i try to copy a file or write a file to the mounted > partion it gives a lot of > > **>>yaffs chunk 1 was not erased > ................... > **>> yaffs chunk 32567 was not erased > **>> yaffs chunk 32568 was not erased > **>> yaffs chunk 32569 was not erased > **>> yaffs chunk 32570 was not erased > **>> yaffs chunk 32571 was not erased > **>> yaffs chunk 32572 was not erased > **>> yaffs chunk 32573 was not erased > **>> yaffs chunk 32574 was not erased > **>> yaffs chunk 32575 was not erased > **>> Block 1017 retired > **>> yaffs write required 32544 attempts > cp: unable to open `/mnt/yaffs/startup': Cannot allocate memory > > and df will show me full usage > Filesystem 1k-blocks Used Available Use% Mounted on > rootfs 31488 8944 22544 28% / > /dev/mtdblock2 31488 8944 22544 28% / > /dev/mtdblock3 16368 16368 0 100% /mnt/yaffs > > after the failed attemp to copy. > I have tried enabling and disabling both IGNORE_CHUNK_ERASED = > -DCONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK in the Makefile but to no > avail. > > I am erasing the nand device like this > [root@manav /root]#./mkyaffs /dev/mtd3 > Erasing and programming NAND > Erasing block at 0x080 > Block at 0x084000 is damaged and is not being formatted > Erasingnand_erase: attempt to erase a bad block at page 0x00000060 > block at 0x088000 > Erasing block at 0x08c000 > > MTD Erase failure > : Input/output error > > Any clues or suggestions are welcome ? > > regards, > Manav > From dave-gnus@bfnet.com Tue Oct 26 13:24:27 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Tue, 26 Oct 2004 05:24:27 -0700 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect References: <20041021220341.183BE197C0@desire.actrix.co.nz> <20041024031833.12CAF6264@blood.actrix.co.nz> Message-ID: Charles> You won't be able to use any file system with NAND unless you Charles> can write the OOB. I haven't had any problem using flash for CRAMFS and various other filesystems of my own design without using the OOB. Charles> Have a look at the code for mkyaffs. This should give you a Charles> good kick-off point for programming YAFFS. I am aware of at Charles> least one smartphone manufacturer pre-programming NAND chips Charles> directly with YAFFS. OK, thanks. From dave-gnus@bfnet.com Wed Oct 27 23:06:24 2004 From: dave-gnus@bfnet.com (David Wuertele) Date: Wed, 27 Oct 2004 15:06:24 -0700 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect References: <20041021220341.183BE197C0@desire.actrix.co.nz> <20041024031833.12CAF6264@blood.actrix.co.nz> Message-ID: Charles> Have a look at the code for mkyaffs. This should give you a Charles> good kick-off point for programming YAFFS. OK, after perusing mkyaffs.c, I am about to write a program for extracting data from a yaffs partition. Instead of using dd if=/dev/mtd/2 of=/yaffs.img I will use myprog /dev/mtd/2 > /yaffs.img I think that "myprog" can be written by copying mkyaffs.c to readyaffs.c, removing the erase code, and changing the part that writes the data to this: if(addr) { for(offset = 0; offset --=-=-= I've written a program called "readyaffs" (see attached) --- well, "written" is a little strong, basically I just copied mkyaffs.c over to readyaffs.c and changed the reads to writes and the writes to reads, and voila I have a system for taking a snapshot of a YAFFS filesystem: readyaffs /dev/mtd/2 > yaffs.dump verified that I can then reload this dump onto a different filesystem elsewhere: mkyaffs /dev/mtd/2 yaffs.dump My problem is that yaffs.dump is huge --- it is the same size as the whole partition. But I know my data doesn't fill that partition. Is there an easy way to discover where the end of the data is, and truncate yaffs.dump to only be that long? Thanks, Dave --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=readyaffs.c Content-Transfer-Encoding: base64 LyoKICogWUFGRlM6IFlldCBhbm90aGVyIEZGUy4gQSBOQU5ELWZsYXNoIHNwZWNpZmljIGZpbGUg c3lzdGVtLiAKICogbWt5YWZmcy5jIEZvcm1hdCBhIGNodW5rIG9mIE5BTkQgZm9yIFlBRkZTLgog KgogKiBDb3B5cmlnaHQgKEMpIDIwMDIgQWxlcGggT25lIEx0ZC4KICogICBmb3IgVG9ieSBDaHVy Y2hpbGwgTHRkIGFuZCBCcmlnaHRzdGFyIEVuZ2luZWVyaW5nCiAqCiAqIENyZWF0ZWQgYnkgQ2hh cmxlcyBNYW5uaW5nIDxjaGFybGVzQGFsZXBoMS5jby51az4KICoKICogVGhpcyBwcm9ncmFtIGlz IGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICog aXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJz aW9uIDIgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAq CiAqICBBY2tub3dsZWRnZW1lbnQ6CiAqICBUaGlzIGZpbGUgaXMgY3JhZnRlZCBmcm9tIG5hbmR0 ZXN0LmMgYnkgIE1pZ3VlbCBGcmVpdGFzIChtaWd1ZWxAY2V0dWMucHVjLXJpby5icikKICogIGFu ZCBTdGV2ZW4gSi4gSGlsbCAoc2poaWxsQGNvdHcuY29tKQogKgogKiBPdmVydmlldzoKICogRm9y bWF0dGluZyBhIFlBRkZTIGRldmljZSBpcyB2ZXJ5IHNpbXBsZS4gSnVzdCBlcmFzZSBhbGwgdW5k YW1hZ2VkIGJsb2Nrcy4gCiAqIE5CIERvbid0IGVyYXNlIGJsb2NrcyBtYWtlZCBhcyBkYW1hZ2Vk LgogKi8KCiNkZWZpbmUgX0dOVV9TT1VSQ0UKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxm Y250bC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8 dGltZS5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVk ZSA8c3lzL2lvY3RsLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPGFzbS90eXBl cy5oPgojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9tdGQvbXRkLmg+ Cgpjb25zdCBjaGFyICpta3lhZmZzX2NfdmVyc2lvbiA9ICIkSWQ6IG1reWFmZnMuYyx2IDEuOCAy MDAzLzAzLzEyIDE5OjU0OjA3IGNoYXJsZXMgRXhwICQiOwoKLy8gY291bnRCaXRzIGlzIGEgcXVp Y2sgd2F5IG9mIGNvdW50aW5nIHRoZSBudW1iZXIgb2YgYml0cyBpbiBhIGJ5dGUuCi8vIGllLiBj b3VudEJpdHNbbl0gaG9sZHMgdGhlIG51bWJlciBvZiAxIGJpdHMgaW4gYSBieXRlIHdpdGggdGhl IHZhbHVlIG4uCgpzdGF0aWMgY29uc3QgY2hhciBjb3VudEJpdHNbMjU2XSA9CnsKMCwxLDEsMiwx LDIsMiwzLDEsMiwyLDMsMiwzLDMsNCwKMSwyLDIsMywyLDMsMyw0LDIsMywzLDQsMyw0LDQsNSwK MSwyLDIsMywyLDMsMyw0LDIsMywzLDQsMyw0LDQsNSwKMiwzLDMsNCwzLDQsNCw1LDMsNCw0LDUs NCw1LDUsNiwKMSwyLDIsMywyLDMsMyw0LDIsMywzLDQsMyw0LDQsNSwKMiwzLDMsNCwzLDQsNCw1 LDMsNCw0LDUsNCw1LDUsNiwKMiwzLDMsNCwzLDQsNCw1LDMsNCw0LDUsNCw1LDUsNiwKMyw0LDQs NSw0LDUsNSw2LDQsNSw1LDYsNSw2LDYsNywKMSwyLDIsMywyLDMsMyw0LDIsMywzLDQsMyw0LDQs NSwKMiwzLDMsNCwzLDQsNCw1LDMsNCw0LDUsNCw1LDUsNiwKMiwzLDMsNCwzLDQsNCw1LDMsNCw0 LDUsNCw1LDUsNiwKMyw0LDQsNSw0LDUsNSw2LDQsNSw1LDYsNSw2LDYsNywKMiwzLDMsNCwzLDQs NCw1LDMsNCw0LDUsNCw1LDUsNiwKMyw0LDQsNSw0LDUsNSw2LDQsNSw1LDYsNSw2LDYsNywKMyw0 LDQsNSw0LDUsNSw2LDQsNSw1LDYsNSw2LDYsNywKNCw1LDUsNiw1LDYsNiw3LDUsNiw2LDcsNiw3 LDcsOAp9OwoKLyoKICogQnVmZmVyIGFycmF5cyB1c2VkIGZvciBydW5uaW5nIHRlc3RzCiAqLwoK dW5zaWduZWQgY2hhciBvb2JidWZbMTZdOwp1bnNpZ25lZCBjaGFyIGltZ3BhZ2VbNTI4XTsKCiNp Zm5kZWYgQ09ORklHX1lBRkZTX1VTRV9PTERfTVRECi8qCiAqIE9PQiBsYXlvdXQKICovCgpzdHJ1 Y3QgbmFuZF9vb2JpbmZvIHlhZmZzX29vYmluZm8gPSB7Cgl1c2VlY2M6IDEsCgllY2Nwb3M6IHs4 LCA5LCAxMCwgMTMsIDE0LCAxNX0KfTsKCnN0cnVjdCBuYW5kX29vYmluZm8geWFmZnNfbm9lY2Np bmZvID0gewoJdXNlZWNjOiAwLAp9OwojZW5kaWYKCgovKgogKiBNYWluIHByb2dyYW0KICovCmlu dCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJdW5zaWduZWQgbG9uZyBhZGRyOwoJdW5z aWduZWQgbG9uZyBvZmZzZXQ7CglpbnQgZmQ7CglpbnQgaW1nPS0xOwoJaW50IG9wdGNudCA9IDE7 CglpbnQgdXNlbXRkZWNjID0gMDsKCWludCBpbWdsZW4gPSAwOwoJaW50IHNob3dIZWxwID0gMDsK CXN0cnVjdCBtdGRfb29iX2J1ZiBvb2IgPSB7MCwgMTYsICh1bnNpZ25lZCBjaGFyICopICZvb2Ji dWZ9OwoJbXRkX2luZm9fdCBtZW1pbmZvOwoJZXJhc2VfaW5mb190IGVyYXNlOwojaWZuZGVmIENP TkZJR19ZQUZGU19VU0VfT0xEX01URAoJc3RydWN0IG5hbmRfb29iaW5mbyBvb2JzZWw7CiNlbmRp ZgoKCWlmIChhcmdjID4gMSAmJiBzdHJjbXAgKGFyZ3Zbb3B0Y250XSwgIi0/IikgPT0gMCkgewoJ CXNob3dIZWxwID0gMTsKCX0KCglpZiAoYXJnYyA+IDEgJiYgc3RyY21wIChhcmd2W29wdGNudF0s ICItaCIpID09IDApIHsKCQlzaG93SGVscCA9IDE7Cgl9CgkKCWlmIChhcmdjID4gMSAmJiBzdHJj bXAgKGFyZ3Zbb3B0Y250XSwgIi1lIikgPT0gMCkgewoJCW9wdGNudCsrOwoJCXVzZW10ZGVjYyA9 IDE7Cgl9CgkKCXByaW50ZigiYXJnYyAlZCBzaCAlZCBvcHRjbnQgJWRcbiIsYXJnYywgc2hvd0hl bHAsIG9wdGNudCk7CgkKCS8qIE1ha2Ugc3VyZSBhIGRldmljZSB3YXMgc3BlY2lmaWVkICovCglp ZihzaG93SGVscCB8fCBhcmdjIDwgKG9wdGNudCArIDEpKSB7CgkJcHJpbnRmKCJ1c2FnZTogJXMg Wy1lXSA8bXRkbmFtZT4gW2ltYWdlIG5hbWVdXG4iLCBhcmd2WzBdKTsKCQlwcmludGYoIiAgLWUg ICAgICAgICBVc2UgbXRkIGVjYy4gRGVmYXVsdDogZG8gbm90IHVzZSBtdGQgZWNjXG4iKTsKCQlw cmludGYoIiAgbXRkbmFtZSAgICBOYW1lIG9mIG10ZCBkZXZpY2VcbiIpOwoJCXByaW50ZigiICBp bWFnZSBuYW1lIE5hbWUgb2Ygb3B0aW9uYWwgaW1hZ2UgZmlsZVxuXG4iKTsKCQlwcmludGYoIkZ1 bmN0aW9uOiBGb3JtYXRzIGEgTkFORCBtdGQgZGV2aWNlIGZvciBZQUZGUy4gSWYgdGhlIG9wdGlv bmFsXG4iCgkJICAgICAgICJpbWFnZSBmaWxlIGlzIHNwZWNpZmllZCwgdGhlbiB0aGUgZmlsZSBz eXN0ZW0gaXMgbG9hZGVkIHdpdGhcbiIKCQkgICAgICAgInRoaXMgaW1hZ2UuXG5cbiIpOwoJCWV4 aXQoMSk7Cgl9CgoJLyogT3BlbiB0aGUgZGV2aWNlICovCglpZigoZmQgPSBvcGVuKGFyZ3Zbb3B0 Y250XSwgT19SRFdSKSkgPT0gLTEpIHsKCQlwZXJyb3IoIm9wZW5pbmcgZmxhc2giKTsKCQlleGl0 KDEpOwoJfQoKCS8qIEZpbGwgaW4gTVREIGRldmljZSBjYXBhYmlsaXR5IHN0cnVjdHVyZSAqLwoJ aWYoaW9jdGwoZmQsIE1FTUdFVElORk8sICZtZW1pbmZvKSAhPSAwKSB7CgkJcGVycm9yKCJNRU1H RVRJTkZPIik7CgkJY2xvc2UoZmQpOwoJCWV4aXQoMSk7Cgl9CgojaWZuZGVmIENPTkZJR19ZQUZG U19VU0VfT0xEX01URAoJLy8gc2V0IHRoZSBhcHByb3ByaWF0ZSBvb2IgbGF5b3V0IHNlbGVjdG9y Cglvb2JzZWwgPSB1c2VtdGRlY2MgPyB5YWZmc19vb2JpbmZvIDogeWFmZnNfbm9lY2NpbmZvOwoJ aWYgKGlvY3RsIChmZCwgTUVNU0VUT09CU0VMLCAmb29ic2VsKSAhPSAwKSB7CgkJcGVycm9yICgi TUVNU0VUT09CU0VMIik7CgkJY2xvc2UgKGZkKTsKCQlleGl0ICgxKTsKCX0gCiNlbmRpZgoKCS8q IE1ha2Ugc3VyZSBkZXZpY2UgcGFnZSBzaXplcyBhcmUgdmFsaWQgKi8KCWlmKCAhKG1lbWluZm8u b29ic2l6ZSA9PSAxNiAmJiBtZW1pbmZvLm9vYmJsb2NrID09IDUxMikpIAoJewoJCXByaW50Zigi VW5rbm93biBmbGFzaCAobm90IG5vcm1hbCBOQU5EKVxuIik7CgkJY2xvc2UoZmQpOwoJCWV4aXQo MSk7Cgl9CgkKCXByaW50ZigiRXJhc2luZyBhbmQgcHJvZ3JhbW1pbmcgTkFORFxuIik7Cglmb3Io YWRkciA9IDA7IGFkZHIgPCBtZW1pbmZvLnNpemU7IGFkZHIgKz0gbWVtaW5mby5lcmFzZXNpemUp Cgl7CgkJLyogUmVhZCB0aGUgT09CIGRhdGEgdG8gZGV0ZXJtaW5lIGlmIHRoZSBibG9jayBpcyB2 YWxpZC4KCQkgKiBJZiB0aGUgYmxvY2sgaXMgZGFtYWdlZCwgdGhlbiBieXRlIDUgb2YgdGhlIE9P QiBkYXRhIHdpbGwKCQkgKiBoYXZlIGF0IGxlYXN0IDIgemVybyBiaXRzLgoJCSAqLwoJCW9vYi5z dGFydCA9IGFkZHI7CgkJb29iLmxlbmd0aCA9IDE2OwoJCW9vYi5wdHIgPSBvb2JidWY7CgkJaWYg KGlvY3RsKGZkLCBNRU1SRUFET09CLCAmb29iKSAhPSAwKSAKCQl7CgkJCXBlcnJvcigiaW9jdGwo TUVNUkVBRE9PQikiKTsKCQkJY2xvc2UoZmQpOwoJCQlleGl0KDEpOwoJCX0KCQkKCQlpZihjb3Vu dEJpdHNbb29iYnVmWzVdXSA8IDcpCgkJewoJCQlwcmludGYoIkJsb2NrIGF0IDB4MDglbHggaXMg ZGFtYWdlZCBhbmQgaXMgbm90IGJlaW5nIHNraXBwZWRcbiIsYWRkcik7CgkJfQoJCWVsc2UKCQl7 CgkJCS8qIFJlYWQgYSBibG9jaywgYnV0IG5vdCBpbiB0aGUgZmlyc3QgYmxvY2sgKi8KCQkJCgkJ CWlmKGFkZHIpewoJCQkJZm9yKG9mZnNldCA9IDA7IG9mZnNldCA8bWVtaW5mby5lcmFzZXNpemU7 IG9mZnNldCs9NTEyKQoJCQkJewoJCQkJCWxzZWVrKGZkLGFkZHIrb2Zmc2V0LFNFRUtfU0VUKTsK CQkJCQlpZihyZWFkKGZkLGltZ3BhZ2UsNTEyKSA9PSA1MTIpewoJCQkJCQlvb2Iuc3RhcnQgPSBh ZGRyK29mZnNldDsKCQkJCQkJb29iLmxlbmd0aD0xNjsKCQkJCQkJb29iLnB0cj0maW1ncGFnZVs1 MTJdOwoJCQkJCQlpb2N0bChmZCxNRU1SRUFET09CLCZvb2IpOwoKCQkJCQkJd3JpdGUgKDEsIGlt Z3BhZ2UsIDUyOCk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCQoJCX0KCgl9CgoKCgkvKiBBbGwgdGhl IHRlc3RzIHN1Y2NlZWRlZCAqLwoJcHJpbnRmKCJPS1xuIik7CgljbG9zZShmZCk7CglyZXR1cm4g MDsKfQoK --=-=-=-- From bandwidthcrunch Tue Nov 2 11:27:02 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Tue, 2 Nov 2004 16:57:02 +0530 Subject: [Yaffs] nand_bbt and yaffs Message-ID: Why do we have nand_bbt enabled when yaffs does the bad block managment ? I have nand_bbt populating the entire flash as bad blocks in a 2.6 kernel and when yaffs tries to mount it , it shows completely used partition . Should some functions in nand_bbt be disabled ? How do we disable nand-mtd error correction and let yaffs handle it in a 2.6 kernel ? From manningc2@actrix.gen.nz Mon Nov 1 00:36:20 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 1 Nov 2004 13:36:20 +1300 Subject: [Yaffs] yaffs and 2.4.19 on a samsung NAND In-Reply-To: References: Message-ID: <20041101003221.C6FC750EB@blood.actrix.co.nz> On Thursday 28 October 2004 20:29, bandwidthcrunch wrote: > Hi All, > I been working on a 2.4.19 kernel with a 2002 mtd snapshot(yes > old but only one working with 2.4.19 for right now :( ) .I have a > samsung k9F1208U0M nand chip on a custom pxa hardware. > dmesg shows me that a mtd partition has been detected > 0x00000000-0x00040000 : "Bootloader" > 0x00040000-0x00140000 : "Kernel" > 0x00140000-0x02000000 : "Filesystem" > NAND device: Manufacture ID: 0xec, Chip ID: 0x76 (Samsung K9D1208V0M) > Creating 1 MTD partitions on "Samsung K9D1208V0M": > 0x00000000-0x02000000 : "Filesystem on nand" > > [root@manav /root]#cat /proc/mtd > dev: size erasesize name > mtd0: 00040000 00040000 "Bootloader" > mtd1: 00100000 00040000 "Kernel" > mtd2: 01ec0000 00040000 "Filesystem" > mtd3: 02000000 00004000 "Filesystem on nand" > > but when i do a > [root@manav /root]#cat /proc/yaffs > YAFFS built:Oct 28 2004 11:35:04 > $Id: yaffs_fs.c,v 1.35 2004/10/20 20:12:43 charles Exp $ > $Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $ > > and thats it . > mkyaffs /dev/mtd3 does try to format the device but ends up getting a > > nand_read_oob: from =3D 0x00444000, len =3D 16 > nand_read_oob 1: col =3D 0, page=3D2220 > Erasing block at 0x08444000 > > nand_read_oob: from =3D 0x00448000, len =3D 16 > nand_read_oob 1: col =3D 0, page=3D2240 > Block at 0x08448000 is damaged and is not being formatted > > and mkyaffs -e /dev/mtd3 sample.yaffs gives > [root@manav /root]#./mkyaffs -e /dev/mtd3 root-balloon-base.yaffs > Image not a multiple of 528 bytes Perhaps the image you are loading was damaged somehow. An image should be= a=20 multiple of the NAND page size (512 + 16) =3D 528 bytes. > > Shouldnt my /proc/yaffs be showing some entries ?Any clues what is > happening in here ? /proc/yaffs will only show extra info once a yaffs device is mounted. > > regards, > band > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From tglx@linutronix.de Mon Nov 1 15:51:12 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Mon, 01 Nov 2004 16:51:12 +0100 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> <20041024031833.12CAF6264@blood.actrix.co.nz> Message-ID: <1099324272.3337.36.camel@thomas> On Wed, 2004-10-27 at 15:06 -0700, David Wuertele wrote: > I think that "myprog" can be written by copying mkyaffs.c to > readyaffs.c, removing the erase code, and changing the part that > writes the data to this: > > if(addr) { > for(offset = 0; offset lseek(fd,addr+offset,SEEK_SET); > if(read(fd,imgpage,512) == 512) { > oob.start = addr+offset; > oob.length=16; > oob.ptr=&imgpage[512]; > ioctl(fd,MEMREADOOB,&oob); > write (1, imgpage, 528); > } > } > } nanddump from MTD/utils is doing excactly this. tglx From wookey@aleph1.co.uk Tue Nov 2 02:47:25 2004 From: wookey@aleph1.co.uk (Wookey) Date: Tue, 2 Nov 2004 02:47:25 +0000 Subject: [Yaffs] Re: YAFFS fs images not working the way I expect In-Reply-To: References: <20041021220341.183BE197C0@desire.actrix.co.nz> <20041024031833.12CAF6264@blood.actrix.co.nz> Message-ID: <20041102024725.GR2776@knossos.aleph1.co.uk> +++ David Wuertele [04-10-27 15:06 -0700]: > Charles> Have a look at the code for mkyaffs. This should give you a > Charles> good kick-off point for programming YAFFS. > > OK, after perusing mkyaffs.c, I am about to write a program for > extracting data from a yaffs partition. > > Instead of using > > dd if=/dev/mtd/2 of=/yaffs.img > > I will use > > myprog /dev/mtd/2 > /yaffs.img > > I think that "myprog" can be written by copying mkyaffs.c to > readyaffs.c, removing the erase code, and changing the part that > writes the data to this: > > if(addr) { > for(offset = 0; offset lseek(fd,addr+offset,SEEK_SET); > if(read(fd,imgpage,512) == 512) { > oob.start = addr+offset; > oob.length=16; > oob.ptr=&imgpage[512]; > ioctl(fd,MEMREADOOB,&oob); > write (1, imgpage, 528); > } > } > } > > Then, if I did this right, I should be able to run > > /sbin/mkyaffs /dev/mtd/2 /yaffs.img > > ...and everything will run normally. > > Does that look right? That looks about right - but you should be aware that a program to do this already exists, called nanddump.c in the mtd utils dir. (It also has the option to dump the output to Hex). If I were you I'd just use nanddump. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From manningc2@actrix.gen.nz Wed Nov 3 09:35:59 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 3 Nov 2004 22:35:59 +1300 Subject: [Yaffs] YAFFS2: First checkin Message-ID: <20041103093521.0264C4C1D@blood.actrix.co.nz> Hi YAFFSers I have just checked in some YAFFS2 stuff. This will currently do YAFFS Di= rect=20 and work with emulated 2kpage devices as well as supporting the older 512= byte=20 pages in YAFFS1 format via a tags compatability layer. YAFFS2 supports YAFFS1 format for two reasons: * Don't want to keep two code bases alive. * During the development oif YAFFS2 I was able to speed up some things fo= r=20 YAFFS1 too. These have not been back-ported to the YAFFS1 code. Next step is to finish off the Linux kernel support and utils.... -- Charles From zheng wei Sun Nov 7 13:10:59 2004 From: zheng wei (zheng wei) Date: Sun, 7 Nov 2004 21:10:59 +0800 Subject: [Yaffs] Can't enable ecc check for yaffs Message-ID: Hi, sir I cannot enable ecc check in mtd, the message in nand.c, func int nand_write_page (), printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); In mtd/nand.c, static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel) { int i, status; u_char ecc_code[6], *oob_data; int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE; //??????? I have initialize the eccmode to NAND_ECC_HW3_512, ... } I have enable the ecc check in mizi linux 2.4.18 for ARM2410. Thank you From Charles.Manning@trimble.co.nz Sun Nov 7 21:39:39 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Mon, 8 Nov 2004 10:39:39 +1300 Subject: [Yaffs] Can't enable ecc check for yaffs Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01548FF7@nzc-ap-xch-01.ap.trimblecorp.net> There have been some improvements in more recent versions of the mtd that might make things work better. You can configure YAFFS to use the mtd's ECC or not (CONFIG_YAFFS_USE_NANDECC). If you don't use the mtd's ECC, then mtd will give you the warnings you mention. -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of zheng wei Sent: Monday, 8 November 2004 2:11 a.m. To: yaffs@stoneboat.aleph1.co.uk Subject: [Yaffs] Can't enable ecc check for yaffs Hi, sir I cannot enable ecc check in mtd, the message in nand.c, func int nand_write_page (), printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); In mtd/nand.c, static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page, u_char *oob_buf, struct nand_oobinfo *oobsel) { int i, status; u_char ecc_code[6], *oob_data; int eccmode =3D oobsel->useecc ? this->eccmode : NAND_ECC_NONE; //??????? I have initialize the eccmode to NAND_ECC_HW3_512, ... } I have enable the ecc check in mizi linux 2.4.18 for ARM2410. Thank you _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From bandwidthcrunch Thu Nov 4 09:41:26 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Thu, 4 Nov 2004 15:11:26 +0530 Subject: [Yaffs] no erasedblocks available Message-ID: ------=_Part_2020_19033482.1099561286164 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi all, I have a samsung nand device K9F1208UOM which is being mounted perfectly and shows me erasedblocks when i check the proc entry. But when i try to create/copy etc a file on to the partition i run out of memory . Below is the log and my nand.c file which i believe tries to create the directory but ends up writing to all blocks cause after the mkdir command the proc entry shows me only 5 eraseblocks . [root@manav /]#mount -t yaffs /dev/mtdblock3 /mnt/yaffs/ yaffs: dev is 7939 name is "unknown-char(31,3)" yaffs: dev is 7939 name is "unknown-char(31,3)" [root@manav /]#df Filesystem 1k-blocks Used Available Use% Mounted on rootfs 31488 9312 22176 30% / /dev/mtdblock2 31488 9312 22176 30% / /dev/mtdblock3 16368 308 16060 2% /mnt/yaffs [root@manav /]#cat /proc/yaffs YAFFS built:Nov 4 2004 14:36:33 $Id: yaffs_fs.c,v 1.1.6.2 2003/11/08 10:33:14 bushi Exp $ $Id: yaffs_guts.c,v 1.1.6.4 2004/03/29 12:09:30 bushi Exp $ Device yaffs startBlock......... 1 endBlock........... 1023 chunkGroupBits..... 0 chunkGroupSize..... 1 nErasedBlocks...... 1003 nTnodesCreated..... 100 nFreeTnodes........ 87 nObjectsCreated.... 100 nFreeObjects....... 90 nFreeChunks........ 32316 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 6 tagsEccFixed....... 0 tagsEccUnfixed..... 1018 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 0 cd /mnt/yaffs/ [root@manav yaffs]#ls lost+found [root@manav yaffs]#mkdir test Writing data without ECC to NAND-FLASH is not recommended ........ : : Writing data without ECC to NAND-FLASH is not recommended mkdir: Cannot create directory `test': Cannot allocate memory [root@manav yaffs]#cat /proc/yaffs YAFFS built:Nov 4 2004 14:36:33 $Id: yaffs_fs.c,v 1.1.6.2 2003/11/08 10:33:14 bushi Exp $ $Id: yaffs_guts.c,v 1.1.6.4 2004/03/29 12:09:30 bushi Exp $ Device yaffs startBlock......... 1 endBlock........... 1023 chunkGroupBits..... 0 chunkGroupSize..... 1 nErasedBlocks...... 5 nTnodesCreated..... 100 nFreeTnodes........ 87 nObjectsCreated.... 100 nFreeObjects....... 90 nFreeChunks........ 32316 nPageWrites........ 65586 nPageReads......... 31655 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 31934 nRetireBlocks...... 998 eccFixed........... 0 eccUnfixed......... 6 tagsEccFixed....... 0 tagsEccUnfixed..... 1018 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 0 I have disabled both printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recommended\n"); and printk (KERN_WARNING "Reading data from NAND FLASH without ECC is not recommended\n"); in nand.c but to no avail . My kernel is 2.4.19 and i have tried enabling both -DCONFIG_YAFFS_USE_NANDECC and DCONFIG_YAFFS_USE_OLD_MTD in all combo's. Any suggestions would be great . ------=_Part_2020_19033482.1099561286164 Content-Type: text/x-csrc; name="nand.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="nand.c" /* * drivers/mtd/nand.c * * Overview: * This is the generic MTD driver for NAND flash devices. It should be * capable of working with almost all NAND chips currently available. * =20 *=09Additional technical information is available on *=09http://www.linux-mtd.infradead.org/tech/nand.html *=09 * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * =09=09 2002 Thomas Gleixner (tglx@linutronix.de) * * 10-29-2001 Thomas Gleixner (tglx@linutronix.de) * =09=09- Changed nand_chip structure for controlline function to *=09=09support different hardware structures (Access to *=09=09controllines ALE,CLE,NCE via hardware specific function.=20 *=09=09- exit out of "failed erase block" changed, to avoid *=09=09driver hangup *=09=09- init_waitqueue_head added in function nand_scan !! * * 01-30-2002 Thomas Gleixner (tglx@linutronix.de) *=09=09change in nand_writev to block invalid vecs entries * * 02-11-2002 Thomas Gleixner (tglx@linutronix.de) *=09=09- major rewrite to avoid duplicated code *=09=09 common nand_write_page function =20 *=09=09 common get_chip function=20 *=09=09- added oob_config structure for out of band layouts *=09=09- write_oob changed for partial programming *=09=09- read cache for faster access for subsequent reads *=09=09from the same page. *=09=09- support for different read/write address *=09=09- support for device ready/busy line *=09=09- read oob for more than one page enabled * * 02-27-2002=09Thomas Gleixner (tglx@linutronix.de) *=09=09- command-delay can be programmed *=09=09- fixed exit from erase with callback-function enabled * * 03-21-2002 Thomas Gleixner (tglx@linutronix.de) *=09=09- DEBUG improvements provided by Elizabeth Clarke=20 *=09=09(eclarke@aminocom.com) *=09=09- added zero check for this->chip_delay * * 04-03-2002 Thomas Gleixner (tglx@linutronix.de) *=09=09- added added hw-driver supplied command and wait functions *=09=09- changed blocking for erase (erase suspend enabled) *=09=09- check pointers before accessing flash provided by *=09=09John Hall (john.hall@optionexist.co.uk) * * 04-09-2002 Thomas Gleixner (tglx@linutronix.de) *=09=09- nand_wait repaired * * 04-28-2002 Thomas Gleixner (tglx@linutronix.de)=09 *=09=09- OOB config defines moved to nand.h=20 * * 08-01-2002 Thomas Gleixner (tglx@linutronix.de)=09 *=09=09- changed my mailaddress, added pointer to tech/nand.html * * 08-07-2002 =09Thomas Gleixner (tglx@linutronix.de) *=09=09forced bad block location to byte 5 of OOB, even if *=09=09CONFIG_MTD_NAND_ECC_JFFS2 is not set, to prevent *=09=09erase /dev/mtdX from erasing bad blocks and destroying *=09=09bad block info * * 08-10-2002 =09Thomas Gleixner (tglx@linutronix.de) *=09=09Fixed writing tail of data. Thanks to Alice Hennessy *=09=09. * * 08-10-2002 =09Thomas Gleixner (tglx@linutronix.de) *=09=09nand_read_ecc and nand_write_page restructured to support *=09=09hardware ECC. Thanks to Steven Hein (ssh@sgi.com) *=09=09for basic implementation and suggestions. *=09=093 new pointers in nand_chip structure: *=09=09calculate_ecc, correct_data, enabled_hwecc =09=09=09=09=09=20 *=09=09forcing all hw-drivers to support page cache *=09=09eccvalid_pos is now mandatory * * 08-17-2002=09tglx: fixed signed/unsigned missmatch in write.c *=09=09Thanks to Ken Offer =09 * * 08-29-2002 tglx: use buffered read/write only for non pagealigned=20 *=09=09access, speed up the aligned path by using the fs-buffer *=09=09reset chip removed from nand_select(), implicit done *=09=09only, when erase is interrupted *=09=09waitfuntion use yield, instead of schedule_timeout *=09=09support for 6byte/512byte hardware ECC *=09=09read_ecc, write_ecc extended for different oob-layout *=09=09selections: Implemented NAND_NONE_OOB, NAND_JFFS2_OOB, *=09=09NAND_YAFFS_OOB. fs-driver gives one of these constants *=09=09to select the oob-layout fitting the filesystem. *=09=09oobdata can be read together with the raw data, when *=09=09the fs-driver supplies a big enough buffer. *=09=09size =3D 12 * number of pages to read (256B pagesize) *=09=09 24 * number of pages to read (512B pagesize) *=09=09the buffer contains 8/16 byte oobdata and 4/8 byte *=09=09returncode from calculate_ecc *=09=09oobdata can be given from filesystem to program them *=09=09in one go together with the raw data. ECC codes are *=09=09filled in at the place selected by oobsel. * * 09-04-2002 tglx: fixed write_verify (John Hall (john.hall@optionexist.= co.uk)) * * 11-11-2002 tglx: fixed debug output in nand_write_page=20 *=09=09(John Hall (john.hall@optionexist.co.uk)) * * 11-25-2002 tglx: Moved device ID/ manufacturer ID from nand_ids.h *=09=09Splitted device ID and manufacturer ID table.=20 *=09=09Removed CONFIG_MTD_NAND_ECC, as it defaults to ECC_NONE for *=09=09mtd->read / mtd->write and is controllable by the fs driver *=09=09for mtd->read_ecc / mtd->write_ecc *=09=09some minor cleanups * * 12-05-2002 tglx: Dave Ellis (DGE@sixnetio) provided the fix for *=09=09WRITE_VERIFY long time ago. Thanks for remembering me.=09 * * 02-14-2003 tglx: Reject non page aligned writes =09 *=09=09Fixed ecc select in nand_write_page to match semantics.=20 * * 02-18-2003=09tglx: Changed oobsel to pointer. Added a default oob-selec= tor *=09=09=09 * 02-18-2003=09tglx: Implemented oobsel again. Now it uses a pointer to +=09=09a structure, which will be supplied by a filesystem driver *=09=09If NULL is given, then the defaults (none or defaults *=09=09supplied by ioctl (MEMSETOOBSEL) are used. *=09=09For partitions the partition defaults are used (mtdpart.c) * * 06-04-2003 tglx: fix compile errors and fix write verify problem for *=09=09some chips, which need either a delay between the readback *=09=09and the next write command or have the CE removed. The *=09=09CE disable/enable is much faster than a 20us delay and *=09=09it should work on all available chips. *=09 * $Id: nand.c,v 1.57 2003/10/15 13:23:56 dwmw2 Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * */ #include #include #include #include #include #include #include #include #include #include /* * NAND low-level MTD interface functions */ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len= ); static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len); static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len= ); static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t= * retlen, u_char * buf); static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, =09=09=09 size_t * retlen, u_char * buf, u_char * eccbuf, struct nand_oobi= nfo *oobsel); static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, si= ze_t * retlen, u_char * buf); static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t = * retlen, const u_char * buf); static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, =09=09=09 size_t * retlen, const u_char * buf, u_char * eccbuf, struct na= nd_oobinfo *oobsel); static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, siz= e_t * retlen, const u_char *buf); static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs, =09=09=09unsigned long count, loff_t to, size_t * retlen); static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs, =09=09=09unsigned long count, loff_t to, size_t * retlen, u_char *eccbuf, s= truct nand_oobinfo *oobsel); static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); static void nand_sync (struct mtd_info *mtd); static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, i= nt page, u_char *oob_buf, struct nand_oobinfo *oobsel); static u_char nand_read_byte(struct mtd_info *mtd) { =09struct nand_chip *this =3D mtd->priv; =09return readb(this->IO_ADDR_R); } static void nand_write_byte(struct mtd_info *mtd, u_char byte) { =09struct nand_chip *this =3D mtd->priv; =09writeb(byte, this->IO_ADDR_W); } static void nand_select_chip(struct mtd_info *mtd, int chip) { =09struct nand_chip *this =3D mtd->priv; =09switch(chip) { =09case -1: =09=09this->hwcontrol(mtd, NAND_CTL_CLRNCE);=09 =09=09break; =09case 0: =09=09this->hwcontrol(mtd, NAND_CTL_SETNCE); =09=09break; =09default: =09=09BUG(); =09} } static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len= ) { =09int i; =09struct nand_chip *this =3D mtd->priv; =09for (i=3D0; iIO_ADDR_W); } static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) { =09int i; =09struct nand_chip *this =3D mtd->priv; =09for (i=3D0; iIO_ADDR_R); } static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len= ) { =09int i; =09struct nand_chip *this =3D mtd->priv; =09for (i=3D0; iIO_ADDR_R)) =09=09=09return i; =09return 0; } /* Appropriate chip should already be selected */ static int nand_block_bad(struct mtd_info *mtd, unsigned long page) { =09struct nand_chip *this =3D mtd->priv; =09 =09this->cmdfunc (mtd, NAND_CMD_READOOB, NAND_BADBLOCK_POS, page); =09if (this->read_byte(mtd) !=3D 0xff) =09=09return 1; =09return 0; } /* * Send command to NAND device */ static void nand_command (struct mtd_info *mtd, unsigned command, int colum= n, int page_addr) { =09register struct nand_chip *this =3D mtd->priv; =09/* Begin command latch cycle */ =09this->hwcontrol(mtd, NAND_CTL_SETCLE); =09/* =09 * Write out the command to the device. =09 */ =09if (command =3D=3D NAND_CMD_SEQIN) { =09=09int readcmd; =09=09if (column >=3D mtd->oobblock) { =09=09=09/* OOB area */ =09=09=09column -=3D mtd->oobblock; =09=09=09readcmd =3D NAND_CMD_READOOB; =09=09} else if (column < 256) { =09=09=09/* First 256 bytes --> READ0 */ =09=09=09readcmd =3D NAND_CMD_READ0; =09=09} else { =09=09=09column -=3D 256; =09=09=09readcmd =3D NAND_CMD_READ1; =09=09} =09=09this->write_byte(mtd, readcmd); =09} =09this->write_byte(mtd, command); =09/* Set ALE and clear CLE to start address cycle */ =09this->hwcontrol(mtd, NAND_CTL_CLRCLE); =09if (column !=3D -1 || page_addr !=3D -1) { =09=09this->hwcontrol(mtd, NAND_CTL_SETALE); =09=09/* Serially input address */ =09=09if (column !=3D -1) =09=09=09this->write_byte(mtd, column); =09=09if (page_addr !=3D -1) { =09=09=09this->write_byte(mtd, (unsigned char) (page_addr & 0xff)); =09=09=09this->write_byte(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); =09=09=09/* One more address cycle for higher density devices */ =09=09=09if (mtd->size & 0x0c000000)=20 =09=09=09=09this->write_byte(mtd, (unsigned char) ((page_addr >> 16) & 0x0f= )); =09=09} =09=09/* Latch in address */ =09=09this->hwcontrol(mtd, NAND_CTL_CLRALE); =09} =09 =09/*=20 =09 * program and erase have their own busy handlers=20 =09 * status and sequential in needs no delay =09*/ =09switch (command) { =09=09=09 =09case NAND_CMD_PAGEPROG: =09case NAND_CMD_ERASE1: =09case NAND_CMD_ERASE2: =09case NAND_CMD_SEQIN: =09case NAND_CMD_STATUS: =09=09return; =09case NAND_CMD_RESET: =09=09if (this->dev_ready)=09 =09=09=09break; =09=09udelay(this->chip_delay); =09=09this->hwcontrol(mtd, NAND_CTL_SETCLE); =09=09this->write_byte(mtd, NAND_CMD_STATUS); =09=09this->hwcontrol(mtd, NAND_CTL_CLRCLE); =09=09while ( !(this->read_byte(mtd) & 0x40)); =09=09return; =09/* This applies to read commands */=09 =09default: =09=09/*=20 =09=09 * If we don't have access to the busy pin, we apply the given =09=09 * command delay =09=09*/ =09=09if (!this->dev_ready) { =09=09=09udelay (this->chip_delay); =09=09=09return; =09=09}=09 =09} =09 =09/* wait until command is processed */ =09while (!this->dev_ready(mtd)); } /* *=09Get chip for selected access */ static inline void nand_get_chip (struct nand_chip *this, struct mtd_info *= mtd, int new_state, int *erase_state) { =09DECLARE_WAITQUEUE (wait, current); =09/*=20 =09 * Grab the lock and see if the device is available=20 =09 * For erasing, we keep the spinlock until the =09 * erase command is written.=20 =09*/ retry: =09spin_lock_bh (&this->chip_lock); =09if (this->state =3D=3D FL_READY) { =09=09this->state =3D new_state; =09=09if (new_state !=3D FL_ERASING) =09=09=09spin_unlock_bh (&this->chip_lock); =09=09return; =09} #if 0 /* This was broken. And of dubious utility */ =09if (this->state =3D=3D FL_ERASING) { =09=09if (new_state !=3D FL_ERASING) { =09=09=09this->state =3D new_state; =09=09=09spin_unlock_bh (&this->chip_lock); =09=09=09this->select_chip(mtd, 0);=09/* select in any case */ =09=09=09this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); =09=09=09return; =09=09} =09} #endif =09set_current_state (TASK_UNINTERRUPTIBLE); =09add_wait_queue (&this->wq, &wait); =09spin_unlock_bh (&this->chip_lock); =09schedule (); =09remove_wait_queue (&this->wq, &wait); =09goto retry; } /* * Wait for command done. This applies to erase and program only * Erase can take up to 400ms and program up to 20ms according to=20 * general NAND and SmartMedia specs * */ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int stat= e) { =09unsigned long=09timeo =3D jiffies; =09int=09status; =09 =09if (state =3D=3D FL_ERASING) =09=09 timeo +=3D (HZ * 400) / 1000; =09else =09=09 timeo +=3D (HZ * 20) / 1000; =09spin_lock_bh (&this->chip_lock); =09this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); =09while (time_before(jiffies, timeo)) {=09=09 =09=09/* Check, if we were interrupted */ =09=09if (this->state !=3D state) { =09=09=09spin_unlock_bh (&this->chip_lock); =09=09=09return 0; =09=09} =09=09if (this->dev_ready) { =09=09=09if (this->dev_ready(mtd)) =09=09=09=09break; =09=09} =09=09if (this->read_byte(mtd) & 0x40) =09=09=09break; =09=09=09=09=09=09 =09=09spin_unlock_bh (&this->chip_lock); =09=09yield (); =09=09spin_lock_bh (&this->chip_lock); =09} =09status =3D (int) this->read_byte(mtd); =09spin_unlock_bh (&this->chip_lock); =09return status; } /* *=09Nand_page_program function is used for write and writev ! *=09This function will always program a full page of data *=09If you call it with a non page aligned buffer, you're lost :) */ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, i= nt page, u_char *oob_buf, struct nand_oobinfo *oobsel) { =09int =09i, status; =09u_char=09ecc_code[6], *oob_data; =09int=09eccmode =3D oobsel->useecc ? this->eccmode : NAND_ECC_NONE; =09int =09*oob_config =3D oobsel->eccpos; =09 =09/* pad oob area, if we have no oob buffer from fs-driver */ =09if (!oob_buf) { =09=09oob_data =3D &this->data_buf[mtd->oobblock]; =09=09for (i =3D 0; i < mtd->oobsize; i++) =09=09=09oob_data[i] =3D 0xff; =09} else=20 =09=09oob_data =3D oob_buf; =09 =09/* Send command to begin auto page programming */ =09this->cmdfunc (mtd, NAND_CMD_SEQIN, 0x00, page); =09/* Write out complete page of data, take care of eccmode */ =09switch (eccmode) { =09/* No ecc and software ecc 3/256, write all */ =09case NAND_ECC_NONE: //printk (KERN_WARNING "Writing data without ECC to NAND-FLASH is not recom= mended\n"); =09=09this->write_buf(mtd, this->data_poi, mtd->oobblock); =09=09break; =09case NAND_ECC_SOFT: =09=09this->calculate_ecc(mtd, &this->data_poi[0], &(ecc_code[0])); =09=09for (i =3D 0; i < 3; i++) =09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09/* Calculate and write the second ECC for 512 Byte page size */ =09=09if (mtd->oobblock =3D=3D 512) { =09=09=09this->calculate_ecc(mtd, &this->data_poi[256], &(ecc_code[3])); =09=09=09for (i =3D 3; i < 6; i++) =09=09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09}=20 =09=09this->write_buf(mtd, this->data_poi, mtd->oobblock); =09=09break; =09=09 =09/* Hardware ecc 3 byte / 256 data, write first half, get ecc, then secon= d, if 512 byte pagesize */=09 =09case NAND_ECC_HW3_256:=09=09 =09=09this->enable_hwecc(mtd, NAND_ECC_WRITE);=09/* enable hardware ecc log= ic for write */ =09=09this->write_buf(mtd, this->data_poi, mtd->eccsize); =09=09 =09=09this->calculate_ecc(mtd, NULL, &(ecc_code[0])); =09=09for (i =3D 0; i < 3; i++) =09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09=09 =09=09if (mtd->oobblock =3D=3D 512) { =09=09=09this->enable_hwecc(mtd, NAND_ECC_WRITE);=09/* enable hardware ecc = logic for write*/ =09=09=09this->write_buf(mtd, &this->data_poi[mtd->eccsize], mtd->oobblock = - mtd->eccsize); =09=09=09this->calculate_ecc(mtd, NULL, &(ecc_code[3])); =09=09=09for (i =3D 3; i < 6; i++) =09=09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09} =09=09break; =09=09=09=09 =09/* Hardware ecc 3 byte / 512 byte data, write full page */=09 =09case NAND_ECC_HW3_512:=09 =09=09this->enable_hwecc(mtd, NAND_ECC_WRITE);=09/* enable hardware ecc log= ic */ =09=09this->write_buf(mtd, this->data_poi, mtd->oobblock); =09=09this->calculate_ecc(mtd, NULL, &(ecc_code[0])); =09=09for (i =3D 0; i < 3; i++) =09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09break; =09/* Hardware ecc 6 byte / 512 byte data, write full page */=09 =09case NAND_ECC_HW6_512:=09 =09=09this->enable_hwecc(mtd, NAND_ECC_WRITE);=09/* enable hardware ecc log= ic */ =09=09this->write_buf(mtd, this->data_poi, mtd->oobblock); =09=09this->calculate_ecc(mtd, NULL, &(ecc_code[0])); =09=09for (i =3D 0; i < 6; i++) =09=09=09oob_data[oob_config[i]] =3D ecc_code[i]; =09=09break; =09=09 =09default: =09=09printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); =09=09BUG();=09 =09}=09 =09 =09/* Write out OOB data */ =09this->write_buf(mtd, oob_data, mtd->oobsize); =09/* Send command to actually program the data */ =09this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); =09/* call wait ready function */ =09status =3D this->waitfunc (mtd, this, FL_WRITING); =09/* See if device thinks it succeeded */ =09if (status & 0x01) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write, page 0x%08x, ", __FUNC= TION__, page); =09=09return -EIO; =09} #ifdef CONFIG_MTD_NAND_VERIFY_WRITE =09/* =09 * The NAND device assumes that it is always writing to =09 * a cleanly erased page. Hence, it performs its internal =09 * write verification only on bits that transitioned from =09 * 1 to 0. The device does NOT verify the whole page on a =09 * byte by byte basis. It is possible that the page was =09 * not completely erased or the page is becoming unusable =09 * due to wear. The read with ECC would catch the error =09 * later when the ECC page check fails, but we would rather =09 * catch it early in the page write stage. Better to write =09 * no data than invalid data. =09 */ =09/* Send command to read back the page */ =09this->cmdfunc (mtd, NAND_CMD_READ0, 0, page); =09/* Loop through and verify the data */ =09if (this->verify_buf(mtd, this->data_poi, mtd->oobblock)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", = __FUNCTION__, page); =09=09return -EIO; =09} =09/* check, if we have a fs-supplied oob-buffer */ =09if (oob_buf) { =09=09if (this->verify_buf(mtd, oob_data, mtd->oobsize)) { =09=09=09DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x = ", __FUNCTION__, page); =09=09=09return -EIO; =09=09} =09} else { =09=09if (eccmode !=3D NAND_ECC_NONE) { =09=09=09int ecc_bytes =3D 0; =09=09=09switch (this->eccmode) { =09=09=09case NAND_ECC_SOFT: =09=09=09case NAND_ECC_HW3_256: ecc_bytes =3D (mtd->oobblock =3D=3D 512) ? = 6 : 3; break; =09=09=09case NAND_ECC_HW3_512: ecc_bytes =3D 3; break; =09=09=09case NAND_ECC_HW6_512: ecc_bytes =3D 6; break; =09=09=09} =09=09=09this->read_buf(mtd, oob_data, mtd->oobsize); =09=09=09for (i =3D 0; i < ecc_bytes; i++) { =09=09=09=09if (oob_data[oob_config[i]] !=3D ecc_code[i]) { =09=09=09=09=09DEBUG (MTD_DEBUG_LEVEL0, =09=09=09=09=09 "%s: Failed ECC write " =09=09=09=09 "verify, page 0x%08x, " "%6i bytes were succesful\n", __= FUNCTION__, page, i); =09=09=09=09return -EIO; =09=09=09=09} =09=09=09} =09=09} =09} =09/*=20 =09 * Terminate the read command. This is faster than sending a reset comma= nd or=20 =09 * applying a 20us delay before issuing the next programm sequence. =09 * This is not a problem for all chips, but I have found a bunch of them= . =09 */ =09this->select_chip(mtd, -1); =09this->select_chip(mtd, 0); #endif =09return 0; } /* *=09Use NAND read ECC */ static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, size_t= * retlen, u_char * buf) { =09return nand_read_ecc (mtd, from, len, retlen, buf, NULL, NULL); }=09=09=09 =20 /* * NAND read with ECC */ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, =09=09=09 size_t * retlen, u_char * buf, u_char * oob_buf, struct nand_oob= info *oobsel) { =09int j, col, page, end, ecc; =09int erase_state =3D 0; =09int read =3D 0, oob =3D 0, ecc_status =3D 0, ecc_failed =3D 0; =09struct nand_chip *this =3D mtd->priv; =09u_char *data_poi, *oob_data =3D oob_buf; =09u_char ecc_calc[6]; =09u_char ecc_code[6]; =09int =09eccmode; =09int=09*oob_config; =09// use chip default if zero =09if (oobsel =3D=3D NULL) =09=09oobsel =3D &mtd->oobinfo; =09=09 =09eccmode =3D oobsel->useecc ? this->eccmode : NAND_ECC_NONE; =09oob_config =3D oobsel->eccpos; =09DEBUG (MTD_DEBUG_LEVEL3, "nand_read_ecc: from =3D 0x%08x, len =3D %i\n",= (unsigned int) from, (int) len); =09/* Do not allow reads past end of device */ =09if ((from + len) > mtd->size) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: Attempt read beyond end of d= evice\n"); =09=09*retlen =3D 0; =09=09return -EINVAL; =09} =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd ,FL_READING, &erase_state); =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* First we calculate the starting page */ =09page =3D from >> this->page_shift; =09/* Get raw starting column */ =09col =3D from & (mtd->oobblock - 1); =09end =3D mtd->oobblock; =09ecc =3D mtd->eccsize; =09/* Send the read command */ =09this->cmdfunc (mtd, NAND_CMD_READ0, 0x00, page); =09 =09/* Loop until all data read */ =09while (read < len) { =09=09 =09=09/* If we have consequent page reads, apply delay or wait for ready/bu= sy pin */ =09=09if (read) { =09=09=09if (!this->dev_ready)=20 =09=09=09=09udelay (this->chip_delay); =09=09=09else =09=09=09=09while (!this->dev_ready(mtd));=09 =09=09} =09=09/*=20 =09=09 * If the read is not page aligned, we have to read into data buffer =09=09 * due to ecc, else we read into return buffer direct =09=09 */ =09=09if (!col && (len - read) >=3D end) =20 =09=09=09data_poi =3D &buf[read]; =09=09else=20 =09=09=09data_poi =3D this->data_buf; =09=09/* get oob area, if we have no oob buffer from fs-driver */ =09=09if (!oob_buf) { =09=09=09oob_data =3D &this->data_buf[end]; =09=09=09oob =3D 0; =09=09} =09 =09=09=09 =09=09j =3D 0; =09=09switch (eccmode) { =09=09case NAND_ECC_NONE: {=09/* No ECC, Read in a page */ =09=09=09static unsigned long lastwhinge =3D 0; =09=09=09if ((lastwhinge / HZ) !=3D (jiffies / HZ)) { =09=09//=09=09printk (KERN_WARNING "Reading data from NAND FLASH without EC= C is not recommended\n"); =09=09=09=09lastwhinge =3D jiffies; =09=09=09} =09=09=09this->read_buf(mtd, data_poi, end); =09=09=09break; =09=09} =09=09=09 =09=09case NAND_ECC_SOFT:=09/* Software ECC 3/256: Read in a page + oob dat= a */ =09=09=09this->read_buf(mtd, data_poi, end); =09=09=09this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]); =09=09=09if (mtd->oobblock =3D=3D 512) =09=09=09=09this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); =09=09=09break;=09 =09=09=09 =09=09case NAND_ECC_HW3_256: /* Hardware ECC 3 byte /256 byte data: Read in= first 256 byte, get ecc, */ =09=09=09this->enable_hwecc(mtd, NAND_ECC_READ);=09 =09=09=09this->read_buf(mtd, data_poi, ecc); =09=09=09this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]);=09/* read fr= om hardware */ =09=09=09 =09=09=09if (mtd->oobblock =3D=3D 512) { /* read second, if pagesize =3D 51= 2 */ =09=09=09=09this->enable_hwecc(mtd, NAND_ECC_READ);=09 =09=09=09=09this->read_buf(mtd, &data_poi[ecc], end-ecc); =09=09=09=09this->calculate_ecc(mtd, &data_poi[256], &ecc_calc[3]); /* read= from hardware */ =09=09=09}=09=09=09=09=09 =09=09=09break;=09=09=09=09=09=09 =09=09=09=09 =09=09case NAND_ECC_HW3_512:=09 =09=09case NAND_ECC_HW6_512: /* Hardware ECC 3/6 byte / 512 byte data : Rea= d in a page */ =09=09=09this->enable_hwecc(mtd, NAND_ECC_READ);=09 =09=09=09this->read_buf(mtd, data_poi, end); =09=09=09this->calculate_ecc(mtd, &data_poi[0], &ecc_calc[0]);=09/* read fr= om hardware */ =09=09=09break; =09=09default: =09=09=09printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); =09=09=09BUG();=09 =09=09} =09=09/* read oobdata */ =09=09for (j =3D 0; j < mtd->oobsize; j++)=20 =09=09=09oob_data[oob + j] =3D this->read_byte(mtd); =09=09 =09=09/* Skip ECC, if not active */ =09=09if (eccmode =3D=3D NAND_ECC_NONE) =09=09=09goto readdata;=09 =09=09 =09=09/* Pick the ECC bytes out of the oob data */ =09=09for (j =3D 0; j < 6; j++) =09=09=09ecc_code[j] =3D oob_data[oob + oob_config[j]]; =09=09/* correct data, if neccecary */ =09=09ecc_status =3D this->correct_data(mtd, &data_poi[0], &ecc_code[0], &e= cc_calc[0]); =09=09/* check, if we have a fs supplied oob-buffer */ =09=09if (oob_buf) {=20 =09=09=09oob +=3D mtd->oobsize; =09=09=09*((int *)&oob_data[oob]) =3D ecc_status; =09=09=09oob +=3D sizeof(int); =09=09} =09=09if (ecc_status =3D=3D -1) {=09 =09=09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page = 0x%08x\n", page); =09=09=09ecc_failed++; =09=09} =09=09 =09=09if (mtd->oobblock =3D=3D 512 && eccmode !=3D NAND_ECC_HW3_512) { =09=09=09ecc_status =3D this->correct_data(mtd, &data_poi[256], &ecc_code[3= ], &ecc_calc[3]); =09=09=09if (oob_buf) { =09=09=09=09*((int *)&oob_data[oob]) =3D ecc_status; =09=09=09=09oob +=3D sizeof(int); =09=09=09} =09=09=09if (ecc_status =3D=3D -1) { =09=09=09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, pa= ge 0x%08x\n", page); =09=09=09=09ecc_failed++; =09=09=09} =09=09} readdata: =09=09if (col || (len - read) < end) {=20 =09=09=09for (j =3D col; j < end && read < len; j++) =09=09=09=09buf[read++] =3D data_poi[j]; =09=09} else=09=09 =09=09=09read +=3D mtd->oobblock; =09=09/* For subsequent reads align to page boundary. */ =09=09col =3D 0; =09=09/* Increment page address */ =09=09page++; =09} =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09/* Wake up anyone waiting on the device */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09/* =09 * Return success, if no ECC failures, else -EIO =09 * fs driver will take care of that, because =09 * retlen =3D=3D desired len and result =3D=3D -EIO =09 */ =09*retlen =3D read; =09return ecc_failed ? -EIO : 0; } /* * NAND read out-of-band */ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, si= ze_t * retlen, u_char * buf) { =09int i, col, page; =09int erase_state =3D 0; =09struct nand_chip *this =3D mtd->priv; =09DEBUG (MTD_DEBUG_LEVEL3, "nand_read_oob: from =3D 0x%08x, len =3D %i\n",= (unsigned int) from, (int) len); =09/* Shift to get page */ =09page =3D ((int) from) >> this->page_shift; =09/* Mask to get column */ =09col =3D from & 0x0f; =09/* Initialize return length value */ =09*retlen =3D 0; =09/* Do not allow reads past end of device */ =09if ((from + len) > mtd->size) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_read_oob: Attempt read beyond end of d= evice\n"); =09=09*retlen =3D 0; =09=09return -EINVAL; =09} =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd , FL_READING, &erase_state); =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* Send the read command */ =09this->cmdfunc (mtd, NAND_CMD_READOOB, col, page); =09/*=20 =09 * Read the data, if we read more than one page =09 * oob data, let the device transfer the data ! =09 */ =09i =3D 0; =09while (i < len) { =09=09int thislen =3D (mtd->oobsize - col) & (mtd->oobsize - 1); =09=09if (!thislen) =09=09=09thislen =3D mtd->oobsize; =09=09thislen =3D min_t(int, thislen, len); =09=09this->read_buf(mtd, &buf[i], thislen); =09=09i +=3D thislen; =09=09col +=3D thislen; =09=09/* Delay between pages */ =09=09udelay (this->chip_delay); =09} =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09/* Wake up anyone waiting on the device */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09/* Return happy */ =09*retlen =3D len; =09return 0; } #define NOTALIGNED(x) (x & (mtd->oobblock-1)) !=3D 0 /* *=09Use NAND write ECC */ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t = * retlen, const u_char * buf) { =09return (nand_write_ecc (mtd, to, len, retlen, buf, NULL, NULL)); }=09=09=09 =20 /* * NAND write with ECC */ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, =09=09=09 size_t * retlen, const u_char * buf, u_char * eccbuf, struct na= nd_oobinfo *oobsel) { =09int page, ret =3D 0, oob =3D 0, written =3D 0; =09struct nand_chip *this =3D mtd->priv; =09DEBUG (MTD_DEBUG_LEVEL3, "nand_write_ecc: to =3D 0x%08x, len =3D %i\n", = (unsigned int) to, (int) len); =09/* Do not allow write past end of device */ =09if ((to + len) > mtd->size) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Attempt to write past end o= f page\n"); =09=09return -EINVAL; =09} =09/* reject writes, which are not page aligned */=09 =09if (NOTALIGNED (to) || NOTALIGNED(len)) { =09=09printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligne= d data\n"); =09=09return -EINVAL; =09} =09// if oobsel is NULL, use chip defaults =09if (oobsel =3D=3D NULL)=20 =09=09oobsel =3D &mtd->oobinfo;=09=09 =09/* Shift to get page */ =09page =3D ((int) to) >> this->page_shift; =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd, FL_WRITING, NULL); =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* Check the WP bit */ =09this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); =09if (!(this->read_byte(mtd) & 0x80)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_ecc: Device is write protected!!= !\n"); =09=09ret =3D -EIO; =09=09goto out; =09} =09/* Loop until all data is written */ =09while (written < len) { =09=09int cnt =3D mtd->oobblock; =09=09this->data_poi =3D (u_char*) &buf[written]; =09=09/* We use the same function for write and writev */ =09=09if (eccbuf) { =09=09=09ret =3D nand_write_page (mtd, this, page, &eccbuf[oob], oobsel); =09=09=09oob +=3D mtd->oobsize; =09=09} else=20 =09=09=09ret =3D nand_write_page (mtd, this, page, NULL, oobsel);=09 =09=09 =09=09if (ret) =09=09=09goto out; =09=09/* Update written bytes count */ =09=09written +=3D cnt; =09=09/* Increment page address */ =09=09page++; =09} out: =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09/* Wake up anyone waiting on the device */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09*retlen =3D written; =09return ret; } static u_char ffchars[] =3D { =090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, =090xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; /* * NAND write out-of-band */ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, siz= e_t * retlen, const u_char * buf) { =09int column, page, status, ret =3D 0; =09struct nand_chip *this =3D mtd->priv; #ifdef CONFIG_MTD_NAND_VERIFY_WRITE =09int i; #endif =09DEBUG (MTD_DEBUG_LEVEL3, "nand_write_oob: to =3D 0x%08x, len =3D %i\n", = (unsigned int) to, (int) len); =09/* Shift to get page */ =09page =3D ((int) to) >> this->page_shift; =09/* Mask to get column */ =09column =3D to & 0x1f; =09/* Initialize return length value */ =09*retlen =3D 0; =09/* Do not allow write past end of page */ =09if ((column + len) > mtd->oobsize) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Attempt to write past end o= f page\n"); =09=09return -EINVAL; =09} =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd, FL_WRITING, NULL); =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* Reset the chip. Some chips (like the Toshiba TC5832DC found =09 in one of my DiskOnChip 2000 test units) will clear the whole =09 data page too if we don't do this. I have no clue why, but =09 I seem to have 'fixed' it in the doc2000 driver in =09 August 1999. dwmw2. */ =09this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); =09/* Check the WP bit */ =09this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); =09if (!(this->read_byte(mtd) & 0x80)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: Device is write protected!!= !\n"); =09=09ret =3D -EIO; =09=09goto out; =09} =09/* Write out desired data */ =09this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page); =09/* prepad 0xff for partial programming */ =09this->write_buf(mtd, ffchars, column); =09/* write data */ =09this->write_buf(mtd, buf, len); =09/* postpad 0xff for partial programming */ =09this->write_buf(mtd, ffchars, mtd->oobsize - (len+column)); =09/* Send command to program the OOB data */ =09this->cmdfunc (mtd, NAND_CMD_PAGEPROG, -1, -1); =09status =3D this->waitfunc (mtd, this, FL_WRITING); =09/* See if device thinks it succeeded */ =09if (status & 0x01) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write, page 0x%08= x\n", page); =09=09ret =3D -EIO; =09=09goto out; =09} =09/* Return happy */ =09*retlen =3D len; #ifdef CONFIG_MTD_NAND_VERIFY_WRITE =09/* Send command to read back the data */ =09this->cmdfunc (mtd, NAND_CMD_READOOB, column, page); =09/* Loop through and verify the data */ =09for (i =3D 0; i < len; i++) { =09=09if (buf[i] !=3D this->read_byte(mtd)) { =09=09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, = page 0x%08x\n", page); =09=09=09ret =3D -EIO; =09=09=09goto out; =09=09} =09} #endif out: =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09/* Wake up anyone waiting on the device */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09return ret; } /* * NAND write with iovec */ static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs, uns= igned long count,=20 =09=09loff_t to, size_t * retlen) { =09return (nand_writev_ecc (mtd, vecs, count, to, retlen, NULL, 0));=09 } static int nand_writev_ecc (struct mtd_info *mtd, const struct iovec *vecs,= unsigned long count,=20 =09=09loff_t to, size_t * retlen, u_char *eccbuf, struct nand_oobinfo *oobs= el) { =09int i, page, len, total_len, ret =3D 0, written =3D 0; =09struct nand_chip *this =3D mtd->priv; =09/* Calculate total length of data */ =09total_len =3D 0; =09for (i =3D 0; i < count; i++) =09=09total_len +=3D (int) vecs[i].iov_len; =09DEBUG (MTD_DEBUG_LEVEL3, =09 "nand_writev: to =3D 0x%08x, len =3D %i, count =3D %ld\n", (unsig= ned int) to, (unsigned int) total_len, count); =09/* Do not allow write past end of page */ =09if ((to + total_len) > mtd->size) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Attempted write past end of de= vice\n"); =09=09return -EINVAL; =09} =09/* reject writes, which are not page aligned */=09 =09if (NOTALIGNED (to) || NOTALIGNED(total_len)) { =09=09printk (KERN_NOTICE "nand_write_ecc: Attempt to write not page aligne= d data\n"); =09=09return -EINVAL; =09} =09// if oobsel is NULL, use chip defaults =09if (oobsel =3D=3D NULL)=20 =09=09oobsel =3D &mtd->oobinfo;=09=09 =09/* Shift to get page */ =09page =3D ((int) to) >> this->page_shift; =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd, FL_WRITING, NULL); =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* Check the WP bit */ =09this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); =09if (!(this->read_byte(mtd) & 0x80)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_writev: Device is write protected!!!\n= "); =09=09ret =3D -EIO; =09=09goto out; =09} =09/* Loop until all iovecs' data has been written */ =09len =3D 0; =09while (count) { =09=09/*=20 =09=09 * Check, if the tuple gives us not enough data for a=20 =09=09 * full page write. Then we can use the iov direct,=20 =09=09 * else we have to copy into data_buf.=09=09 =09=09 */ =09=09if ((vecs->iov_len - len) >=3D mtd->oobblock) { =09=09=09this->data_poi =3D (u_char *) vecs->iov_base; =09=09=09this->data_poi +=3D len; =09=09=09len +=3D mtd->oobblock;=20 =09=09=09/* Check, if we have to switch to the next tuple */ =09=09=09if (len >=3D (int) vecs->iov_len) { =09=09=09=09vecs++; =09=09=09=09len =3D 0; =09=09=09=09count--; =09=09=09} =09=09} else { =09=09=09/* =09=09=09 * Read data out of each tuple until we have a full page =09=09=09 * to write or we've read all the tuples. =09=09 =09*/ =09=09=09int cnt =3D 0; =09=09=09while ((cnt < mtd->oobblock) && count) { =09=09=09=09if (vecs->iov_base !=3D NULL && vecs->iov_len) { =09=09=09=09=09this->data_buf[cnt++] =3D ((u_char *) vecs->iov_base)[len++]= ; =09=09=09=09} =09=09=09=09/* Check, if we have to switch to the next tuple */ =09=09=09=09if (len >=3D (int) vecs->iov_len) { =09=09=09=09=09vecs++; =09=09=09=09=09len =3D 0; =09=09=09=09=09count--; =09=09=09=09} =09=09=09}=09 =09=09=09this->data_poi =3D this->data_buf;=09 =09=09} =09=09 =09=09/* We use the same function for write and writev !) */ =09=09ret =3D nand_write_page (mtd, this, page, NULL, oobsel); =09=09if (ret) =09=09=09goto out; =09=09/* Update written bytes count */ =09=09written +=3D mtd->oobblock;; =09=09/* Increment page address */ =09=09page++; =09} out: =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09/* Wake up anyone waiting on the device */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09*retlen =3D written; =09return ret; } /* * NAND erase a block */ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) { =09int page, len, status, pages_per_block, ret; =09struct nand_chip *this =3D mtd->priv; =09DECLARE_WAITQUEUE (wait, current); =09DEBUG (MTD_DEBUG_LEVEL3, =09 "nand_erase: start =3D 0x%08x, len =3D %i\n", (unsigned int) inst= r->addr, (unsigned int) instr->len); =09/* Start address must align on block boundary */ =09if (instr->addr & (mtd->erasesize - 1)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Unaligned address\n"); =09=09return -EINVAL; =09} =09/* Length must align on block boundary */ =09if (instr->len & (mtd->erasesize - 1)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Length not block aligned\n"); =09=09return -EINVAL; =09} =09/* Do not allow erase past end of device */ =09if ((instr->len + instr->addr) > mtd->size) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Erase past end of device\n"); =09=09return -EINVAL; =09} =09/* Grab the lock and see if the device is available */ =09nand_get_chip (this, mtd, FL_ERASING, NULL); =09/* Shift to get first page */ =09page =3D (int) (instr->addr >> this->page_shift); =09/* Calculate pages in each block */ =09pages_per_block =3D mtd->erasesize / mtd->oobblock; =09/* Select the NAND device */ =09this->select_chip(mtd, 0); =09/* Check the WP bit */ =09this->cmdfunc (mtd, NAND_CMD_STATUS, -1, -1); =09if (!(this->read_byte(mtd) & 0x80)) { =09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: Device is write protected!!!\n"= ); =09=09instr->state =3D MTD_ERASE_FAILED; =09=09goto erase_exit; =09} =09/* Loop through the pages */ =09len =3D instr->len; =09instr->state =3D MTD_ERASING; =09while (len) { =09=09/* Check if we have a bad block, we do not erase bad blocks ! */ =09=09if (this->block_bad(mtd, page)) { =09=09=09printk (KERN_WARNING "nand_erase: attempt to erase a bad block at = page 0x%08x\n", page); //#ifndef CONFIG_MIZI // BUSHI =09=09=09instr->state =3D MTD_ERASE_FAILED; =09=09=09goto erase_exit; //#endif /* CONFIG_MIZI */ =09=09} =09=09/* Send commands to erase a page */ =09=09this->cmdfunc (mtd, NAND_CMD_ERASE1, -1, page); =09=09this->cmdfunc (mtd, NAND_CMD_ERASE2, -1, -1); =09=09spin_unlock_bh (&this->chip_lock); =09=09status =3D this->waitfunc (mtd, this, FL_ERASING); =09=09/* Get spinlock, in case we exit */ =09=09spin_lock_bh (&this->chip_lock); =09=09/* See if block erase succeeded */ =09=09if (status & 0x01) { =09=09=09DEBUG (MTD_DEBUG_LEVEL0, "nand_erase: " "Failed erase, page 0x%08x= \n", page); =09=09=09instr->state =3D MTD_ERASE_FAILED; =09=09=09goto erase_exit; =09=09} =09=09 =09=09/* Check, if we were interupted */ =09=09if (this->state =3D=3D FL_ERASING) { =09=09=09/* Increment page address and decrement length */ =09=09=09len -=3D mtd->erasesize; =09=09=09page +=3D pages_per_block; =09=09} =09=09/* Release the spin lock */ =09=09spin_unlock_bh (&this->chip_lock); erase_retry: =09=09spin_lock_bh (&this->chip_lock); =09=09/* Check the state and sleep if it changed */ =09=09if (this->state =3D=3D FL_ERASING || this->state =3D=3D FL_READY) { =09=09=09/* Select the NAND device again, if we were interrupted */ =09=09=09this->state =3D FL_ERASING; =09=09=09this->select_chip(mtd, 0); =09=09=09continue; =09=09} else { =09=09=09set_current_state (TASK_UNINTERRUPTIBLE); =09=09=09add_wait_queue (&this->wq, &wait); =09=09=09spin_unlock_bh (&this->chip_lock); =09=09=09schedule (); =09=09=09remove_wait_queue (&this->wq, &wait); =09=09=09goto erase_retry; =09=09} =09} =09instr->state =3D MTD_ERASE_DONE; erase_exit: =09/* De-select the NAND device */ =09this->select_chip(mtd, -1); =09spin_unlock_bh (&this->chip_lock); =09ret =3D instr->state =3D=3D MTD_ERASE_DONE ? 0 : -EIO;; =09/* Do call back function */ =09if (!ret && instr->callback) =09=09instr->callback (instr); =09/* The device is ready */ =09spin_lock_bh (&this->chip_lock); =09this->state =3D FL_READY; =09wake_up (&this->wq); =09spin_unlock_bh (&this->chip_lock); =09/* Return more or less happy */ =09return ret; } /* * NAND sync */ static void nand_sync (struct mtd_info *mtd) { =09struct nand_chip *this =3D mtd->priv; =09DECLARE_WAITQUEUE (wait, current); =09DEBUG (MTD_DEBUG_LEVEL3, "nand_sync: called\n"); retry: =09/* Grab the spinlock */ =09spin_lock_bh (&this->chip_lock); =09/* See what's going on */ =09switch (this->state) { =09case FL_READY: =09case FL_SYNCING: =09=09this->state =3D FL_SYNCING; =09=09spin_unlock_bh (&this->chip_lock); =09=09break; =09default: =09=09/* Not an idle state */ =09=09add_wait_queue (&this->wq, &wait); =09=09spin_unlock_bh (&this->chip_lock); =09=09schedule (); =09=09remove_wait_queue (&this->wq, &wait); =09=09goto retry; =09} =09/* Lock the device */ =09spin_lock_bh (&this->chip_lock); =09/* Set the device to be ready again */ =09if (this->state =3D=3D FL_SYNCING) { =09=09this->state =3D FL_READY; =09=09wake_up (&this->wq); =09} =09/* Unlock the device */ =09spin_unlock_bh (&this->chip_lock); } /* * Scan for the NAND device */ int nand_scan (struct mtd_info *mtd, int maxchips) { =09int i, nand_maf_id, nand_dev_id; =09struct nand_chip *this =3D mtd->priv; =09/* check for proper chip_delay setup, set 20us if not */ =09if (!this->chip_delay) =09=09this->chip_delay =3D 20; =09/* check, if a user supplied command function given */ =09if (this->cmdfunc =3D=3D NULL) =09=09this->cmdfunc =3D nand_command; =09/* check, if a user supplied wait function given */ =09if (this->waitfunc =3D=3D NULL) =09=09this->waitfunc =3D nand_wait; =09if (!this->block_bad) =09=09this->block_bad =3D nand_block_bad; =09if (!this->select_chip) =09=09this->select_chip =3D nand_select_chip; =09if (!this->write_byte) =09=09this->write_byte =3D nand_write_byte; =09if (!this->read_byte) =09=09this->read_byte =3D nand_read_byte; =09if (!this->write_buf) =09=09this->write_buf =3D nand_write_buf; =09if (!this->read_buf) =09=09this->read_buf =3D nand_read_buf; =09if (!this->verify_buf) =09=09this->verify_buf =3D nand_verify_buf; =09/* Select the device */ =09this->select_chip(mtd, 0); =09/* Send the command for reading device ID */ =09this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); =09/* Read manufacturer and device IDs */ =09nand_maf_id =3D this->read_byte(mtd); =09nand_dev_id =3D this->read_byte(mtd); =09/* Print and store flash device information */ =09for (i =3D 0; nand_flash_ids[i].name !=3D NULL; i++) { =09=09if (nand_dev_id =3D=3D nand_flash_ids[i].id && !mtd->size) { =09=09=09mtd->name =3D nand_flash_ids[i].name; =09=09=09mtd->erasesize =3D nand_flash_ids[i].erasesize; =09=09=09mtd->eccsize =3D 256; =09=09=09this->chipshift =3D nand_flash_ids[i].chipshift; =09=09=09if (nand_flash_ids[i].page256) { =09=09=09=09mtd->oobblock =3D 256; =09=09=09=09mtd->oobsize =3D 8; =09=09=09=09this->page_shift =3D 8; =09=09=09} else { =09=09=09=09mtd->oobblock =3D 512; =09=09=09=09mtd->oobsize =3D 16; =09=09=09=09this->page_shift =3D 9; =09=09=09} =09=09=09/* Try to identify manufacturer */ =09=09=09for (i =3D 0; nand_manuf_ids[i].id !=3D 0x0; i++) { =09=09=09=09if (nand_manuf_ids[i].id =3D=3D nand_maf_id) =09=09=09=09=09break; =09=09=09}=09 =09=09=09printk (KERN_INFO "NAND device: Manufacturer ID:" =09=09=09=09" 0x%02x, Chip ID: 0x%02x (%s %s)\n", nand_maf_id, nand_dev_id,= =20 =09=09=09=09nand_manuf_ids[i].name , mtd->name); =09=09=09break; =09=09} =09} =09if (!mtd->name) { =09=09printk (KERN_WARNING "No NAND device found!!!\n"); =09=09return 1; =09} =09for (i=3D1; i < maxchips; i++) { =09=09this->select_chip(mtd, i); =09=09/* Send the command for reading device ID */ =09=09this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1); =09=09/* Read manufacturer and device IDs */ =09=09if (nand_maf_id !=3D this->read_byte(mtd) || =09=09 nand_dev_id !=3D this->read_byte(mtd)) =09=09=09break; =09} =09if (i > 1) =09=09printk(KERN_INFO "%d NAND chips detected\n", i); =09mtd->size =3D (1 << this->chipshift) /* * i when we fix the rest of the = code */; =09/*=20 =09 * check ECC mode, default to software =09 * if 3byte/512byte hardware ECC is selected and we have 256 byte pagesi= ze =09 * fallback to software ECC=20 =09*/ =09this->eccsize =3D 256;=09/* set default eccsize */=09 =09switch (this->eccmode) { =09case NAND_ECC_HW3_512:=20 =09case NAND_ECC_HW6_512:=20 =09=09if (mtd->oobblock =3D=3D 256) { =09=09=09printk (KERN_WARNING "512 byte HW ECC not possible on 256 Byte pag= esize, fallback to SW ECC \n"); =09=09=09this->eccmode =3D NAND_ECC_SOFT; =09=09=09this->calculate_ecc =3D nand_calculate_ecc; =09=09=09this->correct_data =3D nand_correct_data; =09=09=09break;=09=09 =09=09} else=20 =09=09=09this->eccsize =3D 512; /* set eccsize to 512 and fall through for = function check */ =09case NAND_ECC_HW3_256: =09=09if (this->calculate_ecc && this->correct_data && this->enable_hwecc) =09=09=09break; =09=09printk (KERN_WARNING "No ECC functions supplied, Hardware ECC not pos= sible\n"); =09=09BUG();=09 =09case NAND_ECC_NONE:=20 =09=09printk (KERN_WARNING "NAND_ECC_NONE selected by board driver. This is= not recommended !!\n"); =09=09this->eccmode =3D NAND_ECC_NONE; =09=09break; =09case NAND_ECC_SOFT:=09 =09=09this->calculate_ecc =3D nand_calculate_ecc; =09=09this->correct_data =3D nand_correct_data; =09=09break; =09default: =09=09printk (KERN_WARNING "Invalid NAND_ECC_MODE %d\n", this->eccmode); =09=09BUG();=09 =09}=09 =09 =09/* Initialize state, waitqueue and spinlock */ =09this->state =3D FL_READY; =09init_waitqueue_head (&this->wq); =09spin_lock_init (&this->chip_lock); =09/* De-select the device */ =09this->select_chip(mtd, -1); =09/* Fill in remaining MTD driver data */ =09mtd->type =3D MTD_NANDFLASH; =09mtd->flags =3D MTD_CAP_NANDFLASH | MTD_ECC; =09mtd->ecctype =3D MTD_ECC_SW; =09mtd->erase =3D nand_erase; =09mtd->point =3D NULL; =09mtd->unpoint =3D NULL; =09mtd->read =3D nand_read; =09mtd->write =3D nand_write; =09mtd->read_ecc =3D nand_read_ecc; =09mtd->write_ecc =3D nand_write_ecc; =09mtd->read_oob =3D nand_read_oob; =09mtd->write_oob =3D nand_write_oob; =09mtd->readv =3D NULL; =09mtd->writev =3D nand_writev; =09mtd->writev_ecc =3D nand_writev_ecc; =09mtd->sync =3D nand_sync; =09mtd->lock =3D NULL; =09mtd->unlock =3D NULL; =09mtd->suspend =3D NULL; =09mtd->resume =3D NULL; =09mtd->owner =3D THIS_MODULE; =09/* Return happy */ =09return 0; } EXPORT_SYMBOL (nand_scan); MODULE_LICENSE ("GPL"); MODULE_AUTHOR ("Steven J. Hill , Thomas Gleixner= "); MODULE_DESCRIPTION ("Generic NAND flash driver code"); ------=_Part_2020_19033482.1099561286164-- From tglx@linutronix.de Mon Nov 8 10:53:29 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Mon, 08 Nov 2004 11:53:29 +0100 Subject: [Yaffs] no erasedblocks available In-Reply-To: References: Message-ID: <1099911209.2810.190.camel@thomas> On Thu, 2004-11-04 at 15:11 +0530, bandwidthcrunch wrote: > Hi all, > I have a samsung nand device K9F1208UOM which is being mounted > perfectly and shows me erasedblocks when i check the proc entry. But > when i try to create/copy etc a file on to the partition i run out of > memory . Below is the log and my nand.c file which i believe tries to Read http://www.linux-mtd.infradead.org/#kernelversions tglx From lorenzo.parisi@st.com Tue Nov 9 09:18:12 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Tue, 9 Nov 2004 10:18:12 +0100 Subject: [Yaffs] YAFFS2 Message-ID: Hi, I see the source of YAFFS2. How to I include it in the kernel's tree? I've an embedded system with kernel 2.6.9-rc2-bk13 and mtd (2004/09/19). Thanks. From bandwidthcrunch Tue Nov 9 10:28:57 2004 From: bandwidthcrunch (bandwidthcrunch) Date: Tue, 9 Nov 2004 15:58:57 +0530 Subject: [Yaffs] YAFFS2 In-Reply-To: References: Message-ID: i dont think it is ready yet for integration .... On Tue, 9 Nov 2004 10:18:12 +0100, Lorenzo PARISI wrote: > Hi, > > I see the source of YAFFS2. How to I include it in the > kernel's tree? > I've an embedded system with kernel 2.6.9-rc2-bk13 and mtd > (2004/09/19). > > Thanks. > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > From lorenzo.parisi@st.com Tue Nov 9 10:41:02 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Tue, 9 Nov 2004 11:41:02 +0100 Subject: [Yaffs] YAFFS2 Message-ID: I've a S3C2410 with BAST architecture. It's a Simtec evaluation board, and I work with Samsung and STM NAND Flash. Thanks From nick@cecomputing.co.uk Tue Nov 9 10:37:06 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Tue, 9 Nov 2004 10:37:06 -0000 Subject: [Yaffs] YAFFS2 In-Reply-To: Message-ID: See husaberg.toby-churchill.com/balloon/ for examples of other kernels = with yaffs1. I have not yet tried yaffs2. Nick > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of Lorenzo PARISI > Sent: 09 November 2004 09:18 > To: YAFFS mailing list > Subject: [Yaffs] YAFFS2 >=20 >=20 > Hi, >=20 > I see the source of YAFFS2. How to I include it in the=20 > kernel's tree? > I've an embedded system with kernel 2.6.9-rc2-bk13 and mtd=20 > (2004/09/19). >=20 > Thanks. >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From Charles.Manning@trimble.co.nz Tue Nov 9 20:00:02 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Wed, 10 Nov 2004 09:00:02 +1300 Subject: [Yaffs] YAFFS2 Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01549005@nzc-ap-xch-01.ap.trimblecorp.net> At this stage YAFFS2 still needs to be integrated with the kernel stuff (ie. yaffs_fs.c and the mtd interfacing). What page size NAND do you want to use with it? -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Lorenzo PARISI Sent: Tuesday, 9 November 2004 10:18 p.m. To: YAFFS mailing list Subject: [Yaffs] YAFFS2 Hi, I see the source of YAFFS2. How to I include it in the=20 kernel's tree? I've an embedded system with kernel 2.6.9-rc2-bk13 and mtd=20 (2004/09/19). Thanks. _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From lorenzo.parisi@st.com Wed Nov 10 09:10:19 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Wed, 10 Nov 2004 10:10:19 +0100 Subject: [Yaffs] YAFFS2 Message-ID: I want use 512bit e 1Gbit NAND. From arasv@magellan-technology.com Wed Nov 10 23:21:15 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Thu, 11 Nov 2004 10:21:15 +1100 Subject: [Yaffs] Yaffs for 2.4.27, and other questions Message-ID: <4192A26B.9090203@magellan-technology.com> Hi, I'm running 2.4.27-vrs1 for the AT91RM9200, it's the latest reliable working kernel version for this processor, so I have no other choice but to use it. Unfortunately, the latest MTD code only supports 2.6 kernels. I currently have the Balloon release of YAFFS working, but I am getting all sorts of errors with it. e.g. I tried creating a series of 1MB files, but after a while I noticed that the filenames started getting mangled and I ended up with multiple files with the same name. I'd like to be using the latest code but I'm a little confused as to which version of YAFFS works with which kernel, and which MTD code. Initially, I tried to compile the latest CVS code, but I kept getting so many compiler errors and I gave up when I couldn't fix them any more. e.g. yaffs_mtdif.c:33: unknown field `useecc' specified in initializer I can't find any mention of "useecc" anywhere in my kernel code or the YAFFS code. Does anyone have YAFFS working with this kernel, and can you tell me how you did it? Or can you email me your fs/yaffs and drivers/mtd directories? regards, Aras Vaichas From tglx@linutronix.de Thu Nov 11 00:09:27 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Thu, 11 Nov 2004 01:09:27 +0100 Subject: [Yaffs] Yaffs for 2.4.27, and other questions In-Reply-To: <4192A26B.9090203@magellan-technology.com> References: <4192A26B.9090203@magellan-technology.com> Message-ID: <1100131767.3405.39.camel@thomas> On Thu, 2004-11-11 at 10:21 +1100, Aras Vaichas wrote: > Hi, I'm running 2.4.27-vrs1 for the AT91RM9200, it's the latest reliable > working kernel version for this processor, so I have no other choice but to use > it. Unfortunately, the latest MTD code only supports 2.6 kernels. You can use current MTD with 2.4.27. It's not hard. > I'd like to be using the latest code but I'm a little confused as to which > version of YAFFS works with which kernel, and which MTD code. Initially, I > tried to compile the latest CVS code, but I kept getting so many compiler > errors and I gave up when I couldn't fix them any more. > > e.g. yaffs_mtdif.c:33: unknown field `useecc' specified in initializer > I can't find any mention of "useecc" anywhere in my kernel code or the YAFFS code. useecc is a field of the MTD oobinfo structure tglx From arasv@magellan-technology.com Thu Nov 11 00:27:18 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Thu, 11 Nov 2004 11:27:18 +1100 Subject: [Yaffs] Yaffs for 2.4.27, and other questions In-Reply-To: <1100131767.3405.39.camel@thomas> References: <4192A26B.9090203@magellan-technology.com> <1100131767.3405.39.camel@thomas> Message-ID: <4192B1E6.7080008@magellan-technology.com> Thomas Gleixner wrote: > On Thu, 2004-11-11 at 10:21 +1100, Aras Vaichas wrote: > >>Hi, I'm running 2.4.27-vrs1 for the AT91RM9200, it's the latest reliable >>working kernel version for this processor, so I have no other choice but to use >>it. Unfortunately, the latest MTD code only supports 2.6 kernels. > > > You can use current MTD with 2.4.27. It's not hard. Really? We tried doing that several months ago and we had lots of problems because the code (then) seemed to want to use 2.6 kernel data structures that weren't in the 2.4 kernel. We just couldn't get it to compile successfully. We gave up, and just used what came with the vrs1 patch. I'd be happy to give it another go. regards, Aras Vaichas From zheng wei Fri Nov 12 02:25:54 2004 From: zheng wei (zheng wei) Date: Fri, 12 Nov 2004 10:25:54 +0800 Subject: [Yaffs] =?UTF-8?Q?yaffs_ECC_check_error!_Need_help_=E3=80=82=E3=80=82=E3=80=82?= Message-ID: Hi=EF=BC=8Csir=EF=BC=81 I don't use the MTD ECC, I use the yaffs itself ECC, and there are some err= ors: Mounted devfs on /dev Freeing init memory: 76K zw: mount /etc as ramfs zw: re-create the /etc/mtab entries zw: /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / zw: /sbin/insmod -f /lib/yaffs.o zw: /bin/mount -t yaffs /dev/mtdblock/4 /usr yaffs: dev is 7940 name is "1f:04" ecc_code : c3 ff 33 30 f3 3f ////////////////////////// a little similar !!!! c3 ff and ff c3 ??? ecc_calc : ff c3 33 f3 30 3f oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 30 f3 3f nand_read_ecc: Failed ECC read, page 0x00002020 nand_read_ecc: Failed ECC read, page 0x00002020 ecc_code : c3 ff 33 30 f3 3f ecc_calc : ff c3 33 f3 30 3f oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 30 f3 3f nand_read_ecc: Failed ECC read, page 0x00002022 nand_read_ecc: Failed ECC read, page 0x00002022 ecc_code : cc ff 3f 95 a6 ab ecc_calc : ff cc 3f a6 95 ab oob : 0 0 d0 ff ff ff 5 1 cc ff 3f d8 c1 95 a6 ab nand_read_ecc: Failed ECC read, page 0x00002023 nand_read_ecc: Failed ECC read, page 0x00002023 ecc_code : cc ff 3f 96 a6 67 ecc_calc : ff cc 3f a6 96 67 oob : 0 0 e0 ff ff ff 5 1 cc ff 3f d4 c1 96 a6 67 nand_read_ecc: Failed ECC read, page 0x00002026 nand_read_ecc: Failed ECC read, page 0x00002026 ecc_code : c3 ff 33 65 aa 5b ecc_calc : ff c3 33 aa 65 5b oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 65 aa 5b nand_read_ecc: Failed ECC read, page 0x00002027 nand_read_ecc: Failed ECC read, page 0x00002027 ecc_code : c3 ff 33 a5 a5 97 ecc_calc : ff c3 33 a5 a5 97 oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 a5 a5 97 nand_read_ecc: Failed ECC read, page 0x00002029 ecc_code : a9 aa 67 96 a6 67 ecc_calc : aa a9 67 a6 96 67 oob : 0 0 f0 ff ff ff 5 1 a9 aa 67 80 c1 96 a6 67 nand_read_ecc: Failed ECC read, page 0x0000202a nand_read_ecc: Failed ECC read, page 0x0000202a zw: exec /sbin/init console=3D/dev/co?ole init started: BusyBox v0.60.3 (2002.05.13-08:36+0000) multi-c?l binary Starting pid 22, console /dev/console: '/etc/init.d/rcS' exec: /usr/etc/rc.local: No such file or dire?ory Waiting for enter to start '/bin/sh' (pid 25, terminal /dev/console) Please press Enter to activate this console. # cd /usr # ls ecc_code : c3 ff 33 65 aa 5b ecc_calc : ff c3 33 aa 65 5b oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 65 aa 5b nand_read_ecc: Failed ECC read, page 0x00002027 nand_read_ecc: Failed ECC read, page 0x00002027 ecc_code : cc ff 3f 95 a6 ab ecc_calc : ff cc 3f a6 95 ab oob : 0 0 d0 ff ff ff 5 1 cc ff 3f d8 c1 95 a6 ab nand_read_ecc: Failed ECC read, page 0x00002023 nand_read_ecc: Failed ECC read, page 0x00002023 ecc_code : c3 ff 33 65 aa 5b ecc_calc : ff c3 33 aa 65 5b oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 65 aa 5b nand_read_ecc: Failed ECC read, page 0x00002027 nand_read_ecc: Failed ECC read, page 0x00002027 ecc_code : cc ff 3f 95 a6 ab ecc_calc : ff cc 3f a6 95 ab oob : 0 0 d0 ff ff ff 5 1 cc ff 3f d8 c1 95 a6 ab nand_read_ecc: Failed ECC read, page 0x00002023 nand_read_ecc: Failed ECC read, page 0x00002023 linuxrc lost+found jeanwelly.c From nick@cecomputing.co.uk Fri Nov 12 10:27:53 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Fri, 12 Nov 2004 10:27:53 -0000 Subject: [Yaffs] RE: yaffs problem ? In-Reply-To: <8720012.1100229922798.JavaMail.postfix@mx40.mail.sohu.com> Message-ID: I think this may have to do with swapping or not the oob bytes for = SmartMedia compatability. See the yaffs source. There was a problem with #ifdef and #if in the file. I mentioned it to = Charles and it is now ok in the current cvs Nick > -----Original Message----- > From: jackzheng2002@sohu.com [mailto:jackzheng2002@sohu.com] > Sent: 12 November 2004 03:25 > To: nick@cecomputing.co.uk > Subject: yaffs problem ? >=20 >=20 >=20 >=20 > Sir, Can you help me?=20 > I don't use the MTD ECC, I use the yaffs itself ECC, and there=20 > are some errors: > I don't know how to start? Thank you !!!! > Eager waiting for your response... >=20 > Mounted devfs on /dev > Freeing init memory: 76K > zw: mount /etc as ramfs > zw: re-create the /etc/mtab entries > zw: /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / > zw: /sbin/insmod -f /lib/yaffs.o > zw: /bin/mount -t yaffs /dev/mtdblock/4 /usr > yaffs: dev is 7940 name is "1f:04" > ecc_code : c3 ff 33 30 f3 3f > ecc_calc : ff c3 33 f3 30 3f > oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 30 f3 3f > nand_read_ecc: Failed ECC read, page 0x00002020 > nand_read_ecc: Failed ECC read, page 0x00002020 > ecc_code : c3 ff 33 30 f3 3f > ecc_calc : ff c3 33 f3 30 3f > oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 30 f3 3f > nand_read_ecc: Failed ECC read, page 0x00002022 > nand_read_ecc: Failed ECC read, page 0x00002022 > ecc_code : cc ff 3f 95 a6 ab > ecc_calc : ff cc 3f a6 95 ab > oob : 0 0 d0 ff ff ff 5 1 cc ff 3f d8 c1 95 a6 ab > nand_read_ecc: Failed ECC read, page 0x00002023 > nand_read_ecc: Failed ECC read, page 0x00002023 > ecc_code : cc ff 3f 96 a6 67 > ecc_calc : ff cc 3f a6 96 67 > oob : 0 0 e0 ff ff ff 5 1 cc ff 3f d4 c1 96 a6 67 > nand_read_ecc: Failed ECC read, page 0x00002026 > nand_read_ecc: Failed ECC read, page 0x00002026 > ecc_code : c3 ff 33 65 aa 5b > ecc_calc : ff c3 33 aa 65 5b > oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 65 aa 5b > nand_read_ecc: Failed ECC read, page 0x00002027 > nand_read_ecc: Failed ECC read, page 0x00002027 > ecc_code : c3 ff 33 a5 a5 97 > ecc_calc : ff c3 33 a5 a5 97 > oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 a5 a5 97 > nand_read_ecc: Failed ECC read, page 0x00002029 > ecc_code : a9 aa 67 96 a6 67 > ecc_calc : aa a9 67 a6 96 67 > oob : 0 0 f0 ff ff ff 5 1 a9 aa 67 80 c1 96 a6 67 > nand_read_ecc: Failed ECC read, page 0x0000202a > nand_read_ecc: Failed ECC read, page 0x0000202a > zw: exec /sbin/init > console=3D/dev/co?ole > init started: BusyBox v0.60.3 (2002.05.13-08:36+0000) multi-c?l = binary > Starting pid 22, console /dev/console: '/etc/init.d/rcS' > exec: /usr/etc/rc.local: No such file or dire?ory > Waiting for enter to start '/bin/sh' (pid 25, terminal /dev/console) > =20 > =20 > Please press Enter to activate this console. From wookey@aleph1.co.uk Fri Nov 12 12:08:41 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 12 Nov 2004 12:08:41 +0000 Subject: [Yaffs] Re: yaffs ECC check error! Need help ????????? In-Reply-To: References: Message-ID: <20041112120841.GO25029@court.aleph1.co.uk> +++ zheng wei [04-11-12 10:25 +0800]: > Hi???sir??? > I don't use the MTD ECC, I use the yaffs itself ECC, and there are some errors: > > Mounted devfs on /dev > Freeing init memory: 76K > zw: mount /etc as ramfs > zw: re-create the /etc/mtab entries > zw: /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / > zw: /sbin/insmod -f /lib/yaffs.o > zw: /bin/mount -t yaffs /dev/mtdblock/4 /usr > yaffs: dev is 7940 name is "1f:04" > ecc_code : c3 ff 33 30 f3 3f ////////////////////////// a little > similar !!!! c3 ff and ff c3 ??? > ecc_calc : ff c3 33 f3 30 3f Hmm, yes -I'm nt sure exactly what's going on there but it does look like bytes 1&2 and 4&5 of the ecc are swapped in every case. Looks like you might have an endianess or byte-laning problem somewhere. In the driver? Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From zheng wei Fri Nov 12 13:21:47 2004 From: zheng wei (zheng wei) Date: Fri, 12 Nov 2004 21:21:47 +0800 Subject: [Yaffs] Re: yaffs ECC check error! Need help ????????? In-Reply-To: <20041112120841.GO25029@court.aleph1.co.uk> References: <20041112120841.GO25029@court.aleph1.co.uk> Message-ID: I don't know, I just download the yaffs package, but it seems that the package is for ppc, how can I get the yaffs.tar for ARM. I can't get the yaffs code via cvs. Thank you ! On Fri, 12 Nov 2004 12:08:41 +0000, Wookey wrote: > +++ zheng wei [04-11-12 10:25 +0800]: > > Hi???sir??? > > I don't use the MTD ECC, I use the yaffs itself ECC, and there are some errors: > > > > Mounted devfs on /dev > > Freeing init memory: 76K > > zw: mount /etc as ramfs > > zw: re-create the /etc/mtab entries > > zw: /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / > > zw: /sbin/insmod -f /lib/yaffs.o > > zw: /bin/mount -t yaffs /dev/mtdblock/4 /usr > > yaffs: dev is 7940 name is "1f:04" > > ecc_code : c3 ff 33 30 f3 3f ////////////////////////// a little > > similar !!!! c3 ff and ff c3 ??? > > ecc_calc : ff c3 33 f3 30 3f > > Hmm, yes -I'm nt sure exactly what's going on there but it does look like > bytes 1&2 and 4&5 of the ecc are swapped in every case. Looks like you might > have an endianess or byte-laning problem somewhere. In the driver? > > Wookey > -- > Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 > work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > From wookey@aleph1.co.uk Fri Nov 12 14:06:19 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 12 Nov 2004 14:06:19 +0000 Subject: [Yaffs] Re: yaffs ECC check error! Need help ????????? In-Reply-To: References: <20041112120841.GO25029@court.aleph1.co.uk> Message-ID: <20041112140619.GT25029@court.aleph1.co.uk> +++ zheng wei [04-11-12 21:21 +0800]: > I don't know, I just download the yaffs package, but it seems that the > package is for ppc, how can I get the yaffs.tar for ARM. I can't get > the yaffs code via cvs. > Thank you ! The source is the source. It's not for any particular architecture. That part is defined by the tools you build it with. You are correct that there is a problem with the 'download tarball' function of ViewCVS (the web CVS interface). It generates a Python error for reasons that I haven't yet got to the bottom of. This is being worked on. Are you also unable to use the conventional cvs access via pserver due to firewalls? (see http://www.aleph1.co.uk/cvsuse.html ) Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From wookey@aleph1.co.uk Fri Nov 12 14:07:03 2004 From: wookey@aleph1.co.uk (Wookey) Date: Fri, 12 Nov 2004 14:07:03 +0000 Subject: [Yaffs] Re: yaffs ECC check error! Need help ????????? In-Reply-To: References: <20041112120841.GO25029@court.aleph1.co.uk> Message-ID: <20041112140703.GU25029@court.aleph1.co.uk> +++ zheng wei [04-11-12 21:21 +0800]: > I don't know, I just download the yaffs package, but it seems that the > package is for ppc, how can I get the yaffs.tar for ARM. I can't get > the yaffs code via cvs. > Thank you ! I can mail you a tarball if you like, but it sounds like you already have it running? Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From zheng wei Fri Nov 12 14:54:40 2004 From: zheng wei (zheng wei) Date: Fri, 12 Nov 2004 22:54:40 +0800 Subject: [Yaffs] Re: yaffs ECC check error! Need help ????????? In-Reply-To: <20041112140703.GU25029@court.aleph1.co.uk> References: <20041112120841.GO25029@court.aleph1.co.uk> <20041112140703.GU25029@court.aleph1.co.uk> Message-ID: Ok , Thank you for your help... Can you send me your yaffs tar package , and I want to have a test to find the problem. you can send it to jeanwelly@gmail.com ... Thank you so much. On Fri, 12 Nov 2004 14:07:03 +0000, Wookey wrote: > +++ zheng wei [04-11-12 21:21 +0800]: > > I don't know, I just download the yaffs package, but it seems that the > > package is for ppc, how can I get the yaffs.tar for ARM. I can't get > > the yaffs code via cvs. > > Thank you ! > > I can mail you a tarball if you like, but it sounds like you already have it > running? > > > > Wookey > -- > Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 > work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs > From manningc2@actrix.gen.nz Sun Nov 14 20:28:16 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 15 Nov 2004 09:28:16 +1300 Subject: [Yaffs] Re: FW: RE: yaffs problem ? In-Reply-To: References: Message-ID: <20041114202356.3EA7E15D2D@desire.actrix.co.nz> I agree with Nick as to what the problem most likely is. The original EEC layout is part of the SmartMedia specification. It seems= =20 though that the EEC in mtd (nand_ecc.c) generates the wrong byte ordering= for=20 the ECC bytes.=20 If you're using the ECC in YAFFS (yaffs_ecc.c) then you can configure it = to=20 use the SmartMedia byte ordering (the "correct" one) or the mtd one (the=20 "wrong" one). To get the same result as mtd you must set=20 CONFIG_YAFFS_ECC_WRONG_ORDER . -- Charles > > -----Original Message----- > > From: zhengwei [mailto:jackzheng2002@sohu.com] > > Sent: 14 November 2004 03:32 > > To: Nick Bane > > Subject: Re: RE: yaffs problem ? > > > > > > > > Nick Bane,=C4=FA=BA=C3=A3=A1 > > > > Ok=A3=ACThank you ! Do you have charles's email. I will contact > > him for advice... > > It's urgent for me to solve the problem. > > Thank you so much! > > > > =3D=3D=3D=3D=3D=3D=3D 2004-11-12 10:27:00 =C4=FA=D4=DA=C0=B4=D0=C5=D6= =D0=D0=B4=B5=C0=A3=BA=3D=3D=3D=3D=3D=3D=3D > > > > >I think this may have to do with swapping or not the oob bytes > > > > for SmartMedia compatability. See the yaffs source. > > > > >There was a problem with #ifdef and #if in the file. I mentioned > > > > it to Charles and it is now ok in the current cvs > > > > >Nick > > > > > >> -----Original Message----- > > >> From: jackzheng2002@sohu.com [mailto:jackzheng2002@sohu.com] > > >> Sent: 12 November 2004 03:25 > > >> To: nick@cecomputing.co.uk > > >> Subject: yaffs problem ? > > >> > > >> > > >> > > >> > > >> Sir, Can you help me? > > >> I don't use the MTD ECC, I use the yaffs itself ECC, and there > > >> are some errors: > > >> I don't know how to start? Thank you !!!! > > >> Eager waiting for your response... > > >> > > >> Mounted devfs on /dev > > >> Freeing init memory: 76K > > >> zw: mount /etc as ramfs > > >> zw: re-create the /etc/mtab entries > > >> zw: /bin/mount -f -t cramfs -o remount,ro /dev/mtdblock/3 / > > >> zw: /sbin/insmod -f /lib/yaffs.o > > >> zw: /bin/mount -t yaffs /dev/mtdblock/4 /usr > > >> yaffs: dev is 7940 name is "1f:04" > > >> ecc_code : c3 ff 33 30 f3 3f > > >> ecc_calc : ff c3 33 f3 30 3f > > >> oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 30 f3 3f > > >> nand_read_ecc: Failed ECC read, page 0x00002020 > > >> nand_read_ecc: Failed ECC read, page 0x00002020 > > >> ecc_code : c3 ff 33 30 f3 3f > > >> ecc_calc : ff c3 33 f3 30 3f > > >> oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 30 f3 3f > > >> nand_read_ecc: Failed ECC read, page 0x00002022 > > >> nand_read_ecc: Failed ECC read, page 0x00002022 > > >> ecc_code : cc ff 3f 95 a6 ab > > >> ecc_calc : ff cc 3f a6 95 ab > > >> oob : 0 0 d0 ff ff ff 5 1 cc ff 3f d8 c1 95 a6 ab > > >> nand_read_ecc: Failed ECC read, page 0x00002023 > > >> nand_read_ecc: Failed ECC read, page 0x00002023 > > >> ecc_code : cc ff 3f 96 a6 67 > > >> ecc_calc : ff cc 3f a6 96 67 > > >> oob : 0 0 e0 ff ff ff 5 1 cc ff 3f d4 c1 96 a6 67 > > >> nand_read_ecc: Failed ECC read, page 0x00002026 > > >> nand_read_ecc: Failed ECC read, page 0x00002026 > > >> ecc_code : c3 ff 33 65 aa 5b > > >> ecc_calc : ff c3 33 aa 65 5b > > >> oob : 0 0 d0 ff ff ff 4 1 c3 ff 33 5c c1 65 aa 5b > > >> nand_read_ecc: Failed ECC read, page 0x00002027 > > >> nand_read_ecc: Failed ECC read, page 0x00002027 > > >> ecc_code : c3 ff 33 a5 a5 97 > > >> ecc_calc : ff c3 33 a5 a5 97 > > >> oob : 0 0 e0 ff ff ff 4 1 c3 ff 33 50 c1 a5 a5 97 > > >> nand_read_ecc: Failed ECC read, page 0x00002029 > > >> ecc_code : a9 aa 67 96 a6 67 > > >> ecc_calc : aa a9 67 a6 96 67 > > >> oob : 0 0 f0 ff ff ff 5 1 a9 aa 67 80 c1 96 a6 67 > > >> nand_read_ecc: Failed ECC read, page 0x0000202a > > >> nand_read_ecc: Failed ECC read, page 0x0000202a > > >> zw: exec /sbin/init > > >> console=3D/dev/co?ole > > >> init started: BusyBox v0.60.3 (2002.05.13-08:36+0000) multi-c?l > > >> binary Starting pid 22, console /dev/console: '/etc/init.d/rcS' > > >> exec: /usr/etc/rc.local: No such file or dire?ory > > >> Waiting for enter to start '/bin/sh' (pid 25, terminal /dev/consol= e) > > >> > > >> > > >> Please press Enter to activate this console. > > > > =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D =3D= =3D =3D > > > > > > =A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=D6=C2 > > =C0=F1=A3=A1 > > > > > > =A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1zhengwei > > =A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1jackzheng2002@sohu.co= m > > =A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A1=A12004-11-1= 2 From adam.charrett@philips.com Thu Nov 18 09:27:59 2004 From: adam.charrett@philips.com (adam.charrett@philips.com) Date: Thu, 18 Nov 2004 09:27:59 +0000 Subject: [Yaffs] YAFFS support for 16bit NAND flash Message-ID: I'm currently try to evaluate whether to use YAFFS for a project on one of our chips and having looked at the spec am unsure as to whether YAFFS could/does support 16Bit NAND flash. The only difference between 8Bit NAND flash adn 16bit as far as YAFFS is concerned would be where the Bad Block information is stored and the fact that a 2byte word is used instead of 1 byte. Has any one used YAFFS with a 16bit device? Are there any plans to support 16bit devices? Many thanks Adam From areggiani@ferrari.it Thu Nov 18 14:18:25 2004 From: areggiani@ferrari.it (Reggiani, Adamo) Date: Thu, 18 Nov 2004 15:18:25 +0100 Subject: [Yaffs] YAFFS support for 16bit NAND flash Message-ID: Hi Adam, Yaffs2 should support 16bit Nand flash, and is under development now; = some modifications are already committed to the CVS repository. Anyway i think it's trivial to modify the current Yaffs for 16bit = devices. Regards Adamo > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk > [mailto:yaffs-admin@stoneboat.aleph1.co.uk]On Behalf Of > adam.charrett@philips.com > Sent: gioved=EC 18 novembre 2004 10.28 > To: yaffs@stoneboat.aleph1.co.uk > Subject: [Yaffs] YAFFS support for 16bit NAND flash >=20 >=20 >=20 >=20 >=20 >=20 > I'm currently try to evaluate whether to use YAFFS for a=20 > project on one of > our chips and having looked at the spec am unsure as to whether YAFFS > could/does support 16Bit NAND flash. > The only difference between 8Bit NAND flash adn 16bit as far=20 > as YAFFS is > concerned would be where the Bad Block information is stored=20 > and the fact > that a 2byte word is used instead of 1 byte. >=20 > Has any one used YAFFS with a 16bit device? >=20 > Are there any plans to support 16bit devices? >=20 > Many thanks >=20 > Adam >=20 >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From wookey@aleph1.co.uk Thu Nov 18 15:34:11 2004 From: wookey@aleph1.co.uk (Wookey) Date: Thu, 18 Nov 2004 15:34:11 +0000 Subject: [Yaffs] Re: YAFFS support for 16bit NAND flash In-Reply-To: References: Message-ID: <20041118153411.GL5852@xios> +++ Reggiani, Adamo [04-11-18 15:18 +0100]: > > Hi Adam, > Yaffs2 should support 16bit Nand flash, and is under development now; some modifications are already committed to the CVS repository. > Anyway i think it's trivial to modify the current Yaffs for 16bit devices. So long as they allow page-rewriting. Check the spec. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From adam.charrett@philips.com Fri Nov 19 10:50:14 2004 From: adam.charrett@philips.com (adam.charrett@philips.com) Date: Fri, 19 Nov 2004 10:50:14 +0000 Subject: [Yaffs] Patch for compile bug in direct\yaffsfs.h Message-ID: Line 135 reads, #define S_READ 0000400 but should be #define S_IREAD 0000400 Cheers Adam From adam.charrett@philips.com Fri Nov 19 14:39:06 2004 From: adam.charrett@philips.com (adam.charrett@philips.com) Date: Fri, 19 Nov 2004 14:39:06 +0000 Subject: [Yaffs] Re: YAFFS support for 16bit NAND flash Message-ID: Thanks for the info. The devices we are using are 512B Pages and 16Byte Spare areas and support 1 rewrite to the spare area. The possibility I'm looking into is reducing the number of bytes used by the tags by 1. Bits 15 15-Bit File ID 32K Files 2 2bit serial number 18 18Bit Page ID 9 9Bit counter of the number of bytes (n + 1 ,ie 0 is really 1, as there is no point in allocating a page for 0 bytes? is there?) 12 12Bit ECC 0 Unused 56 Total This would be perfectly acceptable for us, as we don't have a very large device (64MB max) Cheers Adam -----Original Message----- From: Wookey [mailto:wookey@aleph1.co.uk] Sent: 18 Nov 2004 15:34 To: yaffs@stoneboat.aleph1.co.uk Subject: [Yaffs] Re: YAFFS support for 16bit NAND flash +++ Reggiani, Adamo [04-11-18 15:18 +0100]: > > Hi Adam, > Yaffs2 should support 16bit Nand flash, and is under development now; some modifications are already committed to the CVS repository. > Anyway i think it's trivial to modify the current Yaffs for 16bit devices. So long as they allow page-rewriting. Check the spec. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Sun Nov 21 21:46:24 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 22 Nov 2004 10:46:24 +1300 Subject: [Yaffs] Patch for compile bug in direct\yaffsfs.h In-Reply-To: References: Message-ID: <20041121214149.8811C45F1@blood.actrix.co.nz> Thanx This has been fixed now in CVS. -- Charles On Friday 19 November 2004 23:50, adam.charrett@philips.com wrote: > Line 135 reads, > > #define S_READ 0000400 > > but should be > > #define S_IREAD 0000400 > > Cheers > > Adam > > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From manningc2@actrix.gen.nz Sun Nov 21 22:01:10 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 22 Nov 2004 11:01:10 +1300 Subject: [Yaffs] YAFFS support for 16bit NAND flash In-Reply-To: References: Message-ID: <20041121215635.2DDB715D23@desire.actrix.co.nz> On Thursday 18 November 2004 22:27, adam.charrett@philips.com wrote: > I'm currently try to evaluate whether to use YAFFS for a project on one= of > our chips and having looked at the spec am unsure as to whether YAFFS > could/does support 16Bit NAND flash. > The only difference between 8Bit NAND flash adn 16bit as far as YAFFS i= s > concerned would be where the Bad Block information is stored and the fa= ct > that a 2byte word is used instead of 1 byte. > > Has any one used YAFFS with a 16bit device? > > Are there any plans to support 16bit devices? > > Many thanks > > Adam Hi all,=20 Sorry to be so late to the party (was away for a short hike last week). YAFFS will work fine with a 16-bit NAND device (ie. one with a 16-bit bus= but=20 512byte pages/32 pages per block). These devices use 8 bits for accessing= the=20 command registers and use 16-bits for pumping the data.=20 As Wookey has noted, you need to check the rewrite-happiness because YAFF= S1=20 needs to be able to write delete flags to the spare when a page gets=20 discarded. That, however, is independent of the 16-bit bus issue. YAFFS2 = has=20 no such constraint. The bad block marking is no problem at all since YAFFS always reads/write= s=20 either the data (512bytes) or spare (16 bytes) as a single operation. The= re=20 is no access where YAFFS reads only one byte at a time. Where theses devices can really pay off is that the wider bus width can m= ove=20 the data faster (x16 cycles rather than x8 cycles). Futher, with devices = like=20 an ARM you can use ldmxx/stmxx to get way better performance. -- Charles From manningc2@actrix.gen.nz Sun Nov 21 23:41:38 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 22 Nov 2004 12:41:38 +1300 Subject: [Yaffs] Fix in yaffs/direct/yaffsfs.c Message-ID: <20041121233703.4060416083@desire.actrix.co.nz> Hi All I found that there was a problem in the YAFFS/direct device look up which= =20 could cause the wrong device to be matched. If the device list contains a device with a path prefix that is a substri= ng=20 of another (eg. /flash" and "/flash1", then the wrong device could be fou= nd=20 (ie. could find "/flash" instead of "/flash1"). This has been fixed. -- Charles From manningc2@actrix.gen.nz Mon Nov 22 03:43:18 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 22 Nov 2004 16:43:18 +1300 Subject: [Yaffs] More YAFFS2 activity Message-ID: <20041122033842.0275B4D0C@blood.actrix.co.nz> Hi YAFFSers... I have just checked in more YAFFS2 changes and additions. YAFFS2 now works in "YAFFS/Direct" and in the Linux kernel using RAM=20 emulation. The Linux kernel stuff does not yet support mtd. The ram emulation helps = to=20 test that the YAFFS<->Linux file system glue is working, as well as test = out=20 the tags munging, ECC etc. The last phase of the exercise is now underwa= y:=20 the YAFFS<->mtd glue. Except, of course, there is still mkyaffsimage and associated stuff to=20 complete as well as a bit of extra documentation. Any feedback/tests/whatever much appreciated. -- Charles From zhou_yao_hui@163.com Mon Nov 22 15:20:26 2004 From: zhou_yao_hui@163.com (=?gb2312?B?1tzSq7vU?=) Date: Mon, 22 Nov 2004 23:20:26 +0800 Subject: [Yaffs] what's chunk means in yaffs ? Message-ID: <002f01c4d0a6$ceea0bd0$fa00a8c0@keke> SSdtIHNvcnJ5IGZvciBteSBwb29yIGVuZ2xpc2ggIQ0KDQpJbiB5YWZmcyAsY2h1bmsgbWVhbnMg cGFnZXMgYnV0IGV4Y2VwdCBvb2IsYSBibG9jayBoYXMgbXVjaCBjaHVua3MuIElzIGl0IHJpZ2h0 ID8= From frowand@mvista.com Mon Nov 22 23:35:37 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 15:35:37 -0800 Subject: [Yaffs] fix for mkyaffsimage compile error Message-ID: <41A277C9.50803@mvista.com> This is a multi-part message in MIME format. --------------040104080203080701030306 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit When I compile mkyaffsimage on RedHat 9.0, I get errors that look like the errors reported in the email thread "Compile error when using yaffs/direct" started by Daniel Gustafsson, Fri, 8 Oct 2004 15:28:35. The problem is caused by some #define statements in /usr/include/bits/stat.h: # define st_atime st_atim.tv_sec /* Backward compatibility. */ # define st_mtime st_mtim.tv_sec # define st_ctime st_ctim.tv_sec The attached patch is one way to fix the problem for mkyaffsimage. It renames the st_*time fields to st_tim. If this is an acceptable way to fix the problem, then I can update the patch to include the in-kernel files and the files in the direct directory since they reference these same fields. -Frank -- Frank Rowand MontaVista Software, Inc --------------040104080203080701030306 Content-Type: text/plain; name="yaffs_userland_02_fixup_rh9.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_02_fixup_rh9.patch" Index: yaffs/yaffs_guts.h =================================================================== --- yaffs.orig/yaffs_guts.h +++ yaffs/yaffs_guts.h @@ -200,9 +200,12 @@ #else __u32 st_uid; // user ID of owner __u32 st_gid; // group ID of owner - __u32 st_atime; // time of last access - __u32 st_mtime; // time of last modification - __u32 st_ctime; // time of last change +/* + * /usr/include/bits/stat.h defines st_atime, st_mtime, st_ctime + */ + __u32 st_atim; // time of last access + __u32 st_mtim; // time of last modification + __u32 st_ctim; // time of last change #endif // File size applies to files only @@ -349,9 +352,12 @@ #else __u32 st_uid; // user ID of owner __u32 st_gid; // group ID of owner - __u32 st_atime; // time of last access - __u32 st_mtime; // time of last modification - __u32 st_ctime; // time of last change +/* + * /usr/include/bits/stat.h defines st_atime, st_mtime, st_ctime + */ + __u32 st_atim; // time of last access + __u32 st_mtim; // time of last modification + __u32 st_ctim; // time of last change #endif __u32 st_rdev; // device stuff for block and char devices Index: yaffs/utils/mkyaffsimage.c =================================================================== --- yaffs.orig/utils/mkyaffsimage.c +++ yaffs/utils/mkyaffsimage.c @@ -293,9 +293,9 @@ // Regular POSIX. oh->st_uid = SWAP32(oh->st_uid); oh->st_gid = SWAP32(oh->st_gid); - oh->st_atime = SWAP32(oh->st_atime); - oh->st_mtime = SWAP32(oh->st_mtime); - oh->st_ctime = SWAP32(oh->st_ctime); + oh->st_atim = SWAP32(oh->st_atim); + oh->st_mtim = SWAP32(oh->st_mtim); + oh->st_ctim = SWAP32(oh->st_ctim); #endif oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that! @@ -354,9 +354,9 @@ oh->st_uid = s->st_uid; // NCB 12/9/02 oh->st_gid = s->st_uid; oh->st_gid = s->st_gid; - oh->st_atime = s->st_atime; - oh->st_mtime = s->st_mtime; - oh->st_ctime = s->st_ctime; + oh->st_atim = s->st_atime; + oh->st_mtim = s->st_mtime; + oh->st_ctim = s->st_ctime; oh->st_rdev = s->st_rdev; } --------------040104080203080701030306-- From frowand@mvista.com Mon Nov 22 23:40:57 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 15:40:57 -0800 Subject: [Yaffs] patch: fix compile warnings Message-ID: <41A27909.9070806@mvista.com> This is a multi-part message in MIME format. --------------000603050103040204040509 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit If you want to eliminate some compile warnings, the attached patch allows a warning free compile of mkyaffs and mkyaffsimage on RedHat 9.0 -Frank -- Frank Rowand MontaVista Software, Inc --------------000603050103040204040509 Content-Type: text/plain; name="yaffs_userland_03_fix_warnings.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_03_fix_warnings.patch" Index: yaffs/nand_ecc.c =================================================================== --- yaffs.orig/nand_ecc.c +++ yaffs/nand_ecc.c @@ -25,6 +25,7 @@ #endif #include "yportenv.h" +#include "nand_ecc.h" /* * Pre-calculated 256-way 1 byte column parity Index: yaffs/utils/mkyaffsimage.c =================================================================== --- yaffs.orig/utils/mkyaffsimage.c +++ yaffs/utils/mkyaffsimage.c @@ -32,16 +32,13 @@ #include #include "yaffs_guts.h" +#include "nand_ecc.h" #define MAX_OBJECTS 10000 const char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.7 2003/07/16 03:00:48 charles Exp $"; -// External functions for ECC on data -void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); -int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); - typedef struct { @@ -119,6 +116,7 @@ return -1; } +#if 0 // NCB added 10/9/2002 static __u16 yaffs_CalcNameSum(const char *name) { @@ -135,6 +133,7 @@ } return sum; } +#endif static void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare) Index: yaffs/utils/mkyaffs.c =================================================================== --- yaffs.orig/utils/mkyaffs.c +++ yaffs/utils/mkyaffs.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include Index: yaffs/devextras.h =================================================================== --- yaffs.orig/devextras.h +++ yaffs/devextras.h @@ -201,6 +201,7 @@ +#ifndef DT_UNKNOWN /* * File types */ @@ -213,6 +214,7 @@ #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 +#endif #ifndef WIN32 #include Index: yaffs/nand_ecc.h =================================================================== --- /dev/null +++ yaffs/nand_ecc.h @@ -0,0 +1,28 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yportenv.h: Portable services used by yaffs. This is done to allow + * simple migration from kernel space into app space for testing. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + */ + +#ifndef __NAND_ECC_H__ +#define __NAND_ECC_H__ + +/* External functions for ECC on data */ + +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); + +#endif --------------000603050103040204040509-- From frowand@mvista.com Mon Nov 22 23:54:02 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 15:54:02 -0800 Subject: [Yaffs] patch: mkyaffsimage - incorrect argc check Message-ID: <41A27C1A.7030503@mvista.com> This is a multi-part message in MIME format. --------------000304010109050407030607 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The usage for mkyaffsimage is: mkyaffsimage dir image_file [convert] The check for the value of argc fails when the convert argument is not provided. The attached patch allows the convert argument to be ommitted. -Frank -- Frank Rowand MontaVista Software, Inc --------------000304010109050407030607 Content-Type: text/plain; name="yaffs_userland_06_mkyaffsimage_argc.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_06_mkyaffsimage_argc.patch" Index: yaffs/utils/mkyaffsimage.c =================================================================== --- yaffs.orig/utils/mkyaffsimage.c +++ yaffs/utils/mkyaffsimage.c @@ -535,7 +535,7 @@ printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n"); - if(argc <= 3) + if(argc < 3) { printf("usage: mkyaffsimage dir image_file [convert]\n"); printf(" dir the directory tree to be converted\n"); --------------000304010109050407030607-- From frowand@mvista.com Mon Nov 22 23:51:40 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 15:51:40 -0800 Subject: [Yaffs] patch: mkyaffs - detect image too large due to bad blocks Message-ID: <41A27B8C.1090508@mvista.com> This is a multi-part message in MIME format. --------------030306040801060407010302 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The attached patch updates mkyaffs to detect when it was not able to to write the complete image to NAND due to an excessive number of bad blocks. -Frank -- Frank Rowand MontaVista Software, Inc --------------030306040801060407010302 Content-Type: text/plain; name="yaffs_userland_05_mkyaffs_damaged_count.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_05_mkyaffs_damaged_count.patch" Index: yaffs/utils/mkyaffs.c =================================================================== --- yaffs.orig/utils/mkyaffs.c +++ yaffs/utils/mkyaffs.c @@ -88,11 +88,13 @@ { unsigned long addr; unsigned long offset; + int damaged_count = 0; int fd; int img=-1; int optcnt = 1; int usemtdecc = 0; int imglen = 0; + int img_written = 0; int showHelp = 0; struct mtd_oob_buf oob = {0, 16, (unsigned char *) &oobbuf}; mtd_info_t meminfo; @@ -197,6 +199,7 @@ if(countBits[oobbuf[5]] < 7) { + damaged_count++; printf("Block at 0x08%lx is damaged and is not being formatted\n",addr); } else @@ -218,6 +221,7 @@ for(offset = 0; offset This is a multi-part message in MIME format. --------------030507050008040203080800 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The attached patch should allow a 64 bit compile to create a struct yaffs_ObjectHeader with proper field size and alignment. I have not yet tested this on 64 bit hardware, but wanted to share it before it became stale. I also have not tried it with a compiler other than gcc (I'm not sure what people are using for WINCE targets), so I don't know if this will work with other compilers. -Frank -- Frank Rowand MontaVista Software, Inc --------------030507050008040203080800 Content-Type: text/plain; name="yaffs_userland_04_64bit.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_04_64bit.patch" Index: yaffs/yaffs_guts.h =================================================================== --- yaffs.orig/yaffs_guts.h +++ yaffs/yaffs_guts.h @@ -181,16 +181,17 @@ YAFFS_OBJECT_TYPE_DIRECTORY, YAFFS_OBJECT_TYPE_HARDLINK, YAFFS_OBJECT_TYPE_SPECIAL -} yaffs_ObjectType; +} yaffs_ObjectType __attribute__ ((__mode__ (__SI__))); typedef struct { yaffs_ObjectType type; // Apply to everything - int parentObjectId; + __s32 parentObjectId; __u16 sum__NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies char name[YAFFS_MAX_NAME_LENGTH + 1]; + char pad[2]; // Thes following apply to directories, files, symlinks - not hard links __u32 st_mode; // protection @@ -209,10 +210,10 @@ #endif // File size applies to files only - int fileSize; + __s32 fileSize; // Equivalent object id applies to hard links only. - int equivalentObjectId; + __s32 equivalentObjectId; // Alias is for symlinks only. char alias[YAFFS_MAX_ALIAS_LENGTH + 1]; Index: yaffs/devextras.h =================================================================== --- yaffs.orig/devextras.h +++ yaffs/devextras.h @@ -33,9 +33,11 @@ // User space defines -typedef unsigned char __u8; -typedef unsigned short __u16; -typedef unsigned __u32; +typedef int32_t __s32; + +typedef u_int8_t __u8; +typedef u_int16_t __u16; +typedef u_int32_t __u32; /* --------------030507050008040203080800-- From frowand@mvista.com Tue Nov 23 00:05:33 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 16:05:33 -0800 Subject: [Yaffs] patch: mkyaffsimage error handling Message-ID: <41A27ECD.5080800@mvista.com> This is a multi-part message in MIME format. --------------010509010807050701080206 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The attached patch cleans up the error handling in mkyaffsimage a little bit. Some functions return an error value, others directly set the global variable "error". The patch converts all usage to the function error return model. In process_directory(), added a printf() of the name of the unhandled object to the "we don't handle this type" error message. In process_directory(), stop scanning as soon as an error occurs. (This may be a controversial change, but it seemed good to me to make the failure obvious, and not hidden in the output of files that were properly processed.) -Frank -- Frank Rowand MontaVista Software, Inc --------------010509010807050701080206 Content-Type: text/plain; name="yaffs_userland_07_mkyaffsimage_error_handling.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_07_mkyaffsimage_error_handling.patch" Index: yaffs/utils/mkyaffsimage.c =================================================================== --- yaffs.orig/utils/mkyaffsimage.c +++ yaffs/utils/mkyaffsimage.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "yaffs_guts.h" #include "nand_ecc.h" @@ -56,8 +57,6 @@ static int outFile; -static int error; - static int convert_endian = 0; static int obj_compare(const void *a, const void * b) @@ -236,6 +235,7 @@ static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) { + int error; yaffs_Tags t; yaffs_Spare s; @@ -386,7 +386,7 @@ static int process_directory(int parent, const char *path) { - + int error = 0; DIR *dir; struct dirent *entry; @@ -396,7 +396,7 @@ if(dir) { - while((entry = readdir(dir)) != NULL) + while(((entry = readdir(dir)) != NULL) && (error >= 0)) { /* Ignore . and .. */ @@ -518,19 +518,23 @@ } else { + printf("%s",full_name); printf(" we don't handle this type\n"); + error = -1; + errno = EINVAL; } } } } - return 0; + return error; } int main(int argc, char *argv[]) { + int error; struct stat stats; printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n"); @@ -572,8 +576,8 @@ printf("Processing directory %s into image file %s\n",argv[1],argv[2]); error = write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL); - if(error) - error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]); + if (error >= 0) + error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]); close(outFile); --------------010509010807050701080206-- From frowand@mvista.com Tue Nov 23 00:07:46 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 22 Nov 2004 16:07:46 -0800 Subject: [Yaffs] patch: mkyaffsimage - buffer overflow fix Message-ID: <41A27F52.4030503@mvista.com> This is a multi-part message in MIME format. --------------000007010902080807060509 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit The attached patch prevents a buffer overflow which occurs when a path becomes too long. (And with this patch, I'll end my tiny flood of the email list...) -Frank -- Frank Rowand MontaVista Software, Inc --------------000007010902080807060509 Content-Type: text/plain; name="yaffs_userland_08_mkyaffsimage_buf_overflow.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_userland_08_mkyaffsimage_buf_overflow.patch" Index: yaffs/utils/mkyaffsimage.c =================================================================== --- yaffs.orig/utils/mkyaffsimage.c +++ yaffs/utils/mkyaffsimage.c @@ -385,7 +385,9 @@ static int process_directory(int parent, const char *path) { +#define FULL_NAME_LEN 500 int error = 0; + int len; DIR *dir; struct dirent *entry; @@ -402,12 +404,20 @@ if(strcmp(entry->d_name,".") && strcmp(entry->d_name,"..")) { - char full_name[500]; + char full_name[FULL_NAME_LEN]; struct stat stats; int equivalentObj; int newObj; - sprintf(full_name,"%s/%s",path,entry->d_name); + len = snprintf(full_name,FULL_NAME_LEN,"%s/%s",path,entry->d_name); + if (len > FULL_NAME_LEN) + { + printf("%s/%s\n",path,entry->d_name); + printf("ERROR: length of path >= %d\n", FULL_NAME_LEN); + error = -1; + errno = ENAMETOOLONG; + continue; + } lstat(full_name,&stats); --------------000007010902080807060509-- From Charles.Manning@trimble.co.nz Tue Nov 23 00:28:57 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Tue, 23 Nov 2004 13:28:57 +1300 Subject: [Yaffs] what's chunk means in yaffs ? Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E0154901E@nzc-ap-xch-01.ap.trimblecorp.net> QSAiY2h1bmsiIGlzIHRoZSBzYW1lIGFzIGEgcGFnZSBhbmQgaW5jbHVkZXMgYm90aCB0aGUgZGF0 YSBhbmQgdGhlIHNwYXJlL29vYiBhcmVhLg0KVGhlcmUgYXJlIG1hbnkgY2h1bmtzIHRvIG9uZSBi bG9jay4NCg0KDQpUaGUgcmVhc29uIEkgdXNlIHRoZSB0ZXJtICJjaHVuayIgaW5zdGVhZCBvZiBw YWdlIGlzIHRvIG1ha2UgYW4gYWJzdHJhY3Rpb24gYmV0d2VlbiBwaHlzaWNhbCBOQU5EIGZsYXNo IGVudGl0aWVzIGFuZCAibG9naWNhbCIgb25lcyB1c2VkIGluIFlBRkZTLiBUaGlzIGlzIGRvbmUg c28gdGhhdCBpbiB0aGUgZnV0dXJlIGl0IGlzIGVhc2llciB0byB0aGluayBhYm91dCB1c2luZyBj aHVua3Mgb2YgLCBzYXksIDFrQiB3aXRoIHBhZ2VzIG9mIDUxMiBieXRlcyAoaWUuIFR3byBOQU5E IHBhZ2VzID09IG9uZSBZQUZGUyBjaHVuaykuDQoNCkZvciBub3csIGhvd2V2ZXIgeW91IGNhbiBq dXN0IHRoaW5rIG9mIGNodW5rIGFuZCBwYWdlIGFzIHRoZSBzYW1lIHRoaW5nLg0KDQoNCi0tIENo YXJsZXMNCg0KDQotLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KRnJvbTogeWFmZnMtYWRtaW5A c3RvbmVib2F0LmFsZXBoMS5jby51ayBbbWFpbHRvOnlhZmZzLWFkbWluQHN0b25lYm9hdC5hbGVw aDEuY28udWtdIE9uIEJlaGFsZiBPZiB6aG91X3lhb19odWlAMTYzLmNvbQ0KU2VudDogVHVlc2Rh eSwgMjMgTm92ZW1iZXIgMjAwNCA0OjIwIGEubS4NClRvOiB5YWZmc0BzdG9uZWJvYXQuYWxlcGgx LmNvLnVrDQpTdWJqZWN0OiBbWWFmZnNdIHdoYXQncyBjaHVuayBtZWFucyBpbiB5YWZmcyA/DQoN Cg0KSSdtIHNvcnJ5IGZvciBteSBwb29yIGVuZ2xpc2ggIQ0KDQpJbiB5YWZmcyAsY2h1bmsgbWVh bnMgcGFnZXMgYnV0IGV4Y2VwdCBvb2IsYSBibG9jayBoYXMgbXVjaCBjaHVua3MuIElzIGl0IHJp Z2h0ID/pqprnnpc/P+mqmuiPnOa/h2rorJ/mpqzlqrY/7o2Pd++9nuabo+W4kOaTj+WjkO6gq+ad he6gnT/vvZwNCg== From bbeveridge@bluewatersys.com Tue Nov 23 01:24:04 2004 From: bbeveridge@bluewatersys.com (Brad Beveridge) Date: Tue, 23 Nov 2004 14:24:04 +1300 Subject: [Yaffs] Yaffs on MTD, strange umount behaviour Message-ID: <41A29134.6060507@bluewatersys.com> Hi yaffsers. I've noticed some slight strangeness in the yaffs/mtd interaction. I have put debugging code in the drivers/mtd/mtd_blkdevs::blktrans_open/release functions, and when yaffs mounts blktrans_open gets called, and the use count increases. When yaffs is umounted the blktrans_release function is not called - therefore the use count isn't decremented, and other clean up operations aren't done. Normally this is OK, I can mount & umount as many times as I like. However, if I happen to remove my mtd device (if you are curious, I have removable nand storage & I am rmmoding the nand driver module), then add the mtd device back & remount yaffs, it borks. In the below structure (yaffs_fs.c) static struct file_system_type yaffs_fs_type = { .owner = THIS_MODULE, .name = "yaffs", .get_sb = yaffs_read_super, //.kill_sb = kill_block_super, .kill_sb = kill_litter_super, .fs_flags = FS_REQUIRES_DEV, }; .kill_sb is set to kill_litter_super, but there is a (commented out) alternative of .kill_sb = kill_block_super. I have found that setting kill_sb to be kill_block_super causes the blktrans_release function to be called when yaffs is unmounted, and I can happily go through the sequence of - insmod driver - mount yaffs - umount yaffs - rmmod driver My question is: why should the default kill_litter_super be prefered over kill_block_super, and what might I have screwed up in the process of changing from one function to another? Cheers Brad From tibs@sj.co.uk Tue Nov 23 09:43:56 2004 From: tibs@sj.co.uk (Tony Ibbs) Date: Tue, 23 Nov 2004 09:43:56 +0000 Subject: [Yaffs] fix for mkyaffsimage compile error In-Reply-To: <41A277C9.50803@mvista.com> References: <41A277C9.50803@mvista.com> Message-ID: <41A3065C.3010208@sj.co.uk> Frank Rowand wrote: > When I compile mkyaffsimage on RedHat 9.0, I get errors that look > like the errors reported in the email thread "Compile error when using > yaffs/direct" started by Daniel Gustafsson, Fri, 8 Oct 2004 15:28:35. > > The problem is caused by some #define statements in > /usr/include/bits/stat.h: > > # define st_atime st_atim.tv_sec /* Backward compatibility. */ > # define st_mtime st_mtim.tv_sec > # define st_ctime st_ctim.tv_sec > > The attached patch is one way to fix the problem for mkyaffsimage. An alternative is to specify -D_POSIX_SOURCE to gcc, as suggested by the FreeBSD "man 2 stat" (so I assume this problem would show up on BSD as well). Not sure if that's a better or worse solution. Tibs From lorenzo.parisi@st.com Tue Nov 23 14:25:46 2004 From: lorenzo.parisi@st.com (Lorenzo PARISI) Date: Tue, 23 Nov 2004 15:25:46 +0100 Subject: [Yaffs] YAFFS vs JFFS2 Message-ID: Hi, I've done this writing on NAND: 1) 4000 files whit size 4k 2) 250 files, 64k 3) 32 files, 1M 4) 4 files, 8M 5) 2 files, 16M 6) 1 file with size 1M. And, the results are: JFFS2 YAFFS ----- ----- 1) 1m50 2m1 2) 0m15 0m42 3) 0m17 1m18 4) 0m17 1m21 5) 0m17 1m24 6) 0m25 1m28 The results are much differents. Why? Thanks. PS: I've a bast machine, with a NAND STMicroelectronics and a NAND Samsung. From tglx@linutronix.de Tue Nov 23 15:45:59 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Tue, 23 Nov 2004 16:45:59 +0100 Subject: [Yaffs] YAFFS vs JFFS2 In-Reply-To: References: Message-ID: <1101224759.3888.43.camel@tglx.tec.linutronix.de> On Tue, 2004-11-23 at 15:25 +0100, Lorenzo PARISI wrote: > Hi, > > I've done this writing on NAND: > 1) 4000 files whit size 4k > 2) 250 files, 64k > 3) 32 files, 1M > 4) 4 files, 8M > 5) 2 files, 16M > 6) 1 file with size 1M. > > And, the results are: > JFFS2 YAFFS > ----- ----- > 1) 1m50 2m1 > 2) 0m15 0m42 > 3) 0m17 1m18 > 4) 0m17 1m21 > 5) 0m17 1m24 > 6) 0m25 1m28 > > The results are much differents. Why? JFFS2 is compressing the files and writes less bytes to the chip. Depending on the file content the compression can be fast and reduce the size quite well. So it's hard to compare. tglx From manningc2@actrix.gen.nz Tue Nov 23 20:13:38 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 24 Nov 2004 09:13:38 +1300 Subject: [Yaffs] YAFFS vs JFFS2 In-Reply-To: <1101224759.3888.43.camel@tglx.tec.linutronix.de> References: <1101224759.3888.43.camel@tglx.tec.linutronix.de> Message-ID: <20041123200859.0201C4605@blood.actrix.co.nz> As Thomas says, the compression in JFFS2 will help in some cases=20 (particularly if you have highly compressable test files). There are many factors to consider as part of performance measurement=20 including: 1) Comparison of writes and reads of the files you're likely to use - not= =20 just test files. 2) Comparison of performance on a dirty file system (ie. how do they comp= are=20 with garbage collection etc.) 3) Testing overwrite (ie. overwriting parts of a file). The reason both YAFFS and JFFS2 exist is that they both have different=20 properties. One is not always better than the other. To get the best=20 performance you need to select the right file system based on your needs. -- CHarles On Wednesday 24 November 2004 04:45, Thomas Gleixner wrote: > On Tue, 2004-11-23 at 15:25 +0100, Lorenzo PARISI wrote: > > Hi, > > > > I've done this writing on NAND: > > 1) 4000 files whit size 4k > > 2) 250 files, 64k > > 3) 32 files, 1M > > 4) 4 files, 8M > > 5) 2 files, 16M > > 6) 1 file with size 1M. > > > > And, the results are: > > JFFS2 YAFFS > > ----- ----- > > 1) 1m50 2m1 > > 2) 0m15 0m42 > > 3) 0m17 1m18 > > 4) 0m17 1m21 > > 5) 0m17 1m24 > > 6) 0m25 1m28 > > > > The results are much differents. Why? > > JFFS2 is compressing the files and writes less bytes to the chip. > Depending on the file content the compression can be fast and reduce th= e > size quite well. So it's hard to compare. > > tglx > > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From arasv@magellan-technology.com Thu Dec 2 05:19:51 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Thu, 02 Dec 2004 16:19:51 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems Message-ID: <41AEA5F7.6060307@magellan-technology.com> Hello all, I have managed to get the latest MTD code to compile with a 2.4.27-vrs1 kernel. I compiled the latest YAFFS code (from CVS) into the kernel. I mounted a 16MB block of Smartmedia NAND and tried to create some files, I got a load of errors , I reset the machine because it was obviously going crazy. I then noticed that my NAND suddenly had a load of "bad blocks" Can someone help me out here, or tell me what sorts of debug information I have to provide? I have provide some debug information: * kernel boot messages: ... SmartMedia card inserted. NAND device: Manufacturer ID: 0x98, Chip ID: 0x75 (Toshiba NAND 32MiB 3,3V 8-bit) Scanning device for bad blocks Bad eraseblock 1 at 0x00004000 Bad eraseblock 2 at 0x00008000 ... SNIP ... Bad eraseblock 1022 at 0x00ff8000 Bad eraseblock 1023 at 0x00ffc000 Creating 2 MTD partitions on "NAND 32MiB 3,3V 8-bit": 0x00000000-0x01000000 : "NAND partition 1" mtd: Giving out device 4 to NAND partition 1 0x01000000-0x02000000 : "NAND partition 2" mtd: Giving out device 5 to NAND partition 2 * The kernel boot finishes and I mount the NAND /root # mount -t yaffs /dev/mtdblock/5 /mnt/y2 mtdblock_open ok yaffs: dev is 7941 name is "1f:05" nand_read_oob: from = 0x01004000, len = 16 nand_read_oob: from = 0x01004200, len = 16 nand_read_oob: from = 0x01004000, len = 16 nand_read_oob: from = 0x01008000, len = 16 nand_read_oob: from = 0x01008200, len = 16 nand_read_oob: from = 0x01008000, len = 16 ... SNIP ... nand_read_oob: from = 0x01ff8000, len = 16 nand_read_oob: from = 0x01ff8200, len = 16 nand_read_oob: from = 0x01ff8000, len = 16 nand_read_oob: from = 0x01ffc000, len = 16 nand_read_oob: from = 0x01ffc200, len = 16 nand_read_oob: from = 0x01ffc000, len = 16 * I check out the /proc entry y2 # cat /proc/yaffs YAFFS built:Dec 2 2004 15:20:31 $Id: yaffs_fs.c,v 1.35 2004/10/20 20:12:43 charles Exp $ $Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $ Device yaffs startBlock......... 1 endBlock........... 1023 chunkGroupBits..... 0 chunkGroupSize..... 1 nErasedBlocks...... 1023 nTnodesCreated..... 0 nFreeTnodes........ 0 nObjectsCreated.... 100 nFreeObjects....... 97 nFreeChunks........ 32736 nPageWrites........ 0 nPageReads......... 0 nBlockErasures..... 0 nGCCopies.......... 0 garbageCollections. 0 passiveGCs......... 0 nRetriedWrites..... 0 nRetireBlocks...... 0 eccFixed........... 0 eccUnfixed......... 0 tagsEccFixed....... 0 tagsEccUnfixed..... 1023 cacheHits.......... 0 nDeletedFiles...... 0 nUnlinkedFiles..... 0 nBackgroudDeletions 0 useNANDECC......... 0 * I cd to the /mnt/y2 directory and try to create a file (all hell breaks loose) /root # cd /mnt/y2 y2 # touch 1 nand_read_ecc: from = 0x01004000, len = 512 nand_read_oob: from = 0x01004000, len = 16 nand_write_ecc: to = 0x01004000, len = 512 nand_write_oob: to = 0x01004000, len = 16 nand_read_ecc: from = 0x01004000, len = 512 nand_read_ecc: Failed ECC read, page 0x00008020 nand_read_ecc: Failed ECC read, page 0x00008020 nand_read_oob: from = 0x01004000, len = 16 nand_write_oob: to = 0x01004000, len = 16 nand_read_ecc: from = 0x01004200, len = 512 nand_read_oob: from = 0x01004200, len = 16 nand_write_ecc: to = 0x01004200, len = 512 nand_write_oob: to = 0x01004200, len = 16 nand_read_ecc: from = 0x01004200, len = 512 nand_read_ecc: Failed ECC read, page 0x00008021 nand_read_ecc: Failed ECC read, page 0x00008021 ... SNIP ... nand_read_ecc: from = 0x0101aa00, len = 512 nand_read_oob: from = 0x0101aa00, len = 16 nand_write_ecc: to = 0x0101aa00, len = 512 nand_write_oob: to = 0x0101aa00, len = 16 nand_read_ecc: from = 0x0101aa00, len = 512 nand_read_ecc: Failed ECC read, page 0x000080d5 ... at which point it never ends, so I reset it * After I reboot I get a load of bad blocks! NAND device: Manufacturer ID: 0x98, Chip ID: 0x75 (Toshiba NAND 32MiB 3,3V 8-bit) Scanning device for bad blocks Bad eraseblock 1 at 0x00004000 Bad eraseblock 2 at 0x00008000 Bad eraseblock 3 at 0x0000c000 ... SNIP Bad eraseblock 1021 at 0x00ff4000 Bad eraseblock 1022 at 0x00ff8000 Bad eraseblock 1023 at 0x00ffc000 I know that these blocks aren't bad, this is a brand new Flash chip! Is there software that will verify every block and correctly mark it bad or not? I tried some operations on the YAFFS partition, but get loads of errors: / # cd /mnt/y1 y1 # ll nand_read_ecc: from = 0x00203800, len = 512 nand_read_ecc: Failed ECC read, page 0x0000101c nand_read_ecc: Failed ECC read, page 0x0000101c nand_read_ecc: from = 0x00203200, len = 512 nand_read_ecc: Failed ECC read, page 0x00001019 nand_read_ecc: Failed ECC read, page 0x00001019 nand_read_ecc: from = 0x00203000, len = 512 nand_read_ecc: Failed ECC read, page 0x00001018 nand_read_ecc: Failed ECC read, page 0x00001018 drw-rw-rw- 1 root root 512 Dec 2 15:03 ./ drwxrwxr-x 9 root 100 4096 Nov 11 10:17 ../ -rw-rw-r-- 1 root root 0 Nov 19 12:47 c -rw-rw-r-- 1 root root 0 Nov 18 10:39 d -rw-rw-r-- 1 root root 0 Nov 18 10:39 e drw-rw-rw- 1 root root 512 Dec 2 15:03 lost+found/ y1 # df Filesystem 1k-blocks Used Available Use% Mounted on /dev/root 102901816 76756844 20917824 79% / tmpfs 15428 360 15068 2% /var /dev/mtdblock/4 16368 8884 7484 54% /mnt/y1 /dev/mtdblock/5 16368 180 16188 1% /mnt/y2 y1 # cd /mnt/y2 y2 # ll nand_read_ecc: from = 0x0101aa00, len = 512 nand_read_ecc: Failed ECC read, page 0x000080d5 nand_read_ecc: Failed ECC read, page 0x000080d5 drw-rw-rw- 1 root root 512 Dec 2 15:08 ./ drwxrwxr-x 9 root 100 4096 Nov 11 10:17 ../ -rw-rw-r-- 1 root root 0 Dec 2 14:31 1 drw-rw-rw- 1 root root 512 Dec 2 15:08 lost+found/ y2 # df Filesystem 1k-blocks Used Available Use% Mounted on /dev/root 102901816 76756844 20917824 79% / tmpfs 15428 364 15064 2% /var /dev/mtdblock/4 16368 8884 7484 54% /mnt/y1 /dev/mtdblock/5 16368 180 16188 1% /mnt/y2 y2 # You can see that there is loads of memory missing from /dev/mtdblock/4 ! * my linux/fs/yaffs directory root@gentoo linux-2.4.27-vrs1-yaffs # ll fs/yaffs/ total 492 drwxrwxr-x 2 arasv users 4096 Dec 2 15:20 . drwxrwxr-x 49 arasv users 4096 Dec 2 15:20 .. -rw-rw-r-- 1 arasv users 7692 Dec 2 15:18 .depend -rw-rw-r-- 1 root root 177 Dec 2 15:20 .yaffs.o.flags -rw-rw-r-- 1 root root 610 Dec 2 15:20 .yaffs_ecc.o.flags -rw-rw-r-- 1 root root 607 Dec 2 15:20 .yaffs_fs.o.flags -rw-rw-r-- 1 root root 613 Dec 2 15:20 .yaffs_guts.o.flags -rw-rw-r-- 1 root root 616 Dec 2 15:20 .yaffs_mtdif.o.flags -rw-rw-r-- 1 root root 616 Dec 2 15:20 .yaffs_ramem.o.flags -rw-rw-r-- 1 arasv users 4536 Dec 1 11:34 Makefile -rw-rw-r-- 1 arasv users 4393 Dec 1 10:57 Makefile.old -rw-r--r-- 1 arasv users 6139 Dec 1 14:35 devextras.h -rw-rw-r-- 1 root root 62546 Dec 2 15:20 yaffs.o -rw-r--r-- 1 arasv users 5537 Dec 1 11:15 yaffs_ecc.c -rw-r--r-- 1 arasv users 970 Dec 1 11:15 yaffs_ecc.h -rw-rw-r-- 1 root root 2132 Dec 2 15:20 yaffs_ecc.o -rw-r--r-- 1 arasv users 42100 Dec 1 10:54 yaffs_fs.c -rw-rw-r-- 1 root root 23080 Dec 2 15:20 yaffs_fs.o -rw-r--r-- 1 arasv users 113357 Dec 1 10:54 yaffs_guts.c -rw-r--r-- 1 arasv users 15691 Dec 1 14:35 yaffs_guts.h -rw-rw-r-- 1 root root 38484 Dec 2 15:20 yaffs_guts.o -rw-r--r-- 1 arasv users 4028 Dec 1 10:54 yaffs_mtdif.c -rw-r--r-- 1 arasv users 1010 Dec 1 14:35 yaffs_mtdif.h -rw-rw-r-- 1 root root 2000 Dec 2 15:20 yaffs_mtdif.o -rw-r--r-- 1 arasv users 5173 Dec 1 11:20 yaffs_ramem.c -rw-rw-r-- 1 root root 832 Dec 2 15:20 yaffs_ramem.o -rw-r--r-- 1 arasv users 14604 Dec 1 11:15 yaffsdev.c -rw-r--r-- 1 arasv users 53248 Dec 1 11:15 yaffsdev.proj -rw-r--r-- 1 arasv users 659 Dec 1 10:54 yaffsinterface.h -rw-r--r-- 1 arasv users 3032 Dec 1 14:35 yportenv.h * This is the object list from the Makefile obj-y := yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o yaffs_ecc.o obj-m := $(O_TARGET) I'm not entirely sure what options I should include in the Makefile either. I want to use the latest MTD code with a NAND/Smartmedia device. Which options should I include? Thanks in advance! regards, Aras From tglx@linutronix.de Thu Dec 2 07:19:12 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Thu, 02 Dec 2004 08:19:12 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41AEA5F7.6060307@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> Message-ID: <1101971952.13353.68.camel@tglx.tec.linutronix.de> On Thu, 2004-12-02 at 16:19 +1100, Aras Vaichas wrote: > Hello all, > > I have managed to get the latest MTD code to compile with a 2.4.27-vrs1 kernel. > I compiled the latest YAFFS code (from CVS) into the kernel. I mounted a 16MB > block of Smartmedia NAND and tried to create some files, I got a load of errors > , I reset the machine because it was obviously going crazy. I then noticed that > my NAND suddenly had a load of "bad blocks" Obviously some errors resulted in marking the blocks bad. Can you first verify that your driver works correctly without a filesystem ? Use nandwrite to write a file to the chip and nanddump to read it back. tglx From arasv@magellan-technology.com Fri Dec 3 01:57:30 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Fri, 03 Dec 2004 12:57:30 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1101971952.13353.68.camel@tglx.tec.linutronix.de> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> Message-ID: <41AFC80A.6020004@magellan-technology.com> Thomas Gleixner wrote: > On Thu, 2004-12-02 at 16:19 +1100, Aras Vaichas wrote: >=20 >>Hello all, >> >>I have managed to get the latest MTD code to compile with a 2.4.27-vrs1= kernel.=20 >>I compiled the latest YAFFS code (from CVS) into the kernel. I mounted = a 16MB=20 >>block of Smartmedia NAND and tried to create some files, I got a load o= f errors=20 >>, I reset the machine because it was obviously going crazy. I then noti= ced that=20 >>my NAND suddenly had a load of "bad blocks" >=20 > Obviously some errors resulted in marking the blocks bad. >=20 > Can you first verify that your driver works correctly without a > filesystem ? Use nandwrite to write a file to the chip and nanddump to > read it back. hmm, it *sort* of works, but it looks like there is corruption. nandtest # echo "Hello World!=20 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" > text.or= ig &&=20 nandwrite -a -p /dev/mtd/4 text.orig MTD_open MTD_ioctl MTD_ioctl WriMTD_ioctl tinand_isbad_bbt(): bbt info for offs 0x00000000: (block 0) 0x00 ng data to block 0 MTD_write nand_write_ecc: to =3D 0x00000000, len =3D 512 MTD_close nand_sync: called nandtest # nanddump /dev/mtd/4 text.out 0 512 && cat text.out MTD_open MTD_ioctl Would you like formatted output? n DumMTD_read pnand_read_ecc: from =3D 0x00000000, len =3D 512 ing nand_read_ecc: Failed ECC read, page 0x00000000 data starting at 0x00000000 and ending at 0x00000200.MTD_ioctl ..nand_read_oob: from =3D 0x00000000, len =3D 16 Dumping 0 MTD_close nand_sync: called Hello World AC@A@@@@ LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BFaA.=C3=BF=C3=BF=C3=BF=C3=BF=C3=BFaa.=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF nandtest # nandtest # mtd_debug info /dev/mtd/4 MTD_open MTD_ioctl MTD_ioctl mtd.type =3DMTD_close nand_sync: called MTD_NANDFLASH mtd.flags =3D MTD_CLEAR_BITS | MTD_ERASEABLE | MTD_OOB | MTD_ECC mtd.size =3D 16777216 (16M) mtd.erasesize =3D 16384 (16K) mtd.oobblock =3D 512 mtd.oobsize =3D 16 mtd.ecctype =3D MTD_ECC_NONE regions =3D 0 From arasv@magellan-technology.com Fri Dec 3 02:59:42 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Fri, 03 Dec 2004 13:59:42 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41AFC80A.6020004@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> Message-ID: <41AFD69E.4080906@magellan-technology.com> Aras Vaichas wrote: > Thomas Gleixner wrote: >=20 >> On Thu, 2004-12-02 at 16:19 +1100, Aras Vaichas wrote: >> >>> Hello all, >>> >>> I have managed to get the latest MTD code to compile with a=20 >>> 2.4.27-vrs1 kernel. I compiled the latest YAFFS code (from CVS) into=20 >>> the kernel. I mounted a 16MB block of Smartmedia NAND and tried to=20 >>> create some files, I got a load of errors , I reset the machine=20 >>> because it was obviously going crazy. I then noticed that my NAND=20 >>> suddenly had a load of "bad blocks" >> >> >> Obviously some errors resulted in marking the blocks bad. >> >> Can you first verify that your driver works correctly without a >> filesystem ? Use nandwrite to write a file to the chip and nanddump to >> read it back. >=20 >=20 > hmm, it *sort* of works, but it looks like there is corruption. Aaah, but if I use a brand new NAND/Smartmedia, there is no corruption th= at I=20 can tell ... Surely it's not the easy to "break" a NAND chip? Can my original NAND be = recovered? nandtest # echo "Hello World!=20 ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" > text.or= ig &&=20 nandwrite -y -p /dev/mtd/4 text.orig MTD_open MTD_ioctl MTD_ioctl WriMTD_ioctl tinand_isbad_bbt(): bbt info for offs 0x00000000: (block 0) 0x00 ng data to block 0 MTD_write nand_write_ecc: to =3D 0x00000000, len =3D 512 MTD_close nand_sync: called nandtest # nanddump usage: nanddump [start addr] [length] nandtest # nanddump /dev/mtd/4 text.out 0 512 MTD_open MTD_ioctl Would you like formatted output? n DumMTD_read pinand_read_ecc: from =3D 0x00000000, len =3D 512 ng data starting at 0x00000000 and ending atMTD_ioctl 0nand_read_oob: from =3D 0x00000000, len =3D 16 x00000200... Dumping 0 MTD_close nand_sync: called nandtest # cat out.txt cat: out.txt: No such file or directory nandtest # cat text.out Hello World! ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567= 89 =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BFaUW=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF nandtest # Aras From tglx@linutronix.de Fri Dec 3 20:24:49 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 03 Dec 2004 21:24:49 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41AFC80A.6020004@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> Message-ID: <1102105489.13353.249.camel@tglx.tec.linutronix.de> On Fri, 2004-12-03 at 12:57 +1100, Aras Vaichas wrote: > > Can you first verify that your driver works correctly without a > > filesystem ? Use nandwrite to write a file to the chip and nanddump t= o > > read it back. >=20 > hmm, it *sort* of works, but it looks like there is corruption. > nandtest # echo "Hello World!=20 > ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" > text.= orig &&=20 > > Hello World AC@A@@@@ > LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 > =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF > =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF > =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF > =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF=C3=BF= =C3=BF=C3=BFaA.=C3=BF=C3=BF=C3=BF=C3=BF=C3=BFaa.=C3=BF=C3=BF=C3=BF=C3=BF=C3= =BF > nandtest # Hmm, can you verify that the chip is erased correctly, when you do an flash_eraseall ? Dump it and check for nonzero pages.=20 tglx From tglx@linutronix.de Fri Dec 3 20:26:11 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 03 Dec 2004 21:26:11 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41AFD69E.4080906@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <41AFD69E.4080906@magellan-technology.com> Message-ID: <1102105571.13353.252.camel@tglx.tec.linutronix.de> On Fri, 2004-12-03 at 13:59 +1100, Aras Vaichas wrote: > Aras Vaichas wrote: > > hmm, it *sort* of works, but it looks like there is corruption. > > Aaah, but if I use a brand new NAND/Smartmedia, there is no corruption that I > can tell ... > > Surely it's not the easy to "break" a NAND chip? Can my original NAND be recovered? > It's quite easy, if the timing is wrong or if the rdy/busy check is not reliable. Can I have a look at your board driver ? tglx From arasv@magellan-technology.com Mon Dec 6 01:25:57 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Mon, 06 Dec 2004 12:25:57 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102105489.13353.249.camel@tglx.tec.linutronix.de> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> Message-ID: <41B3B525.30105@magellan-technology.com> This is a multi-part message in MIME format. --------------020601090004020608000204 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Thomas Gleixner wrote: > Hmm, can you verify that the chip is erased correctly, when you do an > flash_eraseall ? Dump it and check for nonzero pages. I used: # flash_eraseall /dev/mtd/4 # nanddump /dev/mtd/4 dump.out No, not all spages are erased after doing a flash_eraseall. i.e. they were not all 0xff. The very first 8MB Flash partition that I started using for development is missing about 60% of its space due to "bad eraseblocks". The second 8MB Flash partition is missing only 1%. Luckily I make my own Smartmedia cards, so I can simply solder in a new Flash chip for further development. From now on I think I will make my partitions much smaller so I don't "lose" as many. ;) y2 # df Filesystem 1k-blocks Used Available Use% Mounted on /dev/root 102901816 77308708 20365960 79% / tmpfs 15428 152 15276 1% /var /dev/mtdblock/4 16368 9904 6464 61% /mnt/y1 /dev/mtdblock/5 16368 176 16192 1% /mnt/y2 y2 # ll /mnt/y1 yaffs_readdir: starting at 0 yaffs_readdir: starting at 3 drw-rw-rw- 1 root root 512 Dec 6 11:12 ./ drwxrwxr-x 9 root 100 4096 Nov 11 10:17 ../ drw-rw-rw- 1 root root 512 Dec 6 11:12 lost+found/ y2 # ll /mnt/y2 yaffs_readdir: starting at 0 yaffs_readdir: starting at 3 drw-rw-rw- 1 root root 512 Dec 6 11:12 ./ drwxrwxr-x 9 root 100 4096 Nov 11 10:17 ../ drw-rw-rw- 1 root root 512 Dec 6 11:12 lost+found/ >>Surely it's not the easy to "break" a NAND chip? Can my original NAND be recovered? >> > It's quite easy, if the timing is wrong or if the rdy/busy check is not > reliable. Is there a utility that writes to every single page, reads back the data and then marks the pages correctly? Or are those "bad eraseblocks" permanently lost? > Can I have a look at your board driver ? Sure, see attached. I simply modified the existing at91_nand.c file to compile with the latest MTD drivers. see http://lists.infradead.org/pipermail/linux-mtd/2004-December/011039.html for details on the changes I made to at91_nand.c regards, Aras Vaichas --------------020601090004020608000204 Content-Type: text/plain; name="at91_nand.c" Content-Transfer-Encoding: base64 Content-Disposition: inline; filename="at91_nand.c" LyoKICogZHJpdmVycy9hdDkxL210ZC9hdDkxX25hbmQuYwogKgogKiAgQ29weXJpZ2h0IChj KSAyMDAzIFJpY2sgQnJvbnNvbgogKgogKiAgRGVyaXZlZCBmcm9tIGRyaXZlcnMvbXRkL25h bmQvYXV0Y3B1MTIuYwogKgkgQ29weXJpZ2h0IChjKSAyMDAxIFRob21hcyBHbGVpeG5lciAo Z2xlaXhuZXJAYXV0cm9uaXguZGUpCiAqCiAqICBEZXJpdmVkIGZyb20gZHJpdmVycy9tdGQv c3BpYS5jCiAqCSBDb3B5cmlnaHQgKEMpIDIwMDAgU3RldmVuIEouIEhpbGwgKHNqaGlsbEBj b3R3LmNvbSkKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4g cmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9m IHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICogcHVibGlz aGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqCiAqLwoKI2luY2x1ZGUg PGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGlu dXgvbXRkL210ZC5oPgojaW5jbHVkZSA8bGludXgvbXRkL25hbmQuaD4KI2luY2x1ZGUgPGxp bnV4L210ZC9wYXJ0aXRpb25zLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGFz bS9hcmNoL2hhcmR3YXJlLmg+CiNpbmNsdWRlIDxhc20vc2l6ZXMuaD4KI2luY2x1ZGUgPGxp bnV4L2luaXQuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL3Bpby5oPgojaW5jbHVkZSAiYXQ5MV9u YW5kLmgiCgovKgogKiBNVEQgc3RydWN0dXJlIGZvciBBVDkxIGJvYXJkCiAqLwpzdGF0aWMg c3RydWN0IG10ZF9pbmZvICphdDkxX210ZCA9IE5VTEw7CnN0YXRpYyBzdHJ1Y3QgbmFuZF9j aGlwICpteV9uYW5kX2NoaXAgPSBOVUxMOwoKc3RhdGljIGludCBhdDkxX2Zpb19iYXNlOwoK I2lmZGVmIENPTkZJR19NVERfUEFSVElUSU9OUwoKLyoKICogRGVmaW5lIHBhcnRpdGlvbnMg Zm9yIGZsYXNoIGRldmljZXMKICovCgpzdGF0aWMgc3RydWN0IG10ZF9wYXJ0aXRpb24gcGFy dGl0aW9uX2luZm8zMmtbXSA9IHsKCgoJeyBuYW1lOiAgIk5BTkQgcGFydGl0aW9uIDEiLAoJ ICBvZmZzZXQ6IDAsCgkgIHNpemU6ICAgMTYgKiBTWl8xTSB9LAoKCXsgbmFtZTogICJOQU5E IHBhcnRpdGlvbiAyIiwKCSAgb2Zmc2V0OiAxNiAqIFNaXzFNLAoJICBzaXplOgkgIDE2ICog U1pfMU0gfSwKCi8vCXsgbmFtZTogIkFUOTEgTkFORCBwYXJ0aXRpb24gMSwga2VybmVsIiwK Ly8JICBvZmZzZXQ6ICAwLAovLwkgIHNpemU6ICAgMSAqIFNaXzFNIH0sCi8vCXsgbmFtZTog IkFUOTEgTkFORCBwYXJ0aXRpb24gMiwgZmlsZXN5c3RlbSIsCi8vCSAgb2Zmc2V0OiAgMSAq IFNaXzFNLAovLwkgIHNpemU6ICAgMTYgKiBTWl8xTSB9LAovLwl7IG5hbWU6ICJBVDkxIE5B TkQgcGFydGl0aW9uIDNhLCBzdG9yYWdlIiwKLy8JICBvZmZzZXQ6ICgxICogU1pfMU0pICsg KDE2ICogU1pfMU0pLAovLwkgIHNpemU6ICAgMSAqIFNaXzFNIH0sCi8vCXsgbmFtZTogIkFU OTEgTkFORCBwYXJ0aXRpb24gM2IsIHN0b3JhZ2UiLAovLwkgIG9mZnNldDogKDIgKiBTWl8x TSkgKyAoMTYgKiBTWl8xTSksCi8vCSAgc2l6ZTogICAxICogU1pfMU0gfSwKLy8JeyBuYW1l OiAiQVQ5MSBOQU5EIHBhcnRpdGlvbiAzYywgc3RvcmFnZSIsCi8vCSAgb2Zmc2V0OiAoMyAq IFNaXzFNKSArICgxNiAqIFNaXzFNKSwKLy8JICBzaXplOiAgIDEgKiBTWl8xTSB9LAovLwl7 IG5hbWU6ICJBVDkxIE5BTkQgcGFydGl0aW9uIDNkLCBzdG9yYWdlIiwKLy8JICBvZmZzZXQ6 ICg0ICogU1pfMU0pICsgKDE2ICogU1pfMU0pLAovLwkgIHNpemU6ICAgMSAqIFNaXzFNIH0s Cn07CgpzdGF0aWMgc3RydWN0IG10ZF9wYXJ0aXRpb24gcGFydGl0aW9uX2luZm82NGtbXSA9 IHsKCXsgbmFtZTogIkFUOTEgTkFORCBwYXJ0aXRpb24gMSwga2VybmVsIiwKCSAgb2Zmc2V0 OiAgMCwKCSAgc2l6ZTogICAxICogU1pfMU0gfSwKCXsgbmFtZTogIkFUOTEgTkFORCBwYXJ0 aXRpb24gMiwgZmlsZXN5c3RlbSIsCgkgIG9mZnNldDogIDEgKiBTWl8xTSwKCSAgc2l6ZTog ICAxNiAqIFNaXzFNIH0sCgl7IG5hbWU6ICJBVDkxIE5BTkQgcGFydGl0aW9uIDMsIHN0b3Jh Z2UiLAoJICBvZmZzZXQ6ICgxICogU1pfMU0pICsgKDE2ICogU1pfMU0pLAoJICBzaXplOiAg IDQ3ICogU1pfMU0gfSwKfTsKCiNlbmRpZgoKLyoKICogSGFyZHdhcmUgc3BlY2lmaWMgYWNj ZXNzIHRvIGNvbnRyb2wtbGluZXMKICovCi8vIEFSQVNWCnN0YXRpYyB2b2lkIGF0OTFfaHdj b250cm9sKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQgY21kKQp7CglzdHJ1Y3QgbmFuZF9j aGlwICpteV9uYW5kID0gbXlfbmFuZF9jaGlwOwoJc3dpdGNoKGNtZCkKCXsKCWNhc2UgTkFO RF9DVExfU0VUQ0xFOgoJCW15X25hbmQtPklPX0FERFJfVyA9IGF0OTFfZmlvX2Jhc2UgKyBB VDkxX1NNQVJUX01FRElBX0NMRTsKCQlicmVhazsKCWNhc2UgTkFORF9DVExfQ0xSQ0xFOgoJ CW15X25hbmQtPklPX0FERFJfVyA9IGF0OTFfZmlvX2Jhc2U7CgkJYnJlYWs7CgljYXNlIE5B TkRfQ1RMX1NFVEFMRToKCQlteV9uYW5kLT5JT19BRERSX1cgPSBhdDkxX2Zpb19iYXNlICsg QVQ5MV9TTUFSVF9NRURJQV9BTEU7CgkJYnJlYWs7CgljYXNlIE5BTkRfQ1RMX0NMUkFMRToK CQlteV9uYW5kLT5JT19BRERSX1cgPSBhdDkxX2Zpb19iYXNlOwoJCWJyZWFrOwoJY2FzZSBO QU5EX0NUTF9TRVROQ0U6CgkJYnJlYWs7CgljYXNlIE5BTkRfQ1RMX0NMUk5DRToKCQlicmVh azsKCX0KfQoKLyoKICogU2VuZCBjb21tYW5kIHRvIE5BTkQgZGV2aWNlCiAqLwpzdGF0aWMg dm9pZCBhdDkxX25hbmRfY29tbWFuZCAoc3RydWN0IG10ZF9pbmZvICptdGQsIHVuc2lnbmVk IGNvbW1hbmQsIGludCBjb2x1bW4sIGludCBwYWdlX2FkZHIpCnsKCXJlZ2lzdGVyIHN0cnVj dCBuYW5kX2NoaXAgKm15X25hbmQgPSBtdGQtPnByaXY7CgoJLyogQmVnaW4gY29tbWFuZCBs YXRjaCBjeWNsZSAqLwoJcmVnaXN0ZXIgdW5zaWduZWQgbG9uZyBOQU5EX0lPX0FERFIgPSBt eV9uYW5kLT5JT19BRERSX1cgKyBBVDkxX1NNQVJUX01FRElBX0NMRTsKCgkvKgoJICogV3Jp dGUgb3V0IHRoZSBjb21tYW5kIHRvIHRoZSBkZXZpY2UuCgkgKi8KCWlmIChjb21tYW5kICE9 IE5BTkRfQ01EX1NFUUlOKQoJCXdyaXRlYiAoY29tbWFuZCwgTkFORF9JT19BRERSKTsKCWVs c2UgewoJCWlmIChtdGQtPm9vYmJsb2NrID09IDI1NiAmJiBjb2x1bW4gPj0gMjU2KSB7CgkJ CWNvbHVtbiAtPSAyNTY7CgkJCXdyaXRlYiAoTkFORF9DTURfUkVTRVQsIE5BTkRfSU9fQURE Uik7CgkJCXdyaXRlYiAoTkFORF9DTURfUkVBRE9PQiwgTkFORF9JT19BRERSKTsKCQkJd3Jp dGViIChOQU5EX0NNRF9TRVFJTiwgTkFORF9JT19BRERSKTsKCQl9CgkJZWxzZQoJCQlpZiAo bXRkLT5vb2JibG9jayA9PSA1MTIgJiYgY29sdW1uID49IDI1NikgewoJCQkJaWYgKGNvbHVt biA8IDUxMikgewoJCQkJCWNvbHVtbiAtPSAyNTY7CgkJCQkJd3JpdGViIChOQU5EX0NNRF9S RUFEMSwgTkFORF9JT19BRERSKTsKCQkJCQl3cml0ZWIgKE5BTkRfQ01EX1NFUUlOLCBOQU5E X0lPX0FERFIpOwoJCQkJfSBlbHNlIHsKCQkJCQljb2x1bW4gLT0gNTEyOwoJCQkJCXdyaXRl YiAoTkFORF9DTURfUkVBRE9PQiwgTkFORF9JT19BRERSKTsKCQkJCQl3cml0ZWIgKE5BTkRf Q01EX1NFUUlOLCBOQU5EX0lPX0FERFIpOwoJCQkJfQoJCQl9IGVsc2UgewoJCQkJd3JpdGVi IChOQU5EX0NNRF9SRUFEMCwgTkFORF9JT19BRERSKTsKCQkJCXdyaXRlYiAoTkFORF9DTURf U0VRSU4sIE5BTkRfSU9fQUREUik7CgkJCX0KCX0KCgkvKiBTZXQgQUxFIGFuZCBjbGVhciBD TEUgdG8gc3RhcnQgYWRkcmVzcyBjeWNsZSAqLwoJTkFORF9JT19BRERSID0gYXQ5MV9maW9f YmFzZTsKCglpZiAoY29sdW1uICE9IC0xIHx8IHBhZ2VfYWRkciAhPSAtMSkKCQlOQU5EX0lP X0FERFIgKz0gQVQ5MV9TTUFSVF9NRURJQV9BTEU7CgoJLyogU2VyaWFsbHkgaW5wdXQgYWRk cmVzcyAqLwoJaWYgKGNvbHVtbiAhPSAtMSkKCQl3cml0ZWIgKGNvbHVtbiwgTkFORF9JT19B RERSKTsKCWlmIChwYWdlX2FkZHIgIT0gLTEpIHsKCQl3cml0ZWIgKCh1bnNpZ25lZCBjaGFy KSAocGFnZV9hZGRyICYgMHhmZiksIE5BTkRfSU9fQUREUik7CgkJd3JpdGViICgodW5zaWdu ZWQgY2hhcikgKChwYWdlX2FkZHIgPj4gOCkgJiAweGZmKSwgTkFORF9JT19BRERSKTsKCQkv KiBPbmUgbW9yZSBhZGRyZXNzIGN5Y2xlIGZvciBoaWdoZXIgZGVuc2l0eSBkZXZpY2VzICov CgkJaWYgKG10ZC0+c2l6ZSAmIDB4MGMwMDAwMDApIHsKCQkJd3JpdGViICgodW5zaWduZWQg Y2hhcikgKChwYWdlX2FkZHIgPj4gMTYpICYgMHgwZiksIE5BTkRfSU9fQUREUik7CgkJfQoJ fQoKCS8qIHdhaXQgdW50aWwgY29tbWFuZCBpcyBwcm9jZXNzZWQgKi8KCXdoaWxlICghbXlf bmFuZC0+ZGV2X3JlYWR5KGF0OTFfbXRkKSkKCQk7Cn0KCi8qCiAqIFJlYWQgdGhlIERldmlj ZSBSZWFkeSBwaW4uCiAqLwpzdGF0aWMgaW50IGF0OTFfZGV2aWNlX3JlYWR5KHN0cnVjdCBt dGRfaW5mbyAqbXRkKQp7CglyZXR1cm4gQVQ5MV9QSU9fU21hcnRNZWRpYV9SRFkoKTsKfQov KgogKiBNYWluIGluaXRpYWxpemF0aW9uIHJvdXRpbmUKICovCgpzdGF0aWMgaW50IF9faW5p dCBhdDkxX2luaXQgKHZvaWQpCnsKCXN0cnVjdCBuYW5kX2NoaXAgKm15X25hbmQ7CglpbnQg ZXJyID0gMDsKCglwcmludGsoICJhdDkxX2luaXQgZW50ZXJyZWRcbiIgKTsKCS8qIEFsbG9j YXRlIG1lbW9yeSBmb3IgTVREIGRldmljZSBzdHJ1Y3R1cmUgYW5kIHByaXZhdGUgZGF0YSAq LwoJYXQ5MV9tdGQgPSBrbWFsbG9jIChzaXplb2Yoc3RydWN0IG10ZF9pbmZvKSArIHNpemVv ZiAoc3RydWN0IG5hbmRfY2hpcCksIEdGUF9LRVJORUwpOwoJaWYgKCFhdDkxX210ZCkgewoJ CXByaW50ayAoIlVuYWJsZSB0byBhbGxvY2F0ZSBBVDkxIE5BTkQgTVREIGRldmljZSBzdHJ1 Y3R1cmUuXG4iKTsKCQllcnIgPSAtRU5PTUVNOwoJCWdvdG8gb3V0OwoJfQoKCS8qIG1hcCBw aHlzaWNhbCBhZHJlc3MgKi8KCWF0OTFfZmlvX2Jhc2UgPSAodW5zaWduZWQgbG9uZykgaW9y ZW1hcChBVDkxX1NNQVJUTUVESUFfQkFTRSwgU1pfOE0pOwoJaWYoIWF0OTFfZmlvX2Jhc2Up IHsKCQlwcmludGsoImlvcmVtYXAgQVQ5MSBOQU5EIGZhaWxlZFxuIik7CgkJZXJyID0gLUVJ TzsKCQlnb3RvIG91dF9tdGQ7Cgl9CgoJLyogR2V0IHBvaW50ZXIgdG8gcHJpdmF0ZSBkYXRh ICovCglteV9uYW5kX2NoaXAgPSBteV9uYW5kID0gKHN0cnVjdCBuYW5kX2NoaXAgKikgKCZh dDkxX210ZFsxXSk7CgoJLyogSW5pdGlhbGl6ZSBzdHJ1Y3R1cmVzICovCgltZW1zZXQoKGNo YXIgKikgYXQ5MV9tdGQsIDAsIHNpemVvZihzdHJ1Y3QgbXRkX2luZm8pKTsKCW1lbXNldCgo Y2hhciAqKSBteV9uYW5kLCAwLCBzaXplb2Yoc3RydWN0IG5hbmRfY2hpcCkpOwoKCS8qIExp bmsgdGhlIHByaXZhdGUgZGF0YSB3aXRoIHRoZSBNVEQgc3RydWN0dXJlICovCglhdDkxX210 ZC0+cHJpdiA9IG15X25hbmQ7CgoJLyogU2V0IGFkZHJlc3Mgb2YgTkFORCBJTyBsaW5lcyAq LwoJbXlfbmFuZC0+SU9fQUREUl9SID0gYXQ5MV9maW9fYmFzZTsKCW15X25hbmQtPklPX0FE RFJfVyA9IGF0OTFfZmlvX2Jhc2U7CglteV9uYW5kLT5od2NvbnRyb2wgPSBhdDkxX2h3Y29u dHJvbDsKCW15X25hbmQtPmRldl9yZWFkeSA9IGF0OTFfZGV2aWNlX3JlYWR5OwoJbXlfbmFu ZC0+Y21kZnVuYyA9IGF0OTFfbmFuZF9jb21tYW5kOwkvKiB3ZSBuZWVkIG91ciBvd24gKi8K CW15X25hbmQtPmVjY21vZGUgPSBOQU5EX0VDQ19TT0ZUOwkvKiBlbmFibGUgRUNDICovCgkv KiAyMCB1cyBjb21tYW5kIGRlbGF5IHRpbWUgKi8KCW15X25hbmQtPmNoaXBfZGVsYXkgPSAy MDsKCgkvKiBTZXR1cCBTbWFydCBNZWRpYSwgZmlyc3QgZW5hYmxlIHRoZSBhZGRyZXNzIHJh bmdlIG9mIENTMyAqLwoJQVQ5MV9TWVMtPkVCSV9DU0EgfD0gQVQ5MUNfRUJJX0NTM0FfU01D X1NtYXJ0TWVkaWE7CgkvKiBzZXQgdGhlIGJ1cyBpbnRlcmZhY2UgY2hhcmFjdGVyaXN0aWNz IGJhc2VkIG9uCgkgICB0RFMgRGF0YSBTZXQgdXAgVGltZSAzMCAtIG5zCgkgICB0REggRGF0 YSBIb2xkIFRpbWUgMjAgLSBucwoJICAgdEFMUyBBTEUgU2V0IHVwIFRpbWUgMjAgLSBucwoJ ICAgMTZucyBhdCA2MCBNSHogfj0gMyAgKi8KI2RlZmluZSBBVDkxQ19TTV9JRF9SV0gJKDUg PDwgMjgpCQkvKiBvcmlnID0gNSAqLwojZGVmaW5lIEFUOTFDX1NNX1JXSAkoMSA8PCAyOCkJ CS8qIG9yaWcgPSAxICovCiNkZWZpbmUgQVQ5MUNfU01fUldTCSgwIDw8IDI0KQkJLyogb3Jp ZyA9IDAgKi8KI2RlZmluZSBBVDkxQ19TTV9UREYJKDEgPDwgOCkJCS8qIG9yaWcgPSAxICov CiNkZWZpbmUgQVQ5MUNfU01fTldTCSg1KQkJCS8qIG9yaWcgPSAzICovCglBVDkxX1NZUy0+ RUJJX1NNQzJfQ1NSWzNdID0gKCBBVDkxQ19TTV9SV0ggfCBBVDkxQ19TTV9SV1MgfAoJCQkJ CSBBVDkxQ19TTUMyX0FDU1NfU1RBTkRBUkQgfAoJCQkJCSBBVDkxQ19TTUMyX0RCV184IHwg QVQ5MUNfU01fVERGIHwKCQkJCQkgQVQ5MUNfU01DMl9XU0VOIHwgQVQ5MUNfU01fTldTKTsK CglBVDkxX0NmZ1BJT19TbWFydE1lZGlhKCk7CgoJaWYgKEFUOTFfUElPX1NtYXJ0TWVkaWFf Q2FyZERldGVjdCgpKQoJCXByaW50ayAoIk5vICIpOwoJcHJpbnRrICgiU21hcnRNZWRpYSBj YXJkIGluc2VydGVkLlxuIik7CgoJLyogU2NhbiB0byBmaW5kIGV4aXN0YW5jZSBvZiB0aGUg ZGV2aWNlICovCi8vIEFSQVNWCiNkZWZpbmUgQ0hJUFNfVE9fU0NBTgkxCglpZiAobmFuZF9z Y2FuIChhdDkxX210ZCwgQ0hJUFNfVE9fU0NBTikpIHsKCQllcnIgPSAtRU5YSU87CgkJZ290 byBvdXRfaW9yOwoJfQoKCS8qIEFsbG9jYXRlIG1lbW9yeSBmb3IgaW50ZXJuYWwgZGF0YSBi dWZmZXIgKi8KCW15X25hbmQtPmRhdGFfYnVmID0ga21hbGxvYyAoc2l6ZW9mKHVfY2hhcikg KiAoYXQ5MV9tdGQtPm9vYmJsb2NrICsgYXQ5MV9tdGQtPm9vYnNpemUpLCBHRlBfS0VSTkVM KTsKCWlmICghbXlfbmFuZC0+ZGF0YV9idWYpIHsKCQlwcmludGsgKCJVbmFibGUgdG8gYWxs b2NhdGUgQVQ5MSBOQU5EIGRhdGEgYnVmZmVyLlxuIik7CgkJZXJyID0gLUVOT01FTTsKCQln b3RvIG91dF9pb3I7Cgl9CgoJLyogQWxsb2NhdGUgbWVtb3J5IGZvciBpbnRlcm5hbCBkYXRh IGJ1ZmZlciAqLwovLyBBUkFTVgovLwlteV9uYW5kLT5kYXRhX2NhY2hlID0ga21hbGxvYyAo c2l6ZW9mKHVfY2hhcikgKiAoYXQ5MV9tdGQtPm9vYmJsb2NrICsgYXQ5MV9tdGQtPm9vYnNp emUpLCBHRlBfS0VSTkVMKTsKLy8JaWYgKCFteV9uYW5kLT5kYXRhX2NhY2hlKSB7Ci8vCQlw cmludGsgKCJVbmFibGUgdG8gYWxsb2NhdGUgQVQ5MSBOQU5EIGRhdGEgY2FjaGUuXG4iKTsK Ly8JCWVyciA9IC1FTk9NRU07Ci8vCQlnb3RvIG91dF9idWY7Ci8vCX0KLy8JbXlfbmFuZC0+ Y2FjaGVfcGFnZSA9IC0xOwoKI2lmZGVmIENPTkZJR19NVERfUEFSVElUSU9OUwoJLyogUmVn aXN0ZXIgdGhlIHBhcnRpdGlvbnMgKi8KCXN3aXRjaChhdDkxX210ZC0+c2l6ZSkKCXsKCWNh c2UgU1pfMzJNOgoJCWVyciA9IGFkZF9tdGRfcGFydGl0aW9ucyhhdDkxX210ZCwgcGFydGl0 aW9uX2luZm8zMmssCgkJCQlBUlJBWV9TSVpFIChwYXJ0aXRpb25faW5mbzMyaykpOwoJCWJy ZWFrOwoJY2FzZSBTWl82NE06CgkJZXJyID0gYWRkX210ZF9wYXJ0aXRpb25zKGF0OTFfbXRk LCBwYXJ0aXRpb25faW5mbzY0aywKCQkJCUFSUkFZX1NJWkUgKHBhcnRpdGlvbl9pbmZvNjRr KSk7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXByaW50ayAoIlVuc3VwcG9ydGVkIFNtYXJ0TWVk aWEgZGV2aWNlXG4iKTsKCQllcnIgPSAtRU5YSU87CgkJZ290byBvdXRfY2FjOwoJfQojZWxz ZQoJZXJyID0gYWRkX210ZF9kZXZpY2UoYXQ5MV9tdGQpOwojZW5kaWYKCWdvdG8gb3V0OwoK IG91dF9jYWM6Ci8vIEFSQVNWCi8vCWtmcmVlIChteV9uYW5kLT5kYXRhX2NhY2hlKTsKIG91 dF9idWY6CglrZnJlZSAobXlfbmFuZC0+ZGF0YV9idWYpOwogb3V0X2lvcjoKCWlvdW5tYXAo KHZvaWQgKilhdDkxX2Zpb19iYXNlKTsKIG91dF9tdGQ6CglrZnJlZSAoYXQ5MV9tdGQpOwog b3V0OgoJcmV0dXJuIGVycjsKfQoKLyoKICogQ2xlYW4gdXAgcm91dGluZQogKi8Kc3RhdGlj IHZvaWQgX19leGl0IGF0OTFfY2xlYW51cCAodm9pZCkKewoJc3RydWN0IG5hbmRfY2hpcCAq bXlfbmFuZCA9IChzdHJ1Y3QgbmFuZF9jaGlwICopICZhdDkxX210ZFsxXTsKCgkvKiBVbnJl Z2lzdGVyIHBhcnRpdGlvbnMgKi8KCWRlbF9tdGRfcGFydGl0aW9ucyhhdDkxX210ZCk7CgoJ LyogVW5yZWdpc3RlciB0aGUgZGV2aWNlICovCglkZWxfbXRkX2RldmljZSAoYXQ5MV9tdGQp OwoKCS8qIEZyZWUgaW50ZXJuYWwgZGF0YSBidWZmZXJzICovCglrZnJlZSAobXlfbmFuZC0+ ZGF0YV9idWYpOwovLyBBUkFTVgovLwlrZnJlZSAobXlfbmFuZC0+ZGF0YV9jYWNoZSk7CgoJ LyogdW5tYXAgcGh5c2ljYWwgYWRyZXNzICovCglpb3VubWFwKCh2b2lkICopYXQ5MV9maW9f YmFzZSk7CgoJLyogRnJlZSB0aGUgTVREIGRldmljZSBzdHJ1Y3R1cmUgKi8KCWtmcmVlIChh dDkxX210ZCk7Cn0KCm1vZHVsZV9pbml0KGF0OTFfaW5pdCk7Cm1vZHVsZV9leGl0KGF0OTFf Y2xlYW51cCk7CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BVVRIT1IoIlJpY2sg QnJvbnNvbiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkdsdWUgbGF5ZXIgZm9yIFNtYXJ0TWVk aWFDYXJkIG9uIEFUTUVMIEFUOTFSTTkyMDAiKTsK --------------020601090004020608000204-- From tglx@linutronix.de Mon Dec 6 14:17:52 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Mon, 06 Dec 2004 15:17:52 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B3B525.30105@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> <41B3B525.30105@magellan-technology.com> Message-ID: <1102342672.2983.8.camel@lap02.tec.linutronix.de> On Mon, 2004-12-06 at 02:25, Aras Vaichas wrote: > > It's quite easy, if the timing is wrong or if the rdy/busy check is not > > reliable. > > Is there a utility that writes to every single page, reads back the data and > then marks the pages correctly? No. > Or are those "bad eraseblocks" permanently lost? You can hack nand_base.c to allow the erasing of the blocks which are marked bad. > static void at91_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) my_nand->cmdfunc = at91_nand_command; /* we need our own */ You don't need your own command function. There is no reason for it. It is just duplicated code. > /* Scan to find existance of the device */ > // ARASV > #define CHIPS_TO_SCAN 1 > if (nand_scan (at91_mtd, CHIPS_TO_SCAN)) { > err = -ENXIO; > goto out_ior; > } > > /* Allocate memory for internal data buffer */ > my_nand->data_buf = kmalloc (sizeof(u_char) * (at91_mtd->oobblock + at91_mtd->oobsize), GFP_KERNEL); > if (!my_nand->data_buf) { > printk ("Unable to allocate AT91 NAND data buffer.\n"); > err = -ENOMEM; > goto out_ior; > } The data buffer is already allocated inside nand_scan. tglx From tglx@linutronix.de Mon Dec 6 20:33:09 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Mon, 06 Dec 2004 21:33:09 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102342672.2983.8.camel@lap02.tec.linutronix.de> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> <41B3B525.30105@magellan-technology.com> <1102342672.2983.8.camel@lap02.tec.linutronix.de> Message-ID: <1102365189.13353.411.camel@tglx.tec.linutronix.de> On Mon, 2004-12-06 at 15:17 +0100, Thomas Gleixner wrote: > > static void at91_nand_command (struct mtd_info *mtd, unsigned command, int column, int page_addr) > > my_nand->cmdfunc = at91_nand_command; /* we need our own */ > > You don't need your own command function. There is no reason for it. It > is just duplicated code. It's not only duplicated code, it's also complete broken code. I bet, that's the reason for your problem. tglx From arasv@magellan-technology.com Mon Dec 6 22:25:46 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Tue, 07 Dec 2004 09:25:46 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102342672.2983.8.camel@lap02.tec.linutronix.de> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> <41B3B525.30105@magellan-technology.com> <1102342672.2983.8.camel@lap02.tec.linutronix.de> Message-ID: <41B4DC6A.7000905@magellan-technology.com> Thomas Gleixner wrote: > On Mon, 2004-12-06 at 02:25, Aras Vaichas wrote: >>Is there a utility that writes to every single page, reads back the data and >>then marks the pages correctly? > No. >>Or are those "bad eraseblocks" permanently lost? > You can hack nand_base.c to allow the erasing of the blocks which are > marked bad. Yes, I eventually realised that nand_base.c was stopping me from erasing the badly marked blocks which means that there is no way to force the chip to erase those blocks. I guess that this is a policy issue considering that it would be unusual to create so many bad blocks except during development (like happened to me). What I am hoping now is that the write-verify code in YAFFS will rediscover which blocks are actually bad and mark them as such. e.g. in the YAFFS makefile, I keep this commented out #IGNORE_WRITE_VERIFY = -DCONFIG_YAFFS_DISBLE_WRITE_VERIFY Aras From arasv@magellan-technology.com Tue Dec 7 01:54:55 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Tue, 07 Dec 2004 12:54:55 +1100 Subject: [Yaffs] YAFFS compilation warnings Message-ID: <41B50D6F.10604@magellan-technology.com> I'm in the middle of tracking down a bizarre single bit flipping error that seems to be related to the name of the file that I am trying to create and I'd like to make sure that my YAFFS is compiling correctly. I get these warnings when I compile my kernel, can someone verify that these are OK? I'm using latest MTD, latest YAFFS and 2.4.27-vrs1. make[3]: Entering directory `/samba/development/40_Magellan_Standard_Software/MAL/kernel/linux-2.4.27-vrs1-yaffs/fs/yaffs' /usr/local/arm/2.95.3/bin/arm-linux-gcc -D__KERNEL__ -I/samba/development/40_Magellan_Standard_Software/MAL/kernel/linux-2.4.27-vrs1-yaffs/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -Uarm -fno-common -pipe -mapcs-32 -D__LINUX_ARM_ARCH__=4 -march=armv4 -mtune=arm9tdmi -mshort-load-bytes -msoft-float -Uarm -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -nostdinc -iwithprefix include -DKBUILD_BASENAME=yaffs_guts -c -o yaffs_guts.o yaffs_guts.c yaffs_guts.c: In function `yaffs_SoftDeleteWorker': yaffs_guts.c:1141: warning: unused variable `chunkDeleted' yaffs_guts.c:1140: warning: unused variable `found' yaffs_guts.c:1139: warning: unused variable `tags' yaffs_guts.c:1136: warning: unused variable `chunkInInode' yaffs_guts.c: In function `yaffs_FlushFilesChunkCache': yaffs_guts.c:3157: warning: unused variable `nBytes' yaffs_guts.c:3153: warning: `lowest' might be used uninitialized in this function yaffs_guts.c:3156: warning: `chunkWritten' might be used uninitialized in this function yaffs_guts.c: At top level: yaffs_guts.c:1933: warning: `yaffs_CheckObjectHashSanity' defined but not used yaffs_guts.c:454: warning: `yaffs_RewriteBufferedBlock' defined but not used yaffs_guts.c:483: warning: `yaffs_CheckWrittenBlock' defined but not used yaffs_guts.c:2380: warning: `yaffs_DoUnlinkedFileDeletion' defined but not used rm -f yaffs.o Thanks, Aras From tglx@linutronix.de Tue Dec 7 08:53:30 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Tue, 07 Dec 2004 09:53:30 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B4DC6A.7000905@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> <41B3B525.30105@magellan-technology.com> <1102342672.2983.8.camel@lap02.tec.linutronix.de> <41B4DC6A.7000905@magellan-technology.com> Message-ID: <1102409610.13353.413.camel@tglx.tec.linutronix.de> On Tue, 2004-12-07 at 09:25 +1100, Aras Vaichas wrote: > Thomas Gleixner wrote: > > On Mon, 2004-12-06 at 02:25, Aras Vaichas wrote: > >>Is there a utility that writes to every single page, reads back the data and > >>then marks the pages correctly? > > No. > >>Or are those "bad eraseblocks" permanently lost? > > You can hack nand_base.c to allow the erasing of the blocks which are > > marked bad. > > Yes, I eventually realised that nand_base.c was stopping me from erasing the > badly marked blocks which means that there is no way to force the chip to erase > those blocks. I guess that this is a policy issue considering that it would be > unusual to create so many bad blocks except during development (like happened > to me). > > What I am hoping now is that the write-verify code in YAFFS will rediscover > which blocks are actually bad and mark them as such. > > e.g. in the YAFFS makefile, I keep this commented out > #IGNORE_WRITE_VERIFY = -DCONFIG_YAFFS_DISBLE_WRITE_VERIFY Get rid of the command function in your driver first. tglx From thom@ipi.ac.ru Mon Dec 6 13:19:44 2004 From: thom@ipi.ac.ru (Timofei V. Bondarenko) Date: Mon, 06 Dec 2004 16:19:44 +0300 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B3B525.30105@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <1101971952.13353.68.camel@tglx.tec.linutronix.de> <41AFC80A.6020004@magellan-technology.com> <1102105489.13353.249.camel@tglx.tec.linutronix.de> <41B3B525.30105@magellan-technology.com> Message-ID: <41B45C70.9060708@ipi.ac.ru> Hi. Aras Vaichas wrote: > Thomas Gleixner wrote: >>>Surely it's not the easy to "break" a NAND chip? Can my original NAND be recovered? >>> >> It's quite easy, if the timing is wrong or if the rdy/busy check is not >> reliable. > > Is there a utility that writes to every single page, reads back the data and then marks the pages correctly? Or are those "bad eraseblocks" permanently lost? > AFAIK, the eraseall can't erase blocks already marked bad. To do it i'm just comment out a 'goto' near "attempt to erase bad block" warning in drivers/mtd/nand/nand_base.c Not the best way, though there were no appropriate ioctl to do it else. You'll have to reboot after eraseall, since bad block list still reside in memory. Regards. Timofei. From Charles.Manning@trimble.co.nz Tue Dec 7 19:48:00 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Wed, 8 Dec 2004 08:48:00 +1300 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E01549070@nzc-ap-xch-01.ap.trimblecorp.net> Eraseall will not try to erase blocks marked bad. Anyway, the mtd will also not allow this. If I understand the thread properly, you want to erase blocks that were marked bad by YAFFS but were not marked bad by manufacturing. Attempting to erase a factory marked bad block **might** destroy the flash and make is unusable. To do this, I suggest doing the following: * Modify eraseall to skip the check, as Thomas suggests. Instead of checking for bad blocks, check for some other pattern to distinguish between YAFFS-marked and factory-marked bad blocks. The actual patterns used by factories depends on the make, part number etc but most often the whole OOB area of a bad block will be zero. A YAFFS-marked bad block will be zero only in the bad-block byte and only then in the first two pages.=20 * You will also need to bypass the check in mtd. -- Charles -----Original Message----- From: yaffs-admin@stoneboat.aleph1.co.uk [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Timofei V. Bondarenko Sent: Tuesday, 7 December 2004 2:20 a.m. To: Aras Vaichas Cc: yaffs@stoneboat.aleph1.co.uk Subject: Re: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems Hi. Aras Vaichas wrote: > Thomas Gleixner wrote: >>>Surely it's not the easy to "break" a NAND chip? Can my original NAND >>>be recovered? >>> >> It's quite easy, if the timing is wrong or if the rdy/busy check is=20 >> not reliable. >=20 > Is there a utility that writes to every single page, reads back the=20 > data and then marks the pages correctly? Or are those "bad=20 > eraseblocks" permanently lost? >=20 AFAIK, the eraseall can't erase blocks already marked bad. To do it i'm just comment out a 'goto' near "attempt to erase bad block" warning in drivers/mtd/nand/nand_base.c Not the best way, though there were no appropriate ioctl to do it else. You'll have to reboot after eraseall, since bad block list still reside=20 in memory. Regards. Timofei. _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From arasv@magellan-technology.com Thu Dec 9 06:55:03 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Thu, 09 Dec 2004 17:55:03 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41AEA5F7.6060307@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> Message-ID: <41B7F6C7.904@magellan-technology.com> Aras Vaichas wrote: > Hello all, > > I have managed to get the latest MTD code to compile with a 2.4.27-vrs1 > kernel. I compiled the latest YAFFS code (from CVS) into the kernel. I > mounted a 16MB block of Smartmedia NAND and tried to create some files, > I got a load of errors , I reset the machine because it was obviously > going crazy. I then noticed that my NAND suddenly had a load of "bad > blocks" It's been a long journey, but I'm almost there. I've finally nailed down a solution to what was causing the occasional bit flip and thus all the lost/bad-pages on my NAND. If I comment out "#USE_NANDECC = -DCONFIG_YAFFS_USE_NANDECC" in my YAFFS Makefile, then my files are read back correctly. The only thing that happens now is that I get that "Reading data from NAND FLASH without ECC is not recommended" warning message BUT my system appears to be working. I am guessing that the ECC stuff is being handled twice or it is being mishandled somewhere when I define CONFIG_YAFFS_USE_NANDECC. Comments? I am now able to copy, say, a 15MB file from NAND without any problems, and without losing massive numbers of blocks due to incorrectly labelled bad blocks. Thank you very much to those that helped me get this far, especially Thomas and Charles. regards, Aras Vaichas ------- test details ------ I designed a test to see if multiple readings of the same file from NAND would produce bit errors in different locations in the copied file. This was found to be true, and therefore something was wrong with the reading and processing of the data from the Flash. For example with CONFIG_YAFFS_USE_NANDECC defined I run the same test twice and get two different results: /root # ll /mnt/y1 drw-rw-rw- 1 root root 512 Dec 9 14:57 ./ drwxrwxr-x 15 563 100 4096 Dec 6 11:51 ../ drw-rw-rw- 1 root root 512 Dec 9 14:57 lost+found/ -rw-rw-r-- 1 root root 15728640 Dec 9 12:00 random.copy.bin /root # ./readbacktest.sh /mnt/y1 copying random.copy.bin from FLASH to local ... converting with hexdump ... comparing copy to original ... 19096301 65 61 ... 11 errors in total ... 44852526 146 142 /root # ./readbacktest.sh /mnt/y1 copying random.copy.bin from FLASH to local ... converting with hexdump ... comparing copy to original ... 13223325 142 63 ... 14 errors in total ... 41558756 64 66 The first column is the offset of the difference between original and copy, the second and third columns are the octal value (I'm using cmp in Busybox). This test shows that about 1 bit in 10 million is corrupt after a read, and you can see that the location of the bit flip is not the same between reads, therefore something caused by the hardware is creating this problem and it isn't being fixed correctly in software. If I don't include CONFIG_YAFFS_USE_NANDECC you will see that I don't get any errors (after reading back a 15MB file) but I do get warnings from nand_base.c /root # ./readbacktest.sh /mnt/y2 copying random.copy.bin from FLASH to local ... Reading data from NAND FLASH without ECC is not recommended ... SNIP ... Reading data from NAND FLASH without ECC is not recommended converting with hexdump ... comparing copy to original ... no differences found /root # From tglx@linutronix.de Thu Dec 9 10:12:11 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Thu, 09 Dec 2004 11:12:11 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B7F6C7.904@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <41B7F6C7.904@magellan-technology.com> Message-ID: <1102587131.3306.32.camel@tglx.tec.linutronix.de> On Thu, 2004-12-09 at 17:55 +1100, Aras Vaichas wrote: > I've finally nailed down a solution to what was causing the occasional bit flip > and thus all the lost/bad-pages on my NAND. > > If I comment out "#USE_NANDECC = -DCONFIG_YAFFS_USE_NANDECC" in my YAFFS > Makefile, then my files are read back correctly. The only thing that happens > now is that I get that "Reading data from NAND FLASH without ECC is not > recommended" warning message BUT my system appears to be working. > > I am guessing that the ECC stuff is being handled twice or it is being > mishandled somewhere when I define CONFIG_YAFFS_USE_NANDECC. Comments? Yes. :) 1. Are you using the generic command function now ? 2. In yaffs_mtdif.c struct nand_oobinfo yaffs_oobinfo = { useecc: 1, #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) // this is for versions of mtd nand driver in kernel 2.6.8 and later eccbytes: 6, #endif eccpos: {8, 9, 10, 13, 14, 15} }; The eccbytes setup is neccecary for current MTD CVS. Did you modify the #if (LINUX_ ....) ? tglx From nick@cecomputing.co.uk Thu Dec 9 21:10:02 2004 From: nick@cecomputing.co.uk (Nick Bane) Date: Thu, 9 Dec 2004 21:10:02 -0000 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B7F6C7.904@magellan-technology.com> Message-ID: > It's been a long journey, but I'm almost there. >=20 Well struggled. It is often worth the eductaional side effects. > If I comment out "#USE_NANDECC =3D -DCONFIG_YAFFS_USE_NANDECC" in my = YAFFS=20 > Makefile, then my files are read back correctly. The only thing=20 > that happens=20 > now is that I get that "Reading data from NAND FLASH without ECC is = not=20 > recommended" warning message BUT my system appears to be working. >=20 > I am guessing that the ECC stuff is being handled twice or it is being = > mishandled somewhere when I define CONFIG_YAFFS_USE_NANDECC. Comments? >=20 That is precisely what I do and I comment out the MTD whinge. It is = clearly important that SOMEONE does the ECC and it is a mild pity that = the MTD layer assumes that only it is competant to do so. It is probably that yaffs should get the MTD layer to do its ecc = eventually as standard. Nick From wookey@aleph1.co.uk Thu Dec 9 22:24:26 2004 From: wookey@aleph1.co.uk (Wookey) Date: Thu, 9 Dec 2004 22:24:26 +0000 Subject: [Yaffs] Re: cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: References: <41B7F6C7.904@magellan-technology.com> Message-ID: <20041209222426.GO7282@xios> +++ Nick Bane [04-12-09 21:10 -0000]: > > I am guessing that the ECC stuff is being handled twice or it is being > > mishandled somewhere when I define CONFIG_YAFFS_USE_NANDECC. Comments? > > > That is precisely what I do and I comment out the MTD whinge. It is > clearly important that SOMEONE does the ECC and it is a mild pity that the > MTD layer assumes that only it is competant to do so. > > It is probably that yaffs should get the MTD layer to do its ecc > eventually as standard. That's OK for use with linux and the MTD, but yaffs needs to be able to run standalone so it needs to retain the ability to do it's own ECC. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From tglx@linutronix.de Thu Dec 9 23:01:19 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 10 Dec 2004 00:01:19 +0100 Subject: [Yaffs] Re: cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <20041209222426.GO7282@xios> References: <41B7F6C7.904@magellan-technology.com> <20041209222426.GO7282@xios> Message-ID: <1102633279.3306.54.camel@tglx.tec.linutronix.de> On Thu, 2004-12-09 at 22:24 +0000, Wookey wrote: > +++ Nick Bane [04-12-09 21:10 -0000]: > > > I am guessing that the ECC stuff is being handled twice or it is being > > > mishandled somewhere when I define CONFIG_YAFFS_USE_NANDECC. Comments? > > > > > > That is precisely what I do and I comment out the MTD whinge. It is > > clearly important that SOMEONE does the ECC and it is a mild pity that the > > MTD layer assumes that only it is competant to do so. > > > > > It is probably that yaffs should get the MTD layer to do its ecc > > eventually as standard. > > That's OK for use with linux and the MTD, but yaffs needs to be able to run > standalone so it needs to retain the ability to do it's own ECC. I can't see, how YAFFS can deal with HW ECC. For standalone you need an hardware interface layer, which should either utilize YAFFS builtin ECC or do its own thing. tglx From tglx@linutronix.de Thu Dec 9 22:55:27 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Thu, 09 Dec 2004 23:55:27 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: References: Message-ID: <1102632927.3306.51.camel@tglx.tec.linutronix.de> On Thu, 2004-12-09 at 21:10 +0000, Nick Bane wrote: > That is precisely what I do and I comment out the MTD whinge. > It is clearly important that SOMEONE does the ECC and it is a > mild pity that the MTD layer assumes that only it is competant to do so. It's not a pity. It's correct. If you do software ECC, fine. If you have hardware ECC then it _CAN_ only be done in the MTD layer. The filesystem layer does not know anything about the available hardware. So it makes totaly sense that ECC is done in the MTD/NAND layer and nowhere else. A filesystem is a filesystem and is not competent to fiddle around with hardware. I know that there are OS targets for YAFFS where YAFFS has to do everything, but MTD does it the right way. > It is probably that yaffs should get the MTD layer to do its ecc > eventually as standard. Can you please explain this statement to somebody who's native language is German ? What do you mean ? Fix YAFFS or hack MTD ? tglx From manningc2@actrix.gen.nz Fri Dec 10 00:32:53 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 10 Dec 2004 13:32:53 +1300 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102632927.3306.51.camel@tglx.tec.linutronix.de> References: <1102632927.3306.51.camel@tglx.tec.linutronix.de> Message-ID: <20041210002743.118D5161EA@desire.actrix.co.nz> On Friday 10 December 2004 11:55, Thomas Gleixner wrote: > On Thu, 2004-12-09 at 21:10 +0000, Nick Bane wrote: > > That is precisely what I do and I comment out the MTD whinge. > > It is clearly important that SOMEONE does the ECC and it is a > > mild pity that the MTD layer assumes that only it is competant to do = so. > > It's not a pity. It's correct. If you do software ECC, fine. If you hav= e > hardware ECC then it _CAN_ only be done in the MTD layer. The filesyste= m > layer does not know anything about the available hardware. So it makes > totaly sense that ECC is done in the MTD/NAND layer and nowhere else. > > A filesystem is a filesystem and is not competent to fiddle around with > hardware. I know that there are OS targets for YAFFS where YAFFS has to > do everything, but MTD does it the right way. I might argue the latter point here. I believe the ECC byte ordering=20 calculated by SJHill's nand_ecc.c is wrong. yaffs_ecc.c can calculate t= his=20 ECC order or the SmartMedia "correct" order. yaffs_ecc.c is also slightl= y=20 faster than nand_ecc.c ;-). I don't think I have a gripe with the ECC stuff, it's the write verificat= ion=20 that gets me. > > > It is probably that yaffs should get the MTD layer to do its ecc > > eventually as standard. > > Can you please explain this statement to somebody who's native language > is German ? > > What do you mean ? > Fix YAFFS or hack MTD ? >From my understanding this is only a configuration issue. YAFFS can be build with CONFIG_YAFFS_USE_NAND_ECC which means yaffs won't= do=20 ECC - it lets mtd do all ECC. This is, IMHO, the best way to do things wi= th=20 Linux - particularly if there are other non-yaffs users of the NAND. With non-Linux usage, I recommend using yaffs_ecc.c if software ECC is=20 required. Where things do break down a bit is with mkyaffs which does calculate ECC= .=20 You need to be careful to use a consistent ECC strategy. From arasv@magellan-technology.com Fri Dec 10 05:40:07 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Fri, 10 Dec 2004 16:40:07 +1100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102587131.3306.32.camel@tglx.tec.linutronix.de> References: <41AEA5F7.6060307@magellan-technology.com> <41B7F6C7.904@magellan-technology.com> <1102587131.3306.32.camel@tglx.tec.linutronix.de> Message-ID: <41B936B7.9020902@magellan-technology.com> Thomas Gleixner wrote: > On Thu, 2004-12-09 at 17:55 +1100, Aras Vaichas wrote: > >>I've finally nailed down a solution to what was causing the occasional bit flip >>and thus all the lost/bad-pages on my NAND. >> > 1. Are you using the generic command function now ? Oh yeah, thanks for the previous help. I made all the changes that you recommended. > 2. In yaffs_mtdif.c > > struct nand_oobinfo yaffs_oobinfo = { > useecc: 1, > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) > // this is for versions of mtd nand driver in kernel 2.6.8 and later > eccbytes: 6, > #endif > eccpos: {8, 9, 10, 13, 14, 15} > }; > > The eccbytes setup is neccecary for current MTD CVS. Did you modify the > #if (LINUX_ ....) ? Hmm, I didn't know about this one. I defined eccbytes and it works now with CONFIG_YAFFS_USE_NANDECC defined. I tested it by transferring 60MB without a single failure so I think I can trust it. ;) Have a good weekend, Aras Vaichas From tglx@linutronix.de Fri Dec 10 08:23:32 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 10 Dec 2004 09:23:32 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <41B936B7.9020902@magellan-technology.com> References: <41AEA5F7.6060307@magellan-technology.com> <41B7F6C7.904@magellan-technology.com> <1102587131.3306.32.camel@tglx.tec.linutronix.de> <41B936B7.9020902@magellan-technology.com> Message-ID: <1102667012.3306.57.camel@tglx.tec.linutronix.de> On Fri, 2004-12-10 at 16:40 +1100, Aras Vaichas wrote: > Thomas Gleixner wrote: > > On Thu, 2004-12-09 at 17:55 +1100, Aras Vaichas wrote: > > > >>I've finally nailed down a solution to what was causing the occasional bit flip > >>and thus all the lost/bad-pages on my NAND. > >> > > 1. Are you using the generic command function now ? > > Oh yeah, thanks for the previous help. I made all the changes that you recommended. Care to push the driver into MTD CVS ? > > 2. In yaffs_mtdif.c > > > > struct nand_oobinfo yaffs_oobinfo = { > > useecc: 1, > > #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) > > // this is for versions of mtd nand driver in kernel 2.6.8 and later > > eccbytes: 6, > > #endif > > eccpos: {8, 9, 10, 13, 14, 15} > > }; > > > > The eccbytes setup is neccecary for current MTD CVS. Did you modify the > > #if (LINUX_ ....) ? > > Hmm, I didn't know about this one. I defined eccbytes and it works now with > CONFIG_YAFFS_USE_NANDECC defined. I tested it by transferring 60MB without a > single failure so I think I can trust it. ;) Ok From tglx@linutronix.de Fri Dec 10 08:47:06 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Fri, 10 Dec 2004 09:47:06 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <20041210002743.118D5161EA@desire.actrix.co.nz> References: <1102632927.3306.51.camel@tglx.tec.linutronix.de> <20041210002743.118D5161EA@desire.actrix.co.nz> Message-ID: <1102668426.3306.76.camel@tglx.tec.linutronix.de> On Fri, 2004-12-10 at 13:32 +1300, Charles Manning wrote: > I might argue the latter point here. I believe the ECC byte ordering > calculated by SJHill's nand_ecc.c is wrong. yaffs_ecc.c can calculate this > ECC order or the SmartMedia "correct" order. yaffs_ecc.c is also slightly > faster than nand_ecc.c ;-). I have no problem to put a faster algorithm into nand_ecc.c. The byte ordering is simple to fix by - eccpos: {8, 9, 10, 13, 14, 15} + eccpos: {9, 8, 10, 14, 13, 15} or whatever byte ordering is the correct one. > I don't think I have a gripe with the ECC stuff, it's the write verification > that gets me. Why ? The nand driver provides write verify and tells you when it failed. > From my understanding this is only a configuration issue. > > YAFFS can be build with CONFIG_YAFFS_USE_NAND_ECC which means yaffs won't do > ECC - it lets mtd do all ECC. This is, IMHO, the best way to do things with > Linux - particularly if there are other non-yaffs users of the NAND. > > With non-Linux usage, I recommend using yaffs_ecc.c if software ECC is > required. Sure, but I strongly recommend to seperate this from the filesystem. > Where things do break down a bit is with mkyaffs which does calculate ECC. > You need to be careful to use a consistent ECC strategy. Yep, but I notice that most newer designs use hardware ecc, which sometimes leads to strange page layouts and uses other algorithms e.g. Reed-Solomon, so the generic mkyaffs - generate everything - will not work anymore. As we discussed before the only way to solve this is ECC autoplacement, which is unfortunately not possible with YAFFS1 although it could be tweaked to use it. YAFFS2 uses autoplacement ? To provide images which can be programmed into the FLASH during manufacturing you will need a different approach. - mkyaffs provides the filesystem data - an ecc generator which must be aware of the algortihm and the placement builds the final image which can be programmed to the chip - If you can programm it from the OS, then you can read the image back from the chip and you do not need a software emulation of the ecc and placement tglx From mikee@logicpd.com Fri Dec 10 22:33:35 2004 From: mikee@logicpd.com (Michael Erickson) Date: Fri, 10 Dec 2004 16:33:35 -0600 Subject: [Yaffs] Problems compiling YAFFS direct interface. Message-ID: <41BA243F.2070309@logicpd.com> Hello all, Just wondering if anyone has actually ever used the direct interface. I got the latest version out of CVS yesterday. When I try and build the code I get the following error: [snip] mikee 03:57 PM $ make all ln -s ../devextras.h devextras.h ln -s ../yaffs_ecc.c yaffs_ecc.c ln -s ../yaffs_ecc.h yaffs_ecc.h ln -s ../yaffs_guts.c yaffs_guts.c ln -s ../yaffs_guts.h yaffs_guts.h ln -s ../yaffsinterface.h yaffsinterface.h ln -s ../yportenv.h yportenv.h gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g dtest.c -o dtest.o In file included from dtest.c:9: yaffsfs.h:169: warning: no semicolon at end of struct or union yaffsfs.h:169: error: syntax error before '.' token yaffsfs.h:170: error: syntax error before '.' token yaffsfs.h:171: error: syntax error before '.' token dtest.c: In function `copy_in_a_file': dtest.c:18: warning: implicit declaration of function `open' dtest.c:21: warning: implicit declaration of function `read' dtest.c:32: warning: implicit declaration of function `close' dtest.c: In function `dumpDirFollow': dtest.c:184: error: storage size of `s' isn't known dtest.c:222: warning: int format, off_t arg (arg 3) dtest.c:184: warning: unused variable `s' dtest.c: In function `dumpDir': dtest.c:229: error: storage size of `s' isn't known dtest.c:267: warning: int format, off_t arg (arg 3) dtest.c:229: warning: unused variable `s' dtest.c: In function `long_test': dtest.c:306: error: storage size of `ystat' isn't known dtest.c:468: warning: int format, off_t arg (arg 2) dtest.c:518: warning: implicit declaration of function `yaffs_DumpDevStruct' dtest.c:306: warning: unused variable `ystat' dtest.c: In function `cache_bypass_bug_test': dtest.c:621: warning: unused variable `i' make: *** [dtest.o] Error 1 [/snip] I've searched through the code quite a bit but can't seem to come up with what is wrong with the structure. It seems as though my development system's header files are over-riding something. Is YAFFS direct compile-able on a Linux box? Can I _not_ include standard headers? The documentation on the direct interface says the following: [snip] Compilation Configuration Configuration is done in four places: * yaffscfg.c: OS specific functions * yaffscfg.h: Preferably only change YAFFSFS_N_HANDLES, the number of files that can be simultaneously opened. * yportenv.h: Preferably do not change this. * Compile options. The valid compile options for the YAFFS direct interface are: * CONFIG_YAFFS_DIRECT must be enabled to use the direct interface. * CONFIG_YAFFS_SHORT_NAMES_IN_RAM define to enable short name caching. This is suggested in cases unless RAM is very limited. [/snip] I checked yaffscfg.c and it appeared to have reasonably stubbed-out functions which should allow the system to compile. Everything else listed there says to not change it. So, I guess I'm stuck for the moment. Any input would be greatly appreciated. Thanks, --mike -- Michael Erickson Senior Software Engineer Logic Product Development (612) 436-5118 mailto:mikee@logicpd.com http://www.logicpd.com From jacob.dall@operamail.com Fri Dec 10 23:24:14 2004 From: jacob.dall@operamail.com (Jacob Dall) Date: Sat, 11 Dec 2004 00:24:14 +0100 Subject: [Yaffs] Need help replacing yaffs1 by yaffs2 Message-ID: <20041210232414.330AB3AA515@ws5-8.us4.outblaze.com> Please, I need some help. I want to replace yaffs1 direct with yaffs2 direct, but I've some trouble. I've compiled the code with the CFLAGS as defined in the direct/makefile: C= ONFIG_YAFFS_DIRECT, CONFIG_YAFFS_SHORT_NAMES_IN_RAM and CONFIG_YAFFS_YAFFS2= . I'm a bit in doubt about the last define - is it ok setting it when one w= ants to do what I want? I've completed a low-lewel check of the flash, using my implementation of t= he interface functions in direct/yaffs_flashif.c. The test is done by writi= ng some well-known values to the data and spare area of each chunk, reading= it back and verifying byte by byte. I do not allow any diffs. It runs to p= erfection - I get no errors at all.=20 Now, starting up yaffs (of course I did erase all blocks after the low-leve= l check was completed), mounting a device and opening, writing and closing = some files, for each file I get some 'ecc error unfixed' notes, and a block= is marked for retirement. I don't get that, taking into consideration that= my previous test showed no issues at all. Digging into the code, I can't seem to locate the spot where data ecc is ca= lculated (beyond some code not being active, either by #ifdef 0 or //). I tend to believe that what I want to achieve is either unsupported or unte= sted. Am I right? Still, I don't get it - where is the data ecc supposed to be calculated? Thanks, Jacob Dall From manningc2@actrix.gen.nz Sun Dec 12 22:01:01 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 13 Dec 2004 11:01:01 +1300 Subject: [Yaffs] Problems compiling YAFFS direct interface. In-Reply-To: <41BA243F.2070309@logicpd.com> References: <41BA243F.2070309@logicpd.com> Message-ID: <20041212215544.255EE16869@desire.actrix.co.nz> I compile with yaffs direct all the time. This is how I do all the YAFFS = file=20 systel "guts" development, using Linux.=20 the directtest builds for me fine (with a few warnings) but the bootloade= r =20 does not (missing nand_ecc.c). I shall fix that by moving it to yaffs_ecc= .c The direct test in CVS should build fine. Please fetch from CVS again int= o a=20 clean directory. More below On Saturday 11 December 2004 11:33, Michael Erickson wrote: > Hello all, > > Just wondering if anyone has actually ever used the direct interface. I > got the latest version out of CVS yesterday. When I try and build the > code I get the following error: > > [snip] > mikee 03:57 PM $ make all > ln -s ../devextras.h devextras.h > ln -s ../yaffs_ecc.c yaffs_ecc.c > ln -s ../yaffs_ecc.h yaffs_ecc.h > ln -s ../yaffs_guts.c yaffs_guts.c > ln -s ../yaffs_guts.h yaffs_guts.h > ln -s ../yaffsinterface.h yaffsinterface.h > ln -s ../yportenv.h yportenv.h > gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g > dtest.c -o dtest.o > In file included from dtest.c:9: > yaffsfs.h:169: warning: no semicolon at end of struct or union > yaffsfs.h:169: error: syntax error before '.' token > yaffsfs.h:170: error: syntax error before '.' token > yaffsfs.h:171: error: syntax error before '.' token These messages don't seem to be consistent with the source. > dtest.c: In function `copy_in_a_file': > dtest.c:18: warning: implicit declaration of function `open' > dtest.c:21: warning: implicit declaration of function `read' > dtest.c:32: warning: implicit declaration of function `close' > dtest.c: In function `dumpDirFollow': > dtest.c:184: error: storage size of `s' isn't known > dtest.c:222: warning: int format, off_t arg (arg 3) > dtest.c:184: warning: unused variable `s' > dtest.c: In function `dumpDir': > dtest.c:229: error: storage size of `s' isn't known > dtest.c:267: warning: int format, off_t arg (arg 3) > dtest.c:229: warning: unused variable `s' > dtest.c: In function `long_test': > dtest.c:306: error: storage size of `ystat' isn't known > dtest.c:468: warning: int format, off_t arg (arg 2) > dtest.c:518: warning: implicit declaration of function > `yaffs_DumpDevStruct' dtest.c:306: warning: unused variable `ystat' > dtest.c: In function `cache_bypass_bug_test': > dtest.c:621: warning: unused variable `i' > make: *** [dtest.o] Error 1 > [/snip] > > I've searched through the code quite a bit but can't seem to come up > with what is wrong with the structure. It seems as though my developmen= t > system's header files are over-riding something. > > Is YAFFS direct compile-able on a Linux box? > Can I _not_ include standard headers? > > The documentation on the direct interface says the following: > > [snip] > Compilation Configuration > > Configuration is done in four places: > * yaffscfg.c: OS specific functions > * yaffscfg.h: Preferably only change YAFFSFS_N_HANDLES, the > number of files that can be simultaneously opened. > * yportenv.h: Preferably do not change this. > * Compile options. The valid compile options for the YAFFS > direct interface are: > * CONFIG_YAFFS_DIRECT must be enabled to use the direct > interface. > * CONFIG_YAFFS_SHORT_NAMES_IN_RAM define to enable short name > caching. This is suggested in cases unless RAM is very > limited. > [/snip] > > I checked yaffscfg.c and it appeared to have reasonably stubbed-out > functions which should allow the system to compile. > > Everything else listed there says to not change it. So, I guess I'm > stuck for the moment. > > Any input would be greatly appreciated. > > Thanks, > --mike From manningc2@actrix.gen.nz Sun Dec 12 22:09:21 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 13 Dec 2004 11:09:21 +1300 Subject: [Yaffs] Need help replacing yaffs1 by yaffs2 In-Reply-To: <20041210232414.330AB3AA515@ws5-8.us4.outblaze.com> References: <20041210232414.330AB3AA515@ws5-8.us4.outblaze.com> Message-ID: <20041212220404.01AB04AB0@blood.actrix.co.nz> On Saturday 11 December 2004 12:24, Jacob Dall wrote: > Please, I need some help. > > I want to replace yaffs1 direct with yaffs2 direct, but I've some troub= le. > > I've compiled the code with the CFLAGS as defined in the direct/makefil= e: > CONFIG_YAFFS_DIRECT, CONFIG_YAFFS_SHORT_NAMES_IN_RAM and > CONFIG_YAFFS_YAFFS2. I'm a bit in doubt about the last define - is it o= k > setting it when one wants to do what I want? > > I've completed a low-lewel check of the flash, using my implementation = of > the interface functions in direct/yaffs_flashif.c. The test is done by > writing some well-known values to the data and spare area of each chunk= , > reading it back and verifying byte by byte. I do not allow any diffs. I= t > runs to perfection - I get no errors at all. > > Now, starting up yaffs (of course I did erase all blocks after the > low-level check was completed), mounting a device and opening, writing = and > closing some files, for each file I get some 'ecc error unfixed' notes,= and > a block is marked for retirement. I don't get that, taking into > consideration that my previous test showed no issues at all. > > Digging into the code, I can't seem to locate the spot where data ecc i= s > calculated (beyond some code not being active, either by #ifdef 0 or //= ). In YAFFS2 the ecc tests have been moved out of yaffs_guts to make a bette= r=20 partitioning of the file system from the NAND and ECC logic. The ECC is done within the ReadChunkWithTags and WriteChunkWithTags funct= ions. If you use 512-byte pages (and yaffs1 mode compatabiliuty mode) then you=20 can use the tags compatability functions. These will call yaffs_ecc.c. For 2kbyte pages etc, using full-blown yaffs2 mode, the ECC must be done = in=20 the NAND layer. THis can be done using yaffs_ecc.c > > I tend to believe that what I want to achieve is either unsupported or > untested. Am I right? It is supported in a more flexible way. It just mean that ECC checking fo= r 2k=20 pages should be done in the NAND access layer. > > Still, I don't get it - where is the data ecc supposed to be calculated= ? From manningc2@actrix.gen.nz Sun Dec 12 22:16:42 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Mon, 13 Dec 2004 11:16:42 +1300 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <1102668426.3306.76.camel@tglx.tec.linutronix.de> References: <20041210002743.118D5161EA@desire.actrix.co.nz> <1102668426.3306.76.camel@tglx.tec.linutronix.de> Message-ID: <20041212221124.93F2F16CDE@desire.actrix.co.nz> On Friday 10 December 2004 21:47, Thomas Gleixner wrote: > On Fri, 2004-12-10 at 13:32 +1300, Charles Manning wrote: > > I might argue the latter point here. I believe the ECC byte ordering > > calculated by SJHill's nand_ecc.c is wrong. yaffs_ecc.c can calcula= te > > this ECC order or the SmartMedia "correct" order. yaffs_ecc.c is als= o > > slightly faster than nand_ecc.c ;-). > > I have no problem to put a faster algorithm into nand_ecc.c. The byte > ordering is simple to fix by > > - eccpos: {8, 9, 10, 13, 14, 15} > + eccpos: {9, 8, 10, 14, 13, 15} > > or whatever byte ordering is the correct one. > > > I don't think I have a gripe with the ECC stuff, it's the write > > verification that gets me. > > Why ? The nand driver provides write verify and tells you when it > failed. When I write the deletion markers or bad block marking I don't want to u= se=20 verification.=20 When you program NAND, writing 0xFF does not mean "set this to 0xFF" it m= eans=20 "don't do anything to these bytes". The verifying does not work this way.= =20 Perhaps it would be nice to have a flag to apply or ignore verification. > > > From my understanding this is only a configuration issue. > > > > YAFFS can be build with CONFIG_YAFFS_USE_NAND_ECC which means yaffs w= on't > > do ECC - it lets mtd do all ECC. This is, IMHO, the best way to do th= ings > > with Linux - particularly if there are other non-yaffs users of the N= AND. > > > > With non-Linux usage, I recommend using yaffs_ecc.c if software ECC i= s > > required. > > Sure, but I strongly recommend to seperate this from the filesystem. In YAFFS2 it is so :-). > > > Where things do break down a bit is with mkyaffs which does calculate > > ECC. You need to be careful to use a consistent ECC strategy. > > Yep, but I notice that most newer designs use hardware ecc, which > sometimes leads to strange page layouts and uses other algorithms e.g. > Reed-Solomon, so the generic mkyaffs - generate everything - will not > work anymore. > > As we discussed before the only way to solve this is ECC autoplacement, > which is unfortunately not possible with YAFFS1 although it could be > tweaked to use it. YAFFS2 uses autoplacement ? It would be quite simple to modify YAFFS1 to work with autoplacement. YAF= FS2=20 uses autoplacement. > > To provide images which can be programmed into the FLASH during > manufacturing you will need a different approach. > > - mkyaffs provides the filesystem data > > - an ecc generator which must be aware of the algortihm and the > placement builds the final image which can be programmed to the chip > > - If you can programm it from the OS, then you can read the image back > from the chip and you do not need a software emulation of the ecc and > placement > > tglx > > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From arasv@magellan-technology.com Mon Dec 13 05:09:08 2004 From: arasv@magellan-technology.com (Aras Vaichas) Date: Mon, 13 Dec 2004 16:09:08 +1100 Subject: [Yaffs] patch for using ECC + YAFFS + cvs MTD + 2.4.x Message-ID: <41BD23F4.5060305@magellan-technology.com> This is a patch for YAFFS source code that allows you to use the CONFIG_YAFFS_USE_NANDECC option with a 2.4.x kernel and the latest MTD code. If you don't have this patch, the struct member "eccbytes" will not be setup correctly and you will get ECC style errors when reading from a NAND device. i.e. random single bit flips in large blocks of data My patch assumes that if CONFIG_YAFFS_USE_OLD_MTD is NOT defined then you must be using the latest MTD code and therefore it should work with 2.4.x kernels. Thanks to Thomas Gleixner for pointing this one out to me. Aras # diff -Naur yaffs_mtdif.c.old yaffs_mtdif.c --- yaffs_mtdif.c.old 2004-12-10 13:06:36.000000000 +1100 +++ yaffs_mtdif.c 2004-12-13 11:30:52.304493960 +1100 @@ -31,7 +31,7 @@ struct nand_oobinfo yaffs_oobinfo = { useecc: 1, -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) || (!CONFIG_YAFFS_USE_OLD_MTD) // this is for versions of mtd nand driver in kernel 2.6.8 and later eccbytes: 6, #endif From tglx@linutronix.de Mon Dec 13 06:14:00 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Mon, 13 Dec 2004 07:14:00 +0100 Subject: [Yaffs] cvs YAFFS + MTD cvs + 2.4.27-vrs1 problems In-Reply-To: <20041212221124.93F2F16CDE@desire.actrix.co.nz> References: <20041210002743.118D5161EA@desire.actrix.co.nz> <1102668426.3306.76.camel@tglx.tec.linutronix.de> <20041212221124.93F2F16CDE@desire.actrix.co.nz> Message-ID: <1102918440.3306.99.camel@tglx.tec.linutronix.de> On Mon, 2004-12-13 at 11:16 +1300, Charles Manning wrote: > > Why ? The nand driver provides write verify and tells you when it > > failed. > > When I write the deletion markers or bad block marking I don't want to use > verification. > > When you program NAND, writing 0xFF does not mean "set this to 0xFF" it means > "don't do anything to these bytes". The verifying does not work this way. > Perhaps it would be nice to have a flag to apply or ignore verification. Yeah, did not think about that. You need this for oob writes only, right ? It should be not a big problem to make this runtime enabled. Will look into this. tglx From frowand@mvista.com Mon Dec 13 18:53:23 2004 From: frowand@mvista.com (Frank Rowand) Date: Mon, 13 Dec 2004 10:53:23 -0800 Subject: [Yaffs] Problems compiling YAFFS direct interface. In-Reply-To: <20041212215544.255EE16869@desire.actrix.co.nz> References: <41BA243F.2070309@logicpd.com> <20041212215544.255EE16869@desire.actrix.co.nz> Message-ID: <41BDE523.2070607@mvista.com> Charles Manning wrote: > I compile with yaffs direct all the time. This is how I do all the YAFFS file > systel "guts" development, using Linux. > > the directtest builds for me fine (with a few warnings) but the bootloader > does not (missing nand_ecc.c). I shall fix that by moving it to yaffs_ecc.c > > The direct test in CVS should build fine. Please fetch from CVS again into a > clean directory. > > More below > > > On Saturday 11 December 2004 11:33, Michael Erickson wrote: > >>Hello all, >> >>Just wondering if anyone has actually ever used the direct interface. I >>got the latest version out of CVS yesterday. When I try and build the >>code I get the following error: >> >>[snip] >>mikee 03:57 PM $ make all >>ln -s ../devextras.h devextras.h >>ln -s ../yaffs_ecc.c yaffs_ecc.c >>ln -s ../yaffs_ecc.h yaffs_ecc.h >>ln -s ../yaffs_guts.c yaffs_guts.c >>ln -s ../yaffs_guts.h yaffs_guts.h >>ln -s ../yaffsinterface.h yaffsinterface.h >>ln -s ../yportenv.h yportenv.h >>gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g >>dtest.c -o dtest.o >>In file included from dtest.c:9: >>yaffsfs.h:169: warning: no semicolon at end of struct or union >>yaffsfs.h:169: error: syntax error before '.' token >>yaffsfs.h:170: error: syntax error before '.' token >>yaffsfs.h:171: error: syntax error before '.' token I have not tried using the direct interface, but the cause of the above errors is probably the same as I reported on 11/22 (look for an email with the subject "fix for mkyaffsimage compile error"). What I wrote there is: When I compile mkyaffsimage on RedHat 9.0, I get errors that look like the errors reported in the email thread "Compile error when using yaffs/direct" started by Daniel Gustafsson, Fri, 8 Oct 2004 15:28:35. The problem is caused by some #define statements in /usr/include/bits/stat.h: # define st_atime st_atim.tv_sec /* Backward compatibility. */ # define st_mtime st_mtim.tv_sec # define st_ctime st_ctim.tv_sec The attached patch is one way to fix the problem for mkyaffsimage. It renames the st_*time fields to st_tim. If this is an acceptable way to fix the problem, then I can update the patch to include the in-kernel files and the files in the direct directory since they reference these same fields. > > > These messages don't seem to be consistent with the source. > > >>dtest.c: In function `copy_in_a_file': >>dtest.c:18: warning: implicit declaration of function `open' >>dtest.c:21: warning: implicit declaration of function `read' >>dtest.c:32: warning: implicit declaration of function `close' >>dtest.c: In function `dumpDirFollow': >>dtest.c:184: error: storage size of `s' isn't known >>dtest.c:222: warning: int format, off_t arg (arg 3) >>dtest.c:184: warning: unused variable `s' >>dtest.c: In function `dumpDir': >>dtest.c:229: error: storage size of `s' isn't known >>dtest.c:267: warning: int format, off_t arg (arg 3) >>dtest.c:229: warning: unused variable `s' >>dtest.c: In function `long_test': >>dtest.c:306: error: storage size of `ystat' isn't known >>dtest.c:468: warning: int format, off_t arg (arg 2) >>dtest.c:518: warning: implicit declaration of function >>`yaffs_DumpDevStruct' dtest.c:306: warning: unused variable `ystat' >>dtest.c: In function `cache_bypass_bug_test': >>dtest.c:621: warning: unused variable `i' >>make: *** [dtest.o] Error 1 >>[/snip] >> >>I've searched through the code quite a bit but can't seem to come up >>with what is wrong with the structure. It seems as though my development >>system's header files are over-riding something. >> >>Is YAFFS direct compile-able on a Linux box? >>Can I _not_ include standard headers? >> >>The documentation on the direct interface says the following: >> >>[snip] >>Compilation Configuration >> >>Configuration is done in four places: >> * yaffscfg.c: OS specific functions >> * yaffscfg.h: Preferably only change YAFFSFS_N_HANDLES, the >> number of files that can be simultaneously opened. >> * yportenv.h: Preferably do not change this. >> * Compile options. The valid compile options for the YAFFS >> direct interface are: >> * CONFIG_YAFFS_DIRECT must be enabled to use the direct >> interface. >> * CONFIG_YAFFS_SHORT_NAMES_IN_RAM define to enable short name >> caching. This is suggested in cases unless RAM is very >> limited. >>[/snip] >> >>I checked yaffscfg.c and it appeared to have reasonably stubbed-out >>functions which should allow the system to compile. >> >>Everything else listed there says to not change it. So, I guess I'm >>stuck for the moment. >> >>Any input would be greatly appreciated. >> >>Thanks, >> --mike -Frank -- Frank Rowand MontaVista Software, Inc From mikee@logicpd.com Mon Dec 13 20:00:55 2004 From: mikee@logicpd.com (Michael Erickson) Date: Mon, 13 Dec 2004 14:00:55 -0600 Subject: [Yaffs] Problems compiling YAFFS direct interface. In-Reply-To: <41BDE523.2070607@mvista.com> References: <41BA243F.2070309@logicpd.com> <20041212215544.255EE16869@desire.actrix.co.nz> <41BDE523.2070607@mvista.com> Message-ID: <41BDF4F7.7000705@logicpd.com> Frank, thanks for the email. It appears that I am having the same problem as you. In file /direct/yaffsfs.h, I re-named the following members of structure yaffs_stat: st_atime => st_atim st_mtime => st_mtim st_ctime => st_ctim Doing so got rid of the compile error I was having. Of course it introduced several others which now have to be fixed :) So, the question now becomes two parts: 1) Charles, why is it that you don't get the same errors? 2) How should we go about fixing them in a uniform way? Anyone have any input on how to proceed? Best regards, --mikee Frank Rowand wrote: > Charles Manning wrote: > >> I compile with yaffs direct all the time. This is how I do all the >> YAFFS file systel "guts" development, using Linux. >> the directtest builds for me fine (with a few warnings) but the >> bootloader does not (missing nand_ecc.c). I shall fix that by moving >> it to yaffs_ecc.c >> >> The direct test in CVS should build fine. Please fetch from CVS again >> into a clean directory. >> >> More below >> >> >> On Saturday 11 December 2004 11:33, Michael Erickson wrote: >> >>> Hello all, >>> >>> Just wondering if anyone has actually ever used the direct interface. I >>> got the latest version out of CVS yesterday. When I try and build the >>> code I get the following error: >>> >>> [snip] >>> mikee 03:57 PM $ make all >>> ln -s ../devextras.h devextras.h >>> ln -s ../yaffs_ecc.c yaffs_ecc.c >>> ln -s ../yaffs_ecc.h yaffs_ecc.h >>> ln -s ../yaffs_guts.c yaffs_guts.c >>> ln -s ../yaffs_guts.h yaffs_guts.h >>> ln -s ../yaffsinterface.h yaffsinterface.h >>> ln -s ../yportenv.h yportenv.h >>> gcc -c -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -g >>> dtest.c -o dtest.o >>> In file included from dtest.c:9: >>> yaffsfs.h:169: warning: no semicolon at end of struct or union >>> yaffsfs.h:169: error: syntax error before '.' token >>> yaffsfs.h:170: error: syntax error before '.' token >>> yaffsfs.h:171: error: syntax error before '.' token > > > I have not tried using the direct interface, but the cause of the > above errors is probably the same as I reported on 11/22 (look > for an email with the subject "fix for mkyaffsimage compile error"). > > What I wrote there is: > > When I compile mkyaffsimage on RedHat 9.0, I get errors that look > like the errors reported in the email thread "Compile error when using > yaffs/direct" started by Daniel Gustafsson, Fri, 8 Oct 2004 15:28:35. > > The problem is caused by some #define statements in > /usr/include/bits/stat.h: > > # define st_atime st_atim.tv_sec /* Backward compatibility. */ > # define st_mtime st_mtim.tv_sec > # define st_ctime st_ctim.tv_sec > > The attached patch is one way to fix the problem for mkyaffsimage. It > renames the st_*time fields to st_tim. > > If this is an acceptable way to fix the problem, then I can update > the patch to include the in-kernel files and the files in the direct > directory since they reference these same fields. > > >> >> >> These messages don't seem to be consistent with the source. >> >> >>> dtest.c: In function `copy_in_a_file': >>> dtest.c:18: warning: implicit declaration of function `open' >>> dtest.c:21: warning: implicit declaration of function `read' >>> dtest.c:32: warning: implicit declaration of function `close' >>> dtest.c: In function `dumpDirFollow': >>> dtest.c:184: error: storage size of `s' isn't known >>> dtest.c:222: warning: int format, off_t arg (arg 3) >>> dtest.c:184: warning: unused variable `s' >>> dtest.c: In function `dumpDir': >>> dtest.c:229: error: storage size of `s' isn't known >>> dtest.c:267: warning: int format, off_t arg (arg 3) >>> dtest.c:229: warning: unused variable `s' >>> dtest.c: In function `long_test': >>> dtest.c:306: error: storage size of `ystat' isn't known >>> dtest.c:468: warning: int format, off_t arg (arg 2) >>> dtest.c:518: warning: implicit declaration of function >>> `yaffs_DumpDevStruct' dtest.c:306: warning: unused variable `ystat' >>> dtest.c: In function `cache_bypass_bug_test': >>> dtest.c:621: warning: unused variable `i' >>> make: *** [dtest.o] Error 1 >>> [/snip] >>> >>> I've searched through the code quite a bit but can't seem to come up >>> with what is wrong with the structure. It seems as though my development >>> system's header files are over-riding something. >>> >>> Is YAFFS direct compile-able on a Linux box? >>> Can I _not_ include standard headers? >>> >>> The documentation on the direct interface says the following: >>> >>> [snip] >>> Compilation Configuration >>> >>> Configuration is done in four places: >>> * yaffscfg.c: OS specific functions >>> * yaffscfg.h: Preferably only change YAFFSFS_N_HANDLES, the >>> number of files that can be simultaneously opened. >>> * yportenv.h: Preferably do not change this. >>> * Compile options. The valid compile options for the YAFFS >>> direct interface are: >>> * CONFIG_YAFFS_DIRECT must be enabled to use the direct >>> interface. >>> * CONFIG_YAFFS_SHORT_NAMES_IN_RAM define to enable short name >>> caching. This is suggested in cases unless RAM is very >>> limited. >>> [/snip] >>> >>> I checked yaffscfg.c and it appeared to have reasonably stubbed-out >>> functions which should allow the system to compile. >>> >>> Everything else listed there says to not change it. So, I guess I'm >>> stuck for the moment. >>> >>> Any input would be greatly appreciated. >>> >>> Thanks, >>> --mike > > > -Frank -- Michael Erickson Senior Software Engineer Logic Product Development (612) 436-5118 mailto:mikee@logicpd.com http://www.logicpd.com From Charles.Manning@trimble.co.nz Mon Dec 13 21:20:10 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Tue, 14 Dec 2004 10:20:10 +1300 Subject: [Yaffs] Problems compiling YAFFS direct interface. Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E0154909E@nzc-ap-xch-01.ap.trimblecorp.net> It would seem that on your box st_atime etc must be macros that expand to something with a '.' in it, judging from the compiler warnings you get. The machine I use for testing etc is pretty old (well the Linux on it is). I will try with a machine loaded with FC2 and see what happens. -- Charles > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk=20 > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of=20 > Michael Erickson > Sent: Tuesday, 14 December 2004 9:01 a.m. > To: Frank Rowand > Cc: manningc2@actrix.gen.nz; yaffs@stoneboat.aleph1.co.uk > Subject: Re: [Yaffs] Problems compiling YAFFS direct interface. >=20 >=20 > Frank, thanks for the email. It appears that I am having the same=20 > problem as you. >=20 > In file /direct/yaffsfs.h, I re-named the following members=20 > of structure=20 > yaffs_stat: >=20 > st_atime =3D> st_atim > st_mtime =3D> st_mtim > st_ctime =3D> st_ctim >=20 > Doing so got rid of the compile error I was having. Of course it=20 > introduced several others which now have to be fixed :) >=20 > So, the question now becomes two parts: >=20 > 1) Charles, why is it that you don't get the same errors? > 2) How should we go about fixing them in a uniform way? >=20 > Anyone have any input on how to proceed? >=20 > Best regards, > --mikee >=20 >=20 > Frank Rowand wrote: > > Charles Manning wrote: > >=20 > >> I compile with yaffs direct all the time. This is how I do all the > >> YAFFS file systel "guts" development, using Linux. > >> the directtest builds for me fine (with a few warnings) but the=20 > >> bootloader does not (missing nand_ecc.c). I shall fix=20 > that by moving=20 > >> it to yaffs_ecc.c > >> > >> The direct test in CVS should build fine. Please fetch=20 > from CVS again > >> into a clean directory. > >> > >> More below > >> > >> > >> On Saturday 11 December 2004 11:33, Michael Erickson wrote: > >> > >>> Hello all, > >>> > >>> Just wondering if anyone has actually ever used the direct=20 > >>> interface. I got the latest version out of CVS yesterday.=20 > When I try=20 > >>> and build the code I get the following error: > >>> > >>> [snip] > >>> mikee 03:57 PM $ make all > >>> ln -s ../devextras.h devextras.h > >>> ln -s ../yaffs_ecc.c yaffs_ecc.c > >>> ln -s ../yaffs_ecc.h yaffs_ecc.h > >>> ln -s ../yaffs_guts.c yaffs_guts.c > >>> ln -s ../yaffs_guts.h yaffs_guts.h > >>> ln -s ../yaffsinterface.h yaffsinterface.h > >>> ln -s ../yportenv.h yportenv.h > >>> gcc -c -Wall -DCONFIG_YAFFS_DIRECT=20 > -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM=20 > >>> -g dtest.c -o dtest.o In file included from dtest.c:9: > >>> yaffsfs.h:169: warning: no semicolon at end of struct or union > >>> yaffsfs.h:169: error: syntax error before '.' token > >>> yaffsfs.h:170: error: syntax error before '.' token > >>> yaffsfs.h:171: error: syntax error before '.' token > >=20 > >=20 > > I have not tried using the direct interface, but the cause of the > > above errors is probably the same as I reported on 11/22 (look > > for an email with the subject "fix for mkyaffsimage compile error"). > >=20 > > What I wrote there is: > >=20 > > When I compile mkyaffsimage on RedHat 9.0, I get errors that look > > like the errors reported in the email thread "Compile error=20 > when using > > yaffs/direct" started by Daniel Gustafsson, Fri, 8 Oct 2004=20 > 15:28:35. > >=20 > > The problem is caused by some #define statements in > > /usr/include/bits/stat.h: > >=20 > > # define st_atime st_atim.tv_sec /* Backward=20 > compatibility. */ > > # define st_mtime st_mtim.tv_sec > > # define st_ctime st_ctim.tv_sec > >=20 > > The attached patch is one way to fix the problem for=20 > mkyaffsimage. It > > renames the st_*time fields to st_tim. > >=20 > > If this is an acceptable way to fix the problem, then I can update > > the patch to include the in-kernel files and the files in the direct > > directory since they reference these same fields. > >=20 > >=20 > >> > >> > >> These messages don't seem to be consistent with the source. > >> > >> > >>> dtest.c: In function `copy_in_a_file': > >>> dtest.c:18: warning: implicit declaration of function `open' > >>> dtest.c:21: warning: implicit declaration of function `read' > >>> dtest.c:32: warning: implicit declaration of function `close' > >>> dtest.c: In function `dumpDirFollow': > >>> dtest.c:184: error: storage size of `s' isn't known > >>> dtest.c:222: warning: int format, off_t arg (arg 3) > >>> dtest.c:184: warning: unused variable `s' > >>> dtest.c: In function `dumpDir': > >>> dtest.c:229: error: storage size of `s' isn't known > >>> dtest.c:267: warning: int format, off_t arg (arg 3) > >>> dtest.c:229: warning: unused variable `s' > >>> dtest.c: In function `long_test': > >>> dtest.c:306: error: storage size of `ystat' isn't known > >>> dtest.c:468: warning: int format, off_t arg (arg 2) > >>> dtest.c:518: warning: implicit declaration of function > >>> `yaffs_DumpDevStruct' dtest.c:306: warning: unused=20 > variable `ystat' > >>> dtest.c: In function `cache_bypass_bug_test': > >>> dtest.c:621: warning: unused variable `i' > >>> make: *** [dtest.o] Error 1 > >>> [/snip] > >>> > >>> I've searched through the code quite a bit but can't seem=20 > to come up > >>> with what is wrong with the structure. It seems as though=20 > my development > >>> system's header files are over-riding something. > >>> > >>> Is YAFFS direct compile-able on a Linux box? > >>> Can I _not_ include standard headers? > >>> > >>> The documentation on the direct interface says the following: > >>> > >>> [snip] > >>> Compilation Configuration > >>> > >>> Configuration is done in four places: > >>> * yaffscfg.c: OS specific functions > >>> * yaffscfg.h: Preferably only change YAFFSFS_N_HANDLES, the > >>> number of files that can be simultaneously opened. > >>> * yportenv.h: Preferably do not change this. > >>> * Compile options. The valid compile options for the YAFFS > >>> direct interface are: > >>> * CONFIG_YAFFS_DIRECT must be enabled to use the direct > >>> interface. > >>> * CONFIG_YAFFS_SHORT_NAMES_IN_RAM define to enable short name > >>> caching. This is suggested in cases unless RAM is very > >>> limited. > >>> [/snip] > >>> > >>> I checked yaffscfg.c and it appeared to have reasonably=20 > stubbed-out > >>> functions which should allow the system to compile. > >>> > >>> Everything else listed there says to not change it. So, I=20 > guess I'm > >>> stuck for the moment. > >>> > >>> Any input would be greatly appreciated. > >>> > >>> Thanks, > >>> --mike > >=20 > >=20 > > -Frank >=20 > --=20 > Michael Erickson > Senior Software Engineer > Logic Product Development > (612) 436-5118 > mailto:mikee@logicpd.com > http://www.logicpd.com >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs >=20 From frowand@mvista.com Tue Dec 14 21:22:32 2004 From: frowand@mvista.com (Frank Rowand) Date: Tue, 14 Dec 2004 13:22:32 -0800 Subject: [Yaffs] patch: mkyaffs printf format In-Reply-To: <8285CB7241FCFC4BB721A6F953F9B35E0154909E@nzc-ap-xch-01.ap.trimblecorp.net> References: <8285CB7241FCFC4BB721A6F953F9B35E0154909E@nzc-ap-xch-01.ap.trimblecorp.net> Message-ID: <41BF5998.1060207@mvista.com> This is a multi-part message in MIME format. --------------000101050906060608060002 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit In mkyaffs, the printf() of the blocks being erased and the blocks that are damaged was using a format of "0x08%lx" instead of "0x%08lx", so the value printed was prefixed with the constant "08" instead of being set to a field width of 8. The attached patch fixes the problem. -Frank -- Frank Rowand MontaVista Software, Inc --------------000101050906060608060002 Content-Type: text/plain; name="patch_printf_format" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="patch_printf_format" diff -ruNp yaffs/utils/mkyaffs.c yaffs_new/utils/mkyaffs.c --- yaffs/utils/mkyaffs.c 2003-03-12 11:54:07.000000000 -0800 +++ yaffs_new/utils/mkyaffs.c 2004-12-14 13:16:32.000000000 -0800 @@ -196,14 +196,14 @@ int main(int argc, char **argv) if(countBits[oobbuf[5]] < 7) { - printf("Block at 0x08%lx is damaged and is not being formatted\n",addr); + printf("Block at 0x%08lx is damaged and is not being formatted\n",addr); } else { /* Erase this block */ erase.start = addr; erase.length = meminfo.erasesize; - printf("Erasing block at 0x08%lx\n",addr); + printf("Erasing block at 0x%08lx\n",addr); if(ioctl(fd, MEMERASE, &erase) != 0) { perror("\nMTD Erase failure\n"); --------------000101050906060608060002-- From jacob.dall@operamail.com Wed Dec 15 07:52:18 2004 From: jacob.dall@operamail.com (Jacob Dall) Date: Wed, 15 Dec 2004 08:52:18 +0100 Subject: [Yaffs] Need help replacing yaffs1 by yaffs2 In-Reply-To: <20041212220404.01AB04AB0@blood.actrix.co.nz> References: <20041210232414.330AB3AA515@ws5-8.us4.outblaze.com> <20041212220404.01AB04AB0@blood.actrix.co.nz> Message-ID: <6.2.0.14.2.20041215082349.02d4fab8@pop3.operamail.com> Hello Charles, I understand what you are saying, but as I read the code, that's not what's in fact happening. I use 512-byte pages (and yaffs1 compatability mode) and dev->writeChunkWithTagsToNAND is not defined. Then, reading the yaffs_WriteChunkWithTagsToNAND in yaffs_guts.c, it shows that a yaffs_TagsCompatabilityWriteChunkWithTagsToNAND function is executed: static Y_INLINE int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND, const __u8 *buffer, yaffs_ExtendedTags *tags) { if(dev->writeChunkWithTagsToNAND) return dev->writeChunkWithTagsToNAND(dev,chunkInNAND,buffer,tags); else return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,chunkInNAND,buffer,tags); } In yaffs_TagsCompatabilityWriteChunkWithTagsToNAND (yaffs_tagscompat.c), yaffs_LoadTagsIntoSpare is called. In here, an ECC is generated for the tags. Having loaded tags into spare, the yaffs_WriteChunkToNAND is called, and it just calls dev->writeChunkToNAND. You were saying: >If you use 512-byte pages (and yaffs1 mode compatabiliuty mode) then you >can use the tags compatability functions. These will call yaffs_ecc.c. Could you please explain where the data ECC is generated? I do not see from where the call to yaffs_ecc code is executed. Though I see some code that's either commented out or hidden from the compiler by #if 0. I've fetched the latest yaffs2 code from cvs, and I've made no changes to the code, except for the yaffs_flashif part. Thanks, Jacob At 23:09 12-12-2004, Charles Manning wrote: >On Saturday 11 December 2004 12:24, Jacob Dall wrote: > > Please, I need some help. > > > > I want to replace yaffs1 direct with yaffs2 direct, but I've some trouble. > > > > I've compiled the code with the CFLAGS as defined in the direct/makefile: > > CONFIG_YAFFS_DIRECT, CONFIG_YAFFS_SHORT_NAMES_IN_RAM and > > CONFIG_YAFFS_YAFFS2. I'm a bit in doubt about the last define - is it ok > > setting it when one wants to do what I want? > > > > I've completed a low-lewel check of the flash, using my implementation of > > the interface functions in direct/yaffs_flashif.c. The test is done by > > writing some well-known values to the data and spare area of each chunk, > > reading it back and verifying byte by byte. I do not allow any diffs. It > > runs to perfection - I get no errors at all. > > > > Now, starting up yaffs (of course I did erase all blocks after the > > low-level check was completed), mounting a device and opening, writing and > > closing some files, for each file I get some 'ecc error unfixed' notes, and > > a block is marked for retirement. I don't get that, taking into > > consideration that my previous test showed no issues at all. > > > > Digging into the code, I can't seem to locate the spot where data ecc is > > calculated (beyond some code not being active, either by #ifdef 0 or //). > >In YAFFS2 the ecc tests have been moved out of yaffs_guts to make a better >partitioning of the file system from the NAND and ECC logic. > >The ECC is done within the ReadChunkWithTags and WriteChunkWithTags functions. > >If you use 512-byte pages (and yaffs1 mode compatabiliuty mode) then you >can use the tags compatability functions. These will call yaffs_ecc.c. > >For 2kbyte pages etc, using full-blown yaffs2 mode, the ECC must be done in >the NAND layer. THis can be done using yaffs_ecc.c > > > > > I tend to believe that what I want to achieve is either unsupported or > > untested. Am I right? > >It is supported in a more flexible way. It just mean that ECC checking for 2k >pages should be done in the NAND access layer. > > > > > Still, I don't get it - where is the data ecc supposed to be calculated? From rajivd@sj.symbol.com Wed Dec 15 23:50:17 2004 From: rajivd@sj.symbol.com (Rajiv Dhingra) Date: Wed, 15 Dec 2004 15:50:17 -0800 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 Message-ID: We were running Linux 2.4.20, Yaffs, and using a NAND device with 512 byte = pages. Everything was working fine. =20 Then the hardware guys replaced the 512 byte page NAND device with a 2k = page NAND device. So, I now have to hack yaffs to support a 2k page size, or start using = Yaffs2. What would the recommendation of this newsgroup be? Would it be = easy enough for me to hack yaffs to start supporting the bigger page size? = Is yaffs2 stable enough and does it run with the 2.4.20 kernel, making it = a better option. Thank you very much in advance. Rajiv From Charles.Manning@trimble.co.nz Thu Dec 16 01:10:17 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Thu, 16 Dec 2004 14:10:17 +1300 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E015490B6@nzc-ap-xch-01.ap.trimblecorp.net> I sometimes deal with hw guys like that too :-). YAFFS2 is the easier way to go. Checkin of the final bits of Linux support is real soon now. Don't let that scare you though. YAFFS2 has been pretty well tested and is shipping in Non-Linux devices. > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk=20 > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Rajiv Dhingra > Sent: Thursday, 16 December 2004 12:50 p.m. > To: yaffs@stoneboat.aleph1.co.uk > Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 >=20 >=20 >=20 > We were running Linux 2.4.20, Yaffs, and using a NAND device=20 > with 512 byte pages. Everything was working fine. =20 >=20 > Then the hardware guys replaced the 512 byte page NAND device=20 > with a 2k page NAND device. >=20 > So, I now have to hack yaffs to support a 2k page size, or=20 > start using Yaffs2. What would the recommendation of this=20 > newsgroup be? Would it be easy enough for me to hack yaffs=20 > to start supporting the bigger page size? Is yaffs2 stable=20 > enough and does it run with the 2.4.20 kernel, making it a=20 > better option. >=20 > Thank you very much in advance. >=20 > Rajiv >=20 >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk=20 > http://stoneboat.aleph1.co.uk/cgi-> bin/mailman/listinfo/yaffs >=20 From tglx@linutronix.de Thu Dec 16 08:41:17 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Thu, 16 Dec 2004 09:41:17 +0100 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 In-Reply-To: References: Message-ID: <1103186477.3406.191.camel@tglx.tec.linutronix.de> On Wed, 2004-12-15 at 15:50 -0800, Rajiv Dhingra wrote: > We were running Linux 2.4.20, Yaffs, and using a NAND > device with 512 byte pages. Everything was working fine. > Then the hardware guys replaced the 512 byte page NAND > device with a 2k page NAND device. > So, I now have to hack yaffs to support a 2k page size, > or start using Yaffs2. What would the recommendation > of this newsgroup be? Would it be easy enough for me > to hack yaffs to start supporting the bigger page size? > Is yaffs2 stable enough and does it run with the 2.4.20 > kernel, making it a better option. Be prepared to upgrade your kernel. The MTD NAND layer which has the support for 2k chips is definitely not portable to 2.4.20. Read http://www.linux-mtd.infradead.org/#kernelversions tglx From frowand@mvista.com Fri Dec 17 00:35:58 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 16:35:58 -0800 Subject: [Yaffs] yaffs kill_sb function and umount error Message-ID: <41C229EE.6030206@mvista.com> When I umount a yaffs file system on linux 2.6.9, I get the error: VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... In yaffs/yaffs_fs.c, I changed the .kill_sb function from kill_litter_super() to kill_block_super(). This made the symptom of the error message disappear. This area of the kernel is not my area of expertise - this was not a fully informed fix, but more of a stab in the dark. Can anyone provide advice on whether this is a good way to fix the problem or whether a different approach would be more correct? Thanks! -Frank -- Frank Rowand MontaVista Software, Inc From frowand@mvista.com Fri Dec 17 01:30:54 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:30:54 -0800 Subject: [Yaffs] set of patches for yaffs on Linux 2.6.9 Message-ID: <41C236CE.6000609@mvista.com> I am submitting a set of patches that enabled me to get yaffs working on Linux 2.6.9. (Not vanilla 2.6.9, but 2.6.9 plus a few changes, but I don't think the changes matter in this context.) Please add any of these changes back into yaffs as appropriate, and provide comments as needed. I have compiled for x86 RAM based yaffs (but not tested) and for ARM little endian MTD based yaffs. I have compiled as in-kernel and as modules (but have not loaded the module version). The ARM version has been through basic crash and burn testing, but I have not yet begun serious testing. The changes are broken into a series of patches to isolate the different types of changes, and will each be sent in a following email. The patches apply in the following order: patches/yaffs_kernel_01_base.patch A direct copy of the yaffs files from the yaffs website, as of November 16, 2004. This patch puts the files into the Linux kernel tree at fs/yaffs/. Not all of the files in this directory are actually used by me, but I was being thorough. yaffs_kernel_02_fixup_in_kernel_tree.patch The changes needed to incorporate yaffs into the Linux build system and to allow yaffs to build Changes to Makefiles, Kconfig files, added include of to various yaffs source files. Changed sb->u.generic_sbp to sb->s_fs_info #if kernel version > 2.5.0 (in which case u.generic_sbp no longer exists). The struct file_system_type initializer for ram fs type was not properly named (so the compile failed). yaffs_kernel_03_fix_warnings.patch Fix compile warnings. I don't like compile warnings because they make it harder for me to notice the real problems that I create when I modify code. This patch is not really the proper way to fix some of the warnings, if it is desired to submit yaffs to the Linux kernel. (Changing to Linux kernel coding standards would be more correct in that case.) This is really just a quick and dirty approach, trying to minimize change so that if these patches are not accepted I will still be able to move forward to later versions of the community yaffs with minimal pain to myself. I rename BLOCK_SIZE to NAND_BLOCK_SIZE so I could keep things straighter in my head, as I was reading code. yaffs_kernel_04_disable_no_page_cache.patch Charles had mentioned that the disable no page cache feature was broken and that he should pull it out. http://www.aleph1.co.uk/pipermail/yaffs/2004q4/000747.html This patch does not actually remove the feature but just hard-codes the config option so the feature is not available. (Again, trying to make changes in a manner that would make it easy for me to move forward to later versions of the community yaffs.) yaffs_kernel_05_64bit_target.patch Changes to struct yaffs_ObjectHeader so that yaffs should work properly on a 64 bit system. This change not yet actually tested on a 64 bit system. yaffs_kernel_06_kdevname.patch kdevname in yaffs was temporarilly stubbed out for Linux > 2.6.5. This patch gets the device name via bdevname(). yaffs_kernel_07_kill_sb.patch When I umount'ed a yaffs file system, I got the error: VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... This patch removes the symptom by changing sb_kill from kill_litter_super() to kill_block_super(). I am not sure if this is actually the correct or best way to solve the underlying problem. See my post asking for advice at: http://www.aleph1.co.uk/pipermail/yaffs/2004q4/000878.html -Frank -- Frank Rowand MontaVista Software, Inc From bbeveridge@bluewatersys.com Fri Dec 17 01:25:32 2004 From: bbeveridge@bluewatersys.com (Brad Beveridge) Date: Fri, 17 Dec 2004 14:25:32 +1300 Subject: [Yaffs] yaffs kill_sb function and umount error In-Reply-To: <41C229EE.6030206@mvista.com> References: <41C229EE.6030206@mvista.com> Message-ID: <41C2358C.80408@bluewatersys.com> I have also made this change in my yaffs tree. Though the reason I made it was to support a removable nand device. Without calling kill_block_super, the MTD block device system wouldn't rmmod cleanly. I posted here about the change & more details about my situation a few weeks ago. Brad Frank Rowand wrote: > When I umount a yaffs file system on linux 2.6.9, I get the error: > > VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a > nice day... > > > In yaffs/yaffs_fs.c, I changed the .kill_sb function from > kill_litter_super() to kill_block_super(). This made the symptom > of the error message disappear. > > This area of the kernel is not my area of expertise - this was > not a fully informed fix, but more of a stab in the dark. Can > anyone provide advice on whether this is a good way to fix the > problem or whether a different approach would be more correct? > > Thanks! > > -Frank -- Bluewater Systems Ltd - ARM Technology Solution Centre Brad Beveridge Bluewater Systems Ltd Phone: +64 3 3779127 (Aus +1 800 148 751) Level 17, 119 Armagh St Fax: +64 3 3779135 PO Box 13889 Email: bbeveridge@bluewatersys.com Christchurch Web: http://www.bluewatersys.com New Zealand From Charles.Manning@trimble.co.nz Fri Dec 17 01:37:26 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Fri, 17 Dec 2004 14:37:26 +1300 Subject: [Yaffs] yaffs kill_sb function and umount error Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E015490BF@nzc-ap-xch-01.ap.trimblecorp.net> Brad Beveridge observed and tried something similar. I accepted the changes from Nick Bane in blind faith. I expect Nick lifted this from somewhere else. I'll just change as per your suggestion. If it breaks they will complain :-). -- Charles > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk=20 > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of Frank Rowand > Sent: Friday, 17 December 2004 1:36 p.m. > To: yaffs@stoneboat.aleph1.co.uk > Cc: frowand@mvista.com > Subject: [Yaffs] yaffs kill_sb function and umount error >=20 >=20 > When I umount a yaffs file system on linux 2.6.9, I get the error: >=20 > VFS: Busy inodes after unmount. Self-destruct in 5=20 > seconds. Have a nice day... >=20 >=20 > In yaffs/yaffs_fs.c, I changed the .kill_sb function from > kill_litter_super() to kill_block_super(). This made the=20 > symptom of the error message disappear. >=20 > This area of the kernel is not my area of expertise - this=20 > was not a fully informed fix, but more of a stab in the dark.=20 > Can anyone provide advice on whether this is a good way to=20 > fix the problem or whether a different approach would be more correct? >=20 > Thanks! >=20 > -Frank > --=20 > Frank Rowand > MontaVista Software, Inc >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk=20 > http://stoneboat.aleph1.co.uk/cgi-> bin/mailman/listinfo/yaffs >=20 From frowand@mvista.com Fri Dec 17 01:36:44 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:36:44 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 6 of 7 Message-ID: <41C2382C.7000306@mvista.com> This is a multi-part message in MIME format. --------------040607000007070406020601 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------040607000007070406020601 Content-Type: text/plain; name="yaffs_kernel_06_kdevname.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_06_kdevname.patch" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -54,13 +54,15 @@ #include #define UnlockPage(p) unlock_page(p) #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) -//#define kdevname(x) cdevname(to_kdev_t(x)) -#define kdevname(x) "(unavailable)" // temporary fix +#define yaffs_devname(sb, buf) bdevname(sb->s_bdev, buf) #else #include +#define BDEVNAME_SIZE 1 +#define yaffs_devname(sb, buf) kdevname(sb->s_dev) + #endif @@ -1301,6 +1303,7 @@ struct inode * inode; struct dentry * root; yaffs_Device *dev; + char bdevname_buf[BDEVNAME_SIZE]; sb->s_magic = YAFFS_MAGIC; sb->s_op = &yaffs_super_ops; @@ -1309,10 +1312,12 @@ printk(KERN_INFO"yaffs: sb is NULL\n"); else if(!sb->s_dev) printk(KERN_INFO"yaffs: sb->s_dev is NULL\n"); - else if(! kdevname(sb->s_dev)) - printk(KERN_INFO"yaffs: kdevname is NULL\n"); + else if(! yaffs_devname(sb, bdevname_buf)) + printk(KERN_INFO"yaffs: yaffs_devname is NULL\n"); else - printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, kdevname(sb->s_dev)); + printk(KERN_INFO"yaffs: dev is %u.%u name is \"%s\"\n", + MAJOR(sb->s_dev), MINOR(sb->s_dev), + yaffs_devname(sb, bdevname_buf)); @@ -1379,7 +1384,7 @@ struct mtd_info *mtd; printk(KERN_DEBUG "yaffs: Attempting MTD mount on %u.%u, \"%s\"\n", - MAJOR(sb->s_dev),MINOR(sb->s_dev),kdevname(sb->s_dev)); + MAJOR(sb->s_dev),MINOR(sb->s_dev),yaffs_devname(sb, bdevname_buf)); // Check it's an mtd device..... if(MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) --------------040607000007070406020601-- From frowand@mvista.com Fri Dec 17 01:34:53 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:34:53 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 2 of 7 Message-ID: <41C237BD.9020203@mvista.com> This is a multi-part message in MIME format. --------------040608000804060800070607 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------040608000804060800070607 Content-Type: text/plain; name="yaffs_kernel_02_fixup_in_kernel_tree.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_02_fixup_in_kernel_tree.patch" Index: linux-2.6.9/fs/Makefile =================================================================== --- linux-2.6.9.orig/fs/Makefile +++ linux-2.6.9/fs/Makefile @@ -93,3 +93,4 @@ obj-$(CONFIG_BEFS_FS) += befs/ obj-$(CONFIG_HOSTFS) += hostfs/ obj-$(CONFIG_HPPFS) += hppfs/ +obj-$(CONFIG_YAFFS_FS) += yaffs/ Index: linux-2.6.9/fs/yaffs/Makefile =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/Makefile @@ -0,0 +1,13 @@ + +# +# Makefile for the linux YAFFS filesystem routines. +# + +obj-$(CONFIG_YAFFS_FS) += yaffs.o + +# do not need to build nand_ecc.o yaffsdev.o yaffs_fileem.o yaffs-header.c + +yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o + +yaffs-$(CONFIG_YAFFS_MTD_ENABLED) += yaffs_mtdif.o +yaffs-$(CONFIG_YAFFS_RAM_ENABLED) += yaffs_ramem.o Index: linux-2.6.9/fs/Kconfig =================================================================== --- linux-2.6.9.orig/fs/Kconfig +++ linux-2.6.9/fs/Kconfig @@ -1371,6 +1371,133 @@ Say Y here if you want to try writing to UFS partitions. This is experimental, so you should back up your UFS partitions beforehand. +config YAFFS_FS + tristate "Yet Another Flash Filing System(YAFFS) file system support" + help + YAFFS, for Yet Another Flash Filing System, is a filing system + optimised for NAND Flash chips. + + To compile the YAFFS file system support as a module, choose M here: + the module will be called yaffs. + + If unsure, say N. + + Further information on YAFFS is available at + . + +config YAFFS_MTD_ENABLED + bool "NAND mtd support" + depends on YAFFS_FS + help + This adds the yaffs file system support for working with a NAND mtd. + + If unsure, say Y. + +config YAFFS_RAM_ENABLED + bool "yaffsram file system support" + depends on YAFFS_FS + help + This adds the yaffsram file system support. Nice for testing on x86, + but uses 2MB of RAM. Don't enable for NAND-based targets. + + If unsure, say N. + +comment "WARNING: mtd and/or yaffsram support should be selected" + depends on YAFFS_FS && !YAFFS_MTD_ENABLED && !YAFFS_RAM_ENABLED + +config YAFFS_USE_OLD_MTD + bool "Old mtd support" + depends on YAFFS_FS && 0 + help + Enable this to use the old MTD stuff that did not have yaffs support. + You can use this to get around compilation problems, but the best + thing to do is to upgrade your MTD support. You will get better speed. + + If unsure, say N. + +config YAFFS_USE_NANDECC + bool "Use ECC functions of the generic MTD-NAND driver" + depends on YAFFS_FS + default y + help + This enables the ECC functions of the generic MTD-NAND driver. + This will not work if you are using the old mtd. + + NB Use NAND ECC does not work at present with yaffsram. + + If unsure, say Y. + +config YAFFS_ECC_WRONG_ORDER + bool "Use the same ecc byte order as Steven Hill's nand_ecc.c" + depends on YAFFS_FS + help + This makes yaffs_ecc.c use the same ecc byte order as + Steven Hill's nand_ecc.c. If not set, then you get the + same ecc byte order as SmartMedia. + + If unsure, say N. + +config YAFFS_USE_GENERIC_RW + bool "Use Linux file caching layer" + default y + depends on YAFFS_FS + help + Use generic_read/generic_write for reading/writing files. This + enables the use of the Linux file caching layer. + + If you disable this, then caching is disabled and file read/write + is direct. + + If unsure, say Y. + +config YAFFS_USE_HEADER_FILE_SIZE + bool "Use object header size" + depends on YAFFS_FS + help + When the flash is scanned, two file sizes are constructed: + * The size taken from the object header for the file. + * The size figured out by scanning the data chunks. + If this option is enabled, then the object header size is used, + otherwise the scanned size is used. + + If unsure, say N. + +config YAFFS_DISABLE_CHUNK_ERASED_CHECK + bool "Turn off debug chunk erase check" + depends on YAFFS_FS + default y + help + Enabling this turns off the test that chunks are erased in flash + before writing to them. This is safe, since the write verification + will fail. Suggest enabling the test (ie. say N) + during development to help debug things. + + If unsure, say Y. + +#config YAFFS_DISABLE_WRITE_VERIFY +# bool "Disable write verify (DANGEROUS)" +# depends on YAFFS_FS && EXPERIMENTAL +# help +# I am severely reluctant to provide this config. Disabling the +# verification is not a good thing to do since NAND writes can +# fail silently. Disabling the write verification will cause your +# teeth to rot, rats to eat your corn and give you split ends. +# You have been warned. ie. Don't uncomment the following line. +# +# If unsure, say N. +# + +config YAFFS_SHORT_NAMES_IN_RAM + bool "Cache short names in RAM" + depends on YAFFS_FS + default y + help + If this config is set, then short names are stored with the + yaffs_Object. This costs an extra 16 bytes of RAM per object, + but makes look-ups faster. + + If unsure, say Y. + endmenu menu "Network File Systems" Index: linux-2.6.9/fs/yaffs/yaffs_ecc.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_ecc.c +++ linux-2.6.9/fs/yaffs/yaffs_ecc.c @@ -31,6 +31,7 @@ const char *yaffs_ecc_c_version = "$Id: yaffs_ecc.c,v 1.3 2004/04/04 03:47:02 charles Exp $"; +#include #include "yaffs_ecc.h" Index: linux-2.6.9/fs/yaffs/yaffs_guts.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_guts.c +++ linux-2.6.9/fs/yaffs/yaffs_guts.c @@ -16,6 +16,8 @@ const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $"; +#include + #include "yportenv.h" #include "yaffsinterface.h" Index: linux-2.6.9/fs/yaffs/yaffs_ramem.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_ramem.c +++ linux-2.6.9/fs/yaffs/yaffs_ramem.c @@ -17,6 +17,8 @@ const char *yaffs_ramem_c_version = "$Id: yaffs_ramem.c,v 1.6 2002/11/26 01:15:37 charles Exp $"; +#include + #ifndef __KERNEL__ #define CONFIG_YAFFS_RAM_ENABLED #endif Index: linux-2.6.9/fs/yaffs/yaffs_mtdif.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_mtdif.c +++ linux-2.6.9/fs/yaffs/yaffs_mtdif.c @@ -15,6 +15,8 @@ const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.10 2004/09/19 08:14:50 charles Exp $"; +#include + #ifdef CONFIG_YAFFS_MTD_ENABLED #include "yportenv.h" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -1301,7 +1301,11 @@ #ifdef CONFIG_YAFFS_RAM_ENABLED // Set the yaffs_Device up for ram emulation +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); +#else sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); +#endif if(!dev) { // Deep shit could not allocate device structure @@ -1525,13 +1529,15 @@ /* changes NCB 2.5.70 */ //static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV); -static struct file_system_type yaffs_fs_type = { +static struct file_system_type yaffs_ram_fs_type = { .owner = THIS_MODULE, .name = "yaffsram", .get_sb = yaffs_ram_read_super, // .kill_sb = kill_block_super, .kill_sb = kill_litter_super, +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) .fs_flags = FS_SINGLE, +#endif }; #else static struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent) --------------040608000804060800070607-- From frowand@mvista.com Fri Dec 17 01:35:17 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:35:17 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 3 of 7 Message-ID: <41C237D5.6010708@mvista.com> This is a multi-part message in MIME format. --------------090409070607060904070109 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------090409070607060904070109 Content-Type: text/plain; name="yaffs_kernel_03_fix_warnings.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_03_fix_warnings.patch" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -103,7 +103,9 @@ static void yaffs_put_super(struct super_block *sb); +#if !defined(CONFIG_YAFFS_USE_GENERIC_RW) static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos); +#endif static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos); static int yaffs_file_flush(struct file* file); @@ -141,19 +143,25 @@ #endif static void yaffs_read_inode (struct inode *inode); +#ifdef CONFIG_YAFFS_MTD_ENABLED //#if defined(CONFIG_KERNEL_2_5) #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) static struct super_block *yaffs_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data); #else static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent); #endif +#endif static void yaffs_put_inode (struct inode *inode); static void yaffs_delete_inode(struct inode *); static void yaffs_clear_inode(struct inode *); static int yaffs_readpage(struct file *file, struct page * page); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_writepage(struct page *page, struct writeback_control *wbc); +#else static int yaffs_writepage(struct page *page); +#endif static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to); static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to); @@ -499,7 +507,11 @@ // writepage inspired by/stolen from smbfs // +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_writepage(struct page *page, struct writeback_control *wbc) +#else static int yaffs_writepage(struct page *page) +#endif { struct address_space *mapping = page->mapping; struct inode *inode; @@ -677,6 +689,7 @@ return inode; } +#if !defined(CONFIG_YAFFS_USE_GENERIC_RW) static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) { yaffs_Object *obj; @@ -720,6 +733,7 @@ return nRead; } +#endif static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos) @@ -1330,6 +1344,10 @@ yaffsram_dev = dev; +#else + /* Resolve compile warning that dev might not be initialized. */ + printk(KERN_ERR "yaffs: not RAM_ENABLED but useRam true"); + return NULL; #endif } @@ -1438,6 +1456,10 @@ yaffs_dev = dev; +#else + /* Resolve compile warning that dev might not be initialized. */ + printk(KERN_ERR "yaffs: not MTD_ENABLED but useRam false"); + return NULL; #endif } @@ -1478,14 +1500,19 @@ return sb; } +#ifdef CONFIG_YAFFS_RAM_ENABLED static int yaffs_internal_read_super_ram(struct super_block * sb, void * data, int silent) { return yaffs_internal_read_super(1,sb,data,silent) ? 0 : -1; } +#endif + +#ifdef CONFIG_YAFFS_MTD_ENABLED static int yaffs_internal_read_super_mtd(struct super_block * sb, void * data, int silent) { return yaffs_internal_read_super(0,sb,data,silent) ? 0 : -1; } +#endif #ifdef CONFIG_YAFFS_MTD_ENABLED @@ -1551,7 +1578,9 @@ static struct proc_dir_entry *my_proc_entry; +#if 0 static struct proc_dir_entry *my_proc_ram_write_entry; +#endif static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name) { @@ -1616,6 +1645,7 @@ } +#if 0 static int yaffs_proc_ram_write( char *page, char **start, @@ -1629,6 +1659,7 @@ printk(KERN_DEBUG "yaffs write size %d\n",count); return count; } +#endif static int __init init_yaffs_fs(void) { Index: linux-2.6.9/fs/yaffs/yaffs_guts.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_guts.c +++ linux-2.6.9/fs/yaffs/yaffs_guts.c @@ -69,7 +69,7 @@ // Local prototypes -static int yaffs_CheckObjectHashSanity(yaffs_Device *dev); +static void yaffs_CheckObjectHashSanity(yaffs_Device *dev); static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr); static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr); static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan); @@ -92,7 +92,9 @@ static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare); static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_Spare *spare); +#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND); +#endif static int yaffs_UnlinkWorker(yaffs_Object *obj); static void yaffs_AbortHalfCreatedObject(yaffs_Object *obj); @@ -118,6 +120,18 @@ static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in); static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId); + +#undef DEBUG_OBJECT_TEST +#ifndef DEBUG_OBJECT_TEST +static __inline__ void yaffs_CheckObjectHashSanity(yaffs_Device *dev) +{ +} + +void __inline__ yaffs_ObjectTest(yaffs_Device *dev) +{ +} +#endif + // Chunk bitmap manipulations static __inline __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk) @@ -316,6 +330,7 @@ } +#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND) { @@ -340,6 +355,7 @@ return YAFFS_OK; } +#endif @@ -452,6 +468,7 @@ +#if 0 static int yaffs_RewriteBufferedBlock(yaffs_Device *dev) { dev->doingBufferedBlockRewrite = 1; @@ -464,6 +481,7 @@ return 1; } +#endif static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND) @@ -480,10 +498,11 @@ // NB recursion } - +#if 0 static void yaffs_CheckWrittenBlock(yaffs_Device *dev,int chunkInNAND) { } +#endif static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare) { @@ -1118,12 +1137,8 @@ static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset) { int i; - int chunkInInode; int theChunk; yaffs_BlockInfo *theBlock; - yaffs_Tags tags; - int found; - int chunkDeleted; int allDone = 1; @@ -1571,7 +1586,7 @@ __u32 n = (__u32)bucket; - //yaffs_CheckObjectHashSanity(); + yaffs_CheckObjectHashSanity(dev); while(!found) { @@ -1914,7 +1929,8 @@ -static int yaffs_CheckObjectHashSanity(yaffs_Device *dev) +#ifdef DEBUG_OBJECT_TEST +static void yaffs_CheckObjectHashSanity(yaffs_Device *dev) { // Scan the buckets and check that the lists // have as many members as the count says there are @@ -1938,11 +1954,8 @@ ok = YAFFS_FAIL; } } - - return ok; } -#if 0 void yaffs_ObjectTest(yaffs_Device *dev) { yaffs_Object *in[1000]; @@ -1998,7 +2011,6 @@ } } - #endif /////////////////////////// Block Management and Page Allocation /////////////////// @@ -2338,6 +2350,7 @@ } +#if 0 static yaffs_Object *yaffs_FindDeletedUnlinkedFile(yaffs_Device *dev) { // find a file to delete @@ -2359,8 +2372,10 @@ } return NULL; } +#endif +#if 0 static void yaffs_DoUnlinkedFileDeletion(yaffs_Device *dev) { // This does background deletion on unlinked files.. only deleted ones. @@ -2396,6 +2411,7 @@ } } } +#endif #if 0 @@ -3139,13 +3155,16 @@ int i; yaffs_ChunkCache *cache; int chunkWritten; +#if 0 int nBytes; +#endif int nCaches = obj->myDev->nShortOpCaches; if (nCaches > 0) { do{ cache = NULL; + lowest = YAFFS_MAX_CHUNK_ID; /* eliminate compile warning */ // Find the dirty cache for this object with the lowest chunk id. for(i = 0; i < nCaches; i++) Index: linux-2.6.9/fs/yaffs/yaffs_fileem.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fileem.c +++ linux-2.6.9/fs/yaffs/yaffs_fileem.c @@ -30,10 +30,10 @@ // #define YAFFS_ERROR_TESTING -#define BLOCK_SIZE (32 * 528) +#define NAND_BLOCK_SIZE (32 * 528) #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) #define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG) -#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE) +#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * NAND_BLOCK_SIZE) static int h; @@ -250,7 +250,7 @@ printf("Erasing block %d\n",blockInNAND); } - lseek(h,blockInNAND * BLOCK_SIZE,SEEK_SET); + lseek(h,blockInNAND * NAND_BLOCK_SIZE,SEEK_SET); for(i = 0; i < 32; i++) { write(h,ffChunk,528); Index: linux-2.6.9/fs/yaffs/yaffs_ramem.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_ramem.c +++ linux-2.6.9/fs/yaffs/yaffs_ramem.c @@ -35,10 +35,10 @@ #define EM_SIZE_IN_MEG 2 -#define BLOCK_SIZE (32 * 528) +#define NAND_BLOCK_SIZE (32 * 528) #define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) #define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG) -#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE) +#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * NAND_BLOCK_SIZE) Index: linux-2.6.9/fs/yaffs/devextras.h =================================================================== --- linux-2.6.9.orig/fs/yaffs/devextras.h +++ linux-2.6.9/fs/yaffs/devextras.h @@ -201,6 +201,7 @@ +#ifndef DT_UNKNOWN /* * File types */ @@ -213,6 +214,7 @@ #define DT_LNK 10 #define DT_SOCK 12 #define DT_WHT 14 +#endif #ifndef WIN32 #include --------------090409070607060904070109-- From frowand@mvista.com Fri Dec 17 01:35:48 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:35:48 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 4 of 7 Message-ID: <41C237F4.6010302@mvista.com> This is a multi-part message in MIME format. --------------090906000504000501060502 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------090906000504000501060502 Content-Type: text/plain; name="yaffs_kernel_04_disable_no_page_cache.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_04_disable_no_page_cache.patch" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -103,6 +103,28 @@ static void yaffs_put_super(struct super_block *sb); +/* + * http://www.aleph1.co.uk/pipermail/yaffs/2004q4/000747.html + * + * from: Charles Manning Charles.Manning@trimble.co.nz + * subject: [Yaffs] CONFIG_YAFFS_USE_GENERIC_RW + * date: Thu, 14 Oct 2004 12:12:36 +1300 + * + * The direct read/write stuff was iimplemented first, and I followed it by + * generic read/write when memory mapping was implemented. During the + * transition both options worked. Things have now moved on and not + * defining USE_GENERIC_RW is broken, with no real motivation to fix it. + * + * Ie. You should always define USE_GENERIC_RW. + * + * This comes up every couple of months on the list. I guess I should pull + * it out. + * + * -- Charles + */ + +#define CONFIG_YAFFS_USE_GENERIC_RW + #if !defined(CONFIG_YAFFS_USE_GENERIC_RW) static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos); #endif Index: linux-2.6.9/fs/Kconfig =================================================================== --- linux-2.6.9.orig/fs/Kconfig +++ linux-2.6.9/fs/Kconfig @@ -1437,19 +1437,6 @@ If unsure, say N. -config YAFFS_USE_GENERIC_RW - bool "Use Linux file caching layer" - default y - depends on YAFFS_FS - help - Use generic_read/generic_write for reading/writing files. This - enables the use of the Linux file caching layer. - - If you disable this, then caching is disabled and file read/write - is direct. - - If unsure, say Y. - config YAFFS_USE_HEADER_FILE_SIZE bool "Use object header size" depends on YAFFS_FS --------------090906000504000501060502-- From frowand@mvista.com Fri Dec 17 01:36:15 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:36:15 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 5 of 7 Message-ID: <41C2380F.5080603@mvista.com> This is a multi-part message in MIME format. --------------020704000600000000010202 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------020704000600000000010202 Content-Type: text/plain; name="yaffs_kernel_05_64bit_target.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_05_64bit_target.patch" Index: linux-2.6.9/fs/yaffs/yaffs_guts.h =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_guts.h +++ linux-2.6.9/fs/yaffs/yaffs_guts.h @@ -181,16 +181,17 @@ YAFFS_OBJECT_TYPE_DIRECTORY, YAFFS_OBJECT_TYPE_HARDLINK, YAFFS_OBJECT_TYPE_SPECIAL -} yaffs_ObjectType; +} yaffs_ObjectType __attribute__ ((__mode__ (__SI__))); typedef struct { yaffs_ObjectType type; // Apply to everything - int parentObjectId; + __s32 parentObjectId; __u16 sum__NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies char name[YAFFS_MAX_NAME_LENGTH + 1]; + char pad[2]; // Thes following apply to directories, files, symlinks - not hard links __u32 st_mode; // protection @@ -206,10 +207,10 @@ #endif // File size applies to files only - int fileSize; + __s32 fileSize; // Equivalent object id applies to hard links only. - int equivalentObjectId; + __s32 equivalentObjectId; // Alias is for symlinks only. char alias[YAFFS_MAX_ALIAS_LENGTH + 1]; --------------020704000600000000010202-- From frowand@mvista.com Fri Dec 17 01:36:54 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:36:54 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 7 of 7 Message-ID: <41C23836.3060600@mvista.com> This is a multi-part message in MIME format. --------------030005090305020308040704 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------030005090305020308040704 Content-Type: text/plain; name="yaffs_kernel_07_kill_sb.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_07_kill_sb.patch" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -1557,8 +1557,10 @@ .owner = THIS_MODULE, .name = "yaffs", .get_sb = yaffs_read_super, -// .kill_sb = kill_block_super, - .kill_sb = kill_litter_super, + .kill_sb = kill_block_super, +// using kill_litter_super() results in error on umount: +// VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... +// .kill_sb = kill_litter_super, .fs_flags = FS_REQUIRES_DEV, }; #else @@ -1587,8 +1589,10 @@ .owner = THIS_MODULE, .name = "yaffsram", .get_sb = yaffs_ram_read_super, -// .kill_sb = kill_block_super, - .kill_sb = kill_litter_super, + .kill_sb = kill_block_super, +// using kill_litter_super() results in error on umount: +// VFS: Busy inodes after unmount. Self-destruct in 5 seconds. Have a nice day... +// .kill_sb = kill_litter_super, #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,0)) .fs_flags = FS_SINGLE, #endif --------------030005090305020308040704-- From manningc2@actrix.gen.nz Fri Dec 17 04:46:39 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 17 Dec 2004 17:46:39 +1300 Subject: [Yaffs] YAFFS2 on Linux checked in Message-ID: <20041217044113.5B0BD512E@blood.actrix.co.nz> The YAFFS2 for Linux stuff to work with mtd is now checked in. I have tested this with a mtd "device" that is actually ram dressed up to= =20 look like nand. Let the sports begin! -- Charles From jnewell@wgate.com Fri Dec 17 16:01:57 2004 From: jnewell@wgate.com (James Newell) Date: Fri, 17 Dec 2004 11:01:57 -0500 Subject: [Yaffs] YAFFS2 on Linux checked in Message-ID: <42C66B69F1F5D411B99300508BAC45460DB095CA@mail.tvol.net> This message is in MIME format. Since your mail reader does not understand this format, some or all of this message may not be legible. ------_=_NextPart_000_01C4E451.BC0C1990 Content-Type: multipart/alternative; boundary="----_=_NextPart_001_01C4E451.BC0C1990" ------_=_NextPart_001_01C4E451.BC0C1990 Content-Type: text/plain; charset="windows-1252" Using the attached Makefile (for a Montavista 2.4.18 xscale kernel) from the original yaffs Makefile. I don't have the new MTD working with this kernel (I don't have a choice to upgrade to a new kernel either). So, I patched the yaffs_fs.c file, and only used the yaffs_mtdif.c (not sure if this will break anything yet). It compiles now with warnings. I will look into the warnings first then give it a try on my target machine. I've included the small patch, and the Makefile (you will have to modify it to work in your build system). Jim Newell [jnewell@ya yaffs2]$ make xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_fs.c -o yaffs_fs.o yaffs_fs.c: In function `yaffs_internal_read_super': yaffs_fs.c:1411: warning: unsigned int format, pointer arg (arg 2) yaffs_fs.c:1412: warning: unsigned int format, pointer arg (arg 2) yaffs_fs.c:1413: warning: unsigned int format, pointer arg (arg 2) yaffs_fs.c:1414: warning: unsigned int format, pointer arg (arg 2) yaffs_fs.c:1415: warning: unsigned int format, pointer arg (arg 2) yaffs_fs.c:1512: warning: assignment from incompatible pointer type yaffs_fs.c:1526: warning: assignment from incompatible pointer type yaffs_fs.c:1296: warning: `dev' might be used uninitialized in this function yaffs_fs.c: At top level: yaffs_fs.c:1586: warning: `yaffs_internal_read_super_ram' defined but not used yaffs_fs.c:1590: warning: `yaffs_internal_read_super_mtd' defined but not used yaffs_fs.c:1595: warning: `yaffs2_internal_read_super_ram' defined but not used yaffs_fs.c:1599: warning: `yaffs2_internal_read_super_mtd' defined but not used yaffs_fs.c:1727: warning: `my_proc_ram_write_entry' defined but not used yaffs_fs.c:1801: warning: `yaffs_proc_ram_write' defined but not used xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_guts.c - o yaffs_guts.o yaffs_guts.c: In function `yaffs_FlushFilesChunkCache': yaffs_guts.c:3491: warning: `lowest' might be used uninitialized in this function yaffs_guts.c:3494: warning: `chunkWritten' might be used uninitialized in this function yaffs_guts.c: At top level: yaffs_guts.c:68: warning: `yaffs_CountBits' defined but not used yaffs_guts.c:2015: warning: `yaffs_CheckObjectHashSanity' defined but not used yaffs_guts.c:598: warning: `yaffs_HandleReadDataError' defined but not used yaffs_guts.c:584: warning: `yaffs_RewriteBufferedBlock' defined but not used yaffs_guts.c:613: warning: `yaffs_CheckWrittenBlock' defined but not used yaffs_guts.c:2313: warning: `yaffs_DumpBlockStats' defined but not used xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_ramem.c -o yaffs_ramem.o xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_mtdif.c -o yaffs_mtdif.o xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_ecc.c -o yaffs_ecc.o xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_packedta gs1.c -o yaffs_packedtags1.o xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_packedta gs2.c -o yaffs_packedtags2.o yaffs_packedtags2.c: In function `yaffs_UnpackTags2': yaffs_packedtags2.c:45: warning: passing arg 3 of `yaffs_ECCCorrectOther' discards qualifiers from pointer target type xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_ramem2k. c -o yaffs_ramem2k.o xscale_be-gcc -c -D__KERNEL__ -DMODULE -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER IC_RW -DCONFIG_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD -I../../kernel/include -O2 -Wall yaffs_tagscomp at.c -o yaffs_tagscompat.o yaffs_tagscompat.c:484: warning: `yaffs_CheckWrittenBlock' defined but not used yaffs_tagscompat.c:488: warning: `yaffs_HandleWriteChunkOk' defined but not used yaffs_tagscompat.c:492: warning: `yaffs_HandleUpdateChunk' defined but not used yaffs_tagscompat.c:496: warning: `yaffs_HandleWriteChunkError' defined but not used yaffs_tagscompat.c:311: warning: `yaffs_CheckChunkErased' defined but not used yaffs_tagscompat.c:509: warning: `yaffs_VerifyCompare' defined but not used xscale_be-ld -r yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o yaffs_ecc.o yaffs_packedtags1.o yaffs_packedtags2.o yaffs_ramem2k.o yaff s_tagscompat.o -o yaffs2.o mkdir -p /usr/proj/ojopvp/dev_jnewell/utils/install-bin cp -p yaffs2.o /usr/proj/ojopvp/dev_jnewell/utils/install-bin -----Original Message----- From: Charles Manning [mailto:manningc2@actrix.gen.nz] Sent: Thursday, December 16, 2004 11:47 PM To: yaffs@lists.aleph1.co.uk Subject: [Yaffs] YAFFS2 on Linux checked in The YAFFS2 for Linux stuff to work with mtd is now checked in. I have tested this with a mtd "device" that is actually ram dressed up to look like nand. Let the sports begin! -- Charles _______________________________________________ yaffs mailing list yaffs@stoneboat.aleph1.co.uk http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs --- Incoming mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.804 / Virus Database: 546 - Release Date: 11/30/2004 --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.804 / Virus Database: 546 - Release Date: 11/30/2004 ------_=_NextPart_001_01C4E451.BC0C1990 Content-Type: text/html; charset="windows-1252" Content-Transfer-Encoding: quoted-printable RE: [Yaffs] YAFFS2 on Linux checked in

Using the attached Makefile (for a Montavista 2.4.18 = xscale kernel) from the original yaffs Makefile.
I don't have the new MTD working with this kernel (I = don't have a choice to upgrade to a new kernel either).  So, I = patched the yaffs_fs.c file, and only used the yaffs_mtdif.c (not sure = if this will break anything yet). 

It compiles now with warnings.  I will look into = the warnings first then give it a try on my target machine.

I've included the small patch, and the Makefile (you = will have to modify it to work in your build system).

Jim Newell

[jnewell@ya yaffs2]$ make
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_fs.c -o

yaffs_fs.o
yaffs_fs.c: In function = `yaffs_internal_read_super':
yaffs_fs.c:1411: warning: unsigned int format, = pointer arg (arg 2)
yaffs_fs.c:1412: warning: unsigned int format, = pointer arg (arg 2)
yaffs_fs.c:1413: warning: unsigned int format, = pointer arg (arg 2)
yaffs_fs.c:1414: warning: unsigned int format, = pointer arg (arg 2)
yaffs_fs.c:1415: warning: unsigned int format, = pointer arg (arg 2)
yaffs_fs.c:1512: warning: assignment from = incompatible pointer type
yaffs_fs.c:1526: warning: assignment from = incompatible pointer type
yaffs_fs.c:1296: warning: `dev' might be used = uninitialized in this function
yaffs_fs.c: At top level:
yaffs_fs.c:1586: warning: = `yaffs_internal_read_super_ram' defined but not used
yaffs_fs.c:1590: warning: = `yaffs_internal_read_super_mtd' defined but not used
yaffs_fs.c:1595: warning: = `yaffs2_internal_read_super_ram' defined but not used
yaffs_fs.c:1599: warning: = `yaffs2_internal_read_super_mtd' defined but not used
yaffs_fs.c:1727: warning: `my_proc_ram_write_entry' = defined but not used
yaffs_fs.c:1801: warning: `yaffs_proc_ram_write' = defined but not used
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_guts.c -

o yaffs_guts.o
yaffs_guts.c: In function = `yaffs_FlushFilesChunkCache':
yaffs_guts.c:3491: warning: `lowest' might be used = uninitialized in this function
yaffs_guts.c:3494: warning: `chunkWritten' might be = used uninitialized in this function
yaffs_guts.c: At top level:
yaffs_guts.c:68: warning: `yaffs_CountBits' defined = but not used
yaffs_guts.c:2015: warning: = `yaffs_CheckObjectHashSanity' defined but not used
yaffs_guts.c:598: warning: = `yaffs_HandleReadDataError' defined but not used
yaffs_guts.c:584: warning: = `yaffs_RewriteBufferedBlock' defined but not used
yaffs_guts.c:613: warning: `yaffs_CheckWrittenBlock' = defined but not used
yaffs_guts.c:2313: warning: `yaffs_DumpBlockStats' = defined but not used
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_ramem.c

-o yaffs_ramem.o
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_mtdif.c

-o yaffs_mtdif.o
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_ecc.c -o

 yaffs_ecc.o
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_packedta

gs1.c -o yaffs_packedtags1.o
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_packedta

gs2.c -o yaffs_packedtags2.o
yaffs_packedtags2.c: In function = `yaffs_UnpackTags2':
yaffs_packedtags2.c:45: warning: passing arg 3 of = `yaffs_ECCCorrectOther' discards qualifiers from pointer target = type
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_ramem2k.

c -o yaffs_ramem2k.o
xscale_be-gcc -c -D__KERNEL__ -DMODULE = -DCONFIG_YAFFS_YAFFS2 -DCONFIG_YAFFS2_RAM_ENABLED = -DCONFIG_YAFFS_MTD_ENABLED -DCONFIG_YAFFS_USE_GENER

IC_RW    -DCONFIG_SHORT_NAMES_IN_RAM = -DCONFIG_YAFFS_USE_NANDECC -DCONFIG_YAFFS_USE_OLD_MTD   = -I../../kernel/include -O2 -Wall yaffs_tagscomp

at.c -o yaffs_tagscompat.o
yaffs_tagscompat.c:484: warning: = `yaffs_CheckWrittenBlock' defined but not used
yaffs_tagscompat.c:488: warning: = `yaffs_HandleWriteChunkOk' defined but not used
yaffs_tagscompat.c:492: warning: = `yaffs_HandleUpdateChunk' defined but not used
yaffs_tagscompat.c:496: warning: = `yaffs_HandleWriteChunkError' defined but not used
yaffs_tagscompat.c:311: warning: = `yaffs_CheckChunkErased' defined but not used
yaffs_tagscompat.c:509: warning: = `yaffs_VerifyCompare' defined but not used
xscale_be-ld -r yaffs_fs.o yaffs_guts.o = yaffs_ramem.o yaffs_mtdif.o yaffs_ecc.o yaffs_packedtags1.o = yaffs_packedtags2.o yaffs_ramem2k.o yaff

s_tagscompat.o -o yaffs2.o
mkdir -p = /usr/proj/ojopvp/dev_jnewell/utils/install-bin
cp -p yaffs2.o = /usr/proj/ojopvp/dev_jnewell/utils/install-bin  

-----Original Message-----
From: Charles Manning [mailto:manningc2@actrix.gen.nz]
Sent: Thursday, December 16, 2004 11:47 PM
To: yaffs@lists.aleph1.co.uk
Subject: [Yaffs] YAFFS2 on Linux checked in

The YAFFS2 for Linux stuff to work with mtd is now = checked in.

I have tested this with a mtd "device" that = is actually ram dressed up to look like nand.

Let the sports begin!

-- Charles

_______________________________________________
yaffs mailing list
yaffs@stoneboat.aleph1.co.uk
http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo= /yaffs

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.804 / Virus Database: 546 - Release = Date: 11/30/2004
 

---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.804 / Virus Database: 546 - Release Date: 11/30/2004
 
   =20

  ------_=_NextPart_001_01C4E451.BC0C1990-- ------_=_NextPart_000_01C4E451.BC0C1990 Content-Type: application/octet-stream; name="Makefile" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="Makefile" #Makefile for YAFFS as a module=0A= #=0A= # NB this is not yet suitable for putting into the kernel tree.=0A= # YAFFS: Yet another FFS. A NAND-flash specific file system. =0A= #=0A= # Copyright (C) 2002 Aleph One Ltd.=0A= # for Toby Churchill Ltd and Brightstar Engineering=0A= #=0A= # Created by Charles Manning =0A= #=0A= # This program is free software; you can redistribute it and/or = modify=0A= # it under the terms of the GNU General Public License version 2 as=0A= # published by the Free Software Foundation.=0A= #=0A= # $Id: Makefile,v 1.2 2004/08/12 21:29:27 jwurtz Exp $=0A= #=0A= =0A= ## Change or override KERNELDIR to your kernel=0A= ## comment out USE_xxxx if you don't want these features.=0A= =0A= KERNELDIR =3D ../../kernel=0A= =0A= =0A= REVHOME :=3D ../../..=0A= USES =3D $(REVHOME)/uses=0A= include $(USES)=0A= =0A= FLASHIU_TOOLS_D =3D $(REVHOME)/utils/install-bin=0A= =0A= ## Change if you are using a cross-compiler=0A= MAKETOOLS =3D xscale_be-=0A= =0A= CC=3D$(MAKETOOLS)gcc=0A= LD=3D$(MAKETOOLS)ld=0A= =0A= # Configurations...=0A= # Comment out the stuff you don't want.=0A= #=0A= =0A= # CONFIG_YAFFS_YAFFS2=0A= USE_YAFFS_VERSION =3D -DCONFIG_YAFFS_YAFFS2=0A= =0A= # CONFIG_YAFFS_RAM_ENABLED.=0A= # This adds the yaffsram file system support. Nice for testing on x86, = but uses 2MB of RAM.=0A= # Don't enable for NAND-based targets.=0A= =0A= USE_RAM_FOR_TEST =3D -DCONFIG_YAFFS2_RAM_ENABLED=0A= =0A= =0A= # CONFIG_YAFFS_MTD_ENABLED.=0A= # This adds the yaffs file system support for working with a NAND = mtd.=0A= =0A= USE_MTD =3D -DCONFIG_YAFFS_MTD_ENABLED=0A= =0A= # CONFIG_YAFFS_USE_OLD_MTD=0A= # Enable this to use the old MTD stuff that did not have yaffs = support.=0A= # You can use this to get around compilation problems, but the best=0A= # thing to do is to upgrade your MTD support. You will get better = speed.=0A= =0A= USE_OLD_MTD =3D -DCONFIG_YAFFS_USE_OLD_MTD=0A= =0A= USE_MTDIF =3D yaffs_mtdif.o=0A= =0A= # CONFIG_YAFFS_USE_NANDECC=0A= # This enables the ECC functions of the generic MTD-NAND driver.=0A= # This will not work if you are using the old mtd.=0A= #=0A= # NB UseNANDECC does not work at present with yaffsram.=0A= =0A= USE_NANDECC =3D -DCONFIG_YAFFS_USE_NANDECC=0A= =0A= # CONFIG_YAFFS_ECC_WRONG_ORDER=0A= # This makes yaffs_ecc.c use the same ecc byte order as=0A= # Steven Hill's nand_ecc.c. If not set, then you get the=0A= # same ecc byte order as SmartMedia.=0A= =0A= #USE_WRONGECC =3D -DCONFIG_YAFFS_ECC_WRONG_ORDER=0A= =0A= # CONFIG_YAFFS_USE_GENERIC_RW=0A= # Use generic_read/generic_write for reading/writing files. This = enables the use of the Linux=0A= # file caching layer.=0A= #=0A= # If you disable this, then caching is disabled and file read/write is = direct.=0A= =0A= USE_GENERIC_RW =3D -DCONFIG_YAFFS_USE_GENERIC_RW=0A= =0A= # CONFIG_YAFFS_USE_HEADER_FILE_SIZE=0A= # When the flash is scanned, two file sizes are constructed:=0A= # * The size taken from the object header for the file.=0A= # * The size figured out by scanning the data chunks.=0A= # If this option is enabled, then the object header size is used, = otherwise the scanned size is used.=0A= # Suggest leaving this disabled.=0A= =0A= #USE_HEADER_FILE_SIZE =3D -DCONFIG_YAFFS_USE_HEADER_FILE_SIZE=0A= =0A= #CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=0A= # Enabling this turns off the test that chunks are erased in flash = before writing to them.=0A= # this is safe, since the write verification will fail.=0A= # Suggest enabling the test (ie. keep the following line commented) = during development to help debug things.=0A= =0A= #IGNORE_CHUNK_ERASED =3D -DCONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK=0A= =0A= #CONFIG_YAFFS_DISABLE_WRITE_VERIFY=0A= # I am severely reluctant to provide this config. Disabling the = verification is not a good thing to do=0A= # since NAND writes can fail silently.=0A= # Disabling the write verification will cause your teeth to rot, rats = to eat your corn and give you split ends.=0A= # You have been warned. ie. Don't uncomment the following line.=0A= =0A= #IGNORE_WRITE_VERIFY =3D -DCONFIG_YAFFS_DISBLE_WRITE_VERIFY=0A= =0A= #CONFIG_YAFFS_SHORT_NAMES_IN_RAM=0A= # If this config is set, then short names are stored with the = yaffs_Object=0A= # This costs an extra 16 bytes of RAM per object, but makes look-ups = faster.=0A= =0A= ENABLE_SHORT_NAMES_IN_RAM =3D -DCONFIG_SHORT_NAMES_IN_RAM=0A= =0A= # End of configuration options.=0A= =0A= YAFFS_CONFIGS =3D $(USE_YAFFS_VERSION) \=0A= $(USE_RAM_FOR_TEST) \=0A= $(USE_MTD) \=0A= $(USE_GENERIC_RW) \=0A= $(USE_HEADER_FILE_SIZE) \=0A= $(IGNORE_CHUNK_ERASED) \=0A= $(IGNORE_WRITE_VERIFY) \=0A= $(ENABLE_SHORT_NAMES_IN_RAM) \=0A= $(USE_NANDECC) \=0A= $(USE_OLD_MTD) \=0A= $(USE_WRONGECC)=0A= =0A= CFLAGS =3D -D__KERNEL__ -DMODULE $(YAFFS_CONFIGS) = -I$(KERNELDIR)/include -O2 -Wall=0A= =0A= =0A= OBJS =3D yaffs_fs.o \=0A= yaffs_guts.o \=0A= yaffs_ramem.o \=0A= $(USE_MTDIF) \=0A= yaffs_ecc.o \=0A= yaffs_packedtags1.o \=0A= yaffs_packedtags2.o \=0A= yaffs_ramem2k.o \=0A= yaffs_tagscompat.o=0A= =0A= install: all=0A= mkdir -p $(FLASHIU_TOOLS_D)=0A= cp -p yaffs2.o $(FLASHIU_TOOLS_D)=0A= =0A= all: yaffs2.o=0A= =0A= $(OBJS): %.o: %.c Makefile=0A= $(CC) -c $(CFLAGS) $< -o $@=0A= =0A= yaffs2.o: $(OBJS)=0A= $(LD) -r $(OBJS) -o $@=0A= =0A= clean:=0A= rm -f $(OBJS) corei yaffs2.o=0A= =0A= ------_=_NextPart_000_01C4E451.BC0C1990 Content-Type: application/octet-stream; name="yaffs_fs.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="yaffs_fs.diff" Index: yaffs_fs.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /home/aleph1/cvs/yaffs2/yaffs_fs.c,v=0A= retrieving revision 1.1=0A= diff -c -r1.1 yaffs_fs.c=0A= *** yaffs_fs.c 17 Dec 2004 04:39:04 -0000 1.1=0A= --- yaffs_fs.c 17 Dec 2004 15:58:28 -0000=0A= ***************=0A= *** 1413,1420 ****=0A= T(YAFFS_TRACE_OS,(" write %x\n",mtd->write));=0A= T(YAFFS_TRACE_OS,(" readoob %x\n",mtd->read_oob));=0A= T(YAFFS_TRACE_OS,(" writeoob %x\n",mtd->write_oob));=0A= ! T(YAFFS_TRACE_OS,(" block_isbad %x\n",mtd->block_isbad));=0A= T(YAFFS_TRACE_OS,(" block_markbad %x\n",mtd->block_markbad));=0A= T(YAFFS_TRACE_OS,(" oobblock %d\n",mtd->oobblock));=0A= T(YAFFS_TRACE_OS,(" oobsize %d\n",mtd->oobsize));=0A= T(YAFFS_TRACE_OS,(" erasesize %d\n",mtd->erasesize));=0A= --- 1413,1422 ----=0A= T(YAFFS_TRACE_OS,(" write %x\n",mtd->write));=0A= T(YAFFS_TRACE_OS,(" readoob %x\n",mtd->read_oob));=0A= T(YAFFS_TRACE_OS,(" writeoob %x\n",mtd->write_oob));=0A= ! #ifndef CONFIG_YAFFS_USE_OLD_MTD =0A= ! T(YAFFS_TRACE_OS,(" block_isbad %x\n",mtd->block_isbad));=0A= T(YAFFS_TRACE_OS,(" block_markbad %x\n",mtd->block_markbad));=0A= + #endif=0A= T(YAFFS_TRACE_OS,(" oobblock %d\n",mtd->oobblock));=0A= T(YAFFS_TRACE_OS,(" oobsize %d\n",mtd->oobsize));=0A= T(YAFFS_TRACE_OS,(" erasesize %d\n",mtd->erasesize));=0A= ***************=0A= *** 1424,1431 ****=0A= --- 1426,1435 ----=0A= {=0A= // Check for version 2 style functions=0A= if(!mtd->erase ||=0A= + #ifndef CONFIG_YAFFS_USE_OLD_MTD=0A= !mtd->block_isbad ||=0A= !mtd->block_markbad ||=0A= + #endif=0A= !mtd->read ||=0A= !mtd->write ||=0A= #ifndef CONFIG_YAFFS_USE_OLD_MTD=0A= ------_=_NextPart_000_01C4E451.BC0C1990-- From frowand@mvista.com Fri Dec 17 22:34:42 2004 From: frowand@mvista.com (Frank Rowand) Date: Fri, 17 Dec 2004 14:34:42 -0800 Subject: [Yaffs] Re: set of patches for yaffs on Linux 2.6.9 In-Reply-To: <41C236CE.6000609@mvista.com> References: <41C236CE.6000609@mvista.com> Message-ID: <41C35F02.6040006@mvista.com> Frank Rowand wrote: > I am submitting a set of patches that enabled me to get yaffs > working on Linux 2.6.9. (Not vanilla 2.6.9, but 2.6.9 plus > a few changes, but I don't think the changes matter in this > context.) > > Please add any of these changes back into yaffs as appropriate, > and provide comments as needed. > > I have compiled for x86 RAM based yaffs (but not tested) and > for ARM little endian MTD based yaffs. I have compiled as > in-kernel and as modules (but have not loaded the module > version). The ARM version has been through basic crash > and burn testing, but I have not yet begun serious testing. > > The changes are broken into a series of patches to isolate > the different types of changes, and will each be sent in > a following email. The patches apply in the following > order: > > patches/yaffs_kernel_01_base.patch > > A direct copy of the yaffs files from the yaffs website, > as of November 16, 2004. This patch puts the files into > the Linux kernel tree at fs/yaffs/. Not all of the files > in this directory are actually used by me, but I was > being thorough. < stuff deleted > The email containing patch yaffs_kernel_01_base.patch is awaiting moderator approval (it is too large, ~237000 bytes). If anyone would like a copy of it directly, email me. Hopefully it will soon get approved, or at least put into the archive. -Frank -- Frank Rowand MontaVista Software, Inc From Charles.Manning@trimble.co.nz Sun Dec 19 19:59:35 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Mon, 20 Dec 2004 08:59:35 +1300 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E015490C4@nzc-ap-xch-01.ap.trimblecorp.net> Rajiv I've thought about this a bit... While Thomas it technically correct that YAFFS2 needs more recent mtd (which no longer supports older kernels), I think it rather simple to hack the mtd you have to support YAFFS2. Basically, all you'd need to do is: 1) Modify the nand write/read functions to work with 2k pages (change the size of the for loop), and a few other minor changes to handle ECC etc. 2) Add a couple more required fields to the mtd_info structure. 3) Add two new functions block_markbad() and block_isbad() for bad block handling. Whether it is the right time for you to switch to a newer kernel or not is your choice and should not be forced by mtd changes. -- Charles =20 > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk=20 > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of=20 > Thomas Gleixner > Sent: Thursday, 16 December 2004 9:41 p.m. > To: Rajiv Dhingra > Cc: YAFFS > Subject: Re: [Yaffs] Yaffs with 2k Pages OR Yaffs2 >=20 >=20 > On Wed, 2004-12-15 at 15:50 -0800, Rajiv Dhingra wrote: > > We were running Linux 2.4.20, Yaffs, and using a NAND > > device with 512 byte pages. Everything was working fine. > > Then the hardware guys replaced the 512 byte page NAND > > device with a 2k page NAND device. > > So, I now have to hack yaffs to support a 2k page size, > > or start using Yaffs2. What would the recommendation > > of this newsgroup be? Would it be easy enough for me > > to hack yaffs to start supporting the bigger page size? > > Is yaffs2 stable enough and does it run with the 2.4.20 > > kernel, making it a better option. >=20 > Be prepared to upgrade your kernel. The MTD NAND layer which=20 > has the support for 2k chips is definitely not portable to 2.4.20. >=20 > Read http://www.linux-mtd.infradead.org/#kernelversions >=20 > tglx >=20 >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk=20 > http://stoneboat.aleph1.co.uk/cgi-> bin/mailman/listinfo/yaffs >=20 From tglx@linutronix.de Sun Dec 19 20:10:15 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Sun, 19 Dec 2004 21:10:15 +0100 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 In-Reply-To: <8285CB7241FCFC4BB721A6F953F9B35E015490C4@nzc-ap-xch-01.ap.trimblecorp.net> References: <8285CB7241FCFC4BB721A6F953F9B35E015490C4@nzc-ap-xch-01.ap.trimblecorp.net> Message-ID: <1103487015.27708.67.camel@tglx.tec.linutronix.de> On Mon, 2004-12-20 at 08:59 +1300, Charles Manning wrote: > Rajiv > > I've thought about this a bit... > While Thomas it technically correct that YAFFS2 needs more recent mtd > (which no longer supports older kernels), I think it rather simple to > hack the mtd you have to support YAFFS2. > > Basically, all you'd need to do is: > 1) Modify the nand write/read functions to work with 2k pages (change > the size of the for loop), and a few other minor changes to handle ECC > etc. > 2) Add a couple more required fields to the mtd_info structure. > 3) Add two new functions block_markbad() and block_isbad() for bad block > handling. So you finally backport the whole mtd driver. :) > Whether it is the right time for you to switch to a newer kernel or not > is your choice and should not be forced by mtd changes. What real good reason is there not to upgrade the kernel ? Backporting major changes is worse than upgrading. Especially if the base you use is well known to be buggy and obsolete. tglx From Charles.Manning@trimble.co.nz Sun Dec 19 20:38:47 2004 From: Charles.Manning@trimble.co.nz (Charles Manning) Date: Mon, 20 Dec 2004 09:38:47 +1300 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 Message-ID: <8285CB7241FCFC4BB721A6F953F9B35E015490C5@nzc-ap-xch-01.ap.trimblecorp.net> Thomas The YAFFS list isn't really the place to argue the kernel version issue. I have no doubt that the newer kernel is "better", but there are many factors that come into making the decision as to what version you are going to ship. If you already have a stable shipping product then changing kernel can be a big issue. That is my major reason for keeping more mature kernel support in YAFFS. Doing some relatively minor hacks to an old mtd is an option that Rajiv has to overcome his current issues and get going with YAFFS2. There are many factors which drive the choices he has to make (hack old mtd vs revamp kernel). I don't wish to force any decision on him as I know I don't have the information I need to make that decision. BTW: At home my desktop runs 2.4.18 most of the time (and 2.4.27 some of the time). The reason I don't run 2.4.27 all the time is because some network etc drivers I have would need rebuilding -- something I have not bothered to do. The reason I don't use 2.6.x at present is similar. I'm no Luddite, but the amount of gain vs pain in not enough to motivate me to change. -- Charles > -----Original Message----- > From: Thomas Gleixner [mailto:tglx@linutronix.de]=20 > Sent: Monday, 20 December 2004 9:10 a.m. > To: Charles Manning > Cc: Rajiv Dhingra; YAFFS > Subject: RE: [Yaffs] Yaffs with 2k Pages OR Yaffs2 >=20 >=20 > On Mon, 2004-12-20 at 08:59 +1300, Charles Manning wrote: > > Rajiv > >=20 > > I've thought about this a bit... > > While Thomas it technically correct that YAFFS2 needs more=20 > recent mtd=20 > > (which no longer supports older kernels), I think it rather=20 > simple to=20 > > hack the mtd you have to support YAFFS2. > >=20 > > Basically, all you'd need to do is: > > 1) Modify the nand write/read functions to work with 2k=20 > pages (change=20 > > the size of the for loop), and a few other minor changes to=20 > handle ECC=20 > > etc. > > 2) Add a couple more required fields to the mtd_info structure. > > 3) Add two new functions block_markbad() and block_isbad() for bad=20 > > block handling. >=20 > So you finally backport the whole mtd driver. :) >=20 > > Whether it is the right time for you to switch to a newer kernel or=20 > > not is your choice and should not be forced by mtd changes. >=20 > What real good reason is there not to upgrade the kernel ?=20 > Backporting major changes is worse than upgrading. Especially=20 > if the base you use is well known to be buggy and obsolete. >=20 > tglx >=20 >=20 >=20 >=20 From frowand@mvista.com Fri Dec 17 01:33:46 2004 From: frowand@mvista.com (Frank Rowand) Date: Thu, 16 Dec 2004 17:33:46 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 1 of 7 Message-ID: <41C2377A.1080907@mvista.com> This is a multi-part message in MIME format. --------------050203010501080701060109 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit --------------050203010501080701060109 Content-Type: text/plain; name="yaffs_kernel_01_base.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_01_base.patch" Index: linux-2.6.9/fs/yaffs/yaffs_ecc.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_ecc.c @@ -0,0 +1,194 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * + * yaffs_ecc.c: ECC generation/correction algorithms. + * + * Copyright (C) 2002 Aleph One Ltd. + * + * Created by Charles Manning + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + */ + + /* + * This code implements the ECC algorithm used in SmartMedia. + * + * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. + * The two unused bit are set to 1. + * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC + * blocks are used on a 512-byte NAND page. + * + */ + +// Table generated by gen-ecc.c +// Using a table means we do not have to calculate p1..p4 and p1'..p4' +// for each byte of data. These are instead provided in a table in bits7..2. +// Bit 0 of each entry indicates whether the entry has an odd or even parity, and therefore +// this bytes influence on the line parity. + +const char *yaffs_ecc_c_version = "$Id: yaffs_ecc.c,v 1.3 2004/04/04 03:47:02 charles Exp $"; + + +#include "yaffs_ecc.h" + +static const unsigned char column_parity_table[] = { +0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, +0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, +0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, +0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, +0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, +0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, +0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, +0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, +0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, +0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, +0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, +0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, +0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, +0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, +0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, +0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, +}; + + +static int yaffs_CountBits(unsigned char x) +{ + int r = 0; + while(x) + { + if(x & 1) r++; + x >>= 1; + } + return r; +} + +void yaffs_ECCCalculate(const unsigned char *data,unsigned char *ecc) +{ + unsigned int i; + + unsigned char col_parity = 0; + unsigned char line_parity = 0; + unsigned char line_parity_prime = 0; + unsigned char t; + unsigned char b; + + for(i = 0; i < 256; i++) + { + b = column_parity_table[*data++]; + col_parity ^= b; + + if(b & 0x01) // odd number of bits in the byte + { + line_parity ^= i; + line_parity_prime ^= ~i; + } + + } + + ecc[2] = (~col_parity) | 0x03; + + t = 0; + if(line_parity & 0x80) t |= 0x80; + if(line_parity_prime & 0x80) t |= 0x40; + if(line_parity & 0x40) t |= 0x20; + if(line_parity_prime & 0x40) t |= 0x10; + if(line_parity & 0x20) t |= 0x08; + if(line_parity_prime & 0x20) t |= 0x04; + if(line_parity & 0x10) t |= 0x02; + if(line_parity_prime & 0x10) t |= 0x01; + ecc[1] = ~t; + + t = 0; + if(line_parity & 0x08) t |= 0x80; + if(line_parity_prime & 0x08) t |= 0x40; + if(line_parity & 0x04) t |= 0x20; + if(line_parity_prime & 0x04) t |= 0x10; + if(line_parity & 0x02) t |= 0x08; + if(line_parity_prime & 0x02) t |= 0x04; + if(line_parity & 0x01) t |= 0x02; + if(line_parity_prime & 0x01) t |= 0x01; + ecc[0] = ~t; + +#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER + // Swap the bytes into the wrong order + t = ecc[0]; + ecc[0] = ecc[1]; + ecc[1] = t; +#endif +} + +int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, const unsigned char *test_ecc) +{ + unsigned char d0, d1, d2; // deltas + + d0 = read_ecc[0] ^ test_ecc[0]; + d1 = read_ecc[1] ^ test_ecc[1]; + d2 = read_ecc[2] ^ test_ecc[2]; + + + + if((d0 | d1 | d2) == 0) + { + // no error + return 0; + } + + if( ((d0 ^ (d0 >> 1)) & 0x55) == 0x55 && + ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 && + ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) + { + // Single bit (recoverable) error in data + + unsigned byte; + unsigned bit; + +#ifdef CONFIG_YAFFS_ECC_WRONG_ORDER + // swap the bytes to correct for the wrong order + unsigned char t; + + t = d0; + d0 = d1; + d1 = t; +#endif + + bit = byte = 0; + + + if(d1 & 0x80) byte |= 0x80; + if(d1 & 0x20) byte |= 0x40; + if(d1 & 0x08) byte |= 0x20; + if(d1 & 0x02) byte |= 0x10; + if(d0 & 0x80) byte |= 0x08; + if(d0 & 0x20) byte |= 0x04; + if(d0 & 0x08) byte |= 0x02; + if(d0 & 0x02) byte |= 0x01; + + if(d2 & 0x80) bit |= 0x04; + if(d2 & 0x20) bit |= 0x02; + if(d2 & 0x08) bit |= 0x01; + + data[byte] ^= (1 << bit); + + return 1; + } + + if((yaffs_CountBits(d0)+yaffs_CountBits(d1)+yaffs_CountBits(d2)) == 1) + { + // Reccoverable error in ecc + + read_ecc[0] = test_ecc[0]; + read_ecc[1] = test_ecc[1]; + read_ecc[2] = test_ecc[2]; + + return 1; + } + + // Unrecoverable error + + return -1; + + +} Index: linux-2.6.9/fs/yaffs/yportenv.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yportenv.h @@ -0,0 +1,137 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yportenv.h: Portable services used by yaffs. This is done to allow + * simple migration from kernel space into app space for testing. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * $Id: yportenv.h,v 1.14 2004/10/10 18:03:35 charles Exp $ + * + */ + +#ifndef __YPORTENV_H__ +#define __YPORTENV_H__ + + +#if defined CONFIG_YAFFS_WINCE + +#include "ywinceenv.h" + +#elif defined __KERNEL__ + + + +// Linux kernel +#include "linux/kernel.h" +#include "linux/version.h" +#include "linux/mm.h" +#include "linux/string.h" +#include "linux/slab.h" + + +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" + +//#define YPRINTF(x) printk x +#define YMALLOC(x) kmalloc(x,GFP_KERNEL) +#define YFREE(x) kfree(x) + +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#define Y_CURRENT_TIME CURRENT_TIME.tv_sec +#define Y_TIME_CONVERT(x) (x).tv_sec +#else +#define Y_CURRENT_TIME CURRENT_TIME +#define Y_TIME_CONVERT(x) (x) +#endif + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#define TENDSTR "\n" +#define TSTR(x) KERN_DEBUG x +#define TOUT(p) printk p + + +#elif defined CONFIG_YAFFS_DIRECT + +// Direct interface +#include "ydirectenv.h" + +#elif defined CONFIG_YAFFS_UTIL + +// Stuff for YAFFS utilities + +#include "stdlib.h" +#include "stdio.h" +#include "string.h" + +#include "devextras.h" + +#define YMALLOC(x) malloc(x) +#define YFREE(x) free(x) + + +//#define YINFO(s) YPRINTF(( __FILE__ " %d %s\n",__LINE__,s)) +//#define YALERT(s) YINFO(s) + + +#define TENDSTR "\n" +#define TSTR(x) x +#define TOUT(p) printf p + + +#define YAFFS_LOSTNFOUND_NAME "lost+found" +#define YAFFS_LOSTNFOUND_PREFIX "obj" +//#define YPRINTF(x) printf x + + +#define CURRENT_TIME 0 +#define YAFFS_ROOT_MODE 0666 +#define YAFFS_LOSTNFOUND_MODE 0666 + +#define yaffs_SumCompare(x,y) ((x) == (y)) +#define yaffs_strcmp(a,b) strcmp(a,b) + +#else +// Should have specified a configuration type +#error Unknown configuration + +#endif + + +extern unsigned yaffs_traceMask; + +#define YAFFS_TRACE_ERROR 0x0001 +#define YAFFS_TRACE_OS 0x0002 +#define YAFFS_TRACE_ALLOCATE 0x0004 +#define YAFFS_TRACE_SCAN 0x0008 +#define YAFFS_TRACE_BAD_BLOCKS 0x0010 +#define YAFFS_TRACE_ERASE 0x0020 +#define YAFFS_TRACE_GC 0x0040 +#define YAFFS_TRACE_TRACING 0x0100 +#define YAFFS_TRACE_ALWAYS 0x0200 +#define YAFFS_TRACE_BUG 0x8000 + +#define T(mask,p) do{ if((mask) & (yaffs_traceMask | YAFFS_TRACE_ERROR)) TOUT(p);} while(0) + + +#ifndef CONFIG_YAFFS_WINCE +#define YBUG() T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__)) +#endif + +#endif + + Index: linux-2.6.9/fs/yaffs/yaffsdev.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffsdev.c @@ -0,0 +1,731 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffsdev.c + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include "yaffsinterface.h" +#include "yportenv.h" + +#if YAFFS_FILEEM +#include "yaffs_fileem.h" +#else +#include "yaffs_nandemul.h" +#endif + +#include "yaffs_guts.h" +#include + +#include +#include +#include +#include + + + +unsigned yaffs_traceMask = 0xFFFFFFFF; + +yaffs_Device device; + + +char *testStr = "this is a test string"; + +char *testStr2 = "abcdefghijklmnopqrstuvwxyz1234567890"; + +void TestTimexxx(yaffs_Device *dev) +{ + yaffs_Object *f; + int x; + + + printf("Start\n"); + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + + x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); + +} + + +void TestTimeasasas(yaffs_Device *dev) +{ + yaffs_Object *f; + int x; + int i; + int b; + char data[200]; + int written; + + + printf("Start\n"); + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + + x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); + + + + for(i = 0; i < 10000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + } + + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + printf("Flush\n"); + + yaffs_FlushFile(f,1); + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + yaffs_DumpObject(f); + + printf("Resize to 3000\n"); + yaffs_ResizeFile(f,3000); + printf("Resize to 2048\n"); + yaffs_ResizeFile(f,2048); + + yaffs_DumpObject(f); + + yaffs_FlushFile(f,1); + + + + +} + +void TestTimeBigDeletes(yaffs_Device *dev) +{ + yaffs_Object *f; + yaffs_Object *sl; + yaffs_Object *lnf; + + yaffs_Object *hl1; + yaffs_Object *hl2; + yaffs_Object *hl3; + yaffs_Object *d, *df; + + int x; + int i; + int b; + char data[200]; + + char * alias; + int written; + + + printf("Exisiting objects\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + printf("Exisiting objects in lost+found\n"); + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject); + + printf("Start\n"); + + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + for(i = 0; i < 100000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + } + + yaffs_FlushFile(f,1); + yaffs_DeleteFile(f); + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + for(i = 0; i < 100000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + } + + yaffs_FlushFile(f,1); + yaffs_DeleteFile(f); + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + for(i = 0; i < 100000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + } + + yaffs_FlushFile(f,1); + yaffs_DeleteFile(f); + +} + +void TestTime(yaffs_Device *dev) +{ + yaffs_Object *f; + yaffs_Object *sl; + yaffs_Object *lnf; + + yaffs_Object *hl1; + yaffs_Object *hl2; + yaffs_Object *hl3; + yaffs_Object *d, *df; + + int x; + int i; + int b; + char data[200]; + + char * alias; + int written; + + + printf("Exisiting objects\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + printf("Exisiting objects in lost+found\n"); + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject); + + printf("Start\n"); + + + // Test the problem of: + // Create file + // Delete file + // Create file with same name + // Delete file <== crash + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + yaffs_Unlink(yaffs_Root(dev),"Name1"); + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + yaffs_Unlink(yaffs_Root(dev),"Name1"); + + + + // Other tests + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + + x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); + +// Write a file with overwrite, then read it back and save outside yaffs +// This is to test that write caching works. + + for(i = 0; i < 100; i++) + { + unsigned char x[500]; + + memset(x,i,500); + + written = yaffs_WriteDataToFile(f,x,i*500,500); + } + + for(i = 0; i < 100; i++) + { + unsigned char x; + + x = i+5; + + written = yaffs_WriteDataToFile(f,&x,i*500 + 2,1); + } + + + { + int h; + + h = open("bork",O_RDWR | O_CREAT | O_TRUNC,0666); + for(i = 0; i < 100; i++) + { + unsigned char x[500]; + + yaffs_ReadDataFromFile(f,x,i*500,500); + write(h,x,500); + } + close(h); + + + } + +// Big write to fill disk + + written = 1; + for(i = 0; i < 1000000 && written > 0; i++) + { + unsigned char x[500]; + + memset(x,i,500); + + written = yaffs_WriteDataToFile(f,x,i*500,500); + } + if(written <= 0) + { + printf("YAFFS full\n"); + } + + // some short reads + for(i = 1000; i < 50000; i+=2) + { + yaffs_ReadDataFromFile(f,data,i,20); + } + + + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + printf("Flush\n"); + + yaffs_FlushFile(f,1); + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + printf("File length is %d\n",yaffs_GetObjectFileLength(f)); + + sl = yaffs_MknodSymLink(yaffs_Root(dev),"sym-link",0,0,0,"/tmp/alias"); + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + printf("\n\nsymlink alias is \"%s\"\n",alias = yaffs_GetSymlinkAlias(sl)); + + free(alias); + + printf("Unlink symlink %d\n",yaffs_Unlink(yaffs_Root(dev),"sym-link")); + + + yaffs_ReadDataFromFile(f,data,1000,50); + data[50] = 0; + + printf("Read data is \"%s\"\n",data); + + yaffs_DumpObject(f); + + printf("Resize 3000\n"); + yaffs_ResizeFile(f,3000); + + printf("Resize 2050\n"); + yaffs_ResizeFile(f,2050); + printf("Resize 2049\n"); + yaffs_ResizeFile(f,2049); + printf("Resize 2048\n"); + yaffs_ResizeFile(f,2048); + + + printf("Resize 2000\n"); + yaffs_ResizeFile(f,2000); + + yaffs_DumpObject(f); + + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + + + + yaffs_FlushFile(f,1); + + + printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename")); + + yaffs_DeleteFile(f); + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + // Create a directory and play with it + + + printf("Find or Create directory and play with it\n"); + d = yaffs_FindObjectByName(yaffs_Root(dev),"direct"); + if(!d) + { + d = yaffs_MknodDirectory(yaffs_Root(dev),"direct",0,0,0); + } + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject); + + printf("Make file in directory\n"); + + df = yaffs_MknodFile(d,"file-in-directory",0,0,0); + yaffs_ApplyToDirectoryChildren(d,yaffs_DumpObject); + + + // Do some stuff with hardlinks + // + // NB Deleting hardlinked objects can mess up pointers to hardlinks. + // The mechanism is as follows: + // * If you unlink a file,softlink or directory that has one or more hardlinks, + // then the object is renamed to one of the hardlinks and that hardlink is unlinked. + // This means that a pointer to a hardlink so deleted will point to an invalid address. + // Thus, make sure that pointers to hardlinks are immediately dereferenced. + + + printf("Hard link tests\n"); + + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + hl1 = yaffs_Link(yaffs_Root(dev),"HardLink 1",f); + hl2 = yaffs_Link(yaffs_Root(dev),"HardLink 2",f); + hl3 = yaffs_Link(yaffs_Root(dev),"HardLink 3",hl2); + + printf("\n\nHard links created\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + yaffs_Unlink(yaffs_Root(dev),"HardLink 1"); + printf("\n\nHard link deleted\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + yaffs_Unlink(yaffs_Root(dev),"Name1"); + printf("\n\nHard linked file deleted\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + yaffs_Unlink(yaffs_Root(dev),"HardLink 2"); + printf("\n\nHard link 2 deleted\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + yaffs_Unlink(yaffs_Root(dev),"HardLink 3"); + + printf("\n\nHard link 3 deleted\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + // NB We don't allow unlinking or rename of the root or lost+found + // We allow setting attributes, but these must not be written to + // NAND since they are not real objects. + + printf("Attempt to rename lost+found - should have failed\n"); + x = yaffs_RenameObject(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME,NULL,"Renamed"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + + f = yaffs_MknodFile(yaffs_Root(dev),"pfile",0,0,0); + if(f) + { + yaffs_WriteDataToFile(f,testStr,0,strlen(testStr)); + } + + yaffs_Link(yaffs_Root(dev),"phl4",f); +} + +void TestTimeDeleteFocussed(yaffs_Device *dev) +{ + yaffs_Object *f; + yaffs_Object *lnf; + + + int x; + int i; + int b; + int written; + + + printf("Exisiting objects\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + printf("Exisiting objects in lost+found\n"); + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject); + + printf("Start\n"); + + + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + + x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); + + for(i = 0; i < 100000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,i,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,i,strlen(testStr2)); + } + + + + yaffs_FlushFile(f,1); + + + printf("Unlink file: %d\n",yaffs_Unlink(yaffs_Root(dev),"Rename")); + + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + +} + +void TestTimeTnodeFocussed(yaffs_Device *dev) +{ + yaffs_Object *f; + yaffs_Object *lnf; + + + int x; + int i; + int b; + int written; + + + printf("Exisiting objects\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + printf("Exisiting objects in lost+found\n"); + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject); + + printf("Start\n"); + + + + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + + x = yaffs_RenameObject(yaffs_Root(dev),"Name1",NULL,"Rename"); + + for(i = 0; i < 10000; i+=20) + { + + b++; + if(b & 1) + written = yaffs_WriteDataToFile(f,testStr,0,strlen(testStr)); + else + written = yaffs_WriteDataToFile(f,testStr2,0,strlen(testStr2)); + } + +} +void TestTimeBackgroundDeleteFocussed(yaffs_Device *dev) +{ + yaffs_Object *f; + yaffs_Object *lnf; + + + int x; + int i,j; + int b; + int written; + + + printf("Exisiting objects\n"); + yaffs_ApplyToDirectoryChildren(yaffs_Root(dev),yaffs_DumpObject); + printf("Exisiting objects in lost+found\n"); + lnf = yaffs_FindObjectByName(yaffs_Root(dev),YAFFS_LOSTNFOUND_NAME); + yaffs_ApplyToDirectoryChildren(lnf,yaffs_DumpObject); + + printf("Start\n"); + + + for(j = 0; j < 20; j++) + { + printf("Run %d\n",j); + + f = yaffs_FindObjectByName(yaffs_Root(dev),"Name1"); + if(f) + { + printf("Found\n"); + } + else + { + f = yaffs_MknodFile(yaffs_Root(dev),"Name1",0,0,0); + printf("Created\n"); + } + + printf("@@@@@@@ Run %d, object %d\n",j,f->objectId); + + for(i = 0; i < 1000000; i+=20) + { + + written = yaffs_WriteDataToFile(f,testStr,i,100); + } + + yaffs_FlushFile(f,1); + + yaffs_DeleteFile(f); + } + +} + +int main(int argc,char *argv[]) +{ + + int nBlocks; + +#if YAFFS_FILEEM + nBlocks =(2 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK) ; + device.writeChunkToNAND = yaffs_FEWriteChunkToNAND; + device.readChunkFromNAND = yaffs_FEReadChunkFromNAND; + device.eraseBlockInNAND = yaffs_FEEraseBlockInNAND; + device.initialiseNAND = yaffs_FEInitialiseNAND; + + printf("Testing on file emulation\n"); +#else + nBlocks = (2 * 1024 * 1024) / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + device.writeChunkToNAND = nandemul_WriteChunkToNAND; + device.readChunkFromNAND = nandemul_ReadChunkFromNAND; + device.eraseBlockInNAND = nandemul_EraseBlockInNAND; + device.initialiseNAND = nandemul_InitialiseNAND; + + printf("Testing on RAM emulation\n"); +#endif + +#ifdef YAFFS_START + device.startBlock = YAFFS_START; // Don't use block 0 + device.endBlock = YAFFS_END; +#else + device.startBlock = 1; // Don't use block 0 + device.endBlock = nBlocks; +#endif + + device.nShortOpCaches = 10; + + + yaffs_GutsInitialise(&device); + + // yaffs_GutsTest(); + + TestTimeBackgroundDeleteFocussed(&device); + + printf("Cache hits %d\n",device.cacheHits); + printf("Retired blocks %d\n",device.nRetiredBlocks); + + printf("Deletions %d\n",device.nDeletions); + printf("Unmarked deletions %d\n",device.nUnmarkedDeletions); + + exit(0); +} Index: linux-2.6.9/fs/yaffs/yaffs_mtdif.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_mtdif.h @@ -0,0 +1,33 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_mtdif.h NAND mtd interface wrappers + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * $Id: yaffs_mtdif.h,v 1.4 2002/09/27 20:50:50 charles Exp $ + */ + +#ifndef __YAFFS_MTDIF_H__ +#define __YAFFS_MTDIF_H__ + +#include "yaffs_guts.h" + +int nandmtd_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare); +int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare); +int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber); +int nandmtd_InitialiseNAND(yaffs_Device *dev); +#endif + + + + Index: linux-2.6.9/fs/yaffs/yaffsinterface.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffsinterface.h @@ -0,0 +1,25 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffsinterface.h: Interface to the guts of yaffs. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + */ + +#ifndef __YAFFSINTERFACE_H__ +#define __YAFFSINTERFACE_H__ + + +int yaffs_Initialise(unsigned nBlocks); + +#endif + Index: linux-2.6.9/fs/yaffs/yaffs_guts.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_guts.c @@ -0,0 +1,5012 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_guts.c The main guts of YAFFS + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + //yaffs_guts.c + +const char *yaffs_guts_c_version="$Id: yaffs_guts.c,v 1.37 2004/10/20 20:12:43 charles Exp $"; + +#include "yportenv.h" + +#include "yaffsinterface.h" +#include "yaffs_guts.h" + +#define YAFFS_PASSIVE_GC_CHUNKS 2 + +#if 0 +// Use Steven Hill's ECC struff instead +// External functions for ECC on data +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); +#define yaffs_ECCCalculate(data,ecc) nand_calculate_ecc(data,ecc) +#define yaffs_ECCCorrect(data,read_ecc,calc_ecc) nand_correct_ecc(data,read_ecc,calc_ecc) +#else +#include "yaffs_ecc.h" +#endif + +// countBits is a quick way of counting the number of bits in a byte. +// ie. countBits[n] holds the number of 1 bits in a byte with the value n. + +static const char yaffs_countBitsTable[256] = +{ +0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, +4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 +}; + +static int yaffs_CountBits(__u8 x) +{ + int retVal; + retVal = yaffs_countBitsTable[x]; + return retVal; +} + + + +// Local prototypes +static int yaffs_CheckObjectHashSanity(yaffs_Device *dev); +static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr); +static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr); +static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan); + +static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type); +static void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *obj); +static int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force); +static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND); +static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj); +static int yaffs_CheckStructures(void); +static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit); +static int yaffs_DoGenericObjectDeletion(yaffs_Object *in); + +static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev,int blockNo); + +// Robustification +static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND); +static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND); +static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND); +static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare); +static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_Spare *spare); + +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND); + +static int yaffs_UnlinkWorker(yaffs_Object *obj); +static void yaffs_AbortHalfCreatedObject(yaffs_Object *obj); + +static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1); + + + +loff_t yaffs_GetFileSize(yaffs_Object *obj); + +static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_Tags *tags, int *chunkDeleted); +static int yaffs_TagsMatch(const yaffs_Tags *tags, int objectId, int chunkInObject, int chunkDeleted); + + +static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve); + +#ifdef YAFFS_PARANOID +static int yaffs_CheckFileSanity(yaffs_Object *in); +#else +#define yaffs_CheckFileSanity(in) +#endif + +static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in); +static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId); + +// Chunk bitmap manipulations + +static __inline __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk) +{ + if(blk < dev->startBlock || blk > dev->endBlock) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),blk)); + YBUG(); + } + return dev->chunkBits + (dev->chunkBitmapStride * (blk - dev->startBlock)); +} + +static __inline__ void yaffs_ClearChunkBits(yaffs_Device *dev,int blk) +{ + __u8 *blkBits = yaffs_BlockBits(dev,blk); + + memset(blkBits,0,dev->chunkBitmapStride); +} + +static __inline__ void yaffs_ClearChunkBit(yaffs_Device *dev,int blk,int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev,blk); + + blkBits[chunk/8] &= ~ (1<<(chunk & 7)); +} + +static __inline__ void yaffs_SetChunkBit(yaffs_Device *dev,int blk,int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev,blk); + + blkBits[chunk/8] |= (1<<(chunk & 7)); +} + +static __inline__ int yaffs_CheckChunkBit(yaffs_Device *dev,int blk,int chunk) +{ + __u8 *blkBits = yaffs_BlockBits(dev,blk); + return (blkBits[chunk/8] & (1<<(chunk & 7))) ? 1 :0; +} + +static __inline__ int yaffs_StillSomeChunkBits(yaffs_Device *dev,int blk) +{ + __u8 *blkBits = yaffs_BlockBits(dev,blk); + int i; + for(i = 0; i < dev->chunkBitmapStride; i++) + { + if(*blkBits) return 1; + blkBits++; + } + return 0; +} + +// Function to manipulate block info +static __inline__ yaffs_BlockInfo* yaffs_GetBlockInfo(yaffs_Device *dev, int blk) +{ + if(blk < dev->startBlock || blk > dev->endBlock) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),blk)); + YBUG(); + } + return &dev->blockInfo[blk - dev->startBlock]; +} + + +static __inline__ int yaffs_HashFunction(int n) +{ + return (n % YAFFS_NOBJECT_BUCKETS); +} + + +yaffs_Object *yaffs_Root(yaffs_Device *dev) +{ + return dev->rootDir; +} + +yaffs_Object *yaffs_LostNFound(yaffs_Device *dev) +{ + return dev->lostNFoundDir; +} + + +static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare) +{ + if(chunkInNAND < dev->startBlock * dev->nChunksPerBlock) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d is not valid" TENDSTR),chunkInNAND)); + return YAFFS_FAIL; + } + + dev->nPageWrites++; + return dev->writeChunkToNAND(dev,chunkInNAND,data,spare); +} + + + +int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev, + int chunkInNAND, + __u8 *data, + yaffs_Spare *spare, + int doErrorCorrection) +{ + int retVal; + yaffs_Spare localSpare; + + dev->nPageReads++; + + + + + if(!spare && data) + { + // If we don't have a real spare, then we use a local one. + // Need this for the calculation of the ecc + spare = &localSpare; + } + + + if(!dev->useNANDECC) + { + retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,spare); + if(data && doErrorCorrection) + { + // Do ECC correction + //Todo handle any errors + int eccResult1,eccResult2; + __u8 calcEcc[3]; + + yaffs_ECCCalculate(data,calcEcc); + eccResult1 = yaffs_ECCCorrect (data,spare->ecc1, calcEcc); + yaffs_ECCCalculate(&data[256],calcEcc); + eccResult2 = yaffs_ECCCorrect(&data[256],spare->ecc2, calcEcc); + + if(eccResult1>0) + { + T(YAFFS_TRACE_ERROR, (TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND)); + dev->eccFixed++; + } + else if(eccResult1<0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND)); + dev->eccUnfixed++; + } + + if(eccResult2>0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND)); + dev->eccFixed++; + } + else if(eccResult2<0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); + dev->eccUnfixed++; + } + + if(eccResult1 || eccResult2) + { + // Hoosterman, we had a data problem on this page + yaffs_HandleReadDataError(dev,chunkInNAND); + } + } + } + else + { + // Must allocate enough memory for spare+2*sizeof(int) for ecc results from device. + struct yaffs_NANDSpare nspare; + retVal = dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare*)&nspare); + memcpy (spare, &nspare, sizeof(yaffs_Spare)); + if(data && doErrorCorrection) + { + if(nspare.eccres1>0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:0" TENDSTR),chunkInNAND)); + } + else if(nspare.eccres1<0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:0" TENDSTR),chunkInNAND)); + } + + if(nspare.eccres2>0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error fix performed on chunk %d:1" TENDSTR),chunkInNAND)); + } + else if(nspare.eccres2<0) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>>ecc error unfixed on chunk %d:1" TENDSTR),chunkInNAND)); + } + + if(nspare.eccres1 || nspare.eccres2) + { + // Hoosterman, we had a data problem on this page + yaffs_HandleReadDataError(dev,chunkInNAND); + } + + } + } + return retVal; +} + + +static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,int chunkInNAND) +{ + + static int init = 0; + static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK]; + static __u8 data[YAFFS_BYTES_PER_CHUNK]; + // Might as well always allocate the larger size for dev->useNANDECC == true; + static __u8 spare[sizeof(struct yaffs_NANDSpare)]; + + dev->readChunkFromNAND(dev,chunkInNAND,data,(yaffs_Spare *)spare); + + if(!init) + { + memset(cmpbuf,0xff,YAFFS_BYTES_PER_CHUNK); + init = 1; + } + + if(memcmp(cmpbuf,data,YAFFS_BYTES_PER_CHUNK)) return YAFFS_FAIL; + if(memcmp(cmpbuf,spare,16)) return YAFFS_FAIL; + + + return YAFFS_OK; + +} + + + +int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND) +{ + dev->nBlockErasures++; + return dev->eraseBlockInNAND(dev,blockInNAND); +} + +int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev) +{ + return dev->initialiseNAND(dev); +} + +static int yaffs_WriteNewChunkToNAND(struct yaffs_DeviceStruct *dev, const __u8 *data, yaffs_Spare *spare,int useReserve) +{ + int chunk; + + int writeOk = 1; + int attempts = 0; + + unsigned char rbData[YAFFS_BYTES_PER_CHUNK]; + yaffs_Spare rbSpare; + + do{ + chunk = yaffs_AllocateChunk(dev,useReserve); + + if(chunk >= 0) + { + + // First check this chunk is erased... +#ifndef CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK + writeOk = yaffs_CheckChunkErased(dev,chunk); +#endif + if(!writeOk) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs chunk %d was not erased" TENDSTR),chunk)); + } + else + { + writeOk = yaffs_WriteChunkToNAND(dev,chunk,data,spare); + } + attempts++; + if(writeOk) + { + // Readback & verify + // If verify fails, then delete this chunk and try again + // To verify we compare everything except the block and + // page status bytes. + // NB We check a raw read without ECC correction applied + yaffs_ReadChunkFromNAND(dev,chunk,rbData,&rbSpare,0); + +#ifndef CONFIG_YAFFS_DISABLE_WRITE_VERIFY + if(!yaffs_VerifyCompare(data,rbData,spare,&rbSpare)) + { + // Didn't verify + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write verify failed on chunk %d" TENDSTR), chunk)); + + writeOk = 0; + } +#endif + + } + if(writeOk) + { + // Copy the data into the write buffer. + // NB We do this at the end to prevent duplicates in the case of a write error. + //Todo + yaffs_HandleWriteChunkOk(dev,chunk,data,spare); + } + else + { + yaffs_HandleWriteChunkError(dev,chunk); + } + } + + } while(chunk >= 0 && ! writeOk); + + if(attempts > 1) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> yaffs write required %d attempts" TENDSTR),attempts)); + dev->nRetriedWrites+= (attempts - 1); + } + + return chunk; +} + +/// +// Functions for robustisizing +// +// + +static void yaffs_RetireBlock(yaffs_Device *dev,int blockInNAND) +{ + // Ding the blockStatus in the first two pages of the block. + + yaffs_Spare spare; + + memset(&spare, 0xff,sizeof(yaffs_Spare)); + + spare.blockStatus = 0; + + // TODO change this retirement marking for other NAND types + yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL , &spare); + yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1, NULL , &spare); + + yaffs_GetBlockInfo(dev,blockInNAND)->blockState = YAFFS_BLOCK_STATE_DEAD; + dev->nRetiredBlocks++; +} + + + +static int yaffs_RewriteBufferedBlock(yaffs_Device *dev) +{ + dev->doingBufferedBlockRewrite = 1; + // + // Remove erased chunks + // Rewrite existing chunks to a new block + // Set current write block to the new block + + dev->doingBufferedBlockRewrite = 0; + + return 1; +} + + +static void yaffs_HandleReadDataError(yaffs_Device *dev,int chunkInNAND) +{ + int blockInNAND = chunkInNAND/dev->nChunksPerBlock; + + // Mark the block for retirement + yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1; + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>>Block %d marked for retirement" TENDSTR),blockInNAND)); + + + //TODO + // Just do a garbage collection on the affected block then retire the block + // NB recursion +} + + +static void yaffs_CheckWrittenBlock(yaffs_Device *dev,int chunkInNAND) +{ +} + +static void yaffs_HandleWriteChunkOk(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare) +{ +} + +static void yaffs_HandleUpdateChunk(yaffs_Device *dev,int chunkInNAND, const yaffs_Spare *spare) +{ +} + +static void yaffs_HandleWriteChunkError(yaffs_Device *dev,int chunkInNAND) +{ + int blockInNAND = chunkInNAND/dev->nChunksPerBlock; + + // Mark the block for retirement + yaffs_GetBlockInfo(dev,blockInNAND)->needsRetiring = 1; + // Delete the chunk + yaffs_DeleteChunk(dev,chunkInNAND,1); +} + + + + +static int yaffs_VerifyCompare(const __u8 *d0, const __u8 * d1, const yaffs_Spare *s0, const yaffs_Spare *s1) +{ + + + if( memcmp(d0,d1,YAFFS_BYTES_PER_CHUNK) != 0 || + s0->tagByte0 != s1->tagByte0 || + s0->tagByte1 != s1->tagByte1 || + s0->tagByte2 != s1->tagByte2 || + s0->tagByte3 != s1->tagByte3 || + s0->tagByte4 != s1->tagByte4 || + s0->tagByte5 != s1->tagByte5 || + s0->tagByte6 != s1->tagByte6 || + s0->tagByte7 != s1->tagByte7 || + s0->ecc1[0] != s1->ecc1[0] || + s0->ecc1[1] != s1->ecc1[1] || + s0->ecc1[2] != s1->ecc1[2] || + s0->ecc2[0] != s1->ecc2[0] || + s0->ecc2[1] != s1->ecc2[1] || + s0->ecc2[2] != s1->ecc2[2] ) + { + return 0; + } + + return 1; +} + + +///////////////////////// Object management ////////////////// +// List of spare objects +// The list is hooked together using the first pointer +// in the object + +// static yaffs_Object *yaffs_freeObjects = NULL; + +// static int yaffs_nFreeObjects; + +// static yaffs_ObjectList *yaffs_allocatedObjectList = NULL; + +// static yaffs_ObjectBucket yaffs_objectBucket[YAFFS_NOBJECT_BUCKETS]; + + +static __u16 yaffs_CalcNameSum(const char *name) +{ + __u16 sum = 0; + __u16 i = 1; + + __u8 *bname = (__u8 *)name; + if(bname) + { + while ((*bname) && (i <=YAFFS_MAX_NAME_LENGTH)) + { + +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE + sum += toupper(*bname) * i; +#else + sum += (*bname) * i; +#endif + i++; + bname++; + } + } + return sum; +} + +void yaffs_SetObjectName(yaffs_Object *obj, const char *name) +{ +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + if(name && strlen(name) <= YAFFS_SHORT_NAME_LENGTH) + { + strcpy(obj->shortName,name); + } + else + { + obj->shortName[0]='\0'; + } +#endif + obj->sum = yaffs_CalcNameSum(name); +} + +void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare) +{ + yaffs_ECCCalculate(data , spare->ecc1); + yaffs_ECCCalculate(&data[256] , spare->ecc2); +} + +void yaffs_CalcTagsECC(yaffs_Tags *tags) +{ + // Calculate an ecc + + unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; + unsigned i,j; + unsigned ecc = 0; + unsigned bit = 0; + + tags->ecc = 0; + + for(i = 0; i < 8; i++) + { + for(j = 1; j &0xff; j<<=1) + { + bit++; + if(b[i] & j) + { + ecc ^= bit; + } + } + } + + tags->ecc = ecc; + + +} + +int yaffs_CheckECCOnTags(yaffs_Tags *tags) +{ + unsigned ecc = tags->ecc; + + yaffs_CalcTagsECC(tags); + + ecc ^= tags->ecc; + + if(ecc && ecc <= 64) + { + // TODO: Handle the failure better. Retire? + unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; + + ecc--; + + b[ecc / 8] ^= (1 << (ecc & 7)); + + // Now recvalc the ecc + yaffs_CalcTagsECC(tags); + + return 1; // recovered error + } + else if(ecc) + { + // Wierd ecc failure value + // TODO Need to do somethiong here + return -1; //unrecovered error + } + + return 0; +} + + +///////////////////////// TNODES /////////////////////// + +// List of spare tnodes +// The list is hooked together using the first pointer +// in the tnode. + +//static yaffs_Tnode *yaffs_freeTnodes = NULL; + +// static int yaffs_nFreeTnodes; + +//static yaffs_TnodeList *yaffs_allocatedTnodeList = NULL; + + + +// yaffs_CreateTnodes creates a bunch more tnodes and +// adds them to the tnode free list. +// Don't use this function directly + +static int yaffs_CreateTnodes(yaffs_Device *dev,int nTnodes) +{ + int i; + yaffs_Tnode *newTnodes; + yaffs_TnodeList *tnl; + + if(nTnodes < 1) return YAFFS_OK; + + // make these things + + newTnodes = YMALLOC(nTnodes * sizeof(yaffs_Tnode)); + + if (!newTnodes) + { + T(YAFFS_TRACE_ERROR,(TSTR("yaffs: Could not allocate Tnodes"TENDSTR))); + return YAFFS_FAIL; + } + + // Hook them into the free list + for(i = 0; i < nTnodes - 1; i++) + { + newTnodes[i].internal[0] = &newTnodes[i+1]; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + newTnodes[i].internal[YAFFS_NTNODES_INTERNAL] = 1; +#endif + } + + newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + newTnodes[nTnodes - 1].internal[YAFFS_NTNODES_INTERNAL] = 1; +#endif + dev->freeTnodes = newTnodes; + dev->nFreeTnodes+= nTnodes; + dev->nTnodesCreated += nTnodes; + + // Now add this bunch of tnodes to a list for freeing up. + // NB If we can't add this to the management list it isn't fatal + // but it just means we can't free this bunch of tnodes later. + tnl = YMALLOC(sizeof(yaffs_TnodeList)); + if(!tnl) + { + T(YAFFS_TRACE_ERROR,(TSTR("yaffs: Could not add tnodes to management list" TENDSTR))); + + } + else + { + tnl->tnodes = newTnodes; + tnl->next = dev->allocatedTnodeList; + dev->allocatedTnodeList = tnl; + } + + + T(YAFFS_TRACE_ALLOCATE,(TSTR("yaffs: Tnodes added" TENDSTR))); + + + return YAFFS_OK; +} + + +// GetTnode gets us a clean tnode. Tries to make allocate more if we run out +static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev) +{ + yaffs_Tnode *tn = NULL; + + // If there are none left make more + if(!dev->freeTnodes) + { + yaffs_CreateTnodes(dev,YAFFS_ALLOCATION_NTNODES); + } + + if(dev->freeTnodes) + { + tn = dev->freeTnodes; +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + if(tn->internal[YAFFS_NTNODES_INTERNAL] != 1) + { + // Hoosterman, this thing looks like it isn't in the list + T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Tnode list bug 1" TENDSTR))); + } +#endif + dev->freeTnodes = dev->freeTnodes->internal[0]; + dev->nFreeTnodes--; + // zero out + memset(tn,0,sizeof(yaffs_Tnode)); + } + + + return tn; +} + + +// FreeTnode frees up a tnode and puts it back on the free list +static void yaffs_FreeTnode(yaffs_Device*dev, yaffs_Tnode *tn) +{ + if(tn) + { +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + if(tn->internal[YAFFS_NTNODES_INTERNAL] != 0) + { + // Hoosterman, this thing looks like it is already in the list + T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: Tnode list bug 2" TENDSTR))); + } + tn->internal[YAFFS_NTNODES_INTERNAL] = 1; +#endif + tn->internal[0] = dev->freeTnodes; + dev->freeTnodes = tn; + dev->nFreeTnodes++; + } +} + + +static void yaffs_DeinitialiseTnodes(yaffs_Device*dev) +{ + // Free the list of allocated tnodes + yaffs_TnodeList *tmp; + + while(dev->allocatedTnodeList) + { + tmp = dev->allocatedTnodeList->next; + + YFREE(dev->allocatedTnodeList->tnodes); + YFREE(dev->allocatedTnodeList); + dev->allocatedTnodeList = tmp; + + } + + dev->freeTnodes = NULL; + dev->nFreeTnodes = 0; +} + +static void yaffs_InitialiseTnodes(yaffs_Device*dev) +{ + dev->allocatedTnodeList = NULL; + dev->freeTnodes = NULL; + dev->nFreeTnodes = 0; + dev->nTnodesCreated = 0; + +} + +#if 0 +void yaffs_TnodeTest(yaffs_Device *dev) +{ + + int i; + int j; + yaffs_Tnode *tn[1000]; + + YINFO("Testing TNodes"); + + for(j = 0; j < 50; j++) + { + for(i = 0; i < 1000; i++) + { + tn[i] = yaffs_GetTnode(dev); + if(!tn[i]) + { + YALERT("Getting tnode failed"); + } + } + for(i = 0; i < 1000; i+=3) + { + yaffs_FreeTnode(dev,tn[i]); + tn[i] = NULL; + } + + } +} +#endif + + +////////////////// END OF TNODE MANIPULATION /////////////////////////// + +/////////////// Functions to manipulate the look-up tree (made up of tnodes) +// The look up tree is represented by the top tnode and the number of topLevel +// in the tree. 0 means only the level 0 tnode is in the tree. + + +// FindLevel0Tnode finds the level 0 tnode, if one exists. +// Used when reading..... +static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,yaffs_FileStructure *fStruct, __u32 chunkId) +{ + + yaffs_Tnode *tn = fStruct->top; + __u32 i; + int requiredTallness; + int level = fStruct->topLevel; + + // Check sane level and chunk Id + if(level < 0 || level > YAFFS_TNODES_MAX_LEVEL) + { +// char str[50]; +// sprintf(str,"Bad level %d",level); +// YALERT(str); + return NULL; + } + + if(chunkId > YAFFS_MAX_CHUNK_ID) + { +// char str[50]; +// sprintf(str,"Bad chunkId %d",chunkId); +// YALERT(str); + return NULL; + } + + // First check we're tall enough (ie enough topLevel) + + i = chunkId >> (/*dev->chunkGroupBits + */YAFFS_TNODES_LEVEL0_BITS); + requiredTallness = 0; + while(i) + { + i >>= YAFFS_TNODES_INTERNAL_BITS; + requiredTallness++; + } + + + if(requiredTallness > fStruct->topLevel) + { + // Not tall enough, so we can't find it, return NULL. + return NULL; + } + + + // Traverse down to level 0 + while (level > 0 && tn) + { + tn = tn->internal[(chunkId >>(/* dev->chunkGroupBits + */ YAFFS_TNODES_LEVEL0_BITS + (level-1) * YAFFS_TNODES_INTERNAL_BITS)) & + YAFFS_TNODES_INTERNAL_MASK]; + level--; + + } + + return tn; +} + +// AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree. +// This happens in two steps: +// 1. If the tree isn't tall enough, then make it taller. +// 2. Scan down the tree towards the level 0 tnode adding tnodes if required. +// +// Used when modifying the tree. +// +static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev, yaffs_FileStructure *fStruct, __u32 chunkId) +{ + + yaffs_Tnode *tn; + + int requiredTallness; + int i; + int l; + + __u32 x; + + + //T((TSTR("AddOrFind topLevel=%d, chunk=%d"),fStruct->topLevel,chunkId)); + + // Check sane level and page Id + if(fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL) + { +// char str[50]; +// sprintf(str,"Bad level %d",fStruct->topLevel); +// YALERT(str); + return NULL; + } + + if(chunkId > YAFFS_MAX_CHUNK_ID) + { +// char str[50]; +// sprintf(str,"Bad chunkId %d",chunkId); +// YALERT(str); + return NULL; + } + + // First check we're tall enough (ie enough topLevel) + + x = chunkId >> (/*dev->chunkGroupBits + */YAFFS_TNODES_LEVEL0_BITS); + requiredTallness = 0; + while(x) + { + x >>= YAFFS_TNODES_INTERNAL_BITS; + requiredTallness++; + } + + //T((TSTR(" required=%d"),requiredTallness)); + + + if(requiredTallness > fStruct->topLevel) + { + // Not tall enough,gotta make the tree taller + for(i = fStruct->topLevel; i < requiredTallness; i++) + { + //T((TSTR(" add new top"))); + + tn = yaffs_GetTnode(dev); + + if(tn) + { + tn->internal[0] = fStruct->top; + fStruct->top = tn; + } + else + { + T(YAFFS_TRACE_ERROR,(TSTR("yaffs: no more tnodes" TENDSTR))); + } + } + + fStruct->topLevel = requiredTallness; + } + + + // Traverse down to level 0, adding anything we need + + l = fStruct->topLevel; + tn = fStruct->top; + while (l > 0 && tn) + { + x = (chunkId >> (/*dev->chunkGroupBits + */YAFFS_TNODES_LEVEL0_BITS + (l-1) * YAFFS_TNODES_INTERNAL_BITS)) & + YAFFS_TNODES_INTERNAL_MASK; + + //T((TSTR(" [%d:%d]"),l,i)); + + if(!tn->internal[x]) + { + //T((TSTR(" added"))); + + tn->internal[x] = yaffs_GetTnode(dev); + } + + tn = tn->internal[x]; + l--; + + } + + //TSTR(TENDSTR))); + + return tn; +} + +// DeleteWorker scans backwards through the tnode tree and deletes all the +// chunks and tnodes in the file +// Returns 1 if the tree was deleted. Returns 0 if it stopped early due to hitting the limit and the delete is incomplete. + +static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset,int *limit) +{ + int i; + int chunkInInode; + int theChunk; + yaffs_Tags tags; + int found; + int chunkDeleted; + int allDone = 1; + + + if(tn) + { + if(level > 0) + { + + for(i = YAFFS_NTNODES_INTERNAL -1; allDone && i >= 0; i--) + { + if(tn->internal[i]) + { + if(limit && (*limit) < 0) + { + allDone = 0; + } + else + { + allDone = yaffs_DeleteWorker(in,tn->internal[i],level - 1, + (chunkOffset << YAFFS_TNODES_INTERNAL_BITS ) + i ,limit); + } + if(allDone) + { + yaffs_FreeTnode(in->myDev,tn->internal[i]); + tn->internal[i] = NULL; + } + } + + } + return (allDone) ? 1 : 0; + } + else if(level == 0) + { + int hitLimit = 0; + + for(i = YAFFS_NTNODES_LEVEL0 -1; i >= 0 && !hitLimit; i--) + { + if(tn->level0[i]) + { + int j; + + chunkInInode = (chunkOffset << YAFFS_TNODES_LEVEL0_BITS ) + i; + + theChunk = tn->level0[i] << in->myDev->chunkGroupBits; + + // Now we need to search for it + for(j = 0,found = 0; theChunk && j < in->myDev->chunkGroupSize && !found; j++) + { + yaffs_ReadChunkTagsFromNAND(in->myDev,theChunk,&tags,&chunkDeleted); + if(yaffs_TagsMatch(&tags,in->objectId,chunkInInode,chunkDeleted)) + { + // found it; + found = 1; + + } + else + { + theChunk++; + } + } + + if(found) + { + yaffs_DeleteChunk(in->myDev,theChunk,1); + in->nDataChunks--; + if(limit) + { + *limit = *limit-1; + if(*limit <= 0) + { + hitLimit = 1; + } + } + + } + + tn->level0[i] = 0; + } + + } + return (i < 0) ? 1 : 0; + + + } + + } + + return 1; + +} + +// SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file. +// All soft deleting does is increment the block's softdelete count and pulls the chunk out +// of the tnode. +// THus, essentially this is the same as DeleteWorker except that the chunks are soft deleted. +// +static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level, int chunkOffset) +{ + int i; + int chunkInInode; + int theChunk; + yaffs_BlockInfo *theBlock; + yaffs_Tags tags; + int found; + int chunkDeleted; + int allDone = 1; + + + if(tn) + { + if(level > 0) + { + + for(i = YAFFS_NTNODES_INTERNAL -1; allDone && i >= 0; i--) + { + if(tn->internal[i]) + { + allDone = yaffs_SoftDeleteWorker(in,tn->internal[i],level - 1, + (chunkOffset << YAFFS_TNODES_INTERNAL_BITS ) + i); + if(allDone) + { + yaffs_FreeTnode(in->myDev,tn->internal[i]); + tn->internal[i] = NULL; + } + else + { + //Hoosterman... how could this happen. + } + } + } + return (allDone) ? 1 : 0; + } + else if(level == 0) + { + + for(i = YAFFS_NTNODES_LEVEL0 -1; i >=0; i--) + { + if(tn->level0[i]) + { + // Note this does not find the real chunk, only the chunk group. + // We make an assumption that a chunk group is niot larger than a block. + theChunk = (tn->level0[i] << in->myDev->chunkGroupBits); + T(YAFFS_TRACE_SCAN,(TSTR("soft delete tch %d cgb %d chunk %d" TENDSTR), + tn->level0[i],in->myDev->chunkGroupBits,theChunk)); + + theBlock = yaffs_GetBlockInfo(in->myDev, theChunk/in->myDev->nChunksPerBlock); + if(theBlock) + { + theBlock->softDeletions++; + } + tn->level0[i] = 0; + } + + } + return 1; + + } + + } + + return 1; + +} + + + +static void yaffs_SoftDeleteFile(yaffs_Object *obj) +{ + if(obj->deleted && + obj->variantType == YAFFS_OBJECT_TYPE_FILE && + !obj->softDeleted) + { + if(obj->nDataChunks <= 0) + { + // Empty file, just delete it immediately + yaffs_FreeTnode(obj->myDev,obj->variant.fileVariant.top); + obj->variant.fileVariant.top = NULL; + T(YAFFS_TRACE_TRACING,(TSTR("yaffs: Deleting empty file %d" TENDSTR),obj->objectId)); + yaffs_DoGenericObjectDeletion(obj); + } + else + { + yaffs_SoftDeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0); + obj->softDeleted = 1; + } + } +} + + + + + +// Pruning removes any part of the file structure tree that is beyond the +// bounds of the file (ie that does not point to chunks). +// +// A file should only get pruned when its size is reduced. +// +// Before pruning, the chunks must be pulled from the tree and the +// level 0 tnode entries must be zeroed out. +// Could also use this for file deletion, but that's probably better handled +// by a special case. + +// yaffs_PruneWorker should only be called by yaffs_PruneFileStructure() + +static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn, __u32 level, int del0) +{ + int i; + int hasData; + + if(tn) + { + hasData = 0; + + for(i = 0; i < YAFFS_NTNODES_INTERNAL; i++) + { + if(tn->internal[i] && level > 0) + { + tn->internal[i] = yaffs_PruneWorker(dev,tn->internal[i],level - 1, ( i == 0) ? del0 : 1); + } + + if(tn->internal[i]) + { + hasData++; + } + } + + if(hasData == 0 && del0) + { + // Free and return NULL + + yaffs_FreeTnode(dev,tn); + tn = NULL; + } + + } + + return tn; + +} + +static int yaffs_PruneFileStructure(yaffs_Device *dev, yaffs_FileStructure *fStruct) +{ + int i; + int hasData; + int done = 0; + yaffs_Tnode *tn; + + if(fStruct->topLevel > 0) + { + fStruct->top = yaffs_PruneWorker(dev,fStruct->top, fStruct->topLevel,0); + + // Now we have a tree with all the non-zero branches NULL but the height + // is the same as it was. + // Let's see if we can trim internal tnodes to shorten the tree. + // We can do this if only the 0th element in the tnode is in use + // (ie all the non-zero are NULL) + + while(fStruct->topLevel && !done) + { + tn = fStruct->top; + + hasData = 0; + for(i = 1; i internal[i]) + { + hasData++; + } + } + + if(!hasData) + { + fStruct->top = tn->internal[0]; + fStruct->topLevel--; + yaffs_FreeTnode(dev,tn); + } + else + { + done = 1; + } + } + } + + return YAFFS_OK; +} + + + + + +/////////////////////// End of File Structure functions. ///////////////// + +// yaffs_CreateFreeObjects creates a bunch more objects and +// adds them to the object free list. +static int yaffs_CreateFreeObjects(yaffs_Device *dev, int nObjects) +{ + int i; + yaffs_Object *newObjects; + yaffs_ObjectList *list; + + if(nObjects < 1) return YAFFS_OK; + + // make these things + + newObjects = YMALLOC(nObjects * sizeof(yaffs_Object)); + + if (!newObjects) + { + T(YAFFS_TRACE_ALLOCATE,(TSTR("yaffs: Could not allocate more objects" TENDSTR))); + return YAFFS_FAIL; + } + + // Hook them into the free list + for(i = 0; i < nObjects - 1; i++) + { + newObjects[i].siblings.next = (struct list_head *)(&newObjects[i+1]); + } + + newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects; + dev->freeObjects = newObjects; + dev->nFreeObjects+= nObjects; + dev->nObjectsCreated+= nObjects; + + // Now add this bunch of Objects to a list for freeing up. + + list = YMALLOC(sizeof(yaffs_ObjectList)); + if(!list) + { + T(YAFFS_TRACE_ALLOCATE,(TSTR("Could not add objects to management list" TENDSTR))); + } + else + { + list->objects = newObjects; + list->next = dev->allocatedObjectList; + dev->allocatedObjectList = list; + } + + + + return YAFFS_OK; +} + + +// AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out +static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev) +{ + yaffs_Object *tn = NULL; + + // If there are none left make more + if(!dev->freeObjects) + { + yaffs_CreateFreeObjects(dev,YAFFS_ALLOCATION_NOBJECTS); + } + + if(dev->freeObjects) + { + tn = dev->freeObjects; + dev->freeObjects = (yaffs_Object *)(dev->freeObjects->siblings.next); + dev->nFreeObjects--; + + // Now sweeten it up... + + memset(tn,0,sizeof(yaffs_Object)); + tn->myDev = dev; + tn->chunkId = -1; + tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN; + INIT_LIST_HEAD(&(tn->hardLinks)); + INIT_LIST_HEAD(&(tn->hashLink)); + INIT_LIST_HEAD(&tn->siblings); + + // Add it to the lost and found directory. + // NB Can't put root or lostNFound in lostNFound so + // check if lostNFound exists first + if(dev->lostNFoundDir) + { + yaffs_AddObjectToDirectory(dev->lostNFoundDir,tn); + } + } + + + return tn; +} + +static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device *dev,int number,__u32 mode) +{ + + yaffs_Object *obj = yaffs_CreateNewObject(dev,number,YAFFS_OBJECT_TYPE_DIRECTORY); + if(obj) + { + obj->fake = 1; // it is fake so it has no NAND presence... + obj->renameAllowed= 0; // ... and we're not allowed to rename it... + obj->unlinkAllowed= 0; // ... or unlink it + obj->deleted = 0; + obj->unlinked = 0; + obj->st_mode = mode; + obj->myDev = dev; + obj->chunkId = 0; // Not a valid chunk. + } + + return obj; + +} + + +static void yaffs_UnhashObject(yaffs_Object *tn) +{ + int bucket; + yaffs_Device *dev = tn->myDev; + + + // If it is still linked into the bucket list, free from the list + if(!list_empty(&tn->hashLink)) + { + list_del_init(&tn->hashLink); + bucket = yaffs_HashFunction(tn->objectId); + dev->objectBucket[bucket].count--; + } + +} + + +// FreeObject frees up a Object and puts it back on the free list +static void yaffs_FreeObject(yaffs_Object *tn) +{ + + yaffs_Device *dev = tn->myDev; + +#ifdef __KERNEL__ + if(tn->myInode) + { + // We're still hooked up to a cached inode. + // Don't delete now, but mark for later deletion + tn->deferedFree = 1; + return; + } +#endif + + yaffs_UnhashObject(tn); + + // Link into the free list. + tn->siblings.next = (struct list_head *)(dev->freeObjects); + dev->freeObjects = tn; + dev->nFreeObjects++; +} + + +#ifdef __KERNEL__ + +void yaffs_HandleDeferedFree(yaffs_Object *obj) +{ + if(obj->deferedFree) + { + yaffs_FreeObject(obj); + } +} + +#endif + + + +static void yaffs_DeinitialiseObjects(yaffs_Device *dev) +{ + // Free the list of allocated Objects + + yaffs_ObjectList *tmp; + + while( dev->allocatedObjectList) + { + tmp = dev->allocatedObjectList->next; + YFREE(dev->allocatedObjectList->objects); + YFREE(dev->allocatedObjectList); + + dev->allocatedObjectList = tmp; + } + + dev->freeObjects = NULL; + dev->nFreeObjects = 0; +} + +static void yaffs_InitialiseObjects(yaffs_Device *dev) +{ + int i; + + dev->allocatedObjectList = NULL; + dev->freeObjects = NULL; + dev->nFreeObjects = 0; + + for(i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) + { + INIT_LIST_HEAD(&dev->objectBucket[i].list); + dev->objectBucket[i].count = 0; + } + +} + + + + + + +int yaffs_FindNiceObjectBucket(yaffs_Device *dev) +{ + static int x = 0; + int i; + int l = 999; + int lowest = 999999; + + + // First let's see if we can find one that's empty. + + for(i = 0; i < 10 && lowest > 0; i++) + { + x++; + x %= YAFFS_NOBJECT_BUCKETS; + if(dev->objectBucket[x].count < lowest) + { + lowest = dev->objectBucket[x].count; + l = x; + } + + } + + // If we didn't find an empty list, then try + // looking a bit further for a short one + + for(i = 0; i < 10 && lowest > 3; i++) + { + x++; + x %= YAFFS_NOBJECT_BUCKETS; + if(dev->objectBucket[x].count < lowest) + { + lowest = dev->objectBucket[x].count; + l = x; + } + + } + + return l; +} + +static int yaffs_CreateNewObjectNumber(yaffs_Device *dev) +{ + int bucket = yaffs_FindNiceObjectBucket(dev); + + // Now find an object value that has not already been taken + // by scanning the list. + + int found = 0; + struct list_head *i; + + __u32 n = (__u32)bucket; + + //yaffs_CheckObjectHashSanity(); + + while(!found) + { + found = 1; + n += YAFFS_NOBJECT_BUCKETS; + if(1 ||dev->objectBucket[bucket].count > 0) + { + list_for_each(i,&dev->objectBucket[bucket].list) + { + // If there is already one in the list + if(i && list_entry(i, yaffs_Object,hashLink)->objectId == n) + { + found = 0; + } + } + } + } + + //T(("bucket %d count %d inode %d\n",bucket,yaffs_objectBucket[bucket].count,n); + + return n; +} + +void yaffs_HashObject(yaffs_Object *in) +{ + int bucket = yaffs_HashFunction(in->objectId); + yaffs_Device *dev = in->myDev; + + if(!list_empty(&in->hashLink)) + { + //YINFO("!!!"); + } + + + list_add(&in->hashLink,&dev->objectBucket[bucket].list); + dev->objectBucket[bucket].count++; + +} + +yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,__u32 number) +{ + int bucket = yaffs_HashFunction(number); + struct list_head *i; + yaffs_Object *in; + + list_for_each(i,&dev->objectBucket[bucket].list) + { + // Look if it is in the list + if(i) + { + in = list_entry(i, yaffs_Object,hashLink); + if(in->objectId == number) + { + return in; + } + } + } + + return NULL; +} + + + +yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev,int number,yaffs_ObjectType type) +{ + + yaffs_Object *theObject; + + if(number < 0) + { + number = yaffs_CreateNewObjectNumber(dev); + } + + theObject = yaffs_AllocateEmptyObject(dev); + + if(theObject) + { + theObject->fake = 0; + theObject->renameAllowed = 1; + theObject->unlinkAllowed = 1; + theObject->objectId = number; + yaffs_HashObject(theObject); + theObject->variantType = type; +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(theObject->win_atime); + theObject->win_ctime[0] = theObject->win_mtime[0] = theObject->win_atime[0]; + theObject->win_ctime[1] = theObject->win_mtime[1] = theObject->win_atime[1]; + +#else + + theObject->st_atime = theObject->st_mtime = theObject->st_ctime = Y_CURRENT_TIME; + +#endif + switch(type) + { + case YAFFS_OBJECT_TYPE_FILE: + theObject->variant.fileVariant.fileSize = 0; + theObject->variant.fileVariant.scannedFileSize = 0; + theObject->variant.fileVariant.topLevel = 0; + theObject->variant.fileVariant.top = yaffs_GetTnode(dev); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + INIT_LIST_HEAD(&theObject->variant.directoryVariant.children); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + // No action required + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + // No action required + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + // No action required + break; + case YAFFS_OBJECT_TYPE_UNKNOWN: + // todo this should not happen + break; + } + } + + return theObject; +} + +yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev, int number,yaffs_ObjectType type) +{ + yaffs_Object *theObject = NULL; + + if(number > 0) + { + theObject = yaffs_FindObjectByNumber(dev,number); + } + + if(!theObject) + { + theObject = yaffs_CreateNewObject(dev,number,type); + } + + return theObject; + +} + +char *yaffs_CloneString(const char *str) +{ + char *newStr = NULL; + + if(str && *str) + { + newStr = YMALLOC(strlen(str) + 1); + strcpy(newStr,str); + } + + return newStr; + +} + +// +// Mknod (create) a new object. +// equivalentObject only has meaning for a hard link; +// aliasString only has meaning for a sumlink. +// rdev only has meaning for devices (a subset of special objects) +yaffs_Object *yaffs_MknodObject( yaffs_ObjectType type, + yaffs_Object *parent, + const char *name, + __u32 mode, + __u32 uid, + __u32 gid, + yaffs_Object *equivalentObject, + const char *aliasString, + __u32 rdev) +{ + yaffs_Object *in; + + yaffs_Device *dev = parent->myDev; + + // Check if the entry exists. If it does then fail the call since we don't want a dup. + if(yaffs_FindObjectByName(parent,name)) + { + return NULL; + } + + in = yaffs_CreateNewObject(dev,-1,type); + + if(in) + { + in->chunkId = -1; + in->valid = 1; + in->variantType = type; + + in->st_mode = mode; + +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(in->win_atime); + in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0]; + in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1]; + +#else + + in->st_atime = in->st_mtime = in->st_ctime = Y_CURRENT_TIME; + in->st_rdev = rdev; + in->st_uid = uid; + in->st_gid = gid; +#endif + in->nDataChunks = 0; + + yaffs_SetObjectName(in,name); + in->dirty = 1; + + yaffs_AddObjectToDirectory(parent,in); + + in->myDev = parent->myDev; + + + switch(type) + { + case YAFFS_OBJECT_TYPE_SYMLINK: + in->variant.symLinkVariant.alias = yaffs_CloneString(aliasString); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + in->variant.hardLinkVariant.equivalentObject = equivalentObject; + in->variant.hardLinkVariant.equivalentObjectId = equivalentObject->objectId; + list_add(&in->hardLinks,&equivalentObject->hardLinks); + break; + case YAFFS_OBJECT_TYPE_FILE: // do nothing + case YAFFS_OBJECT_TYPE_DIRECTORY: // do nothing + case YAFFS_OBJECT_TYPE_SPECIAL: // do nothing + case YAFFS_OBJECT_TYPE_UNKNOWN: + break; + } + + if(/*yaffs_GetNumberOfFreeChunks(dev) <= 0 || */ + yaffs_UpdateObjectHeader(in,name,0) < 0) + { + // Could not create the object header, fail the creation + yaffs_AbortHalfCreatedObject(in); + in = NULL; + } + + } + + return in; +} + +yaffs_Object *yaffs_MknodFile(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_FILE,parent,name,mode,uid,gid,NULL,NULL,0); +} + +yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY,parent,name,mode,uid,gid,NULL,NULL,0); +} + +yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid, __u32 rdev) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY,parent,name,mode,uid,gid,NULL,NULL,rdev); +} + +yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid,const char *alias) +{ + return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SYMLINK,parent,name,mode,uid,gid,NULL,alias,0); +} + +// NB yaffs_Link returns the object id of the equivalent object. +yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *equivalentObject) +{ + // Get the real object in case we were fed a hard link as an equivalent object + equivalentObject = yaffs_GetEquivalentObject(equivalentObject); + + if(yaffs_MknodObject(YAFFS_OBJECT_TYPE_HARDLINK,parent,name,0,0,0,equivalentObject,NULL,0)) + { + return equivalentObject; + } + else + { + return NULL; + } + +} + + +static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir, const char *newName,int force) +{ + int unlinkOp; + + if(newDir == NULL) + { + newDir = obj->parent; // use the old directory + } + + unlinkOp = (newDir == obj->myDev->unlinkedDir && obj->variantType == YAFFS_OBJECT_TYPE_FILE); + + // If the object is a file going into the unlinked directory, then it is OK to just stuff it in since + // duplicate names are allowed. + // Otherwise only proceed if the new name does not exist and if we're putting it into a directory. + if( (unlinkOp|| + force || + !yaffs_FindObjectByName(newDir,newName)) && + newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) + { + yaffs_SetObjectName(obj,newName); + obj->dirty = 1; + + yaffs_AddObjectToDirectory(newDir,obj); + + if(unlinkOp) obj->unlinked = 1; + + + if(yaffs_UpdateObjectHeader(obj,newName,0) >= 0) + { + return YAFFS_OK; + } + } + + return YAFFS_FAIL; +} + + + +int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object *newDir, const char *newName) +{ + yaffs_Object *obj; + int force = 0; + +#ifdef CONFIG_YAFFS_CASE_INSENSITIVE + // Special case for WinCE. + // While look-up is case insensitive, the name isn't. + // THerefore we might want to change x.txt to X.txt + if(oldDir == newDir && _stricmp(oldName,newName) == 0) + { + force = 1; + } +#endif + + obj = yaffs_FindObjectByName(oldDir,oldName); + if(obj && obj->renameAllowed) + { + return yaffs_ChangeObjectName(obj,newDir,newName,force); + } + return YAFFS_FAIL; +} + + + +static int yaffs_CheckObjectHashSanity(yaffs_Device *dev) +{ + // Scan the buckets and check that the lists + // have as many members as the count says there are + int bucket; + int countEm; + struct list_head *j; + int ok = YAFFS_OK; + + for(bucket = 0; bucket < YAFFS_NOBJECT_BUCKETS; bucket++) + { + countEm = 0; + + list_for_each(j,&dev->objectBucket[bucket].list) + { + countEm++; + } + + if(countEm != dev->objectBucket[bucket].count) + { + T(YAFFS_TRACE_ERROR,(TSTR("Inode hash inconsistency" TENDSTR))); + ok = YAFFS_FAIL; + } + } + + return ok; +} + +#if 0 +void yaffs_ObjectTest(yaffs_Device *dev) +{ + yaffs_Object *in[1000]; + int inNo[1000]; + yaffs_Object *inold[1000]; + int i; + int j; + + memset(in,0,1000*sizeof(yaffs_Object *)); + memset(inold,0,1000*sizeof(yaffs_Object *)); + + yaffs_CheckObjectHashSanity(dev); + + for(j = 0; j < 10; j++) + { + //T(("%d\n",j)); + + for(i = 0; i < 1000; i++) + { + in[i] = yaffs_CreateNewObject(dev,-1,YAFFS_OBJECT_TYPE_FILE); + if(!in[i]) + { + YINFO("No more inodes"); + } + else + { + inNo[i] = in[i]->objectId; + } + } + + for(i = 0; i < 1000; i++) + { + if(yaffs_FindObjectByNumber(dev,inNo[i]) != in[i]) + { + //T(("Differnce in look up test\n")); + } + else + { + // T(("Look up ok\n")); + } + } + + yaffs_CheckObjectHashSanity(dev); + + for(i = 0; i < 1000; i+=3) + { + yaffs_FreeObject(in[i]); + in[i] = NULL; + } + + + yaffs_CheckObjectHashSanity(dev); + } + +} + +#endif + +/////////////////////////// Block Management and Page Allocation /////////////////// + + +static int yaffs_InitialiseBlocks(yaffs_Device *dev,int nBlocks) +{ + dev->allocationBlock = -1; // force it to get a new one + //Todo we're assuming the malloc will pass. + dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo)); + // Set up dynamic blockinfo stuff. + dev->chunkBitmapStride = (dev->nChunksPerBlock+7)/8; + dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks); + if(dev->blockInfo && dev->chunkBits) + { + memset(dev->blockInfo,0,nBlocks * sizeof(yaffs_BlockInfo)); + memset(dev->chunkBits,0,dev->chunkBitmapStride * nBlocks); + return YAFFS_OK; + } + + return YAFFS_FAIL; + +} + +static void yaffs_DeinitialiseBlocks(yaffs_Device *dev) +{ + YFREE(dev->blockInfo); + dev->blockInfo = NULL; + YFREE(dev->chunkBits); + dev->chunkBits = NULL; +} + +// FindDiretiestBlock is used to select the dirtiest block (or close enough) +// for garbage collection. + +static int yaffs_FindDirtiestBlock(yaffs_Device *dev,int aggressive) +{ + + int b = dev->currentDirtyChecker; + + int i; + int iterations; + int dirtiest = -1; + int pagesInUse; + yaffs_BlockInfo *bi; + + // If we're doing aggressive GC then we are happy to take a less-dirty block, and + // search further. + + pagesInUse = (aggressive)? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1; + if(aggressive) + { + iterations = dev->endBlock - dev->startBlock + 1; + } + else + { + iterations = dev->endBlock - dev->startBlock + 1; + iterations = iterations / 16; + if(iterations > 200) + { + iterations = 200; + } + } + + for(i = 0; i <= iterations && pagesInUse > 0 ; i++) + { + b++; + if ( b < dev->startBlock || b > dev->endBlock) + { + b = dev->startBlock; + } + + if(b < dev->startBlock || b > dev->endBlock) + { + T(YAFFS_TRACE_ERROR,(TSTR("**>> Block %d is not valid" TENDSTR),b)); + YBUG(); + } + + bi = yaffs_GetBlockInfo(dev,b); + + if(bi->blockState == YAFFS_BLOCK_STATE_FULL && + (bi->pagesInUse - bi->softDeletions )< pagesInUse) + { + dirtiest = b; + pagesInUse = (bi->pagesInUse - bi->softDeletions); + } + } + + dev->currentDirtyChecker = b; + + return dirtiest; +} + + +static void yaffs_BlockBecameDirty(yaffs_Device *dev,int blockNo) +{ + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,blockNo); + + int erasedOk = 0; + + // If the block is still healthy erase it and mark as clean. + // If the block has had a data failure, then retire it. + bi->blockState = YAFFS_BLOCK_STATE_DIRTY; + + if(!bi->needsRetiring) + { + erasedOk = yaffs_EraseBlockInNAND(dev,blockNo); + if(!erasedOk) + { + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>> Erasure failed %d" TENDSTR),blockNo)); + } + } + + if( erasedOk ) + { + // Clean it up... + bi->blockState = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + bi->pagesInUse = 0; + bi->softDeletions = 0; + yaffs_ClearChunkBits(dev,blockNo); + + T(YAFFS_TRACE_ERASE,(TSTR("Erased block %d" TENDSTR),blockNo)); + } + else + { + yaffs_RetireBlock(dev,blockNo); + T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,(TSTR("**>> Block %d retired" TENDSTR),blockNo)); + } +} + + +static int yaffs_FindBlockForAllocation(yaffs_Device *dev) +{ + int i; + + yaffs_BlockInfo *bi; + + if(dev->nErasedBlocks < 1) + { + // Hoosterman we've got a problem. + // Can't get space to gc + T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: no space during gc" TENDSTR))); + + return -1; + } + + // Find an empty block. + + for(i = dev->startBlock; i <= dev->endBlock; i++) + { + dev->allocationBlockFinder++; + if(dev->allocationBlockFinder startBlock || dev->allocationBlockFinder> dev->endBlock) + { + dev->allocationBlockFinder = dev->startBlock; + } + + bi = yaffs_GetBlockInfo(dev,dev->allocationBlockFinder); + + if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY) + { + bi->blockState = YAFFS_BLOCK_STATE_ALLOCATING; + dev->nErasedBlocks--; + return dev->allocationBlockFinder; + } + } + + return -1; +} + + + +static int yaffs_AllocateChunk(yaffs_Device *dev,int useReserve) +{ + int retVal; + yaffs_BlockInfo *bi; + + if(dev->allocationBlock < 0) + { + // Get next block to allocate off + dev->allocationBlock = yaffs_FindBlockForAllocation(dev); + dev->allocationPage = 0; + } + + if(!useReserve && dev->nErasedBlocks <= dev->nReservedBlocks) + { + // Not enough space to allocate unless we're allowed to use the reserve. + return -1; + } + + // Next page please.... + if(dev->allocationBlock >= 0) + { + bi = yaffs_GetBlockInfo(dev,dev->allocationBlock); + + retVal = (dev->allocationBlock * dev->nChunksPerBlock) + + dev->allocationPage; + bi->pagesInUse++; + yaffs_SetChunkBit(dev,dev->allocationBlock,dev->allocationPage); + + dev->allocationPage++; + + dev->nFreeChunks--; + + // If the block is full set the state to full + if(dev->allocationPage >= dev->nChunksPerBlock) + { + bi->blockState = YAFFS_BLOCK_STATE_FULL; + dev->allocationBlock = -1; + } + + + return retVal; + + } + T(YAFFS_TRACE_ERROR,(TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR))); + + return -1; +} + +// To determine if we have enough space we just look at the +// number of erased blocks. +// The cache is allowed to use reserved blocks. + +static int yaffs_CheckSpaceForChunkCache(yaffs_Device *dev) +{ + return (dev->nErasedBlocks >= dev->nReservedBlocks); +} + + +static int yaffs_GarbageCollectBlock(yaffs_Device *dev,int block) +{ + int oldChunk; + int newChunk; + int chunkInBlock; + int markNAND; + + + yaffs_Spare spare; + yaffs_Tags tags; + __u8 buffer[YAFFS_BYTES_PER_CHUNK]; + +// yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,block); + + yaffs_Object *object; + + //T(("Collecting block %d n %d bits %x\n",block, bi->pagesInUse, bi->pageBits)); + + for(chunkInBlock = 0,oldChunk = block * dev->nChunksPerBlock; + chunkInBlock < dev->nChunksPerBlock && yaffs_StillSomeChunkBits(dev,block); + chunkInBlock++, oldChunk++ ) + { + if(yaffs_CheckChunkBit(dev,block,chunkInBlock)) + { + + // This page is in use and might need to be copied off + + markNAND = 1; + + //T(("copying page %x from %d to %d\n",mask,oldChunk,newChunk)); + + yaffs_ReadChunkFromNAND(dev,oldChunk,buffer, &spare,1); + + yaffs_GetTagsFromSpare(dev,&spare,&tags); + + object = yaffs_FindObjectByNumber(dev,tags.objectId); + + if(object && object->deleted && tags.chunkId != 0) + { + // Data chunk in a deleted file, throw it away + // It's a deleted data chunk, + // No need to copy this, just forget about it and fix up the + // object. + + //yaffs_PutChunkIntoFile(object, tags.chunkId, 0,0); + object->nDataChunks--; + + if(object->nDataChunks <= 0) + { + // Time to delete the file too + yaffs_FreeTnode(object->myDev,object->variant.fileVariant.top); + object->variant.fileVariant.top = NULL; + T(YAFFS_TRACE_TRACING,(TSTR("yaffs: About to finally delete object %d" TENDSTR),object->objectId)); + yaffs_DoGenericObjectDeletion(object); + } + markNAND = 0; + } + else if( 0 /* Todo object && object->deleted && object->nDataChunks == 0 */) + { + // Deleted object header with no data chunks. + // Can be discarded and the file deleted. + object->chunkId = 0; + yaffs_FreeTnode(object->myDev,object->variant.fileVariant.top); + object->variant.fileVariant.top = NULL; + yaffs_DoGenericObjectDeletion(object); + + } + else if(object) + { + // It's either a data chunk in a live file or + // an ObjectHeader, so we're interested in it. + // NB Need to keep the ObjectHeaders of deleted files + // until the whole file has been deleted off + tags.serialNumber++; + yaffs_LoadTagsIntoSpare(&spare,&tags); + + dev->nGCCopies++; + + newChunk = yaffs_WriteNewChunkToNAND(dev, buffer, &spare,1); + + if(newChunk < 0) + { + return YAFFS_FAIL; + } + + // Ok, now fix up the Tnodes etc. + + if(tags.chunkId == 0) + { + // It's a header + object->chunkId = newChunk; + object->serial = tags.serialNumber; + } + else + { + // It's a data chunk + yaffs_PutChunkIntoFile(object, tags.chunkId, newChunk,0); + } + } + + yaffs_DeleteChunk(dev,oldChunk,markNAND); + + } + } + + return YAFFS_OK; +} + + +static yaffs_Object *yaffs_FindDeletedUnlinkedFile(yaffs_Device *dev) +{ + // find a file to delete + struct list_head *i; + yaffs_Object *l; + + + //Scan the unlinked files looking for one to delete + list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children) + { + if(i) + { + l = list_entry(i, yaffs_Object,siblings); + if(l->deleted) + { + return l; + } + } + } + return NULL; +} + + +static void yaffs_DoUnlinkedFileDeletion(yaffs_Device *dev) +{ + // This does background deletion on unlinked files.. only deleted ones. + // If we don't have a file we're working on then find one + if(!dev->unlinkedDeletion && dev->nDeletedFiles > 0) + { + dev->unlinkedDeletion = yaffs_FindDeletedUnlinkedFile(dev); + } + + // OK, we're working on a file... + if(dev->unlinkedDeletion) + { + yaffs_Object *obj = dev->unlinkedDeletion; + int delresult; + int limit; // Number of chunks to delete in a file. + // NB this can be exceeded, but not by much. + + limit = -1; + + delresult = yaffs_DeleteWorker(obj, obj->variant.fileVariant.top, obj->variant.fileVariant.topLevel, 0,&limit); + + if(obj->nDataChunks == 0) + { + // Done all the deleting of data chunks. + // Now dump the header and clean up + yaffs_FreeTnode(dev,obj->variant.fileVariant.top); + obj->variant.fileVariant.top = NULL; + yaffs_DoGenericObjectDeletion(obj); + dev->nDeletedFiles--; + dev->nUnlinkedFiles--; + dev->nBackgroundDeletions++; + dev->unlinkedDeletion = NULL; + } + } +} + + +#if 0 +#define YAFFS_GARBAGE_COLLECT_LOW_WATER 2 +static int yaffs_CheckGarbageCollection(yaffs_Device *dev) +{ + int block; + int aggressive=0; + + //yaffs_DoUnlinkedFileDeletion(dev); + + if(dev->nErasedBlocks <= (dev->nReservedBlocks + YAFFS_GARBAGE_COLLECT_LOW_WATER)) + { + aggressive = 1; + } + + if(aggressive) + { + block = yaffs_FindDirtiestBlock(dev,aggressive); + + if(block >= 0) + { + dev->garbageCollections++; + return yaffs_GarbageCollectBlock(dev,block); + } + else + { + return YAFFS_FAIL; + } + } + + return YAFFS_OK; +} +#endif + +// New garbage collector +// If we're very low on erased blocks then we do aggressive garbage collection +// otherwise we do "passive" garbage collection. +// Aggressive gc looks further (whole array) and will accept dirtier blocks. +// Passive gc only inspects smaller areas and will only accept cleaner blocks. +// +// The idea is to help clear out space in a more spread-out manner. +// Dunno if it really does anything useful. +// +static int yaffs_CheckGarbageCollection(yaffs_Device *dev) +{ + int block; + int aggressive=0; + + //yaffs_DoUnlinkedFileDeletion(dev); + + if(dev->nErasedBlocks <= (dev->nReservedBlocks + 1)) + { + aggressive = 1; + } + + block = yaffs_FindDirtiestBlock(dev,aggressive); + + if(block >= 0) + { + dev->garbageCollections++; + if(!aggressive) + { + dev->passiveGarbageCollections++; + } + + T(YAFFS_TRACE_GC,(TSTR("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),dev->nErasedBlocks,aggressive)); + + return yaffs_GarbageCollectBlock(dev,block); + } + + return aggressive ? YAFFS_FAIL : YAFFS_OK; +} + + +//////////////////////////// TAGS /////////////////////////////////////// + +static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr) +{ + yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr; + + yaffs_CalcTagsECC(tagsPtr); + + sparePtr->tagByte0 = tu->asBytes[0]; + sparePtr->tagByte1 = tu->asBytes[1]; + sparePtr->tagByte2 = tu->asBytes[2]; + sparePtr->tagByte3 = tu->asBytes[3]; + sparePtr->tagByte4 = tu->asBytes[4]; + sparePtr->tagByte5 = tu->asBytes[5]; + sparePtr->tagByte6 = tu->asBytes[6]; + sparePtr->tagByte7 = tu->asBytes[7]; +} + +static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,yaffs_Tags *tagsPtr) +{ + yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr; + int result; + + tu->asBytes[0]= sparePtr->tagByte0; + tu->asBytes[1]= sparePtr->tagByte1; + tu->asBytes[2]= sparePtr->tagByte2; + tu->asBytes[3]= sparePtr->tagByte3; + tu->asBytes[4]= sparePtr->tagByte4; + tu->asBytes[5]= sparePtr->tagByte5; + tu->asBytes[6]= sparePtr->tagByte6; + tu->asBytes[7]= sparePtr->tagByte7; + + result = yaffs_CheckECCOnTags(tagsPtr); + if(result> 0) + { + dev->tagsEccFixed++; + } + else if(result <0) + { + dev->tagsEccUnfixed++; + } +} + +static void yaffs_SpareInitialise(yaffs_Spare *spare) +{ + memset(spare,0xFF,sizeof(yaffs_Spare)); +} + +static int yaffs_ReadChunkTagsFromNAND(yaffs_Device *dev,int chunkInNAND, yaffs_Tags *tags, int *chunkDeleted) +{ + if(tags) + { + yaffs_Spare spare; + if(yaffs_ReadChunkFromNAND(dev,chunkInNAND,NULL,&spare,1) == YAFFS_OK) + { + *chunkDeleted = (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0; + yaffs_GetTagsFromSpare(dev,&spare,tags); + return YAFFS_OK; + } + else + { + return YAFFS_FAIL; + } + } + + return YAFFS_OK; +} + +#if 0 +static int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND, const __u8 *buffer, yaffs_Tags *tags) +{ + // NB There must be tags, data is optional + // If there is data, then an ECC is calculated on it. + + yaffs_Spare spare; + + if(!tags) + { + return YAFFS_FAIL; + } + + yaffs_SpareInitialise(&spare); + + if(!dev->useNANDECC && buffer) + { + yaffs_CalcECC(buffer,&spare); + } + + yaffs_LoadTagsIntoSpare(&spare,tags); + + return yaffs_WriteChunkToNAND(dev,chunkInNAND,buffer,&spare); + +} +#endif + + +static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device *dev, const __u8 *buffer, yaffs_Tags *tags, int useReserve) +{ + // NB There must be tags, data is optional + // If there is data, then an ECC is calculated on it. + + yaffs_Spare spare; + + if(!tags) + { + return YAFFS_FAIL; + } + + yaffs_SpareInitialise(&spare); + + if(!dev->useNANDECC && buffer) + { + yaffs_CalcECC(buffer,&spare); + } + + yaffs_LoadTagsIntoSpare(&spare,tags); + + return yaffs_WriteNewChunkToNAND(dev,buffer,&spare,useReserve); + +} + +static int yaffs_TagsMatch(const yaffs_Tags *tags, int objectId, int chunkInObject, int chunkDeleted) +{ + return ( tags->chunkId == chunkInObject && + tags->objectId == objectId && + !chunkDeleted) ? 1 : 0; + +} + + + +int yaffs_FindChunkInFile(yaffs_Object *in,int chunkInInode,yaffs_Tags *tags) +{ + //Get the Tnode, then get the level 0 offset chunk offset + yaffs_Tnode *tn; + int theChunk = -1; + yaffs_Tags localTags; + int i; + int found = 0; + int chunkDeleted; + + yaffs_Device *dev = in->myDev; + + + if(!tags) + { + // Passed a NULL, so use our own tags space + tags = &localTags; + } + + tn = yaffs_FindLevel0Tnode(dev,&in->variant.fileVariant, chunkInInode); + + if(tn) + { + theChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits; + + // Now we need to do the shifting etc and search for it + for(i = 0,found = 0; theChunk && i < dev->chunkGroupSize && !found; i++) + { + yaffs_ReadChunkTagsFromNAND(dev,theChunk,tags,&chunkDeleted); + if(yaffs_TagsMatch(tags,in->objectId,chunkInInode,chunkDeleted)) + { + // found it; + found = 1; + } + else + { + theChunk++; + } + } + } + return found ? theChunk : -1; +} + +int yaffs_FindAndDeleteChunkInFile(yaffs_Object *in,int chunkInInode,yaffs_Tags *tags) +{ + //Get the Tnode, then get the level 0 offset chunk offset + yaffs_Tnode *tn; + int theChunk = -1; + yaffs_Tags localTags; + int i; + int found = 0; + yaffs_Device *dev = in->myDev; + int chunkDeleted; + + if(!tags) + { + // Passed a NULL, so use our own tags space + tags = &localTags; + } + + tn = yaffs_FindLevel0Tnode(dev,&in->variant.fileVariant, chunkInInode); + + if(tn) + { + + theChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] << dev->chunkGroupBits; + + // Now we need to do the shifting etc and search for it + for(i = 0,found = 0; theChunk && i < dev->chunkGroupSize && !found; i++) + { + yaffs_ReadChunkTagsFromNAND(dev,theChunk,tags,&chunkDeleted); + if(yaffs_TagsMatch(tags,in->objectId,chunkInInode,chunkDeleted)) + { + // found it; + found = 1; + } + else + { + theChunk++; + } + } + + // Delete the entry in the filestructure + if(found) + { + tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] = 0; + } + } + else + { + //T(("No level 0 found for %d\n", chunkInInode)); + } + + if(!found) + { + //T(("Could not find %d to delete\n",chunkInInode)); + } + return found ? theChunk : -1; +} + + +#ifdef YAFFS_PARANOID + +static int yaffs_CheckFileSanity(yaffs_Object *in) +{ + int chunk; + int nChunks; + int fSize; + int failed = 0; + int objId; + yaffs_Tnode *tn; + yaffs_Tags localTags; + yaffs_Tags *tags = &localTags; + int theChunk; + int chunkDeleted; + + + if(in->variantType != YAFFS_OBJECT_TYPE_FILE) + { + //T(("Object not a file\n")); + return YAFFS_FAIL; + } + + objId = in->objectId; + fSize = in->variant.fileVariant.fileSize; + nChunks = (fSize + in->myDev->nBytesPerChunk -1)/in->myDev->nBytesPerChunk; + + for(chunk = 1; chunk <= nChunks; chunk++) + { + tn = yaffs_FindLevel0Tnode(in->myDev,&in->variant.fileVariant, chunk); + + if(tn) + { + + theChunk = tn->level0[chunk & YAFFS_TNODES_LEVEL0_MASK] << in->myDev->chunkGroupBits; + + + yaffs_ReadChunkTagsFromNAND(in->myDev,theChunk,tags,&chunkDeleted); + if(yaffs_TagsMatch(tags,in->objectId,chunk,chunkDeleted)) + { + // found it; + + } + else + { + //T(("File problem file [%d,%d] NAND %d tags[%d,%d]\n", + // objId,chunk,theChunk,tags->chunkId,tags->objectId); + + failed = 1; + + } + + } + else + { + //T(("No level 0 found for %d\n", chunk)); + } + } + + return failed ? YAFFS_FAIL : YAFFS_OK; +} + +#endif + +static int yaffs_PutChunkIntoFile(yaffs_Object *in,int chunkInInode, int chunkInNAND, int inScan) +{ + yaffs_Tnode *tn; + yaffs_Device *dev = in->myDev; + int existingChunk; + yaffs_Tags existingTags; + yaffs_Tags newTags; + unsigned existingSerial, newSerial; + + int newChunkDeleted; + + + tn = yaffs_AddOrFindLevel0Tnode(dev,&in->variant.fileVariant, chunkInInode); + if(!tn) + { + return YAFFS_FAIL; + } + + existingChunk = tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK]; + + if(inScan) + { + // If we're scanning then we need to test for duplicates + // NB This does not need to be efficient since it should only ever + // happen when the power fails during a write, then only one + // chunk should ever be affected. + + + if(existingChunk != 0) + { + // NB Right now existing chunk will not be real chunkId if the device >= 32MB + // thus we have to do a FindChunkInFile to get the real chunk id. + // + // We have a duplicate now we need to decide which one to use + // To do this we get both sets of tags and compare serial numbers. + yaffs_ReadChunkTagsFromNAND(dev,chunkInNAND, &newTags,&newChunkDeleted); + + + // Do a proper find + existingChunk = yaffs_FindChunkInFile(in,chunkInInode, &existingTags); + + if(existingChunk <=0) + { + //Hoosterman - how did this happen? + + T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: existing chunk < 0 in scan" TENDSTR))); + + } + + + // NB The deleted flags should be false, otherwise the chunks will + // not be loaded during a scan + + newSerial = newTags.serialNumber; + existingSerial = existingTags.serialNumber; + + if( existingChunk <= 0 || + ((existingSerial+1) & 3) == newSerial) + { + // Use new + // Delete the old one and drop through to update the tnode + yaffs_DeleteChunk(dev,existingChunk,1); + } + else + { + // Use existing. + // Delete the new one and return early so that the tnode isn't changed + yaffs_DeleteChunk(dev,chunkInNAND,1); + return YAFFS_OK; + } + } + + } + + if(existingChunk == 0) + { + in->nDataChunks++; + } + + tn->level0[chunkInInode & YAFFS_TNODES_LEVEL0_MASK] = (chunkInNAND >> dev->chunkGroupBits); + + return YAFFS_OK; +} + + + +int yaffs_ReadChunkDataFromObject(yaffs_Object *in,int chunkInInode, __u8 *buffer) +{ + int chunkInNAND = yaffs_FindChunkInFile(in,chunkInInode,NULL); + + if(chunkInNAND >= 0) + { + return yaffs_ReadChunkFromNAND(in->myDev,chunkInNAND,buffer,NULL,1); + } + else + { + memset(buffer,0,YAFFS_BYTES_PER_CHUNK); + return 0; + } + +} + + +static void yaffs_DeleteChunk(yaffs_Device *dev,int chunkId,int markNAND) +{ + int block; + int page; + yaffs_Spare spare; + yaffs_BlockInfo *bi; + + if(chunkId <= 0) return; + + dev->nDeletions++; + block = chunkId / dev->nChunksPerBlock; + page = chunkId % dev->nChunksPerBlock; + + if(markNAND) + { + yaffs_SpareInitialise(&spare); + +#ifdef CONFIG_MTD_NAND_VERIFY_WRITE + + //read data before write, to ensure correct ecc + //if we're using MTD verification under Linux + yaffs_ReadChunkFromNAND(dev,chunkId,NULL,&spare,0); +#endif + + spare.pageStatus = 0; // To mark it as deleted. + + + yaffs_WriteChunkToNAND(dev,chunkId,NULL,&spare); + yaffs_HandleUpdateChunk(dev,chunkId,&spare); + } + else + { + dev->nUnmarkedDeletions++; + } + + bi = yaffs_GetBlockInfo(dev,block); + + + // Pull out of the management area. + // If the whole block became dirty, this will kick off an erasure. + if( bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || + bi->blockState == YAFFS_BLOCK_STATE_FULL) + { + dev->nFreeChunks++; + + yaffs_ClearChunkBit(dev,block,page); + bi->pagesInUse--; + + if(bi->pagesInUse == 0 && + bi->blockState == YAFFS_BLOCK_STATE_FULL) + { + yaffs_BlockBecameDirty(dev,block); + } + + } + else + { + // T(("Bad news deleting chunk %d\n",chunkId)); + } + +} + + + + +int yaffs_WriteChunkDataToObject(yaffs_Object *in,int chunkInInode, const __u8 *buffer,int nBytes,int useReserve) +{ + // Find old chunk Need to do this to get serial number + // Write new one and patch into tree. + // Invalidate old tags. + + int prevChunkId; + yaffs_Tags prevTags; + + int newChunkId; + yaffs_Tags newTags; + + yaffs_Device *dev = in->myDev; + + yaffs_CheckGarbageCollection(dev); + + // Get the previous chunk at this location in the file if it exists + prevChunkId = yaffs_FindChunkInFile(in,chunkInInode,&prevTags); + + // Set up new tags + newTags.chunkId = chunkInInode; + newTags.objectId = in->objectId; + newTags.serialNumber = (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1; + newTags.byteCount = nBytes; + newTags.unusedStuff = 0xFFFFFFFF; + + yaffs_CalcTagsECC(&newTags); + + newChunkId = yaffs_WriteNewChunkWithTagsToNAND(dev,buffer,&newTags,useReserve); + if(newChunkId >= 0) + { + yaffs_PutChunkIntoFile(in,chunkInInode,newChunkId,0); + + + if(prevChunkId >= 0) + { + yaffs_DeleteChunk(dev,prevChunkId,1); + + } + + yaffs_CheckFileSanity(in); + } + return newChunkId; + + + + + +} + + +// UpdateObjectHeader updates the header on NAND for an object. +// If name is not NULL, then that new name is used. +// +int yaffs_UpdateObjectHeader(yaffs_Object *in,const char *name, int force) +{ + + yaffs_Device *dev = in->myDev; + + int prevChunkId; + + int newChunkId; + yaffs_Tags newTags; + __u8 bufferNew[YAFFS_BYTES_PER_CHUNK]; + __u8 bufferOld[YAFFS_BYTES_PER_CHUNK]; + + yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bufferNew; + yaffs_ObjectHeader *ohOld = (yaffs_ObjectHeader *)bufferOld; + + + if(!in->fake || force) + { + + yaffs_CheckGarbageCollection(dev); + + memset(bufferNew,0xFF,YAFFS_BYTES_PER_CHUNK); + + prevChunkId = in->chunkId; + + if(prevChunkId >= 0) + { + yaffs_ReadChunkFromNAND(dev,prevChunkId,bufferOld,NULL,1); + } + + // Header data + oh->type = in->variantType; + + oh->st_mode = in->st_mode; + +#ifdef CONFIG_YAFFS_WINCE + oh->win_atime[0] = in->win_atime[0]; + oh->win_ctime[0] = in->win_ctime[0]; + oh->win_mtime[0] = in->win_mtime[0]; + oh->win_atime[1] = in->win_atime[1]; + oh->win_ctime[1] = in->win_ctime[1]; + oh->win_mtime[1] = in->win_mtime[1]; +#else + oh->st_uid = in->st_uid; + oh->st_gid = in->st_gid; + oh->st_atime = in->st_atime; + oh->st_mtime = in->st_mtime; + oh->st_ctime = in->st_ctime; + oh->st_rdev = in->st_rdev; +#endif + if(in->parent) + { + oh->parentObjectId = in->parent->objectId; + } + else + { + oh->parentObjectId = 0; + } + + //oh->sum = in->sum; + if(name && *name) + { + memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1); + strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); + } + else if(prevChunkId) + { + memcpy(oh->name, ohOld->name,YAFFS_MAX_NAME_LENGTH + 1); + } + else + { + memset(oh->name,0,YAFFS_MAX_NAME_LENGTH + 1); + } + + switch(in->variantType) + { + case YAFFS_OBJECT_TYPE_UNKNOWN: + // Should not happen + break; + case YAFFS_OBJECT_TYPE_FILE: + oh->fileSize = in->variant.fileVariant.fileSize; + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + oh->equivalentObjectId = in->variant.hardLinkVariant.equivalentObjectId; + break; + case YAFFS_OBJECT_TYPE_SPECIAL: + // Do nothing + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + // Do nothing + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + strncpy(oh->alias,in->variant.symLinkVariant.alias,YAFFS_MAX_ALIAS_LENGTH); + oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0; + break; + } + + // Tags + in->serial++; + newTags.chunkId = 0; + newTags.objectId = in->objectId; + newTags.serialNumber = in->serial; + newTags.byteCount = 0xFFFFFFFF; + newTags.unusedStuff = 0xFFFFFFFF; + + yaffs_CalcTagsECC(&newTags); + + + // Create new chunk in NAND + newChunkId = yaffs_WriteNewChunkWithTagsToNAND(dev,bufferNew,&newTags, (prevChunkId >= 0) ? 1 : 0 ); + + if(newChunkId >= 0) + { + + in->chunkId = newChunkId; + + if(prevChunkId >= 0) + { + yaffs_DeleteChunk(dev,prevChunkId,1); + } + + in->dirty = 0; + } + + return newChunkId; + + } + return 0; +} + + +/////////////////////// Short Operations Cache //////////////////////////////// +// In many siturations where there is no high level buffering (eg WinCE) a lot of +// reads might be short sequential reads, and a lot of writes may be short +// sequential writes. eg. scanning/writing a jpeg file. +// In these cases, a short read/write cache can provide a huge perfomance benefit +// with dumb-as-a-rock code. +// There are a limited number (~10) of cache chunks per device so that we don't +// need a very intelligent search. + + + + + +static void yaffs_FlushFilesChunkCache(yaffs_Object *obj) +{ + yaffs_Device *dev = obj->myDev; + int lowest; + int i; + yaffs_ChunkCache *cache; + int chunkWritten; + int nBytes; + int nCaches = obj->myDev->nShortOpCaches; + + if (nCaches > 0) + { + do{ + cache = NULL; + + // Find the dirty cache for this object with the lowest chunk id. + for(i = 0; i < nCaches; i++) + { + if(dev->srCache[i].object == obj && + dev->srCache[i].dirty) + { + if(!cache || dev->srCache[i].chunkId < lowest) + { + cache = &dev->srCache[i]; + lowest = cache->chunkId; + } + } + } + + if(cache) + { + //Write it out + +#if 0 + nBytes = cache->object->variant.fileVariant.fileSize - ((cache->chunkId -1) * YAFFS_BYTES_PER_CHUNK); + + if(nBytes > YAFFS_BYTES_PER_CHUNK) + { + nBytes= YAFFS_BYTES_PER_CHUNK; + } +#endif + chunkWritten = yaffs_WriteChunkDataToObject(cache->object, + cache->chunkId, + cache->data, + cache->nBytes,1); + + cache->dirty = 0; + cache->object = NULL; + } + + } while(cache && chunkWritten > 0); + + if(cache) + { + //Hoosterman, disk full while writing cache out. + T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: no space during cache write" TENDSTR))); + + } + } + +} + + +// Grab us a chunk for use. +// First look for an empty one. +// Then look for the least recently used non-dirty one. +// Then look for the least recently used dirty one...., flush and look again. +static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev) +{ + int i; + int usage; + int theOne; + + if(dev->nShortOpCaches > 0) + { + for(i = 0; i < dev->nShortOpCaches; i++) + { + if(!dev->srCache[i].object) + { + //T(("Grabbing empty %d\n",i)); + + //printf("Grabbing empty %d\n",i); + + return &dev->srCache[i]; + } + } + + return NULL; + + theOne = -1; + usage = 0; // just to stop the compiler grizzling + + for(i = 0; i < dev->nShortOpCaches; i++) + { + if(!dev->srCache[i].dirty && + ((dev->srCache[i].lastUse < usage && theOne >= 0)|| + theOne < 0)) + { + usage = dev->srCache[i].lastUse; + theOne = i; + } + } + + //T(("Grabbing non-empty %d\n",theOne)); + + //if(theOne >= 0) printf("Grabbed non-empty cache %d\n",theOne); + + return theOne >= 0 ? &dev->srCache[theOne] : NULL; + } + else + { + return NULL; + } + +} + + +static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev) +{ + yaffs_ChunkCache *cache; + yaffs_Object *theObj; + int usage; + int i; + int pushout; + + if(dev->nShortOpCaches > 0) + { + // Try find a non-dirty one... + + cache = yaffs_GrabChunkCacheWorker(dev); + + if(!cache) + { + // They were all dirty, find the last recently used object and flush + // its cache, then find again. + // NB what's here is not very accurate, we actually flush the object + // the last recently used page. + + theObj = dev->srCache[0].object; + usage = dev->srCache[0].lastUse; + cache = &dev->srCache[0]; + pushout = 0; + + for(i = 1; i < dev->nShortOpCaches; i++) + { + if( dev->srCache[i].object && + dev->srCache[i].lastUse < usage) + { + usage = dev->srCache[i].lastUse; + theObj = dev->srCache[i].object; + cache = &dev->srCache[i]; + pushout = i; + } + } + + if(!cache || cache->dirty) + { + + //printf("Dirty "); + yaffs_FlushFilesChunkCache(theObj); + + // Try again + cache = yaffs_GrabChunkCacheWorker(dev); + } + else + { + //printf(" pushout %d\n",pushout); + } + + } + + return cache; + } + else + return NULL; + +} + + +// Find a cached chunk +static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object *obj, int chunkId) +{ + yaffs_Device *dev = obj->myDev; + int i; + if(dev->nShortOpCaches > 0) + { + for(i = 0; i < dev->nShortOpCaches; i++) + { + if(dev->srCache[i].object == obj && + dev->srCache[i].chunkId == chunkId) + { + dev->cacheHits++; + + return &dev->srCache[i]; + } + } + } + return NULL; +} + +// Mark the chunk for the least recently used algorithym +static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache, int isAWrite) +{ + + if(dev->nShortOpCaches > 0) + { + if( dev->srLastUse < 0 || + dev->srLastUse > 100000000) + { + // Reset the cache usages + int i; + for(i = 1; i < dev->nShortOpCaches; i++) + { + dev->srCache[i].lastUse = 0; + } + dev->srLastUse = 0; + } + + dev->srLastUse++; + + cache->lastUse = dev->srLastUse; + + if(isAWrite) + { + cache->dirty = 1; + } + } +} + +// Invalidate a single cache page. +// Do this when a whole page gets written, +// ie the short cache for this page is no longer valid. +static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId) +{ + if(object->myDev->nShortOpCaches > 0) + { + yaffs_ChunkCache *cache = yaffs_FindChunkCache(object,chunkId); + + if(cache) + { + cache->object = NULL; + } + } +} + + +// Invalidate all the cache pages associated with this object +// Do this whenever ther file is deleted or resized. +static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in) +{ + int i; + yaffs_Device *dev = in->myDev; + + if(dev->nShortOpCaches > 0) + { + // Now invalidate it. + for(i = 0; i < dev->nShortOpCaches; i++) + { + if(dev->srCache[i].object == in) + { + dev->srCache[i].object = NULL; + } + } + } +} + + + + + +///////////////////////// File read/write /////////////////////////////// +// Read and write have very similar structures. +// In general the read/write has three parts to it +// * An incomplete chunk to start with (if the read/write is not chunk-aligned) +// * Some complete chunks +// * An incomplete chunk to end off with +// +// Curve-balls: the first chunk might also be the last chunk. + +int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 * buffer, __u32 offset, int nBytes) +{ + + + int chunk; + int start; + int nToCopy; + int n = nBytes; + int nDone = 0; + yaffs_ChunkCache *cache; + + yaffs_Device *dev; + + dev = in->myDev; + + while(n > 0) + { + chunk = offset / YAFFS_BYTES_PER_CHUNK + 1; // The first chunk is 1 + start = offset % YAFFS_BYTES_PER_CHUNK; + + // OK now check for the curveball where the start and end are in + // the same chunk. + if( (start + n) < YAFFS_BYTES_PER_CHUNK) + { + nToCopy = n; + } + else + { + nToCopy = YAFFS_BYTES_PER_CHUNK - start; + } + + cache = yaffs_FindChunkCache(in,chunk); + + // If the chunk is already in the cache or it is less than a whole chunk + // then use the cache (if there is caching) + // else bypass the cache. + if( cache || nToCopy != YAFFS_BYTES_PER_CHUNK) + { + if(dev->nShortOpCaches > 0) + { + + // If we can't find the data in the cache, then load it up. + + if(!cache) + { + cache = yaffs_GrabChunkCache(in->myDev); + cache->object = in; + cache->chunkId = chunk; + cache->dirty = 0; + yaffs_ReadChunkDataFromObject(in,chunk,cache->data); + cache->nBytes = 0; + } + + yaffs_UseChunkCache(dev,cache,0); + + memcpy(buffer,&cache->data[start],nToCopy); + } + else + { + // Read into the local buffer then copy... + yaffs_ReadChunkDataFromObject(in,chunk,dev->localBuffer); + memcpy(buffer,&dev->localBuffer[start],nToCopy); + } + + } + else + { +#ifdef CONFIG_YAFFS_WINCE + + // Under WinCE can't do direct transfer. Need to use a local buffer. + // This is because we otherwise screw up WinCE's memory mapper + yaffs_ReadChunkDataFromObject(in,chunk,dev->localBuffer); + memcpy(buffer,dev->localBuffer,YAFFS_BYTES_PER_CHUNK); +#else + // A full chunk. Read directly into the supplied buffer. + yaffs_ReadChunkDataFromObject(in,chunk,buffer); +#endif + } + + n -= nToCopy; + offset += nToCopy; + buffer += nToCopy; + nDone += nToCopy; + + } + + return nDone; +} + + + +int yaffs_WriteDataToFile(yaffs_Object *in,const __u8 * buffer, __u32 offset, int nBytes) +{ + + int chunk; + int start; + int nToCopy; + int n = nBytes; + int nDone = 0; + int nToWriteBack; + int startOfWrite = offset; + int chunkWritten = 0; + int nBytesRead; + + yaffs_Device *dev; + + dev = in->myDev; + + + while(n > 0 && chunkWritten >= 0) + { + chunk = offset / YAFFS_BYTES_PER_CHUNK + 1; + start = offset % YAFFS_BYTES_PER_CHUNK; + + + // OK now check for the curveball where the start and end are in + // the same chunk. + + if( (start + n) < YAFFS_BYTES_PER_CHUNK) + { + nToCopy = n; + + // Now folks, to calculate how many bytes to write back.... + // If we're overwriting and not writing to then end of file then + // we need to write back as much as was there before. + + nBytesRead = in->variant.fileVariant.fileSize - ((chunk -1) * YAFFS_BYTES_PER_CHUNK); + + if(nBytesRead > YAFFS_BYTES_PER_CHUNK) + { + nBytesRead = YAFFS_BYTES_PER_CHUNK; + } + + nToWriteBack = (nBytesRead > (start + n)) ? nBytesRead : (start +n); + + } + else + { + nToCopy = YAFFS_BYTES_PER_CHUNK - start; + nToWriteBack = YAFFS_BYTES_PER_CHUNK; + } + + if(nToCopy != YAFFS_BYTES_PER_CHUNK) + { + // An incomplete start or end chunk (or maybe both start and end chunk) + if(dev->nShortOpCaches > 0) + { + yaffs_ChunkCache *cache; + // If we can't find the data in the cache, then load it up. + cache = yaffs_FindChunkCache(in,chunk); + if(!cache && yaffs_CheckSpaceForChunkCache(in->myDev)) + { + cache = yaffs_GrabChunkCache(in->myDev); + cache->object = in; + cache->chunkId = chunk; + cache->dirty = 0; + yaffs_ReadChunkDataFromObject(in,chunk,cache->data); + } + + if(cache) + { + yaffs_UseChunkCache(dev,cache,1); + memcpy(&cache->data[start],buffer,nToCopy); + cache->nBytes = nToWriteBack; + } + else + { + chunkWritten = -1; // fail the write + } + } + else + { + // An incomplete start or end chunk (or maybe both start and end chunk) + // Read into the local buffer then copy, then copy over and write back. + + yaffs_ReadChunkDataFromObject(in,chunk,dev->localBuffer); + + memcpy(&dev->localBuffer[start],buffer,nToCopy); + + chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,dev->localBuffer,nToWriteBack,0); + + //T(("Write with readback to chunk %d %d start %d copied %d wrote back %d\n",chunk,chunkWritten,start, nToCopy, nToWriteBack)); + } + + } + else + { + +#ifdef CONFIG_YAFFS_WINCE + // Under WinCE can't do direct transfer. Need to use a local buffer. + // This is because we otherwise screw up WinCE's memory mapper + memcpy(dev->localBuffer,buffer,YAFFS_BYTES_PER_CHUNK); + chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,dev->localBuffer,YAFFS_BYTES_PER_CHUNK,0); +#else + // A full chunk. Write directly from the supplied buffer. + chunkWritten = yaffs_WriteChunkDataToObject(in,chunk,buffer,YAFFS_BYTES_PER_CHUNK,0); +#endif + // Since we've overwritten the cached data, we better invalidate it. + yaffs_InvalidateChunkCache(in,chunk); + //T(("Write to chunk %d %d\n",chunk,chunkWritten)); + } + + if(chunkWritten >= 0) + { + n -= nToCopy; + offset += nToCopy; + buffer += nToCopy; + nDone += nToCopy; + } + + } + + // Update file object + + if((startOfWrite + nDone) > in->variant.fileVariant.fileSize) + { + in->variant.fileVariant.fileSize = (startOfWrite + nDone); + } + + in->dirty = 1; + + return nDone; +} + + +int yaffs_ResizeFile(yaffs_Object *in, int newSize) +{ + int i; + int chunkId; + int oldFileSize = in->variant.fileVariant.fileSize; + int sizeOfPartialChunk = newSize % YAFFS_BYTES_PER_CHUNK; + + yaffs_Device *dev = in->myDev; + + + yaffs_FlushFilesChunkCache(in); + yaffs_InvalidateWholeChunkCache(in); + + if(in->variantType != YAFFS_OBJECT_TYPE_FILE) + { + return yaffs_GetFileSize(in); + } + + if(newSize < oldFileSize) + { + + int lastDel = 1 + (oldFileSize-1)/YAFFS_BYTES_PER_CHUNK; + + int startDel = 1 + (newSize + YAFFS_BYTES_PER_CHUNK - 1)/ + YAFFS_BYTES_PER_CHUNK; + + // Delete backwards so that we don't end up with holes if + // power is lost part-way through the operation. + for(i = lastDel; i >= startDel; i--) + { + // NB this could be optimised somewhat, + // eg. could retrieve the tags and write them without + // using yaffs_DeleteChunk + + chunkId = yaffs_FindAndDeleteChunkInFile(in,i,NULL); + if(chunkId < (dev->startBlock * 32) || chunkId >= ((dev->endBlock+1) * 32)) + { + //T(("Found daft chunkId %d for %d\n",chunkId,i)); + } + else + { + in->nDataChunks--; + yaffs_DeleteChunk(dev,chunkId,1); + } + } + + + if(sizeOfPartialChunk != 0) + { + int lastChunk = 1+ newSize/YAFFS_BYTES_PER_CHUNK; + + // Got to read and rewrite the last chunk with its new size. + // NB Got to zero pad to nuke old data + yaffs_ReadChunkDataFromObject(in,lastChunk,dev->localBuffer); + memset(dev->localBuffer + sizeOfPartialChunk,0, YAFFS_BYTES_PER_CHUNK - sizeOfPartialChunk); + + yaffs_WriteChunkDataToObject(in,lastChunk,dev->localBuffer,sizeOfPartialChunk,1); + + } + + in->variant.fileVariant.fileSize = newSize; + + yaffs_PruneFileStructure(dev,&in->variant.fileVariant); + + return newSize; + + } + else + { + return oldFileSize; + } +} + + +loff_t yaffs_GetFileSize(yaffs_Object *obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + switch(obj->variantType) + { + case YAFFS_OBJECT_TYPE_FILE: + return obj->variant.fileVariant.fileSize; + case YAFFS_OBJECT_TYPE_SYMLINK: + return strlen(obj->variant.symLinkVariant.alias); + default: + return 0; + } +} + + + +// yaffs_FlushFile() updates the file's +// objectId in NAND + +int yaffs_FlushFile(yaffs_Object *in, int updateTime) +{ + int retVal; + if(in->dirty) + { + //T(("flushing object header\n")); + + yaffs_FlushFilesChunkCache(in); + if(updateTime) + { +#ifdef CONFIG_YAFFS_WINCE + yfsd_WinFileTimeNow(in->win_mtime); +#else + in->st_mtime = Y_CURRENT_TIME; +#endif + } + + retVal = (yaffs_UpdateObjectHeader(in,NULL,0) >= 0)? YAFFS_OK : YAFFS_FAIL; + } + else + { + retVal = YAFFS_OK; + } + + return retVal; + +} + + +static int yaffs_DoGenericObjectDeletion(yaffs_Object *in) +{ + + // First off, invalidate the file's data in the cache, without flushing. + yaffs_InvalidateWholeChunkCache(in); + + yaffs_RemoveObjectFromDirectory(in); + yaffs_DeleteChunk(in->myDev,in->chunkId,1); +#if 0 +#ifdef __KERNEL__ + if(in->myInode) + { + in->myInode->u.generic_ip = NULL; + in->myInode = NULL; + } +#endif +#endif + yaffs_FreeObject(in); + return YAFFS_OK; + +} + +// yaffs_DeleteFile deletes the whole file data +// and the inode associated with the file. +// It does not delete the links associated with the file. +static int yaffs_UnlinkFile(yaffs_Object *in) +{ + +#ifdef CONFIG_YAFFS_DISABLE_BACKGROUND_DELETION + + // Delete the file data & tnodes + + yaffs_DeleteWorker(in, in->variant.fileVariant.top, in->variant.fileVariant.topLevel, 0,NULL); + + + yaffs_FreeTnode(in->myDev,in->variant.fileVariant.top); + + return yaffs_DoGenericObjectDeletion(in); +#else + int retVal; + int immediateDeletion=0; + retVal = yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,NULL,0); + if(1 || // Ignore the result of the change name. This will only fail + // if the disk was completely full (an error condition) + // We ignore the error so we can delete files to recover the disk + retVal == YAFFS_OK) + { + //in->unlinked = 1; + //in->myDev->nUnlinkedFiles++; + //in->renameAllowed = 0; +#ifdef __KERNEL__ + if(!in->myInode) + { + // Might be open at present, + // Caught by delete_inode in yaffs_fs.c + immediateDeletion = 1; + + } +#else + if(in->inUse <= 0) + { + immediateDeletion = 1; + + } +#endif + + if(immediateDeletion) + { + T(YAFFS_TRACE_TRACING,(TSTR("yaffs: immediate deletion of file %d" TENDSTR),in->objectId)); + in->deleted=1; + in->myDev->nDeletedFiles++; + yaffs_SoftDeleteFile(in); + } + + } + return retVal; + + +#endif +} + +int yaffs_DeleteFile(yaffs_Object *in) +{ + int retVal = YAFFS_OK; + + if(in->nDataChunks > 0) + { + // Use soft deletion + if(!in->unlinked) + { + retVal = yaffs_UnlinkFile(in); + } + if(retVal == YAFFS_OK && + in->unlinked && + !in->deleted) + { + in->deleted = 1; + in->myDev->nDeletedFiles++; + yaffs_SoftDeleteFile(in); + } + return in->deleted ? YAFFS_OK : YAFFS_FAIL; + } + else + { + // The file has no data chunks so we toss it immediately + yaffs_FreeTnode(in->myDev,in->variant.fileVariant.top); + in->variant.fileVariant.top = NULL; + yaffs_DoGenericObjectDeletion(in); + + return YAFFS_OK; + } +} + +static int yaffs_DeleteDirectory(yaffs_Object *in) +{ + //First check that the directory is empty. + if(list_empty(&in->variant.directoryVariant.children)) + { + return yaffs_DoGenericObjectDeletion(in); + } + + return YAFFS_FAIL; + +} + +static int yaffs_DeleteSymLink(yaffs_Object *in) +{ + YFREE(in->variant.symLinkVariant.alias); + + return yaffs_DoGenericObjectDeletion(in); +} + +static int yaffs_DeleteHardLink(yaffs_Object *in) +{ + // remove this hardlink from the list assocaited with the equivalent + // object + list_del(&in->hardLinks); + return yaffs_DoGenericObjectDeletion(in); +} + + +static void yaffs_AbortHalfCreatedObject(yaffs_Object *obj) +{ + switch(obj->variantType) + { + case YAFFS_OBJECT_TYPE_FILE: yaffs_DeleteFile(obj); break; + case YAFFS_OBJECT_TYPE_DIRECTORY: yaffs_DeleteDirectory(obj); break; + case YAFFS_OBJECT_TYPE_SYMLINK: yaffs_DeleteSymLink(obj); break; + case YAFFS_OBJECT_TYPE_HARDLINK: yaffs_DeleteHardLink(obj); break; + case YAFFS_OBJECT_TYPE_SPECIAL: yaffs_DoGenericObjectDeletion(obj); break; + case YAFFS_OBJECT_TYPE_UNKNOWN: break; // should not happen. + } +} + + +static int yaffs_UnlinkWorker(yaffs_Object *obj) +{ + + + if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) + { + return yaffs_DeleteHardLink(obj); + } + else if(!list_empty(&obj->hardLinks)) + { + // Curve ball: We're unlinking an object that has a hardlink. + // + // This problem arises because we are not strictly following + // The Linux link/inode model. + // + // We can't really delete the object. + // Instead, we do the following: + // - Select a hardlink. + // - Unhook it from the hard links + // - Unhook it from its parent directory (so that the rename can work) + // - Rename the object to the hardlink's name. + // - Delete the hardlink + + + yaffs_Object *hl; + int retVal; + char name[YAFFS_MAX_NAME_LENGTH+1]; + + hl = list_entry(obj->hardLinks.next,yaffs_Object,hardLinks); + + list_del_init(&hl->hardLinks); + list_del_init(&hl->siblings); + + yaffs_GetObjectName(hl,name,YAFFS_MAX_NAME_LENGTH+1); + + retVal = yaffs_ChangeObjectName(obj, hl->parent, name,0); + + if(retVal == YAFFS_OK) + { + retVal = yaffs_DoGenericObjectDeletion(hl); + } + return retVal; + + } + else + { + switch(obj->variantType) + { + case YAFFS_OBJECT_TYPE_FILE: + return yaffs_UnlinkFile(obj); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + return yaffs_DeleteDirectory(obj); + break; + case YAFFS_OBJECT_TYPE_SYMLINK: + return yaffs_DeleteSymLink(obj); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + case YAFFS_OBJECT_TYPE_UNKNOWN: + default: + return YAFFS_FAIL; + } + } +} + +int yaffs_Unlink(yaffs_Object *dir, const char *name) +{ + yaffs_Object *obj; + + obj = yaffs_FindObjectByName(dir,name); + + if(obj && obj->unlinkAllowed) + { + return yaffs_UnlinkWorker(obj); + } + + return YAFFS_FAIL; + +} + +//////////////// Initialisation Scanning ///////////////// + + + +// For now we use the SmartMedia check. +// We look at the blockStatus byte in the first two chunks +// These must be 0xFF to pass as OK. +// todo: this function needs to be modifyable foir different NAND types +// and different chunk sizes. Suggest make this into a per-device configurable +// function. +static int yaffs_IsBlockBad(yaffs_Device *dev, int blk) +{ + yaffs_Spare spare; + + yaffs_ReadChunkFromNAND(dev,blk * dev->nChunksPerBlock,NULL,&spare,1); +#if 1 + if(yaffs_CountBits(spare.blockStatus) < 7) + { + return 1; + } +#else + if(spare.blockStatus != 0xFF) + { + return 1; + } +#endif + yaffs_ReadChunkFromNAND(dev,blk * dev->nChunksPerBlock + 1,NULL,&spare,1); + +#if 1 + if(yaffs_CountBits(spare.blockStatus) < 7) + { + return 1; + } +#else + if(spare.blockStatus != 0xFF) + { + return 1; + } +#endif + + return 0; + +} + +static int yaffs_Scan(yaffs_Device *dev) +{ + yaffs_Spare spare; + yaffs_Tags tags; + int blk; + int chunk; + int c; + int deleted; + yaffs_BlockState state; + yaffs_Object *hardList = NULL; + yaffs_Object *hl; + yaffs_BlockInfo *bi; + + + yaffs_ObjectHeader *oh; + yaffs_Object *in; + yaffs_Object *parent; + + __u8 chunkData[YAFFS_BYTES_PER_CHUNK]; + + + // Scan all the blocks... + + for(blk = dev->startBlock; blk <= dev->endBlock; blk++) + { + deleted = 0; + bi = yaffs_GetBlockInfo(dev,blk); + yaffs_ClearChunkBits(dev,blk); + bi->pagesInUse = 0; + bi->softDeletions = 0; + state = YAFFS_BLOCK_STATE_SCANNING; + + + if(yaffs_IsBlockBad(dev,blk)) + { + state = YAFFS_BLOCK_STATE_DEAD; + T(YAFFS_TRACE_BAD_BLOCKS,(TSTR("block %d is bad" TENDSTR),blk)); + } + + // Read each chunk in the block. + + for(c = 0; c < dev->nChunksPerBlock && + state == YAFFS_BLOCK_STATE_SCANNING; c++) + { + // Read the spare area and decide what to do + chunk = blk * dev->nChunksPerBlock + c; + + yaffs_ReadChunkFromNAND(dev,chunk,NULL,&spare,1); + + + // This block looks ok, now what's in this chunk? + yaffs_GetTagsFromSpare(dev,&spare,&tags); + + if(yaffs_CountBits(spare.pageStatus) < 6) + { + // A deleted chunk + deleted++; + dev->nFreeChunks ++; + //T((" %d %d deleted\n",blk,c)); + } + else if(tags.objectId == YAFFS_UNUSED_OBJECT_ID) + { + // An unassigned chunk in the block + // This means that either the block is empty or + // this is the one being allocated from + + if(c == 0) + { + // the block is unused + state = YAFFS_BLOCK_STATE_EMPTY; + dev->nErasedBlocks++; + } + else + { + // this is the block being allocated from + T(YAFFS_TRACE_SCAN,(TSTR(" Allocating from %d %d" TENDSTR),blk,c)); + state = YAFFS_BLOCK_STATE_ALLOCATING; + dev->allocationBlock = blk; + dev->allocationPage = c; + } + + dev->nFreeChunks += (dev->nChunksPerBlock - c); + } + else if(tags.chunkId > 0) + { + int endpos; + // A data chunk. + yaffs_SetChunkBit(dev,blk,c); + bi->pagesInUse++; + + in = yaffs_FindOrCreateObjectByNumber(dev,tags.objectId,YAFFS_OBJECT_TYPE_FILE); + // PutChunkIntoFIle checks for a clash (two data chunks with + // the same chunkId). + yaffs_PutChunkIntoFile(in,tags.chunkId,chunk,1); + endpos = (tags.chunkId - 1)* YAFFS_BYTES_PER_CHUNK + tags.byteCount; + if(in->variant.fileVariant.scannedFileSize variant.fileVariant.scannedFileSize = endpos; +#ifndef CONFIG_YAFFS_USE_HEADER_FILE_SIZE + in->variant.fileVariant.fileSize = + in->variant.fileVariant.scannedFileSize; +#endif + + } + //T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId)); + } + else + { + // chunkId == 0, so it is an ObjectHeader. + // Thus, we read in the object header and make the object + yaffs_SetChunkBit(dev,blk,c); + bi->pagesInUse++; + + yaffs_ReadChunkFromNAND(dev,chunk,chunkData,NULL,1); + + oh = (yaffs_ObjectHeader *)chunkData; + + in = yaffs_FindOrCreateObjectByNumber(dev,tags.objectId,oh->type); + + if(in->valid) + { + // We have already filled this one. We have a duplicate and need to resolve it. + + unsigned existingSerial = in->serial; + unsigned newSerial = tags.serialNumber; + + if(((existingSerial+1) & 3) == newSerial) + { + // Use new one - destroy the exisiting one + yaffs_DeleteChunk(dev,in->chunkId,1); + in->valid = 0; + } + else + { + // Use existing - destroy this one. + yaffs_DeleteChunk(dev,chunk,1); + } + } + + if(!in->valid && + (tags.objectId == YAFFS_OBJECTID_ROOT || + tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) + { + // We only load some info, don't fiddle with directory structure + in->valid = 1; + in->variantType = oh->type; + + in->st_mode = oh->st_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->st_uid = oh->st_uid; + in->st_gid = oh->st_gid; + in->st_atime = oh->st_atime; + in->st_mtime = oh->st_mtime; + in->st_ctime = oh->st_ctime; + in->st_rdev = oh->st_rdev; +#endif + in->chunkId = chunk; + + } + else if(!in->valid) + { + // we need to load this info + + in->valid = 1; + in->variantType = oh->type; + + in->st_mode = oh->st_mode; +#ifdef CONFIG_YAFFS_WINCE + in->win_atime[0] = oh->win_atime[0]; + in->win_ctime[0] = oh->win_ctime[0]; + in->win_mtime[0] = oh->win_mtime[0]; + in->win_atime[1] = oh->win_atime[1]; + in->win_ctime[1] = oh->win_ctime[1]; + in->win_mtime[1] = oh->win_mtime[1]; +#else + in->st_uid = oh->st_uid; + in->st_gid = oh->st_gid; + in->st_atime = oh->st_atime; + in->st_mtime = oh->st_mtime; + in->st_ctime = oh->st_ctime; + in->st_rdev = oh->st_rdev; +#endif + in->chunkId = chunk; + + yaffs_SetObjectName(in,oh->name); + in->dirty = 0; + + // directory stuff... + // hook up to parent + + parent = yaffs_FindOrCreateObjectByNumber(dev,oh->parentObjectId,YAFFS_OBJECT_TYPE_DIRECTORY); + if(parent->variantType == YAFFS_OBJECT_TYPE_UNKNOWN) + { + // Set up as a directory + parent->variantType = YAFFS_OBJECT_TYPE_DIRECTORY; + INIT_LIST_HEAD(&parent->variant.directoryVariant.children); + } + else if(parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) + { + // Hoosterman, another problem.... + // We're trying to use a non-directory as a directory + + T(YAFFS_TRACE_ERROR, (TSTR("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found." TENDSTR))); + parent = dev->lostNFoundDir; + + } + + yaffs_AddObjectToDirectory(parent,in); + if(parent == dev->unlinkedDir) + { + in->deleted = 1; // If it is unlinked at start up then it wants deleting + dev->nDeletedFiles++; + } + + // Note re hardlinks. + // Since we might scan a hardlink before its equivalent object is scanned + // we put them all in a list. + // After scanning is complete, we should have all the objects, so we run through this + // list and fix up all the chains. + + switch(in->variantType) + { + case YAFFS_OBJECT_TYPE_UNKNOWN: // Todo got a problem + break; + case YAFFS_OBJECT_TYPE_FILE: +#ifdef CONFIG_YAFFS_USE_HEADER_FILE_SIZE + in->variant.fileVariant.fileSize = oh->fileSize; +#endif + break; + case YAFFS_OBJECT_TYPE_HARDLINK: + in->variant.hardLinkVariant.equivalentObjectId = oh->equivalentObjectId; + in->hardLinks.next = (struct list_head *)hardList; + hardList = in; + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: // Do nothing + break; + case YAFFS_OBJECT_TYPE_SPECIAL: // Do nothing + break; + case YAFFS_OBJECT_TYPE_SYMLINK: // Do nothing + in->variant.symLinkVariant.alias = yaffs_CloneString(oh->alias); + break; + } + //T((" %d %d header %d \"%s\" type %d\n",blk,c,tags.objectId,oh->name,in->variantType)); + } + } + } + + if(state == YAFFS_BLOCK_STATE_SCANNING) + { + // If we got this far while scanning, then the block is fully allocated. + state = YAFFS_BLOCK_STATE_FULL; + } + + bi->blockState = state; + + // Now let's see if it was dirty + if( bi->pagesInUse == 0 && + bi->blockState == YAFFS_BLOCK_STATE_FULL) + { + yaffs_BlockBecameDirty(dev,blk); + } + + } + + // Fix up the hard link chains. + // We should now have scanned all the objects, now it's time to add these + // hardlinks. + while(hardList) + { + hl = hardList; + hardList = (yaffs_Object *)(hardList->hardLinks.next); + + in = yaffs_FindObjectByNumber(dev,hl->variant.hardLinkVariant.equivalentObjectId); + + if(in) + { + // Add the hardlink pointers + hl->variant.hardLinkVariant.equivalentObject=in; + list_add(&hl->hardLinks,&in->hardLinks); + } + else + { + //Todo Need to report/handle this better. + // Got a problem... hardlink to a non-existant object + hl->variant.hardLinkVariant.equivalentObject=NULL; + INIT_LIST_HEAD(&hl->hardLinks); + + } + + } + + { + struct list_head *i; + struct list_head *n; + + yaffs_Object *l; + // Soft delete all the unlinked files + list_for_each_safe(i,n,&dev->unlinkedDir->variant.directoryVariant.children) + { + if(i) + { + l = list_entry(i, yaffs_Object,siblings); + if(l->deleted) + { + yaffs_SoftDeleteFile(l); + } + } + } + } + + + return YAFFS_OK; +} + + +////////////////////////// Directory Functions ///////////////////////// + + +static void yaffs_AddObjectToDirectory(yaffs_Object *directory, yaffs_Object *obj) +{ + + if(obj->siblings.prev == NULL) + { + // Not initialised + INIT_LIST_HEAD(&obj->siblings); + + } + else if(!list_empty(&obj->siblings)) + { + // If it is holed up somewhere else, un hook it + list_del_init(&obj->siblings); + } + // Now add it + list_add(&obj->siblings,&directory->variant.directoryVariant.children); + obj->parent = directory; + + if(directory == obj->myDev->unlinkedDir) + { + obj->unlinked = 1; + obj->myDev->nUnlinkedFiles++; + obj->renameAllowed = 0; + } +} + +static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj) +{ + list_del_init(&obj->siblings); + obj->parent = NULL; +} + +yaffs_Object *yaffs_FindObjectByName(yaffs_Object *directory,const char *name) +{ + int sum; + + struct list_head *i; + char buffer[YAFFS_MAX_NAME_LENGTH+1]; + + yaffs_Object *l; + + sum = yaffs_CalcNameSum(name); + + list_for_each(i,&directory->variant.directoryVariant.children) + { + if(i) + { + l = list_entry(i, yaffs_Object,siblings); + + // Special case for lost-n-found + if(l->objectId == YAFFS_OBJECTID_LOSTNFOUND) + { + if(yaffs_strcmp(name,YAFFS_LOSTNFOUND_NAME) == 0) + { + return l; + } + } + else if(yaffs_SumCompare(l->sum, sum)) + { + // Do a real check + yaffs_GetObjectName(l,buffer,YAFFS_MAX_NAME_LENGTH); + if(yaffs_strcmp(name,buffer) == 0) + { + return l; + } + + } + } + } + + return NULL; +} + + +int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object *)) +{ + struct list_head *i; + yaffs_Object *l; + + + list_for_each(i,&theDir->variant.directoryVariant.children) + { + if(i) + { + l = list_entry(i, yaffs_Object,siblings); + if(l && !fn(l)) + { + return YAFFS_FAIL; + } + } + } + + return YAFFS_OK; + +} + + +// GetEquivalentObject dereferences any hard links to get to the +// actual object. + +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj) +{ + if(obj && obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) + { + // We want the object id of the equivalent object, not this one + obj = obj->variant.hardLinkVariant.equivalentObject; + } + return obj; + +} + +int yaffs_GetObjectName(yaffs_Object *obj,char *name,int buffSize) +{ + memset(name,0,buffSize); + + if(obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) + { + strncpy(name,YAFFS_LOSTNFOUND_NAME,buffSize - 1); + } + else if(obj->chunkId <= 0) + { + char locName[20]; + // make up a name + sprintf(locName,"%s%d",YAFFS_LOSTNFOUND_PREFIX,obj->objectId); + strncpy(name,locName,buffSize - 1); + + } +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + else if(obj->shortName[0]) + { + strcpy(name,obj->shortName); + } +#endif + else + { + __u8 buffer[YAFFS_BYTES_PER_CHUNK]; + yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)buffer; + + memset(buffer,0,YAFFS_BYTES_PER_CHUNK); + + if(obj->chunkId >= 0) + { + yaffs_ReadChunkFromNAND(obj->myDev,obj->chunkId,buffer,NULL,1); + } + strncpy(name,oh->name,buffSize - 1); + } + + return strlen(name); +} + +int yaffs_GetObjectFileLength(yaffs_Object *obj) +{ + + // Dereference any hard linking + obj = yaffs_GetEquivalentObject(obj); + + if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) + { + return obj->variant.fileVariant.fileSize; + } + if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) + { + return strlen(obj->variant.symLinkVariant.alias); + } + else + { + // Only a directory should drop through to here + return YAFFS_BYTES_PER_CHUNK; + } +} + +int yaffs_GetObjectLinkCount(yaffs_Object *obj) +{ + int count = 0; + struct list_head *i; + + if(!obj->unlinked) + { + count++; // the object itself + } + list_for_each(i,&obj->hardLinks) + { + count++; // add the hard links; + } + return count; + +} + + +int yaffs_GetObjectInode(yaffs_Object *obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + return obj->objectId; +} + +unsigned yaffs_GetObjectType(yaffs_Object *obj) +{ + obj = yaffs_GetEquivalentObject(obj); + + switch(obj->variantType) + { + case YAFFS_OBJECT_TYPE_FILE: return DT_REG; break; + case YAFFS_OBJECT_TYPE_DIRECTORY: return DT_DIR; break; + case YAFFS_OBJECT_TYPE_SYMLINK: return DT_LNK; break; + case YAFFS_OBJECT_TYPE_HARDLINK: return DT_REG; break; + case YAFFS_OBJECT_TYPE_SPECIAL: + if(S_ISFIFO(obj->st_mode)) return DT_FIFO; + if(S_ISCHR(obj->st_mode)) return DT_CHR; + if(S_ISBLK(obj->st_mode)) return DT_BLK; + if(S_ISSOCK(obj->st_mode)) return DT_SOCK; + default: return DT_REG; break; + } +} + +char *yaffs_GetSymlinkAlias(yaffs_Object *obj) +{ + obj = yaffs_GetEquivalentObject(obj); + if(obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) + { + return yaffs_CloneString(obj->variant.symLinkVariant.alias); + } + else + { + return yaffs_CloneString(""); + } +} + +#ifndef CONFIG_YAFFS_WINCE + +int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr) +{ + unsigned int valid = attr->ia_valid; + + if(valid & ATTR_MODE) obj->st_mode = attr->ia_mode; + if(valid & ATTR_UID) obj->st_uid = attr->ia_uid; + if(valid & ATTR_GID) obj->st_gid = attr->ia_gid; + + if(valid & ATTR_ATIME) obj->st_atime = Y_TIME_CONVERT(attr->ia_atime); + if(valid & ATTR_CTIME) obj->st_ctime = Y_TIME_CONVERT(attr->ia_ctime); + if(valid & ATTR_MTIME) obj->st_mtime = Y_TIME_CONVERT(attr->ia_mtime); + + + if(valid & ATTR_SIZE) yaffs_ResizeFile(obj,attr->ia_size); + + yaffs_UpdateObjectHeader(obj,NULL,1); + + return YAFFS_OK; + +} + +int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr) +{ + unsigned int valid = 0; + + attr->ia_mode = obj->st_mode; valid |= ATTR_MODE; + attr->ia_uid = obj->st_uid; valid |= ATTR_UID; + attr->ia_gid = obj->st_gid; valid |= ATTR_GID; + + + Y_TIME_CONVERT(attr->ia_atime) = obj->st_atime; valid |= ATTR_ATIME; + Y_TIME_CONVERT(attr->ia_ctime) = obj->st_ctime; valid |= ATTR_CTIME; + Y_TIME_CONVERT(attr->ia_mtime) = obj->st_mtime; valid |= ATTR_MTIME; + + attr->ia_size = yaffs_GetFileSize(obj); valid |= ATTR_SIZE; + + attr->ia_valid = valid; + + return YAFFS_OK; + +} + +#endif + +int yaffs_DumpObject(yaffs_Object *obj) +{ +// __u8 buffer[YAFFS_BYTES_PER_CHUNK]; + char name[257]; +// yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)buffer; + +// memset(buffer,0,YAFFS_BYTES_PER_CHUNK); + +// if(obj->chunkId >= 0) +// { +// yaffs_ReadChunkFromNAND(obj->myDev,obj->chunkId,buffer,NULL); +// } + + yaffs_GetObjectName(obj,name,256); + + T(YAFFS_TRACE_ALWAYS,(TSTR("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d chunk %d type %d size %d\n" TENDSTR), + obj->objectId,yaffs_GetObjectInode(obj), name, obj->dirty, obj->valid, obj->serial, + obj->sum, obj->chunkId, yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj))); + +#if 0 + YPRINTF(("Object %d \"%s\"\n dirty %d valid %d serial %d sum %d chunk %d\n", + obj->objectId, oh->name, obj->dirty, obj->valid, obj->serial, + obj->sum, obj->chunkId)); + switch(obj->variantType) + { + case YAFFS_OBJECT_TYPE_FILE: + YPRINTF((" FILE length %d\n",obj->variant.fileVariant.fileSize)); + break; + case YAFFS_OBJECT_TYPE_DIRECTORY: + YPRINTF((" DIRECTORY\n")); + break; + case YAFFS_OBJECT_TYPE_HARDLINK: //todo + case YAFFS_OBJECT_TYPE_SYMLINK: + case YAFFS_OBJECT_TYPE_UNKNOWN: + default: + } +#endif + + return YAFFS_OK; +} + + +///////////////////////// Initialisation code /////////////////////////// + + + +int yaffs_GutsInitialise(yaffs_Device *dev) +{ + unsigned x; + int bits; + int extraBits; + int nBlocks; + + if( dev->nBytesPerChunk != YAFFS_BYTES_PER_CHUNK || + dev->nChunksPerBlock < 2 || + dev->nReservedBlocks < 2 || + dev->startBlock <= 0 || + dev->endBlock <= 0 || + dev->endBlock <= (dev->startBlock + dev->nReservedBlocks) + ) + { + //these parameters must be set before stating yaffs + // Other parameters startBlock, + return YAFFS_FAIL; + } + + + + if(!yaffs_CheckStructures()) + { + T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs_CheckStructures failed\n" TENDSTR))); + return YAFFS_FAIL; + } + + if(dev->isMounted) + { + T(YAFFS_TRACE_ALWAYS,(TSTR("yaffs: device already mounted\n" TENDSTR))); + return YAFFS_FAIL; + } + + dev->isMounted = 1; + + if(dev->startBlock <= 0 || + (dev->endBlock - dev->startBlock) < 10) + { + T(YAFFS_TRACE_ALWAYS,(TSTR("startBlock %d or endBlock %d invalid\n" TENDSTR), + dev->startBlock, dev->endBlock)); + return YAFFS_FAIL; + } + + nBlocks = dev->endBlock - dev->startBlock + 1; + + + + // OK now calculate a few things for the device + // Calculate chunkGroupBits. + // We need to find the next power of 2 > than endBlock + + x = dev->nChunksPerBlock * (dev->endBlock+1); + + for(bits = extraBits = 0; x > 1; bits++) + { + if(x & 1) extraBits++; + x >>= 1; + } + + if(extraBits > 0) bits++; + + + // Level0 Tnodes are 16 bits, so if the bitwidth of the + // chunk range we're using is greater than 16 we need + // to figure out chunk shift and chunkGroupSize + if(bits <= 16) + { + dev->chunkGroupBits = 0; + } + else + { + dev->chunkGroupBits = bits - 16; + } + + dev->chunkGroupSize = 1 << dev->chunkGroupBits; + + if(dev->nChunksPerBlock < dev->chunkGroupSize) + { + // We have a problem because the soft delete won't work if + // the chunk group size > chunks per block. + // This can be remedied by using larger "virtual blocks". + + return YAFFS_FAIL; + } + + + + + // More device initialisation + dev->garbageCollections = 0; + dev->passiveGarbageCollections = 0; + dev->currentDirtyChecker = 0; + dev->bufferedBlock = -1; + dev->doingBufferedBlockRewrite = 0; + dev->nDeletedFiles = 0; + dev->nBackgroundDeletions=0; + dev->nUnlinkedFiles = 0; + dev->eccFixed=0; + dev->eccUnfixed=0; + dev->tagsEccFixed=0; + dev->tagsEccUnfixed=0; + + dev->localBuffer = YMALLOC(dev->nBytesPerChunk); + + + + + yaffs_InitialiseBlocks(dev,nBlocks); + + yaffs_InitialiseTnodes(dev); + + yaffs_InitialiseObjects(dev); + + if(dev->nShortOpCaches > 0) + { + int i; + + if(dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) + { + dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES; + } + + dev->srCache = YMALLOC( dev->nShortOpCaches * sizeof(yaffs_ChunkCache)); + + for(i=0; i < dev->nShortOpCaches; i++) + { + dev->srCache[i].object = NULL; + dev->srCache[i].lastUse = 0; + dev->srCache[i].dirty = 0; + } + dev->srLastUse = 0; + } + + dev->cacheHits = 0; + + + // Initialise the unlinked, root and lost and found directories + dev->lostNFoundDir = dev->rootDir = dev->unlinkedDir = NULL; + + dev->unlinkedDir = yaffs_CreateFakeDirectory(dev,YAFFS_OBJECTID_UNLINKED, S_IFDIR); + + dev->rootDir = yaffs_CreateFakeDirectory(dev,YAFFS_OBJECTID_ROOT,YAFFS_ROOT_MODE | S_IFDIR); + dev->lostNFoundDir = yaffs_CreateFakeDirectory(dev,YAFFS_OBJECTID_LOSTNFOUND,YAFFS_LOSTNFOUND_MODE | S_IFDIR); + yaffs_AddObjectToDirectory(dev->rootDir,dev->lostNFoundDir); + + + // Now scan the flash. + yaffs_Scan(dev); + + // Zero out stats + dev->nPageReads = 0; + dev->nPageWrites = 0; + dev->nBlockErasures = 0; + dev->nGCCopies = 0; + dev->nRetriedWrites = 0; + dev->nRetiredBlocks = 0; + + + return YAFFS_OK; + +} + +void yaffs_Deinitialise(yaffs_Device *dev) +{ + if(dev->isMounted) + { + + yaffs_DeinitialiseBlocks(dev); + yaffs_DeinitialiseTnodes(dev); + yaffs_DeinitialiseObjects(dev); + if(dev->nShortOpCaches > 0) + YFREE(dev->srCache); + YFREE(dev->localBuffer); + } + +} + +#if 0 + +int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev) +{ + int nFree = dev->nFreeChunks - (dev->nChunksPerBlock * YAFFS_RESERVED_BLOCKS); + + struct list_head *i; + yaffs_Object *l; + + + // To the free chunks add the chunks that are in the deleted unlinked files. + list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children) + { + l = list_entry(i, yaffs_Object,siblings); + if(l->deleted) + { + nFree++; + nFree += l->nDataChunks; + } + } + + + // printf("___________ nFreeChunks is %d nFree is %d\n",dev->nFreeChunks,nFree); + + if(nFree < 0) nFree = 0; + + return nFree; + +} + +#endif + +int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev) +{ + int nFree; + int pending; + int b; + int nDirtyCacheChunks=0; + + yaffs_BlockInfo *blk; + + struct list_head *i; + yaffs_Object *l; + + for(nFree = 0, b = dev->startBlock; b <= dev->endBlock; b++) + { + blk = yaffs_GetBlockInfo(dev,b); + + switch(blk->blockState) + { + case YAFFS_BLOCK_STATE_EMPTY: + case YAFFS_BLOCK_STATE_ALLOCATING: + case YAFFS_BLOCK_STATE_FULL: nFree += (dev->nChunksPerBlock - blk->pagesInUse); break; + default: break; + } + } + + + pending = 0; + + // To the free chunks add the chunks that are in the deleted unlinked files. + list_for_each(i,&dev->unlinkedDir->variant.directoryVariant.children) + { + if(i) + { + l = list_entry(i, yaffs_Object,siblings); + if(l->deleted) + { + pending++; + pending += l->nDataChunks; + } + } + } + + + + //printf("___________ really free is %d, pending %d, nFree is %d\n",nFree,pending, nFree+pending); + + if(nFree != dev->nFreeChunks) + { + // printf("___________Different! really free is %d, nFreeChunks %d\n",nFree dev->nFreeChunks); + } + + nFree += pending; + + // Now count the number of dirty chunks in the cache and subtract those + + { + int i; + for(i = 0; i < dev->nShortOpCaches; i++) + { + if(dev->srCache[i].dirty) nDirtyCacheChunks++; + } + } + + nFree -= nDirtyCacheChunks; + + nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock); + + if(nFree < 0) nFree = 0; + + return nFree; + +} + + + +/////////////////// YAFFS test code ////////////////////////////////// + +#define yaffs_CheckStruct(structure,syze, name) \ + if(sizeof(structure) != syze) \ + { \ + T(YAFFS_TRACE_ALWAYS,(TSTR("%s should be %d but is %d\n" TENDSTR),name,syze,sizeof(structure))); \ + return YAFFS_FAIL; \ + } + + +static int yaffs_CheckStructures(void) +{ + yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags") + yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion") + yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare") +#ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG + yaffs_CheckStruct(yaffs_Tnode,2* YAFFS_NTNODES_LEVEL0,"yaffs_Tnode") +#endif + yaffs_CheckStruct(yaffs_ObjectHeader,512,"yaffs_ObjectHeader") + + + return YAFFS_OK; +} + +#if 0 +void yaffs_GutsTest(yaffs_Device *dev) +{ + + if(yaffs_CheckStructures() != YAFFS_OK) + { + T(YAFFS_TRACE_ALWAYS,(TSTR("One or more structures malformed-- aborting\n" TENDSTR))); + return; + } + + yaffs_TnodeTest(dev); + yaffs_ObjectTest(dev); +} +#endif + + + + + + Index: linux-2.6.9/fs/yaffs/yaffs_fileem.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_fileem.c @@ -0,0 +1,271 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_fileem.c NAND emulation on top of files + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + //yaffs_fileem.c + +#include "yaffs_fileem.h" +#include "yaffs_guts.h" +#include "yaffsinterface.h" + +#include +#include +#include +#include +#include +#include +#include + +#define FILE_SIZE_IN_MEG 2 + +// #define YAFFS_ERROR_TESTING + +#define BLOCK_SIZE (32 * 528) +#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) +#define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG) +#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE) + + +static int h; +static __u8 ffChunk[528]; + +static int eraseDisplayEnabled; + +static int markedBadBlocks[] = { 1, 4, -1}; + +static int IsAMarkedBadBlock(int blk) +{ +#if YAFFS_ERROR_TESTING + int *m = markedBadBlocks; + + while(*m >= 0) + { + if(*m == blk) return 1; + m++; + } +#endif + return 0; +} + + +static __u8 yaffs_WriteFailCorruption(int chunkInNAND) +{ +#if YAFFS_ERROR_TESTING + + // Whole blocks that fail + switch(chunkInNAND/YAFFS_CHUNKS_PER_BLOCK) + { + case 50: + case 52: + return 7; + } + + // Single blocks that fail + switch(chunkInNAND) + { + case 2000: + case 2003: + case 3000: + case 3001: + return 3;// ding two bits + case 2001: + case 3003: + case 3004: + case 3005: + case 3006: + case 3007: return 1;// ding one bit + + + } +#endif + return 0; +} + +static void yaffs_ModifyWriteData(int chunkInNAND,__u8 *data) +{ +#if YAFFS_ERROR_TESTING + if(data) + { + *data ^= yaffs_WriteFailCorruption(chunkInNAND); + } +#endif +} + +static __u8 yaffs_ReadFailCorruption(int chunkInNAND) +{ + switch(chunkInNAND) + { +#if YAFFS_ERROR_TESTING + case 500: + return 3;// ding two bits + case 700: + case 750: + return 1;// ding one bit + +#endif + default: return 0; + + } +} + +static void yaffs_ModifyReadData(int chunkInNAND,__u8 *data) +{ +#if YAFFS_ERROR_TESTING + if(data) + { + *data ^= yaffs_ReadFailCorruption(chunkInNAND); + } +#endif +} + + + + + +static void CheckInit(yaffs_Device *dev) +{ + static int initialised = 0; + + int length; + int nWritten; + + + if(!initialised) + { + memset(ffChunk,0xFF,528); + +//#ifdef YAFFS_DUMP +// h = open("yaffs-em-file" , O_RDONLY); +//#else + h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE); +//#endif + if(h < 0) + { + perror("Fatal error opening yaffs emulation file"); + exit(1); + } + initialised = 1; + + length = lseek(h,0,SEEK_END); + nWritten = 528; + while(length < FILE_SIZE_IN_BYTES && nWritten == 528) + { + write(h,ffChunk,528); + length = lseek(h,0,SEEK_END); + } + if(nWritten != 528) + { + perror("Fatal error expanding yaffs emulation file"); + exit(1); + + } + + close(h); + +#ifdef YAFFS_DUMP + h = open("yaffs-em-file" , O_RDONLY); +#else + h = open("yaffs-em-file" , O_RDWR | O_CREAT, S_IREAD | S_IWRITE); +#endif + } +} + +int yaffs_FEWriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) +{ + __u8 localData[512]; + + int pos; + + pos = chunkInNAND * 528; + + CheckInit(dev); + + + if(data) + { + memcpy(localData,data,512); + yaffs_ModifyWriteData(chunkInNAND,localData); + lseek(h,pos,SEEK_SET); + write(h,localData,512); + } + + pos += 512; + + if(spare) + { + lseek(h,pos,SEEK_SET); + write(h,spare,16); + } + + return YAFFS_OK; +} + + +int yaffs_FEReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) +{ + int pos; + + pos = chunkInNAND * 528; + + + CheckInit(dev); + + if(data) + { + lseek(h,pos,SEEK_SET); + read(h,data,512); + yaffs_ModifyReadData(chunkInNAND,data); + } + + pos += 512; + + if(spare) + { + lseek(h,pos,SEEK_SET); + read(h,spare,16); + } + + return YAFFS_OK; +} + + +int yaffs_FEEraseBlockInNAND(yaffs_Device *dev,int blockInNAND) +{ + int i; + + CheckInit(dev); + + if(eraseDisplayEnabled) + { + printf("Erasing block %d\n",blockInNAND); + } + + lseek(h,blockInNAND * BLOCK_SIZE,SEEK_SET); + for(i = 0; i < 32; i++) + { + write(h,ffChunk,528); + } + + switch(blockInNAND) + { + case 10: + case 15: return YAFFS_FAIL; + + } + return YAFFS_OK; +} + +int yaffs_FEInitialiseNAND(yaffs_Device *dev) +{ + return YAFFS_OK; +} Index: linux-2.6.9/fs/yaffs/nand_ecc.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/nand_ecc.c @@ -0,0 +1,223 @@ +/* + * drivers/mtd/nand_ecc.c + * + * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) + * Toshiba America Electronics Components, Inc. + * + * $Id: nand_ecc.c,v 1.3 2002/09/27 20:50:50 charles Exp $ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * version 2.1 as published by the Free Software Foundation. + * + * This file contains an ECC algorithm from Toshiba that detects and + * corrects 1 bit errors in a 256 byte block of data. + */ + // Minor tweak by Charles Manning to prevent exporting symbols + // when compiled in with yaffs. + +const char *nand_ecc_c_version = "$Id: nand_ecc.c,v 1.3 2002/09/27 20:50:50 charles Exp $"; + +#if 0 +#include +#include +#include +#endif + +#include "yportenv.h" + +/* + * Pre-calculated 256-way 1 byte column parity + */ +static const u_char nand_ecc_precalc_table[] = { + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, + 0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, + 0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, + 0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, + 0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, + 0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, + 0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, + 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 +}; + + +/* + * Creates non-inverted ECC code from line parity + */ +static void nand_trans_result(u_char reg2, u_char reg3, + u_char *ecc_code) +{ + u_char a, b, i, tmp1, tmp2; + + /* Initialize variables */ + a = b = 0x80; + tmp1 = tmp2 = 0; + + /* Calculate first ECC byte */ + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ + tmp1 |= b; + b >>= 1; + a >>= 1; + } + + /* Calculate second ECC byte */ + b = 0x80; + for (i = 0; i < 4; i++) { + if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ + tmp2 |= b; + b >>= 1; + a >>= 1; + } + + /* Store two of the ECC bytes */ + ecc_code[0] = tmp1; + ecc_code[1] = tmp2; +} + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code) +{ + u_char idx, reg1, reg2, reg3; + int j; + + /* Initialize variables */ + reg1 = reg2 = reg3 = 0; + ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; + + /* Build up column parity */ + for(j = 0; j < 256; j++) { + + /* Get CP0 - CP5 from table */ + idx = nand_ecc_precalc_table[dat[j]]; + reg1 ^= (idx & 0x3f); + + /* All bit XOR = 1 ? */ + if (idx & 0x40) { + reg3 ^= (u_char) j; + reg2 ^= ~((u_char) j); + } + } + + /* Create non-inverted ECC code from line parity */ + nand_trans_result(reg2, reg3, ecc_code); + + /* Calculate final ECC code */ + ecc_code[0] = ~ecc_code[0]; + ecc_code[1] = ~ecc_code[1]; + ecc_code[2] = ((~reg1) << 2) | 0x03; +} + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc) +{ + u_char a, b, c, d1, d2, d3, add, bit, i; + + /* Do error detection */ + d1 = calc_ecc[0] ^ read_ecc[0]; + d2 = calc_ecc[1] ^ read_ecc[1]; + d3 = calc_ecc[2] ^ read_ecc[2]; + + if ((d1 | d2 | d3) == 0) { + /* No errors */ + return 0; + } + else { + a = (d1 ^ (d1 >> 1)) & 0x55; + b = (d2 ^ (d2 >> 1)) & 0x55; + c = (d3 ^ (d3 >> 1)) & 0x54; + + /* Found and will correct single bit error in the data */ + if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { + c = 0x80; + add = 0; + a = 0x80; + for (i=0; i<4; i++) { + if (d1 & c) + add |= a; + c >>= 2; + a >>= 1; + } + c = 0x80; + for (i=0; i<4; i++) { + if (d2 & c) + add |= a; + c >>= 2; + a >>= 1; + } + bit = 0; + b = 0x04; + c = 0x80; + for (i=0; i<3; i++) { + if (d3 & c) + bit |= b; + c >>= 2; + b >>= 1; + } + b = 0x01; + a = dat[add]; + a ^= (b << bit); + dat[add] = a; + return 1; + } + else { + i = 0; + while (d1) { + if (d1 & 0x01) + ++i; + d1 >>= 1; + } + while (d2) { + if (d2 & 0x01) + ++i; + d2 >>= 1; + } + while (d3) { + if (d3 & 0x01) + ++i; + d3 >>= 1; + } + if (i == 1) { + /* ECC Code Error Correction */ + read_ecc[0] = calc_ecc[0]; + read_ecc[1] = calc_ecc[1]; + read_ecc[2] = calc_ecc[2]; + return 2; + } + else { + /* Uncorrectable Error */ + return -1; + } + } + } + + /* Should never happen */ + return -1; +} + +#if 0 +EXPORT_SYMBOL(nand_calculate_ecc); +EXPORT_SYMBOL(nand_correct_data); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Steven J. Hill "); +MODULE_DESCRIPTION("Generic NAND ECC support"); +#endif Index: linux-2.6.9/fs/yaffs/yaffs_ramem.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_ramem.c @@ -0,0 +1,312 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_ramem.c NAND emulation on top of a chunk of RAM + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + //yaffs_ramem.c + // Since this creates the RAM block at start up it is pretty useless for testing the scanner. + +const char *yaffs_ramem_c_version = "$Id: yaffs_ramem.c,v 1.6 2002/11/26 01:15:37 charles Exp $"; + +#ifndef __KERNEL__ +#define CONFIG_YAFFS_RAM_ENABLED +#endif + +#ifdef CONFIG_YAFFS_RAM_ENABLED + +#include "yportenv.h" + +#include "yaffs_nandemul.h" +#include "yaffs_guts.h" +#include "yaffsinterface.h" +#include "devextras.h" + + +#define EM_SIZE_IN_MEG 2 + +#define BLOCK_SIZE (32 * 528) +#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) +#define FILE_SIZE_IN_BLOCKS (FILE_SIZE_IN_MEG * BLOCKS_PER_MEG) +#define FILE_SIZE_IN_BYTES (FILE_SIZE_IN_BLOCKS * BLOCK_SIZE) + + + +#define DEFAULT_SIZE_IN_MB 2 + +typedef struct +{ + __u8 data[528]; // Data + spare + int count[3]; // The programming count for each area of + // the page (0..255,256..511,512..527 + int empty; // is this empty? +} nandemul_Page; + +typedef struct +{ + nandemul_Page page[32]; // The pages in the block + __u8 damaged; // Is the block damaged? + +} nandemul_Block; + + + +typedef struct +{ + nandemul_Block **block; + int nBlocks; +} nandemul_Device; + +static nandemul_Device ned; + +int sizeInMB = DEFAULT_SIZE_IN_MB; + + +static void nandemul_yield(int n) +{ +#ifdef __KERNEL__ + if(n > 0) schedule_timeout(n); +#endif + +} + + +static void nandemul_ReallyEraseBlock(int blockNumber) +{ + int i; + + nandemul_Block *theBlock = ned.block[blockNumber]; + + for(i = 0; i < 32; i++) + { + memset(theBlock->page[i].data,0xff,528); + theBlock->page[i].count[0] = 0; + theBlock->page[i].count[1] = 0; + theBlock->page[i].count[2] = 0; + theBlock->page[i].empty = 1; + nandemul_yield(2); + } + +} + + +int nandemul_CalcNBlocks(void) +{ + switch(sizeInMB) + { + case 8: + case 16: + case 32: + case 64: + case 128: + case 256: + case 512: + break; + default: + sizeInMB = DEFAULT_SIZE_IN_MB; + } + return sizeInMB * 64; +} + + + +static int CheckInit(void) +{ + static int initialised = 0; + + int i; + int fail = 0; + int nBlocks; + int nAllocated = 0; + + if(initialised) + { + return YAFFS_OK; + } + + + nBlocks = nandemul_CalcNBlocks(); + + ned.block = YMALLOC(sizeof(nandemul_Block *) * nBlocks); + + if(!ned.block) return 0; + + for(i=0; i damaged = 0; + nAllocated++; + } + } + + if(fail) + { + for(i = 0; i < nAllocated; i++) + { + YFREE(ned.block[i]); + } + YFREE(ned.block); + + T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n", + nAllocated/64,sizeInMB)); + return 0; + } + + ned.nBlocks = nBlocks; + + initialised = 1; + + return 1; +} + +int nandemul_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) +{ + int blk; + int pg; + int i; + + __u8 *x; + + __u8 *spareAsBytes = (__u8 *)spare; + + + CheckInit(); + + blk = chunkInNAND/32; + pg = chunkInNAND%32; + + + if(data) + { + x = ned.block[blk]->page[pg].data; + + for(i = 0; i < 512; i++) + { + x[i] &=data[i]; + } + + ned.block[blk]->page[pg].count[0]++; + ned.block[blk]->page[pg].count[1]++; + ned.block[blk]->page[pg].empty = 0; + } + + + if(spare) + { + x = &ned.block[blk]->page[pg].data[512]; + + for(i = 0; i < 16; i++) + { + x[i] &=spareAsBytes[i]; + } + ned.block[blk]->page[pg].count[2]++; + } + + if(spare || data) + { + nandemul_yield(1); + } + + return YAFFS_OK; +} + + +int nandemul_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) +{ + int blk; + int pg; + + + CheckInit(); + + blk = chunkInNAND/32; + pg = chunkInNAND%32; + + + if(data) + { + memcpy(data,ned.block[blk]->page[pg].data,512); + } + + + if(spare) + { + memcpy(spare,&ned.block[blk]->page[pg].data[512],16); + } + + return YAFFS_OK; +} + + +int nandemul_CheckChunkErased(yaffs_Device *dev,int chunkInNAND) +{ + int blk; + int pg; + int i; + + + CheckInit(); + + blk = chunkInNAND/32; + pg = chunkInNAND%32; + + + for(i = 0; i < 528; i++) + { + if(ned.block[blk]->page[pg].data[i] != 0xFF) + { + return YAFFS_FAIL; + } + } + + return YAFFS_OK; + +} + +int nandemul_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) +{ + + CheckInit(); + + if(blockNumber < 0 || blockNumber >= ned.nBlocks) + { + T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); + } + else if(ned.block[blockNumber]->damaged) + { + T(YAFFS_TRACE_ALWAYS,("Attempt to erase damaged block %d\n",blockNumber)); + } + else + { + nandemul_ReallyEraseBlock(blockNumber); + } + + return YAFFS_OK; +} + +int nandemul_InitialiseNAND(yaffs_Device *dev) +{ + return YAFFS_OK; +} + +#endif //YAFFS_RAM_ENABLED + Index: linux-2.6.9/fs/yaffs/yaffs_ecc.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_ecc.h @@ -0,0 +1,30 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * + * yaffs_ecc.c: ECC generation/correction algorithms. + * + * Copyright (C) 2002 Aleph One Ltd. + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + + /* + * This code implements the ECC algorithm used in SmartMedia. + * + * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes. + * The two unused bit are set to 1. + * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC + * blocks are used on a 512-byte NAND page. + * + */ + +#ifndef __YAFFS_ECC_H__ +#define __YAFFS_ECC_H__ +void yaffs_ECCCalculate(const unsigned char *data,unsigned char *ecc); +int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc, const unsigned char *test_ecc); +#endif Index: linux-2.6.9/fs/yaffs/yaffs_nandemul.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_nandemul.h @@ -0,0 +1,38 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * yaffs_nandemul.h: Interface to emulated NAND functions + * + * $Id: yaffs_nandemul.h,v 1.4 2002/09/27 20:50:50 charles Exp $ + */ + +#ifndef __YAFFS_NANDEMUL_H__ +#define __YAFFS_NANDEMUL_H__ + +#include "yaffs_guts.h" + + +/* WriteChunkToNAND and ReadChunkFromNAND are used with two pointers. + * If either of these pointers are null, then that field will not be + * transferred. + */ + +int nandemul_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare); +int nandemul_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare); +int nandemul_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,int blockInNAND); +int nandemul_InitialiseNAND(struct yaffs_DeviceStruct *dev); + +#endif + Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -0,0 +1,1709 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_fs.c + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This is the file system front-end to YAFFS that hooks it up to + * the VFS. + * + * Special notes: + * >> sb->u.generic_sbp points to the yaffs_Device associated with this superblock + * >> inode->u.generic_ip points to the associated yaffs_Object. + * + * + * Acknowledgements: + * * Luc van OostenRyck for numerous patches. + * * Nick Bane for numerous patches. + * * Nick Bane for 2.5/2.6 integration. + * * Andras Toth for mknod rdev issue. + * * Michael Fischer for finding the problem with inode inconsistency. + * * Some code bodily lifted from JFFS2. + */ + + +const char *yaffs_fs_c_version = "$Id: yaffs_fs.c,v 1.35 2004/10/20 20:12:43 charles Exp $"; +extern const char *yaffs_guts_c_version; + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + +#include /* Added NCB 15-8-2003 */ +#include +#define UnlockPage(p) unlock_page(p) +#define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) +//#define kdevname(x) cdevname(to_kdev_t(x)) +#define kdevname(x) "(unavailable)" // temporary fix + +#else + +#include + +#endif + + +#include + +#include "yportenv.h" +#include "yaffs_guts.h" + + + + +unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BAD_BLOCKS; + +#ifdef CONFIG_YAFFS_RAM_ENABLED +#include "yaffs_nandemul.h" +// 2 MB of RAM for emulation +#define YAFFS_RAM_EMULATION_SIZE 0x200000 +#endif //CONFIG_YAFFS_RAM_ENABLED + +#ifdef CONFIG_YAFFS_MTD_ENABLED +#include +#include "yaffs_mtdif.h" +#endif //CONFIG_YAFFS_MTD_ENABLED + +//#define T(x) printk x + + + +#define yaffs_InodeToObject(iptr) ((yaffs_Object *)((iptr)->u.generic_ip)) +#define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode) +//NCB #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) + +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info) +#else +#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp) +#endif + + +static void yaffs_put_super(struct super_block *sb); + +static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos); +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos); +static int yaffs_file_flush(struct file* file); + +static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync); + +static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); + +//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n); +static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n); +#else +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); +static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry); +#endif +static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry); +static int yaffs_unlink(struct inode * dir, struct dentry *dentry); +static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname); +static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode); + +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev); +#else +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev); +#endif +static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry); +static int yaffs_setattr(struct dentry *dentry, struct iattr *attr); + +//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf); +#else +static int yaffs_statfs(struct super_block *sb, struct statfs *buf); +#endif +static void yaffs_read_inode (struct inode *inode); + +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static struct super_block *yaffs_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data); +#else +static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent); +#endif + +static void yaffs_put_inode (struct inode *inode); +static void yaffs_delete_inode(struct inode *); +static void yaffs_clear_inode(struct inode *); + +static int yaffs_readpage(struct file *file, struct page * page); +static int yaffs_writepage(struct page *page); +static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to); +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to); + +static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen); +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); + + + + +static struct address_space_operations yaffs_file_address_operations = { + readpage: yaffs_readpage, + writepage: yaffs_writepage, + prepare_write: yaffs_prepare_write, + commit_write: yaffs_commit_write +}; + + +static struct file_operations yaffs_file_operations = { +#ifdef CONFIG_YAFFS_USE_GENERIC_RW + read: generic_file_read, + write: generic_file_write, +#else + read: yaffs_file_read, + write: yaffs_file_write, +#endif + mmap: generic_file_mmap, + flush: yaffs_file_flush, + fsync: yaffs_sync_object, +}; + + +static struct inode_operations yaffs_file_inode_operations = { + setattr: yaffs_setattr, +}; + + +struct inode_operations yaffs_symlink_inode_operations = +{ + readlink: yaffs_readlink, + follow_link: yaffs_follow_link, + setattr: yaffs_setattr +}; + +static struct inode_operations yaffs_dir_inode_operations = { + create: yaffs_create, + lookup: yaffs_lookup, + link: yaffs_link, + unlink: yaffs_unlink, + symlink: yaffs_symlink, + mkdir: yaffs_mkdir, + rmdir: yaffs_unlink, + mknod: yaffs_mknod, + rename: yaffs_rename, + setattr: yaffs_setattr, +}; + +static struct file_operations yaffs_dir_operations = { + read: generic_read_dir, + readdir: yaffs_readdir, + fsync: yaffs_sync_object, +}; + + +static struct super_operations yaffs_super_ops = { + statfs: yaffs_statfs, + read_inode: yaffs_read_inode, + put_inode: yaffs_put_inode, + put_super: yaffs_put_super, +// remount_fs: + delete_inode: yaffs_delete_inode, + clear_inode: yaffs_clear_inode, +}; + + + +static void yaffs_GrossLock(yaffs_Device *dev) +{ + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs locking\n")); + + down(&dev->grossLock); +} + +static void yaffs_GrossUnlock(yaffs_Device *dev) +{ + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs unlocking\n")); + up(&dev->grossLock); + +} + +static int yaffs_readlink(struct dentry *dentry, char *buffer, int buflen) +{ + unsigned char *alias; + int ret; + + yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; + + + yaffs_GrossLock(dev); + + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + yaffs_GrossUnlock(dev); + + if(!alias) + return -ENOMEM; + + ret = vfs_readlink(dentry, buffer, buflen, alias); + kfree(alias); + return ret; +} + +static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + unsigned char *alias; + int ret; + yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; + + + yaffs_GrossLock(dev); + + alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); + + yaffs_GrossUnlock(dev); + + if(!alias) + return -ENOMEM; + + ret = vfs_follow_link(nd,alias); + kfree(alias); + return ret; +} + + +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj); + +/* + * Lookup is used to find objects in the fs + */ +//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + +static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *n) +#else +static struct dentry * yaffs_lookup(struct inode *dir, struct dentry *dentry) +#endif +{ + yaffs_Object *obj; + struct inode *inode = NULL; // NCB 2.5/2.6 needs NULL here + + yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; + + + yaffs_GrossLock(dev); + + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup for %d:%s\n",yaffs_InodeToObject(dir)->objectId,dentry->d_name.name)); + + obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),dentry->d_name.name); + + obj = yaffs_GetEquivalentObject(obj); // in case it was a hardlink + + + + if(obj) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup found %d\n",obj->objectId)); + + inode = yaffs_get_inode(dir->i_sb, obj->st_mode,0,obj); + + if(inode) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_loookup dentry \n")); +/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to d_add even if NULL inode */ +#if 0 + //dget(dentry); // try to solve directory bug + d_add(dentry,inode); + + yaffs_GrossUnlock(dev); + + // return dentry; + return NULL; +#endif + } + + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_lookup not found\n")); + + } + yaffs_GrossUnlock(dev); + +/* added NCB for 2.5/6 compatability - forces add even if inode is NULL which creates dentry hash*/ + d_add(dentry,inode); + + return NULL; + // return (ERR_PTR(-EIO)); + +} + +// For now put inode is just for debugging +// Put inode is called when the inode **structure** is put. +static void yaffs_put_inode(struct inode *inode) +{ + T(YAFFS_TRACE_OS,("yaffs_put_inode: ino %d, count %d\n",(int)inode->i_ino, atomic_read(&inode->i_count))); + +} + +// clear is called to tell the fs to release any per-inode data it holds +static void yaffs_clear_inode(struct inode *inode) +{ + yaffs_Object *obj; + yaffs_Device *dev; + + obj = yaffs_InodeToObject(inode); + + T(YAFFS_TRACE_OS,("yaffs_clear_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if(obj) + { + dev = obj->myDev; + yaffs_GrossLock(dev); + + // Clear the association between the inode ant the yaffs_Object. + obj->myInode = NULL; + inode->u.generic_ip = NULL; + + // If the object freeing was deferred, then the real free happens now. + // This should fix the inode inconsistency problem. + + yaffs_HandleDeferedFree(obj); + + yaffs_GrossUnlock(dev); + } + + +} + +// delete is called when the link count is zero and the inode +// is put (ie. nobody wants to know about it anymore, time to +// delete the file). +// NB Must call clear_inode() +static void yaffs_delete_inode(struct inode *inode) +{ + yaffs_Object *obj = yaffs_InodeToObject(inode); + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,("yaffs_delete_inode: ino %d, count %d %s\n",(int)inode->i_ino, atomic_read(&inode->i_count), + obj ? "object exists" : "null object")); + + if(obj) + { + dev = obj->myDev; + yaffs_GrossLock(dev); + yaffs_DeleteFile(obj); + yaffs_GrossUnlock(dev); + } + clear_inode(inode); +} + + +static int yaffs_file_flush(struct file* file) +{ + yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry); + + yaffs_Device *dev = obj->myDev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_flush object %d (%s)\n",obj->objectId, + obj->dirty ? "dirty" : "clean")); + + yaffs_GrossLock(dev); + + yaffs_FlushFile(obj,1); + + yaffs_GrossUnlock(dev); + + return 0; +} + + + +static int yaffs_readpage_nolock(struct file *f, struct page * pg) +{ + // Lifted from jffs2 + + yaffs_Object *obj; + unsigned char *pg_buf; + int ret; + + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage at %08x, size %08x\n", + (unsigned)(pg->index << PAGE_CACHE_SHIFT), (unsigned)PAGE_CACHE_SIZE)); + + obj = yaffs_DentryToObject(f->f_dentry); + + dev = obj->myDev; + + + if (!PageLocked(pg)) + PAGE_BUG(pg); + + pg_buf = kmap(pg); + /* FIXME: Can kmap fail? */ + + yaffs_GrossLock(dev); + + ret = yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE); + + yaffs_GrossUnlock(dev); + + if(ret >= 0) ret = 0; + + if (ret) { + ClearPageUptodate(pg); + SetPageError(pg); + } else { + SetPageUptodate(pg); + ClearPageError(pg); + } + + flush_dcache_page(pg); + kunmap(pg); + + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readpage done\n")); + return ret; +} + +static int yaffs_readpage_unlock(struct file *f, struct page *pg) +{ + int ret = yaffs_readpage_nolock(f,pg); + UnlockPage(pg); + return ret; +} + +static int yaffs_readpage(struct file *f, struct page * pg) +{ + return yaffs_readpage_unlock(f,pg); +} + +// writepage inspired by/stolen from smbfs +// + +static int yaffs_writepage(struct page *page) +{ + struct address_space *mapping = page->mapping; + struct inode *inode; + unsigned long end_index; + char *buffer; + yaffs_Object *obj; + int nWritten = 0; + unsigned nBytes; + + if (!mapping) + BUG(); + inode = mapping->host; + if (!inode) + BUG(); + + end_index = inode->i_size >> PAGE_CACHE_SHIFT; + + /* easy case */ + if (page->index < end_index) + { + nBytes = PAGE_CACHE_SIZE; + } + else + { + nBytes = inode->i_size & (PAGE_CACHE_SIZE-1); + } + // What's happening here? + ///* OK, are we completely out? */ + //if (page->index >= end_index+1 || !offset) + // return -EIO; + + get_page(page); + + + buffer = kmap(page); + + obj = yaffs_InodeToObject(inode); + yaffs_GrossLock(obj->myDev); + + + nWritten = yaffs_WriteDataToFile(obj,buffer,page->index << PAGE_CACHE_SHIFT,nBytes); + + yaffs_GrossUnlock(obj->myDev); + + kunmap(page); + SetPageUptodate(page); + UnlockPage(page); + put_page(page); + + return (nWritten == nBytes) ? 0 : -ENOSPC; +} + + + +static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to) +{ + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_prepair_write\n")); + if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) + return yaffs_readpage_nolock(f,pg); + + return 0; + +} + +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to) +{ + + void *addr = page_address(pg) + offset; + loff_t pos = (((loff_t)pg->index) << PAGE_CACHE_SHIFT) + offset; + int nBytes = to - offset; + int nWritten; + + unsigned spos = pos; + unsigned saddr = (unsigned)addr; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write addr %x pos %x nBytes %d\n",saddr,spos,nBytes)); + + nWritten = yaffs_file_write(f,addr, nBytes, &pos); + + if(nWritten != nBytes) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write not same size nWritten %d nBytes %d\n",nWritten,nBytes)); + SetPageError(pg); + ClearPageUptodate(pg); + } + else + { + SetPageUptodate(pg); + } + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten)); + + return nWritten; + +} + + + +static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) +{ + if (inode && obj) + { + inode->i_ino = obj->objectId; + inode->i_mode = obj->st_mode; + inode->i_uid = obj->st_uid; + inode->i_gid = obj->st_gid; + inode->i_blksize = inode->i_sb->s_blocksize; +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + + inode->i_rdev = old_decode_dev(obj->st_rdev); + inode->i_atime.tv_sec = (time_t)(obj->st_atime); + inode->i_atime.tv_nsec = 0; + inode->i_mtime.tv_sec = (time_t)obj->st_mtime; + inode->i_mtime.tv_nsec =0; + inode->i_ctime.tv_sec = (time_t)obj->st_ctime; + inode->i_ctime.tv_nsec = 0; +#else + inode->i_rdev = obj->st_rdev; + inode->i_atime = obj->st_atime; + inode->i_mtime = obj->st_mtime; + inode->i_ctime = obj->st_ctime; +#endif + inode->i_size = yaffs_GetObjectFileLength(obj); + inode->i_blocks = (inode->i_size + 511) >> 9; + + inode->i_nlink = yaffs_GetObjectLinkCount(obj); + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", + inode->i_mode, inode->i_uid, inode->i_gid, (int)inode->i_size, atomic_read(&inode->i_count))); + + switch (obj->st_mode & S_IFMT) + { + default: // fifo, device or socket + init_special_inode(inode, obj->st_mode,(dev_t)(obj->st_rdev)); + break; + case S_IFREG: // file + inode->i_op = &yaffs_file_inode_operations; + inode->i_fop = &yaffs_file_operations; + inode->i_mapping->a_ops = &yaffs_file_address_operations; + break; + case S_IFDIR: // directory + inode->i_op = &yaffs_dir_inode_operations; + inode->i_fop = &yaffs_dir_operations; + break; + case S_IFLNK: // symlink + inode->i_op = &yaffs_symlink_inode_operations; + break; + } + + + inode->u.generic_ip = obj; + obj->myInode = inode; + + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_FileInode invalid parameters\n")); + } + +} + +struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,yaffs_Object *obj) +{ + struct inode * inode; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_get_inode for object %d\n",obj->objectId)); + + inode = iget(sb,obj->objectId); + + // NB Side effect: iget calls back to yaffs_read_inode(). + // iget also increments the inode's i_count + + return inode; +} + +static ssize_t yaffs_file_read(struct file *f, char *buf, size_t n, loff_t *pos) +{ + yaffs_Object *obj; + int nRead,ipos; + struct inode *inode; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_read\n")); + + obj = yaffs_DentryToObject(f->f_dentry); + + dev = obj->myDev; + + yaffs_GrossLock(dev); + + inode = f->f_dentry->d_inode; + + if (*pos < inode->i_size) + { + if (*pos + n > inode->i_size) + { + n = inode->i_size - *pos; + } + } + else + { + n = 0; + } + + nRead = yaffs_ReadDataFromFile(obj,buf,*pos,n); + if(nRead > 0) + { + f->f_pos += nRead; + } + + yaffs_GrossUnlock(dev); + + ipos = *pos; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_read read %d bytes, %d read at %d\n",n,nRead,ipos)); + return nRead; + +} + + +static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_t *pos) +{ + yaffs_Object *obj; + int nWritten,ipos; + struct inode *inode; + yaffs_Device *dev; + + + obj = yaffs_DentryToObject(f->f_dentry); + + dev = obj->myDev; + + yaffs_GrossLock(dev); + + inode = f->f_dentry->d_inode; + + if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) + { + ipos = inode->i_size; + } + else + { + ipos = *pos; + } + + + if(!obj) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write: hey obj is null!\n")); + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write about to write writing %d bytes to object %d at %d\n",n,obj->objectId,ipos)); + } + + nWritten = yaffs_WriteDataToFile(obj,buf,ipos,n); + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos)); + if(nWritten > 0) + { + ipos += nWritten; + *pos = ipos; + if(ipos > inode->i_size) + { + inode->i_size = ipos; + inode->i_blocks = (ipos + 511)>>9; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,(int)(inode->i_blocks))); + } + + } + yaffs_GrossUnlock(dev); + + return nWritten != n ? -ENOSPC : nWritten; +} + + +static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) +{ + yaffs_Object *obj; + yaffs_Device *dev; + struct inode *inode = f->f_dentry->d_inode; + unsigned long offset, curoffs; + struct list_head *i; + yaffs_Object *l; + + char name[YAFFS_MAX_NAME_LENGTH +1]; + + obj = yaffs_DentryToObject(f->f_dentry); + dev = obj->myDev; + + yaffs_GrossLock(dev); + + offset = f->f_pos; + + T(YAFFS_TRACE_OS,("yaffs_readdir: starting at %d\n",(int)offset)); + + if(offset == 0) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry . ino %d \n",(int)inode->i_ino)); + if(filldir(dirent,".",1,offset,inode->i_ino,DT_DIR) < 0) + { + goto out; + } + offset++; + f->f_pos++; + } + if(offset == 1) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: entry .. ino %d \n",(int)f->f_dentry->d_parent->d_inode->i_ino)); + if(filldir(dirent,"..",2,offset,f->f_dentry->d_parent->d_inode->i_ino,DT_DIR) < 0) + { + goto out; + } + offset++; + f->f_pos++; + } + + curoffs = 1; + + list_for_each(i,&obj->variant.directoryVariant.children) + { + curoffs++; + if(curoffs >= offset) + { + l = list_entry(i, yaffs_Object,siblings); + + yaffs_GetObjectName(l,name,YAFFS_MAX_NAME_LENGTH+1); + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_readdir: %s inode %d\n",name,yaffs_GetObjectInode(l))); + + if(filldir(dirent, + name, + strlen(name), + offset, + yaffs_GetObjectInode(l), + yaffs_GetObjectType(l)) + < 0) + { + goto up_and_out; + } + + offset++; + f->f_pos++; + } + } + + up_and_out: + out: + + yaffs_GrossUnlock(dev); + + return 0; +} + + +/* + * File creation. Allocate an inode, and we're done.. + */ +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev) +#else +static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev) +#endif +{ + struct inode *inode; + + yaffs_Object *obj = NULL; + yaffs_Device *dev; + + yaffs_Object *parent = yaffs_InodeToObject(dir); + + int error = -ENOSPC; + + if(parent) + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: parent object %d type %d\n", + parent->objectId,parent->variantType)); + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: could not get parent object\n")); + return -EPERM; + } + + T(YAFFS_TRACE_OS,("yaffs_mknod: making oject for %s, mode %x dev %x\n", + dentry->d_name.name, mode,rdev)); + + dev = parent->myDev; + + yaffs_GrossLock(dev); + + switch (mode & S_IFMT) + { + default: + // Special (socket, fifo, device...) + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making special\n")); + obj = yaffs_MknodSpecial(parent,dentry->d_name.name,mode,current->uid, current->gid,rdev); + break; + case S_IFREG: // file + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n")); + obj = yaffs_MknodFile(parent,dentry->d_name.name,mode,current->uid, current->gid); + break; + case S_IFDIR: // directory + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making directory\n")); + obj = yaffs_MknodDirectory(parent,dentry->d_name.name,mode,current->uid, current->gid); + break; + case S_IFLNK: // symlink + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod: making file\n")); + obj = NULL; // Do we ever get here? + break; + } + + if(obj) + { + inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); + d_instantiate(dentry, inode); + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod created object %d count = %d\n",obj->objectId,atomic_read(&inode->i_count))); + error = 0; + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mknod failed making object\n")); + error = -ENOMEM; + } + + yaffs_GrossUnlock(dev); + + return error; +} + +static int yaffs_mkdir(struct inode * dir, struct dentry * dentry, int mode) +{ + int retVal; + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_mkdir\n")); + retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); +#if 0 + // attempt to fix dir bug - didn't work + if(!retVal) + { + dget(dentry); + } +#endif + return retVal; +} + +//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *n) +#else +static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) +#endif +{ + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_create\n")); + return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); +} + + +static int yaffs_unlink(struct inode * dir, struct dentry *dentry) +{ + int retVal; + + yaffs_Device *dev; + + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_unlink %d:%s\n",(int)(dir->i_ino),dentry->d_name.name)); + + dev = yaffs_InodeToObject(dir)->myDev; + + yaffs_GrossLock(dev); + + + retVal = yaffs_Unlink(yaffs_InodeToObject(dir),dentry->d_name.name); + + + yaffs_GrossUnlock(dev); + + if( retVal == YAFFS_OK) + { + dentry->d_inode->i_nlink--; + mark_inode_dirty(dentry->d_inode); + return 0; + } + else + { + return -ENOTEMPTY; + } +} + + +/* + * Create a link... + */ +static int yaffs_link(struct dentry *old_dentry, struct inode * dir, struct dentry * dentry) +{ + struct inode *inode = old_dentry->d_inode; + yaffs_Object *obj = NULL; + yaffs_Object *link=NULL; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link\n")); + + obj = yaffs_InodeToObject(inode); + dev = obj->myDev; + + yaffs_GrossLock(dev); + + if (!S_ISDIR(inode->i_mode)) // Don't link directories + { + link = yaffs_Link(yaffs_InodeToObject(dir),dentry->d_name.name,obj); + } + + + if(link) + { + old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj); + d_instantiate(dentry, old_dentry->d_inode); + atomic_inc(&old_dentry->d_inode->i_count); + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_link link count %d i_count %d\n", + old_dentry->d_inode->i_nlink,atomic_read(&old_dentry->d_inode->i_count))); + + } + + yaffs_GrossUnlock(dev); + + + if(link) + { + + return 0; + } + + + return -EPERM; +} + + +static int yaffs_symlink(struct inode * dir, struct dentry *dentry, const char * symname) +{ + yaffs_Object *obj; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_symlink\n")); + + dev = yaffs_InodeToObject(dir)->myDev; + yaffs_GrossLock(dev); + obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, + S_IFLNK | S_IRWXUGO, current->uid, current->gid, + symname); + yaffs_GrossUnlock(dev); + + if(obj) + { + + struct inode* inode; + + inode = yaffs_get_inode(dir->i_sb, obj->st_mode, 0, obj); + d_instantiate(dentry, inode); + T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink created OK\n")); + return 0; + } + else + { + T(YAFFS_TRACE_OS,(KERN_DEBUG"symlink not created\n")); + + } + + return -ENOMEM; +} + +static int yaffs_sync_object(struct file * file, struct dentry *dentry, int datasync) +{ + + yaffs_Object *obj; + yaffs_Device *dev; + + obj = yaffs_DentryToObject(dentry); + + dev = obj->myDev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_sync_object\n")); + yaffs_GrossLock(dev); + yaffs_FlushFile(obj,1); + yaffs_GrossUnlock(dev); + return 0; +} + +/* + * The VFS layer already does all the dentry stuff for rename. + * + * NB: POSIX says you can rename an object over an old object of the same name + */ +static int yaffs_rename(struct inode * old_dir, struct dentry *old_dentry, struct inode * new_dir,struct dentry *new_dentry) +{ + yaffs_Device *dev; + int retVal = YAFFS_FAIL; + int removed = 0; + yaffs_Object *target; + + dev = yaffs_InodeToObject(old_dir)->myDev; + + yaffs_GrossLock(dev); + + // Check if the target is an existing directory that is not empty. + target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),new_dentry->d_name.name); + + if(target && + target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY && + !list_empty(&target->variant.directoryVariant.children)) + { + retVal = YAFFS_FAIL; + } + else + { + + // Unlink the target if it exists + removed = yaffs_Unlink(yaffs_InodeToObject(new_dir),new_dentry->d_name.name); + + + retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),old_dentry->d_name.name, + yaffs_InodeToObject(new_dir),new_dentry->d_name.name); + + } + yaffs_GrossUnlock(dev); + + if(retVal == YAFFS_OK) + { + if(removed == YAFFS_OK) + { + new_dentry->d_inode->i_nlink--; + mark_inode_dirty(new_dentry->d_inode); + } + + return 0; + } + else + { + return -ENOTEMPTY; + } + + +} + +static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) +{ + struct inode *inode = dentry->d_inode; + int error; + yaffs_Device *dev; + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_setattr of object %d\n",yaffs_InodeToObject(inode)->objectId)); + + if((error = inode_change_ok(inode,attr)) == 0) + { + + dev = yaffs_InodeToObject(inode)->myDev; + yaffs_GrossLock(dev); + if(yaffs_SetAttributes(yaffs_InodeToObject(inode),attr) == YAFFS_OK) + { + error = 0; + } + else + { + error = -EPERM; + } + yaffs_GrossUnlock(dev); + inode_setattr(inode,attr); + } + return error; +} + +//#if defined(CONFIG_KERNEL_2_5) /* Added NCB 185-8-2003 */ +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) +#else +static int yaffs_statfs(struct super_block *sb, struct statfs *buf) +#endif +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_statfs\n")); + + yaffs_GrossLock(dev); + + buf->f_type = YAFFS_MAGIC; + buf->f_bsize = sb->s_blocksize; + buf->f_namelen = 255; + buf->f_blocks = (dev->endBlock - dev->startBlock + 1) * YAFFS_CHUNKS_PER_BLOCK/ + (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK); + buf->f_files = 0; + buf->f_ffree = 0; + buf->f_bfree = yaffs_GetNumberOfFreeChunks(dev)/ + (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK); + buf->f_bavail = buf->f_bfree; + + yaffs_GrossUnlock(dev); + return 0; +} + +static void yaffs_read_inode (struct inode *inode) +{ + // NB This is called as a side effect of other functions and + // thus gross locking should always be in place already. + + yaffs_Object *obj ; + yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb); + + T(YAFFS_TRACE_OS,(KERN_DEBUG"yaffs_read_inode for %d\n",(int)inode->i_ino)); + + obj = yaffs_FindObjectByNumber(dev,inode->i_ino); + + yaffs_FillInodeFromObject(inode,obj); + +} + + + +static yaffs_Device *yaffs_dev; +static yaffs_Device *yaffsram_dev; + + + +static void yaffs_put_super(struct super_block *sb) +{ + yaffs_Device *dev = yaffs_SuperToDevice(sb); + + yaffs_GrossLock(dev); + if(dev->putSuperFunc) + { + dev->putSuperFunc(sb); + } + yaffs_Deinitialise(dev); + yaffs_GrossUnlock(dev); + + if(dev == yaffs_dev) yaffs_dev = NULL; + if(dev == yaffsram_dev) yaffsram_dev = NULL; + + kfree(dev); +} + + +#ifdef CONFIG_YAFFS_MTD_ENABLED + +static void yaffs_MTDPutSuper(struct super_block *sb) +{ + + struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; + + if(mtd->sync) + { + mtd->sync(mtd); + } + + put_mtd_device(mtd); +} + +#endif + + +static struct super_block *yaffs_internal_read_super(int useRam, struct super_block * sb, void * data, int silent) +{ + int nBlocks; + struct inode * inode; + struct dentry * root; + yaffs_Device *dev; + + sb->s_magic = YAFFS_MAGIC; + sb->s_op = &yaffs_super_ops; + + if(!sb) + printk(KERN_INFO"yaffs: sb is NULL\n"); + else if(!sb->s_dev) + printk(KERN_INFO"yaffs: sb->s_dev is NULL\n"); + else if(! kdevname(sb->s_dev)) + printk(KERN_INFO"yaffs: kdevname is NULL\n"); + else + printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, kdevname(sb->s_dev)); + + + +#ifdef CONFIG_YAFFS_USE_CHUNK_SIZE + sb->s_blocksize = YAFFS_BYTES_PER_CHUNK; + sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT; +#else + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +#endif + T(YAFFS_TRACE_OS,("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",(int)(sb->s_blocksize))); + +#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY + T(YAFFS_TRACE_OS,("yaffs: Write verification disabled. All guarantees null and void\n")); +#endif + + + + if(useRam) + { + +#ifdef CONFIG_YAFFS_RAM_ENABLED + // Set the yaffs_Device up for ram emulation + + sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); + if(!dev) + { + // Deep shit could not allocate device structure + printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\n"); + return NULL; + } + + memset(dev,0,sizeof(yaffs_Device)); + dev->genericDevice = NULL; // Not used for RAM emulation. + + nBlocks = YAFFS_RAM_EMULATION_SIZE / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + dev->startBlock = 1; // Don't use block 0 + dev->endBlock = nBlocks - 1; + dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; + dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; + dev->nReservedBlocks = 5; + + dev->writeChunkToNAND = nandemul_WriteChunkToNAND; + dev->readChunkFromNAND = nandemul_ReadChunkFromNAND; + dev->eraseBlockInNAND = nandemul_EraseBlockInNAND; + dev->initialiseNAND = nandemul_InitialiseNAND; + + yaffsram_dev = dev; + +#endif + + } + else + { +#ifdef CONFIG_YAFFS_MTD_ENABLED + struct mtd_info *mtd; + + printk(KERN_DEBUG "yaffs: Attempting MTD mount on %u.%u, \"%s\"\n", + MAJOR(sb->s_dev),MINOR(sb->s_dev),kdevname(sb->s_dev)); + + // Check it's an mtd device..... + if(MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) + { + return NULL; // This isn't an mtd device + } + + // Get the device + mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); + if (!mtd) + { + printk(KERN_DEBUG "yaffs: MTD device #%u doesn't appear to exist\n", MINOR(sb->s_dev)); + return NULL; + } + + // Check it's NAND + if(mtd->type != MTD_NANDFLASH) + { + printk(KERN_DEBUG "yaffs: MTD device is not NAND it's type %d\n", mtd->type); + return NULL; + } + + //printk(KERN_DEBUG" erase %x\n",mtd->erase); + //printk(KERN_DEBUG" read %x\n",mtd->read); + //printk(KERN_DEBUG" write %x\n",mtd->write); + //printk(KERN_DEBUG" readoob %x\n",mtd->read_oob); + //printk(KERN_DEBUG" writeoob %x\n",mtd->write_oob); + //printk(KERN_DEBUG" oobblock %x\n",mtd->oobblock); + //printk(KERN_DEBUG" oobsize %x\n",mtd->oobsize); + + + if(!mtd->erase || + !mtd->read || + !mtd->write || +#ifndef CONFIG_YAFFS_USE_OLD_MTD + !mtd->write_ecc || + !mtd->read_ecc || +#endif + !mtd->read_oob || + !mtd->write_oob ) + { + printk(KERN_DEBUG "yaffs: MTD device does not support required functions\n"); + return NULL; + } + + if(mtd->oobblock != YAFFS_BYTES_PER_CHUNK || + mtd->oobsize != YAFFS_BYTES_PER_SPARE) + { + printk(KERN_DEBUG "yaffs: MTD device does not support have the right page sizes\n"); + return NULL; + } + + + // OK, so if we got here, we have an MTD that's NAND and looks + // like it has the right capabilities + // Set the yaffs_Device up for ram emulation + +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); +#else + sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device),GFP_KERNEL); +#endif + if(!dev) + { + // Deep shit could not allocate device structure + printk(KERN_DEBUG"yaffs_read_super: Failed trying to allocate yaffs_Device. Terminating debug.\n"); + return NULL; + } + + memset(dev,0,sizeof(yaffs_Device)); + dev->genericDevice = mtd; + + // Set up the memory size parameters.... + + nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); + dev->startBlock = 1; // Don't use block 0 + dev->endBlock = nBlocks - 1; + dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; + dev->nBytesPerChunk = YAFFS_BYTES_PER_CHUNK; + dev->nReservedBlocks = 5; + dev->nShortOpCaches = 10; // Enable short op caching + + + // ... and the functions. + dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; + dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; + dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; + dev->initialiseNAND = nandmtd_InitialiseNAND; + + dev->putSuperFunc = yaffs_MTDPutSuper; + +#ifdef CONFIG_YAFFS_USE_NANDECC + dev->useNANDECC = 1; +#endif + + yaffs_dev = dev; + +#endif + } + + init_MUTEX(&dev->grossLock); + + + yaffs_GrossLock(dev); + yaffs_GutsInitialise(yaffs_SuperToDevice(sb)); + + T(YAFFS_TRACE_OS,("yaffs_read_super: guts initialised\n")); + + // Create root inode + inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,yaffs_Root(yaffs_SuperToDevice(sb))); + + yaffs_GrossUnlock(dev); + + if (!inode) + return NULL; + +// added NCB + inode->i_op = & yaffs_dir_inode_operations; + inode->i_fop = & yaffs_dir_operations; + + T(YAFFS_TRACE_OS,("yaffs_read_super: got root inode\n")); + + + root = d_alloc_root(inode); + + T(YAFFS_TRACE_OS,("yaffs_read_super: d_alloc_root done\n")); + + if (!root) { + iput(inode); + return NULL; + } + sb->s_root = root; + + T(YAFFS_TRACE_OS,("yaffs_read_super: done\n")); + return sb; +} + +static int yaffs_internal_read_super_ram(struct super_block * sb, void * data, int silent) +{ + return yaffs_internal_read_super(1,sb,data,silent) ? 0 : -1; +} +static int yaffs_internal_read_super_mtd(struct super_block * sb, void * data, int silent) +{ + return yaffs_internal_read_super(0,sb,data,silent) ? 0 : -1; +} + + +#ifdef CONFIG_YAFFS_MTD_ENABLED +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static struct super_block *yaffs_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) +{ + + return get_sb_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_mtd); +} + +/* changes NCB 2.5.70 */ +//static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV); +static struct file_system_type yaffs_fs_type = { + .owner = THIS_MODULE, + .name = "yaffs", + .get_sb = yaffs_read_super, +// .kill_sb = kill_block_super, + .kill_sb = kill_litter_super, + .fs_flags = FS_REQUIRES_DEV, +}; +#else +static struct super_block *yaffs_read_super(struct super_block * sb, void * data, int silent) +{ + return yaffs_internal_read_super(0,sb,data,silent); +} + +static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV); +#endif +#endif + +#ifdef CONFIG_YAFFS_RAM_ENABLED + +//#if defined(CONFIG_KERNEL_2_5) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) +static struct super_block *yaffs_ram_read_super(struct file_system_type * fs, int flags, const char *dev_name, void *data) +{ + + return get_sb_bdev(fs, flags, dev_name, data, yaffs_internal_read_super_ram); +} + +/* changes NCB 2.5.70 */ +//static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, FS_REQUIRES_DEV); +static struct file_system_type yaffs_fs_type = { + .owner = THIS_MODULE, + .name = "yaffsram", + .get_sb = yaffs_ram_read_super, +// .kill_sb = kill_block_super, + .kill_sb = kill_litter_super, + .fs_flags = FS_SINGLE, +}; +#else +static struct super_block *yaffs_ram_read_super(struct super_block * sb, void * data, int silent) +{ + return yaffs_internal_read_super(1,sb,data,silent); +} + +static DECLARE_FSTYPE(yaffs_ram_fs_type, "yaffsram", yaffs_ram_read_super, FS_SINGLE); +#endif +#endif // CONFIG_YAFFS_RAM_ENABLED + + +static struct proc_dir_entry *my_proc_entry; +static struct proc_dir_entry *my_proc_ram_write_entry; + +static char * yaffs_dump_dev(char *buf,yaffs_Device *dev,char *name) +{ + buf +=sprintf(buf,"\nDevice %s\n",name); + buf +=sprintf(buf,"startBlock......... %d\n",dev->startBlock); + buf +=sprintf(buf,"endBlock........... %d\n",dev->endBlock); + buf +=sprintf(buf,"chunkGroupBits..... %d\n",dev->chunkGroupBits); + buf +=sprintf(buf,"chunkGroupSize..... %d\n",dev->chunkGroupSize); + buf +=sprintf(buf,"nErasedBlocks...... %d\n",dev->nErasedBlocks); + buf +=sprintf(buf,"nTnodesCreated..... %d\n",dev->nTnodesCreated); + buf +=sprintf(buf,"nFreeTnodes........ %d\n",dev->nFreeTnodes); + buf +=sprintf(buf,"nObjectsCreated.... %d\n",dev->nObjectsCreated); + buf +=sprintf(buf,"nFreeObjects....... %d\n",dev->nFreeObjects); + buf +=sprintf(buf,"nFreeChunks........ %d\n",dev->nFreeChunks); + buf +=sprintf(buf,"nPageWrites........ %d\n",dev->nPageWrites); + buf +=sprintf(buf,"nPageReads......... %d\n",dev->nPageReads); + buf +=sprintf(buf,"nBlockErasures..... %d\n",dev->nBlockErasures); + buf +=sprintf(buf,"nGCCopies.......... %d\n",dev->nGCCopies); + buf +=sprintf(buf,"garbageCollections. %d\n",dev->garbageCollections); + buf +=sprintf(buf,"passiveGCs......... %d\n",dev->passiveGarbageCollections); + buf +=sprintf(buf,"nRetriedWrites..... %d\n",dev->nRetriedWrites); + buf +=sprintf(buf,"nRetireBlocks...... %d\n",dev->nRetiredBlocks); + buf +=sprintf(buf,"eccFixed........... %d\n",dev->eccFixed); + buf +=sprintf(buf,"eccUnfixed......... %d\n",dev->eccUnfixed); + buf +=sprintf(buf,"tagsEccFixed....... %d\n",dev->tagsEccFixed); + buf +=sprintf(buf,"tagsEccUnfixed..... %d\n",dev->tagsEccUnfixed); + buf +=sprintf(buf,"cacheHits.......... %d\n",dev->cacheHits); + buf +=sprintf(buf,"nDeletedFiles...... %d\n",dev->nDeletedFiles); + buf +=sprintf(buf,"nUnlinkedFiles..... %d\n",dev->nUnlinkedFiles); + buf +=sprintf(buf,"nBackgroudDeletions %d\n",dev->nBackgroundDeletions); + buf +=sprintf(buf,"useNANDECC......... %d\n",dev->useNANDECC); + + + return buf; +} + +static int yaffs_proc_read( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data + ) +{ + + char my_buffer[3000]; + char *buf; + buf = my_buffer; + + if (offset > 0) return 0; + + /* Fill the buffer and get its length */ + buf +=sprintf(buf,"YAFFS built:"__DATE__ " "__TIME__"\n%s\n%s\n", yaffs_fs_c_version,yaffs_guts_c_version); + + if(yaffs_dev) buf = yaffs_dump_dev(buf,yaffs_dev,"yaffs"); + if(yaffsram_dev) buf = yaffs_dump_dev(buf,yaffsram_dev,"yaffsram"); + + + strcpy(page,my_buffer); + return strlen(my_buffer); +} + + +static int yaffs_proc_ram_write( + char *page, + char **start, + off_t offset, + int count, + int *eof, + void *data + ) +{ + + printk(KERN_DEBUG "yaffs write size %d\n",count); + return count; +} + +static int __init init_yaffs_fs(void) +{ + int error = 0; + + yaffs_dev = yaffsram_dev = NULL; + + printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n"); +#ifdef CONFIG_YAFFS_USE_GENERIC_RW + printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n"); +#else + printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n"); +#endif + + + /* Install the proc_fs entry */ + my_proc_entry = create_proc_read_entry("yaffs", + S_IRUGO | S_IFREG, + &proc_root, + yaffs_proc_read, + NULL); + if(!my_proc_entry) + { + return -ENOMEM; + } + +#ifdef CONFIG_YAFFS_RAM_ENABLED +#if 0 + my_proc_ram_write_entry = create_proc_entry("yaffs_ram", + S_IRUGO | S_IFREG, + &proc_root); + + if(!my_proc_ram_write_entry) + { + return -ENOMEM; + } + else + { + my_proc_ram_write_entry->write_proc = yaffs_proc_ram_write; + } +#endif + + error = register_filesystem(&yaffs_ram_fs_type); + if(error) + { + return error; + } +#endif //CONFIG_YAFFS_RAM_ENABLED + +#ifdef CONFIG_YAFFS_MTD_ENABLED + error = register_filesystem(&yaffs_fs_type); + if(error) + { +#ifdef CONFIG_YAFFS_RAM_ENABLED + unregister_filesystem(&yaffs_ram_fs_type); +#endif //CONFIG_YAFFS_RAM_ENABLED + } +#endif // CONFIG_YAFFS_MTD_ENABLED + + return error; +} + +static void __exit exit_yaffs_fs(void) +{ + printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Clean up\n"); + + remove_proc_entry("yaffs",&proc_root); + +#ifdef CONFIG_YAFFS_RAM_ENABLED + unregister_filesystem(&yaffs_ram_fs_type); +#endif +#ifdef CONFIG_YAFFS_MTD_ENABLED + unregister_filesystem(&yaffs_fs_type); +#endif + +} + +module_init(init_yaffs_fs) +module_exit(exit_yaffs_fs) + +MODULE_DESCRIPTION("YAFFS - a NAND specific flash file system"); +MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002"); +MODULE_LICENSE("GPL"); + Index: linux-2.6.9/fs/yaffs/yaffs_guts.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_guts.h @@ -0,0 +1,593 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_guts.h: Configuration etc for yaffs_guts + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * $Id: yaffs_guts.h,v 1.18 2004/10/20 20:12:43 charles Exp $ + */ + +#ifndef __YAFFS_GUTS_H__ +#define __YAFFS_GUTS_H__ + +#include "yportenv.h" + +#define YAFFS_OK 1 +#define YAFFS_FAIL 0 + +// Give us a Y=0x59, +// Give us an A=0x41, +// Give us an FF=0xFF +// Give us an S=0x53 +// And what have we got... +#define YAFFS_MAGIC 0x5941FF53 + +#define YAFFS_NTNODES_LEVEL0 16 +#define YAFFS_TNODES_LEVEL0_BITS 4 +#define YAFFS_TNODES_LEVEL0_MASK 0xf + +#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2) +#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1) +#define YAFFS_TNODES_INTERNAL_MASK 0x7 +#define YAFFS_TNODES_MAX_LEVEL 6 + +#define YAFFS_BYTES_PER_SPARE 16 + +#define YAFFS_BYTES_PER_CHUNK 512 +//#define YAFFS_CHUNK_SIZE_SHIFT 9 + + +#define YAFFS_CHUNKS_PER_BLOCK 32 +#define YAFFS_BYTES_PER_BLOCK (YAFFS_CHUNKS_PER_BLOCK*YAFFS_BYTES_PER_CHUNK) + +#define YAFFS_MAX_CHUNK_ID 0x000FFFFF + +#define YAFFS_UNUSED_OBJECT_ID 0x0003FFFF + +#define YAFFS_ALLOCATION_NOBJECTS 100 +#define YAFFS_ALLOCATION_NTNODES 100 +#define YAFFS_ALLOCATION_NLINKS 100 + +#define YAFFS_NOBJECT_BUCKETS 256 + + +#define YAFFS_OBJECT_SPACE 0x40000 +#define YAFFS_MAX_NAME_LENGTH 255 +#define YAFFS_SHORT_NAME_LENGTH 15 + +#define YAFFS_MAX_ALIAS_LENGTH 159 + +#define YAFFS_OBJECTID_ROOT 1 +#define YAFFS_OBJECTID_LOSTNFOUND 2 +#define YAFFS_OBJECTID_UNLINKED 3 + +#define YAFFS_MAX_SHORT_OP_CACHES 20 + + +// ChunkCache is used for short read/write operations. +typedef struct +{ + struct yaffs_ObjectStruct *object; + int chunkId; + int lastUse; + int dirty; + int nBytes; // Only valid if the cache is dirty + __u8 data[YAFFS_BYTES_PER_CHUNK]; +} yaffs_ChunkCache; + +// Tags structures in RAM +// NB This uses bitfield. Bitfields should not straddle a u32 boundary otherwise +// the structure size will get blown out. + +typedef struct +{ + unsigned chunkId:20; + unsigned serialNumber:2; + unsigned byteCount:10; + unsigned objectId:18; + unsigned ecc:12; + unsigned unusedStuff:2; +} yaffs_Tags; + +typedef union +{ + yaffs_Tags asTags; + __u8 asBytes[8]; +} yaffs_TagsUnion; + + +// Spare structure +typedef struct +{ + __u8 tagByte0; + __u8 tagByte1; + __u8 tagByte2; + __u8 tagByte3; + __u8 pageStatus; // set to 0 to delete the chunk + __u8 blockStatus; + __u8 tagByte4; + __u8 tagByte5; + __u8 ecc1[3]; + __u8 tagByte6; + __u8 tagByte7; + __u8 ecc2[3]; +} yaffs_Spare; + +//Special structure for passing through to mtd +struct yaffs_NANDSpare { + yaffs_Spare spare; + int eccres1; + int eccres2; +}; + +// Block data in RAM + +typedef enum { + YAFFS_BLOCK_STATE_UNKNOWN = 0, + YAFFS_BLOCK_STATE_SCANNING, // Used while the block is being scanned. + // NB Don't erase blocks while they're being scanned + + YAFFS_BLOCK_STATE_EMPTY, // This block is empty + + YAFFS_BLOCK_STATE_ALLOCATING, // This block is partially allocated. + // This is the one currently being used for page + // allocation. Should never be more than one of these + + + YAFFS_BLOCK_STATE_FULL, // All the pages in this block have been allocated. + // At least one page holds valid data. + + YAFFS_BLOCK_STATE_DIRTY, // All pages have been allocated and deleted. + // Erase me, reuse me. + + YAFFS_BLOCK_STATE_DEAD // This block has failed and is not in use + +} yaffs_BlockState; + + + + +typedef struct +{ +#ifndef CONFIG_YAFFS_NO_YAFFS2 + __u32 sequenceNumber; // block sequence number for yaffs2 +#endif + int softDeletions:8; // number of soft deleted pages + int pagesInUse:8; // number of pages in use + __u32 blockState:4; // One of the above block states + __u32 needsRetiring:1; // Data has failed on this block, need to get valid data off + // and retire the block. +} yaffs_BlockInfo; + + +//////////////////// Object structure /////////////////////////// +// This is the object structure as stored on NAND + +typedef enum +{ + YAFFS_OBJECT_TYPE_UNKNOWN, + YAFFS_OBJECT_TYPE_FILE, + YAFFS_OBJECT_TYPE_SYMLINK, + YAFFS_OBJECT_TYPE_DIRECTORY, + YAFFS_OBJECT_TYPE_HARDLINK, + YAFFS_OBJECT_TYPE_SPECIAL +} yaffs_ObjectType; + +typedef struct +{ + yaffs_ObjectType type; + + // Apply to everything + int parentObjectId; + __u16 sum__NoLongerUsed; // checksum of name. Calc this off the name to prevent inconsistencies + char name[YAFFS_MAX_NAME_LENGTH + 1]; + + // Thes following apply to directories, files, symlinks - not hard links + __u32 st_mode; // protection + +#ifdef CONFIG_YAFFS_WINCE + __u32 notForWinCE[5]; +#else + __u32 st_uid; // user ID of owner + __u32 st_gid; // group ID of owner + __u32 st_atime; // time of last access + __u32 st_mtime; // time of last modification + __u32 st_ctime; // time of last change +#endif + + // File size applies to files only + int fileSize; + + // Equivalent object id applies to hard links only. + int equivalentObjectId; + + // Alias is for symlinks only. + char alias[YAFFS_MAX_ALIAS_LENGTH + 1]; + + __u32 st_rdev; // device stuff for block and char devices (maj/min) + +#ifdef CONFIG_YAFFS_WINCE + __u32 win_ctime[2]; + __u32 win_atime[2]; + __u32 win_mtime[2]; + __u32 roomToGrow[6]; +#else + __u32 roomToGrow[12]; +#endif + +} yaffs_ObjectHeader; + + + +//////////////////// Tnode /////////////////////////// + +union yaffs_Tnode_union +{ +#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG + union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL+1]; +#else + union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL]; +#endif + __u16 level0[YAFFS_NTNODES_LEVEL0]; + +}; + +typedef union yaffs_Tnode_union yaffs_Tnode; + +struct yaffs_TnodeList_struct +{ + struct yaffs_TnodeList_struct *next; + yaffs_Tnode *tnodes; +}; + +typedef struct yaffs_TnodeList_struct yaffs_TnodeList; + + + +/////////////////// Object //////////////////////////////// +// An object can be one of: +// - a directory (no data, has children links +// - a regular file (data.... not prunes :->). +// - a symlink [symbolic link] (the alias). +// - a hard link + + +typedef struct +{ + __u32 fileSize; + __u32 scannedFileSize; + int topLevel; + yaffs_Tnode *top; +} yaffs_FileStructure; + +typedef struct +{ + struct list_head children; // list of child links +} yaffs_DirectoryStructure; + +typedef struct +{ + char *alias; +} yaffs_SymLinkStructure; + +typedef struct +{ + struct yaffs_ObjectStruct *equivalentObject; + __u32 equivalentObjectId; +} yaffs_HardLinkStructure; + +typedef union +{ + yaffs_FileStructure fileVariant; + yaffs_DirectoryStructure directoryVariant; + yaffs_SymLinkStructure symLinkVariant; + yaffs_HardLinkStructure hardLinkVariant; +} yaffs_ObjectVariant; + + +struct yaffs_ObjectStruct +{ + __u8 deleted: 1; // This should only apply to unlinked files. + __u8 softDeleted: 1; // it has also been soft deleted + __u8 unlinked: 1; // An unlinked file. The file should be in the unlinked pseudo directory. + __u8 fake:1; // A fake object has no presence on NAND. + __u8 renameAllowed:1; + __u8 unlinkAllowed:1; + __u8 dirty:1; // the object needs to be written to flash + __u8 valid:1; // When the file system is being loaded up, this + // object might be created before the data + // is available (ie. file data records appear before the header). + __u8 serial; // serial number of chunk in NAND. Store here so we don't have to + // read back the old one to update. + __u16 sum; // sum of the name to speed searching + + struct yaffs_DeviceStruct *myDev; // The device I'm on + + + struct list_head hashLink; // list of objects in this hash bucket + + + struct list_head hardLinks; // all the equivalent hard linked objects + // live on this list + // directory structure stuff + struct yaffs_ObjectStruct *parent; //my parent directory + struct list_head siblings; // siblings in a directory + // also used for linking up the free list + + // Where's my data in NAND? + int chunkId; // where it lives + + int nDataChunks; + + __u32 objectId; // the object id value + + + __u32 st_mode; // protection + +#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM + char shortName[YAFFS_SHORT_NAME_LENGTH+1]; +#endif + +#ifndef __KERNEL__ + __u32 inUse; +#endif + +#ifdef CONFIG_YAFFS_WINCE + __u32 win_ctime[2]; + __u32 win_mtime[2]; + __u32 win_atime[2]; +#else + __u32 st_uid; // user ID of owner + __u32 st_gid; // group ID of owner + __u32 st_atime; // time of last access + __u32 st_mtime; // time of last modification + __u32 st_ctime; // time of last change +#endif + + __u32 st_rdev; // device stuff for block and char devices + + + +#ifdef __KERNEL__ + struct inode *myInode; + __u8 deferedFree; // YAFFS has removed the object from NAND, but it is being kept + // Alive until the inode is cleared to prevent inode inconsistencies. +#endif + + + + yaffs_ObjectType variantType; + + yaffs_ObjectVariant variant; + +}; + + + +typedef struct yaffs_ObjectStruct yaffs_Object; + + +struct yaffs_ObjectList_struct +{ + yaffs_Object *objects; + struct yaffs_ObjectList_struct *next; +}; + +typedef struct yaffs_ObjectList_struct yaffs_ObjectList; + +typedef struct +{ + struct list_head list; + int count; +} yaffs_ObjectBucket; + + +//////////////////// Device //////////////////////////////// + +struct yaffs_DeviceStruct +{ + // Entry parameters set up way early. Yaffs sets up the rest. + int nBytesPerChunk; // Should be a power of 2 >= 512 + int nChunksPerBlock; // does not need to be a power of 2 + int startBlock; // Start block we're allowed to use + int endBlock; // End block we're allowed to use + int nReservedBlocks; // We want this tuneable so that we can reduce + // reserved blocks on NOR and RAM. + + int useNANDECC; // Flag to decide whether or not to use NANDECC + int nShortOpCaches; // If <= 0, then short op caching is disabled, else + // the number of short op caches (don't use too many). + + + void *genericDevice; // Pointer to device context + // On an mtd this holds the mtd pointer. + + // NAND access functions (Must be set before calling YAFFS) + + int (*writeChunkToNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, const __u8 *data, yaffs_Spare *spare); + int (*readChunkFromNAND)(struct yaffs_DeviceStruct *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare); + int (*eraseBlockInNAND)(struct yaffs_DeviceStruct *dev,int blockInNAND); + int (*initialiseNAND)(struct yaffs_DeviceStruct *dev); + + // Runtime parameters. Set up by YAFFS. + + __u16 chunkGroupBits; // 0 for devices <= 32MB. else log2(nchunks) - 16 + __u16 chunkGroupSize; // == 2^^chunkGroupBits + +#ifdef __KERNEL__ + + struct semaphore sem;// Semaphore for waiting on erasure. + struct semaphore grossLock; // Gross locking semaphore + +#endif +#ifdef __KERNEL__ + void (*putSuperFunc)(struct super_block *sb); +#endif + + int isMounted; + + // Block Info + yaffs_BlockInfo *blockInfo; + __u8 *chunkBits; // bitmap of chunks in use + int chunkBitmapStride; // Number of bytes of chunkBits per block. + // Must be consistent with nChunksPerBlock. + + + int nErasedBlocks; + int allocationBlock; // Current block being allocated off + __u32 allocationPage; + int allocationBlockFinder; // Used to search for next allocation block + + // Runtime state + int nTnodesCreated; + yaffs_Tnode *freeTnodes; + int nFreeTnodes; + yaffs_TnodeList *allocatedTnodeList; + + + int nObjectsCreated; + yaffs_Object *freeObjects; + int nFreeObjects; + + yaffs_ObjectList *allocatedObjectList; + + yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS]; + + int nFreeChunks; + + int currentDirtyChecker; // Used to find current dirtiest block + + + // Operations since mount + int nPageWrites; + int nPageReads; + int nBlockErasures; + int nGCCopies; + int garbageCollections; + int passiveGarbageCollections; + int nRetriedWrites; + int nRetiredBlocks; + int eccFixed; + int eccUnfixed; + int tagsEccFixed; + int tagsEccUnfixed; + int nDeletions; + int nUnmarkedDeletions; + + yaffs_Object *rootDir; + yaffs_Object *lostNFoundDir; + + // Buffer areas for storing data to recover from write failures +// __u8 bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK]; +// yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK]; + int bufferedBlock; // Which block is buffered here? + int doingBufferedBlockRewrite; + + yaffs_ChunkCache *srCache; + int srLastUse; + + int cacheHits; + + // Stuff for background deletion and unlinked files. + yaffs_Object *unlinkedDir; // Directory where unlinked and deleted files live. + yaffs_Object *unlinkedDeletion; // Current file being background deleted. + int nDeletedFiles; // Count of files awaiting deletion; + int nUnlinkedFiles; // Count of unlinked files. + int nBackgroundDeletions; // Count of background deletions. + + __u8 *localBuffer; + +}; + +typedef struct yaffs_DeviceStruct yaffs_Device; + + + +//////////// YAFFS Functions ////////////////// + +int yaffs_GutsInitialise(yaffs_Device *dev); +void yaffs_Deinitialise(yaffs_Device *dev); + +int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev); + + +// Rename +int yaffs_RenameObject(yaffs_Object *oldDir, const char *oldName, yaffs_Object *newDir, const char *newName); + +// generic Object functions +int yaffs_Unlink(yaffs_Object *dir, const char *name); +int yaffs_DeleteFile(yaffs_Object *obj); + +// Object access functions. +int yaffs_GetObjectName(yaffs_Object *obj,char *name,int buffSize); +int yaffs_GetObjectFileLength(yaffs_Object *obj); +int yaffs_GetObjectInode(yaffs_Object *obj); +unsigned yaffs_GetObjectType(yaffs_Object *obj); +int yaffs_GetObjectLinkCount(yaffs_Object *obj); + +// Change inode attributes +int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr); +int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr); + +// File operations +int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, __u32 offset, int nBytes); +int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, __u32 offset, int nBytes); +int yaffs_ResizeFile(yaffs_Object *obj, int newSize); + +yaffs_Object *yaffs_MknodFile(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid); +int yaffs_FlushFile(yaffs_Object *obj,int updateTime); + + +// Directory operations +yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid); +yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir,const char *name); +int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,int (*fn)(yaffs_Object *)); + +yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev,__u32 number); + +// Link operations +yaffs_Object *yaffs_Link(yaffs_Object *parent, const char *name, yaffs_Object *equivalentObject); + +yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj); + +// Symlink operations +yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const char *name, __u32 mode, __u32 uid, __u32 gid, const char *alias); +char *yaffs_GetSymlinkAlias(yaffs_Object *obj); + +// Special inodes (fifos, sockets and devices) +yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent,const char *name, __u32 mode, __u32 uid, __u32 gid,__u32 rdev); + + +// Special directories +yaffs_Object *yaffs_Root(yaffs_Device *dev); +yaffs_Object *yaffs_LostNFound(yaffs_Device *dev); + +#ifdef CONFIG_YAFFS_WINCE +// CONFIG_YAFFS_WINCE special stuff +void yfsd_WinFileTimeNow(__u32 target[2]); +#endif + +#ifdef __KERNEL__ +void yaffs_HandleDeferedFree(yaffs_Object *obj); +#endif + +// Debug dump +int yaffs_DumpObject(yaffs_Object *obj); + + +void yaffs_GutsTest(yaffs_Device *dev); + + +#endif + + Index: linux-2.6.9/fs/yaffs/devextras.h =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/devextras.h @@ -0,0 +1,271 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * devextras.h + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL. + * + * This file is just holds extra declarations used during development. + * Most of these are from kernel includes placed here so we can use them in + * applications. + * + * $Id: devextras.h,v 1.5 2002/09/27 20:50:50 charles Exp $ + * + */ + +#ifndef __EXTRAS_H__ +#define __EXTRAS_H__ + +#if defined WIN32 +#define __inline__ __inline +#define new newHack +#endif + +#if !(defined __KERNEL__) || (defined WIN32) + +// User space defines + +typedef unsigned char __u8; +typedef unsigned short __u16; +typedef unsigned __u32; + + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + + #define prefetch(x) 1 + + +struct list_head { + struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ + struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ + (ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_add(struct list_head * new, + struct list_head * prev, + struct list_head * next) +{ + next->prev = new; + new->next = next; + new->prev = prev; + prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static __inline__ void list_add(struct list_head *new, struct list_head *head) +{ + __list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) +{ + __list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_del(struct list_head * prev, + struct list_head * next) +{ + next->prev = prev; + prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static __inline__ void list_del(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline__ void list_del_init(struct list_head *entry) +{ + __list_del(entry->prev, entry->next); + INIT_LIST_HEAD(entry); +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static __inline__ int list_empty(struct list_head *head) +{ + return head->next == head; +} + +/** + * list_splice - join two lists + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static __inline__ void list_splice(struct list_head *list, struct list_head *head) +{ + struct list_head *first = list->next; + + if (first != list) { + struct list_head *last = list->prev; + struct list_head *at = head->next; + + first->prev = head; + head->next = first; + + last->next = at; + at->prev = last; + } +} + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ + ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** + * list_for_each - iterate over a list + * @pos: the &struct list_head to use as a loop counter. + * @head: the head for your list. + */ +#define list_for_each(pos, head) \ + for (pos = (head)->next, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(pos->next)) + +/** + * list_for_each_safe - iterate over a list safe against removal of list entry + * @pos: the &struct list_head to use as a loop counter. + * @n: another &struct list_head to use as temporary storage + * @head: the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ + for (pos = (head)->next, n = pos->next; pos != (head); \ + pos = n, n = pos->next) + + + + +/* + * File types + */ +#define DT_UNKNOWN 0 +#define DT_FIFO 1 +#define DT_CHR 2 +#define DT_DIR 4 +#define DT_BLK 6 +#define DT_REG 8 +#define DT_LNK 10 +#define DT_SOCK 12 +#define DT_WHT 14 + +#ifndef WIN32 +#include +#endif + +/* + * Attribute flags. These should be or-ed together to figure out what + * has been changed! + */ +#define ATTR_MODE 1 +#define ATTR_UID 2 +#define ATTR_GID 4 +#define ATTR_SIZE 8 +#define ATTR_ATIME 16 +#define ATTR_MTIME 32 +#define ATTR_CTIME 64 +#define ATTR_ATIME_SET 128 +#define ATTR_MTIME_SET 256 +#define ATTR_FORCE 512 /* Not a change, but a change it */ +#define ATTR_ATTR_FLAG 1024 + + +struct iattr { + unsigned int ia_valid; + unsigned ia_mode; + unsigned ia_uid; + unsigned ia_gid; + unsigned ia_size; + unsigned ia_atime; + unsigned ia_mtime; + unsigned ia_ctime; + unsigned int ia_attr_flags; +}; + +#define KERN_DEBUG + + +#else + +#ifndef WIN32 +#include +#include +#include +#include +#endif + +#endif + + + +#if defined WIN32 +#undef new +#endif + +#endif + Index: linux-2.6.9/fs/yaffs/yaffs_mtdif.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs_mtdif.c @@ -0,0 +1,167 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * yaffs_mtdif.c NAND mtd wrapper functions. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +const char *yaffs_mtdif_c_version = "$Id: yaffs_mtdif.c,v 1.10 2004/09/19 08:14:50 charles Exp $"; + +#ifdef CONFIG_YAFFS_MTD_ENABLED + +#include "yportenv.h" + +#include "yaffs_mtdif.h" + +#include "linux/mtd/mtd.h" +#include "linux/types.h" +#include "linux/time.h" + +#ifndef CONFIG_YAFFS_USE_OLD_MTD +#include "linux/mtd/nand.h" +#endif + +struct nand_oobinfo yaffs_oobinfo = { + useecc: 1, +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)) +// this is for versions of mtd nand driver in kernel 2.6.8 and later + eccbytes: 6, +#endif + eccpos: {8, 9, 10, 13, 14, 15} +}; + +struct nand_oobinfo yaffs_noeccinfo = { + useecc: 0, +}; + + +int nandmtd_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_Spare *spare) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + size_t dummy; + int retval = 0; + + loff_t addr = ((loff_t)chunkInNAND) * dev->nBytesPerChunk; + + __u8 *spareAsBytes = (__u8 *)spare; + +#ifndef CONFIG_YAFFS_USE_OLD_MTD + if(data && spare) + { + if(dev->useNANDECC) + mtd->write_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_oobinfo); + else + mtd->write_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_noeccinfo); + } + else + { +#endif + if(data) + retval = mtd->write(mtd,addr,dev->nBytesPerChunk,&dummy,data); + if(spare) + retval = mtd->write_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes); +#ifndef CONFIG_YAFFS_USE_OLD_MTD + } +#endif + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + size_t dummy; + int retval = 0; + + loff_t addr = ((loff_t)chunkInNAND) * dev->nBytesPerChunk; + + __u8 *spareAsBytes = (__u8 *)spare; + +#ifndef CONFIG_YAFFS_USE_OLD_MTD + if(data && spare) + { + if(dev->useNANDECC) + { // Careful, this call adds 2 ints to the end of the spare data. Calling function should + // allocate enough memory for spare, i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. + retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_oobinfo); + } + else + { + retval = mtd->read_ecc(mtd,addr,dev->nBytesPerChunk,&dummy,data,spareAsBytes,&yaffs_noeccinfo); + } + } + else + { +#endif + if(data) + retval = mtd->read(mtd,addr,dev->nBytesPerChunk,&dummy,data); + if(spare) + retval = mtd->read_oob(mtd,addr,YAFFS_BYTES_PER_SPARE,&dummy,spareAsBytes); +#ifndef CONFIG_YAFFS_USE_OLD_MTD + } +#endif + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +// Callback not needed for NAND +#if 0 +static void nandmtd_EraseCallback(struct erase_info *ei) +{ + yaffs_Device *dev = (yaffs_Device *)ei->priv; + up(&dev->sem); +} +#endif + + +int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) +{ + struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); + __u32 addr = ((loff_t) blockNumber) * dev->nBytesPerChunk * dev->nChunksPerBlock; + struct erase_info ei; + int retval = 0; + + ei.mtd = mtd; + ei.addr = addr; + ei.len = dev->nBytesPerChunk * dev->nChunksPerBlock; + ei.time = 1000; + ei.retries = 2; + ei.callback = NULL; + ei.priv = (u_long)dev; + + // Todo finish off the ei if required + + sema_init(&dev->sem,0); + + retval = mtd->erase(mtd,&ei); + + //No need for callback + // down(&dev->sem); // Wait for the erasure to complete + + if (retval == 0) + return YAFFS_OK; + else + return YAFFS_FAIL; +} + +int nandmtd_InitialiseNAND(yaffs_Device *dev) +{ + return YAFFS_OK; +} + +#endif // CONFIG_YAFFS_MTD_ENABLED + Index: linux-2.6.9/fs/yaffs/yaffs-header.c =================================================================== --- /dev/null +++ linux-2.6.9/fs/yaffs/yaffs-header.c @@ -0,0 +1,13 @@ +/* + * YAFFS: Yet another FFS. A NAND-flash specific file system. + * + * Copyright (C) 2002 Aleph One Ltd. + * for Toby Churchill Ltd and Brightstar Engineering + * + * Created by Charles Manning + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ --------------050203010501080701060109-- From rajivd@sj.symbol.com Tue Dec 21 17:44:28 2004 From: rajivd@sj.symbol.com (Rajiv Dhingra) Date: Tue, 21 Dec 2004 09:44:28 -0800 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 Message-ID: Charles and Thomas: Thank you very much for your responses. It will be a while before we make = a decision (enjoying the holidays), but for the very reasons that you = mentioned Charles, it might well be that I end up back-porting mtd to = 2.4.20. Any pointers in accomplishing this (in addition to the ones = that you have already mentioned) would be truly appreciated. Would most = of the modifications be in the nand drivers or the mtd drivers? Merry Christmas, Rajiv >>> "Charles Manning" 12/19/04 11:59AM >>> Rajiv I've thought about this a bit... While Thomas it technically correct that YAFFS2 needs more recent mtd (which no longer supports older kernels), I think it rather simple to hack the mtd you have to support YAFFS2. Basically, all you'd need to do is: 1) Modify the nand write/read functions to work with 2k pages (change the size of the for loop), and a few other minor changes to handle ECC etc. 2) Add a couple more required fields to the mtd_info structure. 3) Add two new functions block_markbad() and block_isbad() for bad block handling. Whether it is the right time for you to switch to a newer kernel or not is your choice and should not be forced by mtd changes. -- Charles =20 > -----Original Message----- > From: yaffs-admin@stoneboat.aleph1.co.uk=20 > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of=20 > Thomas Gleixner > Sent: Thursday, 16 December 2004 9:41 p.m. > To: Rajiv Dhingra > Cc: YAFFS > Subject: Re: [Yaffs] Yaffs with 2k Pages OR Yaffs2 >=20 >=20 > On Wed, 2004-12-15 at 15:50 -0800, Rajiv Dhingra wrote: > > We were running Linux 2.4.20, Yaffs, and using a NAND > > device with 512 byte pages. Everything was working fine. > > Then the hardware guys replaced the 512 byte page NAND > > device with a 2k page NAND device. > > So, I now have to hack yaffs to support a 2k page size, > > or start using Yaffs2. What would the recommendation > > of this newsgroup be? Would it be easy enough for me > > to hack yaffs to start supporting the bigger page size? > > Is yaffs2 stable enough and does it run with the 2.4.20 > > kernel, making it a better option. >=20 > Be prepared to upgrade your kernel. The MTD NAND layer which=20 > has the support for 2k chips is definitely not portable to 2.4.20. >=20 > Read http://www.linux-mtd.infradead.org/#kernelversions=20 >=20 > tglx >=20 >=20 >=20 > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk=20 > http://stoneboat.aleph1.co.uk/cgi-> bin/mailman/listinfo/yaffs >=20 ________________________________________________________________________ This email has been scanned for computer viruses. From manningc2@actrix.gen.nz Tue Dec 21 18:23:23 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Wed, 22 Dec 2004 07:23:23 +1300 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 In-Reply-To: References: Message-ID: <20041221181743.E352215139@desire.actrix.co.nz> When it comes to back porting, you're pretty much on your own. The mtd fo= lk=20 get very tied up with what they do so handling backports adds complicatio= ns. If you're only wanting to run YAFFS2 on your NAND, then you will probably= =20 find the backport relatively simple since you don't have to do much. ie. = it=20 is not really so much a backport as adding a few mods to what you have no= w. I'd suggest having a look at the mtd emulation I put in the YAFFS2 source= =20 tree. THis shows all the functions you need. -- Charles On Wednesday 22 December 2004 06:44, Rajiv Dhingra wrote: > Charles and Thomas: > > Thank you very much for your responses. It will be a while before we m= ake > a decision (enjoying the holidays), but for the very reasons that you > mentioned Charles, it might well be that I end up back-porting mtd to > 2.4.20. Any pointers in accomplishing this (in addition to the ones = that > you have already mentioned) would be truly appreciated. Would most of = the > modifications be in the nand drivers or the mtd drivers? > > Merry Christmas, > > Rajiv > > >>> "Charles Manning" 12/19/04 11:59AM = >>> > > Rajiv > > I've thought about this a bit... > While Thomas it technically correct that YAFFS2 needs more recent mtd > (which no longer supports older kernels), I think it rather simple to > hack the mtd you have to support YAFFS2. > > Basically, all you'd need to do is: > 1) Modify the nand write/read functions to work with 2k pages (change > the size of the for loop), and a few other minor changes to handle ECC > etc. > 2) Add a couple more required fields to the mtd_info structure. > 3) Add two new functions block_markbad() and block_isbad() for bad bloc= k > handling. > > Whether it is the right time for you to switch to a newer kernel or not > is your choice and should not be forced by mtd changes. > > -- Charles > > > -----Original Message----- > > From: yaffs-admin@stoneboat.aleph1.co.uk > > [mailto:yaffs-admin@stoneboat.aleph1.co.uk] On Behalf Of > > Thomas Gleixner > > Sent: Thursday, 16 December 2004 9:41 p.m. > > To: Rajiv Dhingra > > Cc: YAFFS > > Subject: Re: [Yaffs] Yaffs with 2k Pages OR Yaffs2 > > > > On Wed, 2004-12-15 at 15:50 -0800, Rajiv Dhingra wrote: > > > We were running Linux 2.4.20, Yaffs, and using a NAND > > > device with 512 byte pages. Everything was working fine. > > > Then the hardware guys replaced the 512 byte page NAND > > > device with a 2k page NAND device. > > > So, I now have to hack yaffs to support a 2k page size, > > > or start using Yaffs2. What would the recommendation > > > of this newsgroup be? Would it be easy enough for me > > > to hack yaffs to start supporting the bigger page size? > > > Is yaffs2 stable enough and does it run with the 2.4.20 > > > kernel, making it a better option. > > > > Be prepared to upgrade your kernel. The MTD NAND layer which > > has the support for 2k chips is definitely not portable to 2.4.20. > > > > Read http://www.linux-mtd.infradead.org/#kernelversions > > > > tglx > > > > > > > > _______________________________________________ > > yaffs mailing list > > yaffs@stoneboat.aleph1.co.uk > > http://stoneboat.aleph1.co.uk/cgi-> bin/mailman/listinfo/yaffs > > _______________________________________________________________________= _ > This email has been scanned for computer viruses. > > > _______________________________________________ > yaffs mailing list > yaffs@stoneboat.aleph1.co.uk > http://stoneboat.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs From tglx@linutronix.de Tue Dec 21 21:36:32 2004 From: tglx@linutronix.de (Thomas Gleixner) Date: Tue, 21 Dec 2004 22:36:32 +0100 Subject: [Yaffs] Yaffs with 2k Pages OR Yaffs2 In-Reply-To: References: Message-ID: <1103664992.27708.252.camel@tglx.tec.linutronix.de> On Tue, 2004-12-21 at 09:44 -0800, Rajiv Dhingra wrote: > Charles and Thomas: > > Thank you very much for your responses. > It will be a while before we make a decision (enjoying the holidays), > but for the very reasons that you mentioned Charles, it might well be > that I end up back-porting mtd to 2.4.20. Any pointers in accomplishing > this (in addition to the ones that you have already mentioned) would > be truly appreciated. Would most of the modifications be in the nand > drivers or the mtd drivers? Both mtd and nand. The mtd mailing list archive has a couple of pointers and there are people around who backported to 2.4.20/21 IIRC. I think it's not hard as you do not need the JFFS2 stuff, which has more incompabilities than mtd/nand itself. Merry Christmas also to you tglx From frowand@mvista.com Wed Dec 22 21:31:53 2004 From: frowand@mvista.com (Frank Rowand) Date: Wed, 22 Dec 2004 13:31:53 -0800 Subject: [Yaffs] yaffs on Linux 2.6.9 - patch 8 of 7 Message-ID: <41C9E7C9.4070305@mvista.com> This is a multi-part message in MIME format. --------------000805090202090604060103 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Yep, it really is number 8 of 7. (The need for the eighth patch was found after sending the first seven...) -Frank -- Frank Rowand MontaVista Software, Inc --------------000805090202090604060103 Content-Type: text/plain; name="yaffs_kernel_08_loop_mount.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="yaffs_kernel_08_loop_mount.patch" Index: linux-2.6.9/fs/yaffs/yaffs_fs.c =================================================================== --- linux-2.6.9.orig/fs/yaffs/yaffs_fs.c +++ linux-2.6.9/fs/yaffs/yaffs_fs.c @@ -214,6 +214,9 @@ mmap: generic_file_mmap, flush: yaffs_file_flush, fsync: yaffs_sync_object, +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) + sendfile: generic_file_sendfile, +#endif }; --------------000805090202090604060103-- From frowand@mvista.com Wed Dec 22 21:31:48 2004 From: frowand@mvista.com (Frank Rowand) Date: Wed, 22 Dec 2004 13:31:48 -0800 Subject: [Yaffs] Re: set of patches for yaffs on Linux 2.6.9 In-Reply-To: <41C236CE.6000609@mvista.com> References: <41C236CE.6000609@mvista.com> Message-ID: <41C9E7C4.1020405@mvista.com> Frank Rowand wrote: > I am submitting a set of patches that enabled me to get yaffs > working on Linux 2.6.9. (Not vanilla 2.6.9, but 2.6.9 plus > a few changes, but I don't think the changes matter in this > context.) > > Please add any of these changes back into yaffs as appropriate, > and provide comments as needed. > > I have compiled for x86 RAM based yaffs (but not tested) and > for ARM little endian MTD based yaffs. I have compiled as > in-kernel and as modules (but have not loaded the module > version). The ARM version has been through basic crash > and burn testing, but I have not yet begun serious testing. > > The changes are broken into a series of patches to isolate > the different types of changes, and will each be sent in > a following email. The patches apply in the following > order: > > patches/yaffs_kernel_01_base.patch > yaffs_kernel_02_fixup_in_kernel_tree.patch > yaffs_kernel_03_fix_warnings.patch > yaffs_kernel_04_disable_no_page_cache.patch > yaffs_kernel_05_64bit_target.patch > yaffs_kernel_06_kdevname.patch > yaffs_kernel_07_kill_sb.patch < patch details deleted > One more patch: yaffs_kernel_08_loop_mount.patch A new function (sendfile) has been added in 2.6 to the struct file_operations that is required for mounting via the loop device. This patch adds sendfile to yaffs. An example of loopback mounting is: > mount -t yaffs /dev/mtdblock/8 my_yaffs_fs yaffs: dev is 31.8 name is "mtdblock8" > mount -t cramfs -o loop my_yaffs_fs/my_cramfs_fs_image my_cramfs_fs > umount -d my_cramfs_fs > umount my_yaffs_fs The patch will be sent in a separate email. -Frank -- Frank Rowand MontaVista Software, Inc From mikee@logicpd.com Wed Dec 22 21:38:00 2004 From: mikee@logicpd.com (Michael Erickson) Date: Wed, 22 Dec 2004 15:38:00 -0600 Subject: [Yaffs] Release tags and branches within YAFFS CVS repository. Message-ID: <41C9E938.2070005@logicpd.com> Hello all, I was looking at the CVS repository and saw no tags or branches denoting actual software releases. Am I missing something? I am having to make changes to the source code and would like to always be able to get back to my starting point. I guess I can just use today's date as a marker if I need to. However, typically I would expect to see some sort of branching and tagging scheme that designates release points such that developers can checkout specific revisions of the overall source package. Am I missing something obvious, or does the code simply have no tags other than "HEAD" and no branches other than "MAIN?" Thanks, --mikee -- Michael Erickson Senior Software Engineer Logic Product Development (612) 436-5118 mailto:mikee@logicpd.com http://www.logicpd.com From manningc2@actrix.gen.nz Thu Dec 23 00:57:55 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Thu, 23 Dec 2004 13:57:55 +1300 Subject: [Yaffs] Release tags and branches within YAFFS CVS repository. In-Reply-To: <41C9E938.2070005@logicpd.com> References: <41C9E938.2070005@logicpd.com> Message-ID: <20041223005216.A309B487F@blood.actrix.co.nz> Your eyes do not deceive you - there are no tags and branches. So far pretty much every byte in the yaffs tree has been type by myself, = so=20 there has not been much need for branching etc. YAFFS2 is in a sperate tr= ee. Most people have been using yaffs as a black box, and we've had very few=20 reliability issue, so what has happened so far has seemed to work. With YAFFS2 I will be doing some tagging prior to adding some changes. I will tag YAFFS1 prior to adding some patches from Frank and changes so= me=20 other changes. -- Charles On Thursday 23 December 2004 10:38, Michael Erickson wrote: > Hello all, > > I was looking at the CVS repository and saw no tags or branches denotin= g > actual software releases. Am I missing something? I am having to make > changes to the source code and would like to always be able to get back > to my starting point. I guess I can just use today's date as a marker i= f > I need to. However, typically I would expect to see some sort of > branching and tagging scheme that designates release points such that > developers can checkout specific revisions of the overall source packag= e. > > Am I missing something obvious, or does the code simply have no tags > other than "HEAD" and no branches other than "MAIN?" > > Thanks, > --mikee From manningc2@actrix.gen.nz Thu Dec 23 01:57:25 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Thu, 23 Dec 2004 14:57:25 +1300 Subject: [Yaffs] Frank's mega-patchset In-Reply-To: <41C9E7C9.4070305@mvista.com> References: <41C9E7C9.4070305@mvista.com> Message-ID: <20041223015144.BA8C416723@desire.actrix.co.nz> First off I'd really like to thank Frank for his efforts here. Thanks Frank for structuring the patches in neat logical sets. Herewith a brief analysis of the patches and what I intend to do about th= em: Patchset 1 really copies almost the whole of yaffs, including some obsole= te=20 and test code, into the kernel tree. This is not the best way to do this,= =20 IMHO. What I'd rather do is write a patch_in script which either copies = the=20 useful files into the kernel from a freestanding YAFFS CVS snapshot or=20 creates symlinks. Anyone who's used the mtd patchin will know what I'm=20 talking about. Patchset 2 is a useful kernel makefile and KConfig. These will go into a = new=20 directory in yaffs called yaffs/linux-kernel. These will get copied/symli= nked=20 by the patchin. Patchsets 3..8 Various tidy ups and tweaks, some fixes more recent kernel= =20 changes too. These I will apply, though some of them will have to be don= e=20 manually to prevent breaking other OSs. I'm doing a tag befora applying these changes. -- Charles From wookey@aleph1.co.uk Thu Dec 23 11:12:44 2004 From: wookey@aleph1.co.uk (Wookey) Date: Thu, 23 Dec 2004 11:12:44 +0000 Subject: [Yaffs] Re: Release tags and branches within YAFFS CVS repository. In-Reply-To: <41C9E938.2070005@logicpd.com> References: <41C9E938.2070005@logicpd.com> Message-ID: <20041223111244.GS17393@xios> +++ Michael Erickson [04-12-22 15:38 -0600]: > Hello all, > > I was looking at the CVS repository and saw no tags or branches denoting > actual software releases. Am I missing something? No, so far we've been operating on a simple 'YAFFS' version scheme. i.e. what you get is today's CVS. We could have made a couple of releases of particular versions but it was never clear that that there was ever a time when 'HEAD' wasn't the best answer. I believe the MTD people run their CVS much the same way, although perhaps with daily tags these days. I would like to move to having some releases occaisionally, just so we can point to them and stick them in tarballs for people, and because it is useful for people on a particular project to know exactly which snapshot they used. I think 'HEAD' will generally remain the best answer for most people most of the time. Wookey -- Aleph One Ltd, Bottisham, CAMBRIDGE, CB5 9BA, UK Tel +44 (0) 1223 811679 work: http://www.aleph1.co.uk/ play: http://www.chaos.org.uk/~wookey/ From manningc2@actrix.gen.nz Thu Dec 23 18:26:44 2004 From: manningc2@actrix.gen.nz (Charles Manning) Date: Fri, 24 Dec 2004 07:26:44 +1300 Subject: [Yaffs] Some patching & a directory restructuring Message-ID: <20041223182102.A6D9F15A7E@desire.actrix.co.nz> Hi YAFFSers I have applied some of Frank's patches. I think I have applied all of the= =20 patches that do functional things (the kill_sb and sendfile patches). The= =20 ones that clean up warnings etc have not been applied yet. Things seem to= get=20 away from you at Christmas time (remember in NZ we're a day ahead of most= =20 people :-), but I will still get around to the rest of this fixing as I c= an. I have also done some directory restructuring. From the new README: Where do you want to go today? ------------------------------ direct This is the userspace/RTOS variant of YAFFS. This is used fo= r=20 yaffs core development and for embedding YAFFS in products that don't use Linux or WinCE linux-module This allows you to build YAFFS as a free-standing Linux kern= el module. By "free standing", I mean that this build happens outside the kernel tree. Generally you'd use this for testing. linux-kernel This allows you to hook YAFFS into the kernel tree, to build YAFFS within the kernel tree. utils These are some utilities for Linux. wince Windows CE support. Horribly dated. Contact Aleph One is you'r= e considering YAFFS for a WinCE project. mtdemul An mtd NAND emulation driver for testing YAFFS under Linux. Documentation Some YAFFS documents. Also visit www.aleph1.co.uk. The idea behind this is that you choose the working directory dependent o= n=20 what you're trying to achieve. Everything is symlinked from that director= y to=20 the common code. Linux folks: for now the linux-module gives you what you had. linux-kerne= l is=20 still work in progress, (I still need to do the patchin script), but the = idea=20 is that yaffs will get symlinked into the kernel tree. symlinks keep=20 everything very modular and allow an extra level of plug and play for=20 patching etc.=20 Non-linux folk: Nothing has really changed with the new directory structu= re.