* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
[not found] <OFFED20C5C.C2FC40DE-ON882570FF.005D6B36-C22570FF.005ED903@mindspeed.com>
@ 2006-01-24 13:02 ` Vitaly Wool
0 siblings, 0 replies; 10+ messages in thread
From: Vitaly Wool @ 2006-01-24 13:02 UTC (permalink / raw)
To: yuri.golovach; +Cc: linux-mtd
Hello Yuri,
can you please specify what patches you did apply and what flash you're
using. Thanks!
Vitaly
yuri.golovach@mindspeed.com wrote:
>Good day Vitaly.
>
>I've tried your patches which modifies nand_base.c, other mtdfiles and
>mtdutils to be compatible with yaffs2.
>
>Unfortunately, I've some issues with them.
>
>1)
> my version of mtd is newer then your and I was unable to patch
>nand_base.c with your patch. So, I add this patch manually (but I'm not
>sure - have I done some mistakes or not).
>
>2) After the kernel compiling with your patches I've started it and
>receive a long list of
> Bad eraseblock1 ... at ...x..................
>
> After "mount" and "df" commands I saw that there is no free space
>on flash because all bloks were marked as "bad block" .
> Than I've tried patched version of flash_eraseall but it was not
>able to see blocks also.
>
>
>3) I've changed nand_bbt.c file (in the patched kernel) where simply
>comment the bad blocks checking. Have booted from it and _successfully_
>used patched flash_eraseall.
>
>4) Than I've start the patched kernel _with bad blocks checking_ but these
>(previously erased blocks) were marked like "bad blocks" again (in a
>kernel booting procedure).
>
>
>So, can you, please, provide your vision what should I do to run your
>patch. Or you can send the link on the mtd line which supports yaffs2,
>because I was unable to find your updates in CVS mainline :(
>
>Thank you,
> Yuri Golovach
>
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <OF1F9E1072.64E03318-ON88257102.0060A9BE-C2257102.0060ED3A@mindspeed.com>]
* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
[not found] <OF1F9E1072.64E03318-ON88257102.0060A9BE-C2257102.0060ED3A@mindspeed.com>
@ 2006-01-28 9:15 ` Vitaly Wool
2006-01-29 15:19 ` Vitaly Wool
0 siblings, 1 reply; 10+ messages in thread
From: Vitaly Wool @ 2006-01-28 9:15 UTC (permalink / raw)
To: yuri.golovach; +Cc: manningc2, linux-mtd
Hi Yuri,
can you please supply the patch for the yaffs_mtdif2.c you've done?
Please keep in mind that you have to consider how many spare bytes to
read from an OOB area.
Best regards,
Vitaly
yuri.golovach@mindspeed.com wrote:
>
> Hi Vitaly!
>
> I've successfully applied your patch without any issues, changed
> read_oob and write_oob on read_oobfree and write_oobfree.
>
> No "Bad block" at the booting procedure, but here is result which I've
> resived:
>
> comcerto:/# mount -t yaffs2 /dev/mtdblock3 /mnt/y
>
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000000
> pgd = c2490000
> [00000000] *pgd=03ac3031, *pte=00000000, *ppte=00000000
> Internal error: Oops: 0 [#1]
> Modules linked in:
> CPU: 0
> PC is at 0x0
> LR is at nand_read_oobfree+0x3a0/0x49c
> pc : [<00000000>] lr : [<c010e168>] Not tainted
> sp : c286fbf8 ip : c286fbd4 fp : c286fc44
> r10: c02ffc00 r9 : 00000002 r8 : 00000000
> r7 : 00000000 r6 : 00000000 r5 : c02ffd88 r4 : 00000010
> r3 : c2e94870 r2 : 00000002 r1 : 00000004 r0 : c02ffc00
> Flags: Nzcv IRQs on FIQs on Mode SVC_32 Segment user
> Control: C000717F Table: 03490000 DAC: 00000015
> Process mount (pid: 952, stack limit = 0xc286e194)
> Stack: (0xc286fbf8 to 0xc2870000)
> fbe0: 0000003f
> c291e420
> fc00: 00000000 00000802 00000000 00000000 00006c00 00006c00 00000040
> 00000000
> fc20: 00000000 00000040 03200000 00000000 c286fcd0 00000000 c286fc70
> c286fc48
> fc40: c0100434 c010ddd8 c286fc84 c291e420 c2451000 00000000 c2e00000
> 00000000
> fc60: 00000000 c286fccc c286fc74 c00ce98c c01003cc c286fc84 c291e420
> 03600000
> fc80: 00000000 c286fcb4 c286fc94 c010fc48 c01124c4 00000000 03600000
> 00000000
> fca0: 00000000 c2451000 00000000 00000000 c286fd50 c286fd54 c0326000
> c01af9c8
> fcc0: c286fd3c c286fcd0 c00ceae0 c00ce890 c00556c0 c00554d8 c027d120
> c02059ac
> fce0: c02059a0 c027f400 c01af9c8 c02059b4 c286fd28 c286fd00 c0055904
> c00555e4
> fd00: 40000013 c2451000 c2451000 00000000 c01af9c8 00000000 00000190
> c286fd50
> fd20: c2451000 00000000 00000001 c286fd54 c286fdc8 c286fd40 c00cbe28
> c00cea20
> fd40: c248e000 c0013000 00000000 c00c7800 c0055b1c c2451000 00000000
> 00000003
> fd60: c2451000 c286fd88 c286fd74 c00c7898 c00c78c8 c24ac174 00000002
> c286fdb0
> fd80: c286fd8c c00c7d80 c0036d5c 0000003d 07270e00 c2451000 000041b6
> c01af9c8
> fda0: c03122fc c2451000 c01af9c8 00000118 0000000a 00000000 00000000
> c286fdf0
> fdc0: c286fdcc c00cd4d0 c00cbcb4 c2e00000 c0312a00 c01af9c8 c2451000
> 00000000
> fde0: 00000000 c286fe44 c286fdf4 c00c5bd0 c00cd0b8 c2e9436c 6264746d
> 6b636f6c
> fe00: c2460033 00000000 c286fe24 c0312b40 00000009 00000009 c286fe58
> c028205c
> fe20: c0282040 c0312a00 00000000 00000000 c2461000 00000000 c286fe54
> c286fe48
> fe40: c00c60f4 c00c5974 c286fe98 c286fe58 c007004c c00c60e0 6264746d
> 6b636f6c
> fe60: 00000033 c0011de0 0000000f c0275c60 c0011de0 c248c000 c0275c60
> fffffff4
> fe80: c01afc3c c248c000 00000000 c286feac c286fe9c c00c6120 c006ff2c
> c00c60d0
> fea0: c286fed4 c286feb0 c007028c c00c6114 ffffffff c248c000 00000000
> 00000000
> fec0: c286ff08 00000000 c286fefc c286fed8 c0085e68 c0070240 00000000
> c2457000
> fee0: 00000000 c248c000 00000000 00000000 c286ff70 c286ff00 c0086520
> c0085df0
> ff00: c248c000 00000000 c2cdd4cc c0275240 00000000 000211d0 c2457000
> 00000001
> ff20: 00000001 00000000 c286e000 befffc54 c286ff4c c286ff40 c0051d14
> 000211d0
> ff40: c286ff70 c286ff50 00000000 00000000 000211d0 c0ed0000 c2457000
> c286e000
> ff60: befffc54 c286ffa4 c286ff74 c0086988 c0086400 00000000 00000000
> c248c000
> ff80: c2461000 00000000 000211d0 befffcc8 00000015 c001c9a4 00000000
> c286ffa8
> ffa0: c001c820 c00868f4 00000000 c00237ec 000211d0 000211e8 000211f8
> c0ed0000
> ffc0: 00000000 000211d0 befffcc8 00000000 00000000 befffee8 befffc54
> 00000000
> ffe0: 40104990 befffc48 0000a848 4010499c 60000010 000211d0 00000000
> 00000000
> Backtrace:
> [<c010ddc8>] (nand_read_oobfree+0x0/0x49c) from [<c0100434>]
> (part_read_oobfree)
> [<c01003bc>] (part_read_oobfree+0x0/0xa0) from [<c00ce98c>]
> (nandmtd2_ReadChunk)
> r8 = 00000000 r7 = 00000000 r6 = C2E00000 r5 = 00000000
> r4 = C2451000
> [<c00ce880>] (nandmtd2_ReadChunkWithTagsFromNAND+0x0/0x124) from
> [<c00ceae0>] ()
> [<c00cea10>] (nandmtd2_QueryNANDBlock+0x0/0x114) from [<c00cbe28>]
> (yaffs_ScanB)
> [<c00cbca4>] (yaffs_ScanBackwards+0x0/0xc7c) from [<c00cd4d0>]
> (yaffs_GutsIniti)
> [<c00cd0a8>] (yaffs_GutsInitialise+0x0/0x4e8) from [<c00c5bd0>]
> (yaffs_internal)
> [<c00c5964>] (yaffs_internal_read_super+0x0/0x714) from [<c00c60f4>]
> (yaffs2_in)
> [<c00c60d0>] (yaffs2_internal_read_super_mtd+0x0/0x34) from
> [<c007004c>] (get_s)
> [<c006ff1c>] (get_sb_bdev+0x0/0x17c) from [<c00c6120>]
> (yaffs2_read_super+0x1c/)
> r8 = 00000000 r7 = C248C000 r6 = C01AFC3C r5 = FFFFFFF4
> r4 = C0275C60
> [<c00c6104>] (yaffs2_read_super+0x0/0x24) from [<c007028c>]
> (do_kern_mount+0x5c)
> [<c0070230>] (do_kern_mount+0x0/0xf4) from [<c0085e68>]
> (do_new_mount+0x88/0xb0)
> [<c0085de0>] (do_new_mount+0x0/0xb0) from [<c0086520>]
> (do_mount+0x130/0x168)
> [<c00863f0>] (do_mount+0x0/0x168) from [<c0086988>] (sys_mount+0xa4/0xe8)
> [<c00868e4>] (sys_mount+0x0/0xe8) from [<c001c820>]
> (ret_fast_syscall+0x0/0x2c)
> r8 = C001C9A4 r7 = 00000015 r6 = BEFFFCC8 r5 = 000211D0
> r4 = 00000000
> Code: bad PC value.
> Segmentation fault
>
> Also I've try not mount but simply call
> ioctl(fd,MEMWRITEOOBFREE,&oob); - result was totlay same.
>
> So, can you help me and provide your opinion about?
>
> Thank you,
> Yuri Golovach
>
>
> *Vitaly Wool <vwool@ru.mvista.com>*
>
> 26.01.2006 14:51
>
>
> To
> yuri.golovach@mindspeed.com
> cc
> linux-mtd@lists.infradead.org, manningc2@actrix.gen.nz
> Subject
> Re: [PATCH] treat OOB as a single chunk of oobavail bytes
>
>
>
>
>
>
>
>
>
> Hi Yuri,
>
> well, lemme just summarize what you hafta do in order to make YAFFS2
> work with my patches.
>
> 1. Apply the following patch to the mtd code:
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014648.html
> (yes, it's a single patch!)
> 2. Modify the fs/yaffs2/yaffs_mtdif2.c to use read_oobfree/write_oobfree
> where appropriate.
>
> Hope that helps,
>
> Vitaly
>
> yuri.golovach@mindspeed.com wrote:
>
> >
> > Hi Vitaly,
> >
> > Sure:
> >
> > flash device Samsung K9F1G08UOM
> >
> > patches:
> >
> > http://lists.infradead.org/pipermail/linux-mtd/2005-November/014494.html
> > http://lists.infradead.org/pipermail/linux-mtd/2005-December/014522.html
> > http://lists.infradead.org/pipermail/linux-mtd/2005-December/014523.html
> > http://lists.infradead.org/pipermail/linux-mtd/2005-November/014496.html
> > http://lists.infradead.org/pipermail/linux-mtd/2005-December/014521.html
> >
> >
> >
> > P.S: I've also downloaded ithe mtd version from 24th of November,
> > implements it in my kernel and patched with the same results. Is it
> > possible for you to say me where can I find your mtd version?
> >
> > Thank you,
> > Yuri Golovach
> >
> >
> >
> > *Vitaly Wool <vwool@ru.mvista.com>*
> >
> > 24.01.2006 15:02
> >
> >
> > To
> > yuri.golovach@mindspeed.com
> > cc
> > linux-mtd@lists.infradead.org
> > Subject
> > Re: [PATCH] treat OOB as a single chunk of oobavail
> bytes
> >
> >
> >
> >
> >
> >
> >
> >
> >
> > Hello Yuri,
> >
> > can you please specify what patches you did apply and what flash you're
> > using. Thanks!
> >
> > Vitaly
> >
> > yuri.golovach@mindspeed.com wrote:
> >
> > >Good day Vitaly.
> > >
> > >I've tried your patches which modifies nand_base.c, other mtdfiles and
> > >mtdutils to be compatible with yaffs2.
> > >
> > >Unfortunately, I've some issues with them.
> > >
> > >1)
> > > my version of mtd is newer then your and I was unable to patch
> > >nand_base.c with your patch. So, I add this patch manually (but I'm not
> > >sure - have I done some mistakes or not).
> > >
> > >2) After the kernel compiling with your patches I've started it
> > and
> > >receive a long list of
> > > Bad eraseblock1 ... at ...x..................
> > >
> > > After "mount" and "df" commands I saw that there is no free
> > space
> > >on flash because all bloks were marked as "bad block" .
> > > Than I've tried patched version of flash_eraseall but it
> was not
> > >able to see blocks also.
> > >
> > >
> > >3) I've changed nand_bbt.c file (in the patched kernel) where simply
> > >comment the bad blocks checking. Have booted from it and _successfully_
> > >used patched flash_eraseall.
> > >
> > >4) Than I've start the patched kernel _with bad blocks checking_ but
> > these
> > >(previously erased blocks) were marked like "bad blocks" again (in a
> > >kernel booting procedure).
> > >
> > >
> > >So, can you, please, provide your vision what should I do to run your
> > >patch. Or you can send the link on the mtd line which supports yaffs2,
> > >because I was unable to find your updates in CVS mainline :(
> > >
> > >Thank you,
> > > Yuri Golovach
> > >
> > >
> > >
> > >
> >
> >
> >
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2006-01-28 9:15 ` Vitaly Wool
@ 2006-01-29 15:19 ` Vitaly Wool
0 siblings, 0 replies; 10+ messages in thread
From: Vitaly Wool @ 2006-01-29 15:19 UTC (permalink / raw)
To: yuri.golovach; +Cc: manningc2, linux-mtd
Hi Yuri,
can you please supply the patch for the yaffs_mtdif2.c you've done?
Please keep in mind that you have to consider how many spare bytes to
read from an OOB area.
What NAND flash chip/driver you're using might also be of interest.
Best regards,
Vitaly
yuri.golovach@mindspeed.com wrote:
>
> Hi Vitaly!
>
> I've successfully applied your patch without any issues, changed
> read_oob and write_oob on read_oobfree and write_oobfree.
>
> No "Bad block" at the booting procedure, but here is result which I've
> resived:
>
> comcerto:/# mount -t yaffs2 /dev/mtdblock3 /mnt/y
>
> Unable to handle kernel NULL pointer dereference at virtual address
> 00000000
> pgd = c2490000
> [00000000] *pgd=03ac3031, *pte=00000000, *ppte=00000000
> Internal error: Oops: 0 [#1]
> Modules linked in:
> CPU: 0
> PC is at 0x0
> LR is at nand_read_oobfree+0x3a0/0x49c
> pc : [<00000000>] lr : [<c010e168>] Not tainted
> sp : c286fbf8 ip : c286fbd4 fp : c286fc44
> r10: c02ffc00 r9 : 00000002 r8 : 00000000
> r7 : 00000000 r6 : 00000000 r5 : c02ffd88 r4 : 00000010
> r3 : c2e94870 r2 : 00000002 r1 : 00000004 r0 : c02ffc00
> Flags: Nzcv IRQs on FIQs on Mode SVC_32 Segment user
> Control: C000717F Table: 03490000 DAC: 00000015
> Process mount (pid: 952, stack limit = 0xc286e194)
> Stack: (0xc286fbf8 to 0xc2870000)
> fbe0: 0000003f
> c291e420
> fc00: 00000000 00000802 00000000 00000000 00006c00 00006c00 00000040
> 00000000
> fc20: 00000000 00000040 03200000 00000000 c286fcd0 00000000 c286fc70
> c286fc48
> fc40: c0100434 c010ddd8 c286fc84 c291e420 c2451000 00000000 c2e00000
> 00000000
> fc60: 00000000 c286fccc c286fc74 c00ce98c c01003cc c286fc84 c291e420
> 03600000
> fc80: 00000000 c286fcb4 c286fc94 c010fc48 c01124c4 00000000 03600000
> 00000000
> fca0: 00000000 c2451000 00000000 00000000 c286fd50 c286fd54 c0326000
> c01af9c8
> fcc0: c286fd3c c286fcd0 c00ceae0 c00ce890 c00556c0 c00554d8 c027d120
> c02059ac
> fce0: c02059a0 c027f400 c01af9c8 c02059b4 c286fd28 c286fd00 c0055904
> c00555e4
> fd00: 40000013 c2451000 c2451000 00000000 c01af9c8 00000000 00000190
> c286fd50
> fd20: c2451000 00000000 00000001 c286fd54 c286fdc8 c286fd40 c00cbe28
> c00cea20
> fd40: c248e000 c0013000 00000000 c00c7800 c0055b1c c2451000 00000000
> 00000003
> fd60: c2451000 c286fd88 c286fd74 c00c7898 c00c78c8 c24ac174 00000002
> c286fdb0
> fd80: c286fd8c c00c7d80 c0036d5c 0000003d 07270e00 c2451000 000041b6
> c01af9c8
> fda0: c03122fc c2451000 c01af9c8 00000118 0000000a 00000000 00000000
> c286fdf0
> fdc0: c286fdcc c00cd4d0 c00cbcb4 c2e00000 c0312a00 c01af9c8 c2451000
> 00000000
> fde0: 00000000 c286fe44 c286fdf4 c00c5bd0 c00cd0b8 c2e9436c 6264746d
> 6b636f6c
> fe00: c2460033 00000000 c286fe24 c0312b40 00000009 00000009 c286fe58
> c028205c
> fe20: c0282040 c0312a00 00000000 00000000 c2461000 00000000 c286fe54
> c286fe48
> fe40: c00c60f4 c00c5974 c286fe98 c286fe58 c007004c c00c60e0 6264746d
> 6b636f6c
> fe60: 00000033 c0011de0 0000000f c0275c60 c0011de0 c248c000 c0275c60
> fffffff4
> fe80: c01afc3c c248c000 00000000 c286feac c286fe9c c00c6120 c006ff2c
> c00c60d0
> fea0: c286fed4 c286feb0 c007028c c00c6114 ffffffff c248c000 00000000
> 00000000
> fec0: c286ff08 00000000 c286fefc c286fed8 c0085e68 c0070240 00000000
> c2457000
> fee0: 00000000 c248c000 00000000 00000000 c286ff70 c286ff00 c0086520
> c0085df0
> ff00: c248c000 00000000 c2cdd4cc c0275240 00000000 000211d0 c2457000
> 00000001
> ff20: 00000001 00000000 c286e000 befffc54 c286ff4c c286ff40 c0051d14
> 000211d0
> ff40: c286ff70 c286ff50 00000000 00000000 000211d0 c0ed0000 c2457000
> c286e000
> ff60: befffc54 c286ffa4 c286ff74 c0086988 c0086400 00000000 00000000
> c248c000
> ff80: c2461000 00000000 000211d0 befffcc8 00000015 c001c9a4 00000000
> c286ffa8
> ffa0: c001c820 c00868f4 00000000 c00237ec 000211d0 000211e8 000211f8
> c0ed0000
> ffc0: 00000000 000211d0 befffcc8 00000000 00000000 befffee8 befffc54
> 00000000
> ffe0: 40104990 befffc48 0000a848 4010499c 60000010 000211d0 00000000
> 00000000
> Backtrace:
> [<c010ddc8>] (nand_read_oobfree+0x0/0x49c) from [<c0100434>]
> (part_read_oobfree)
> [<c01003bc>] (part_read_oobfree+0x0/0xa0) from [<c00ce98c>]
> (nandmtd2_ReadChunk)
> r8 = 00000000 r7 = 00000000 r6 = C2E00000 r5 = 00000000
> r4 = C2451000
> [<c00ce880>] (nandmtd2_ReadChunkWithTagsFromNAND+0x0/0x124) from
> [<c00ceae0>] ()
> [<c00cea10>] (nandmtd2_QueryNANDBlock+0x0/0x114) from [<c00cbe28>]
> (yaffs_ScanB)
> [<c00cbca4>] (yaffs_ScanBackwards+0x0/0xc7c) from [<c00cd4d0>]
> (yaffs_GutsIniti)
> [<c00cd0a8>] (yaffs_GutsInitialise+0x0/0x4e8) from [<c00c5bd0>]
> (yaffs_internal)
> [<c00c5964>] (yaffs_internal_read_super+0x0/0x714) from [<c00c60f4>]
> (yaffs2_in)
> [<c00c60d0>] (yaffs2_internal_read_super_mtd+0x0/0x34) from
> [<c007004c>] (get_s)
> [<c006ff1c>] (get_sb_bdev+0x0/0x17c) from [<c00c6120>]
> (yaffs2_read_super+0x1c/)
> r8 = 00000000 r7 = C248C000 r6 = C01AFC3C r5 = FFFFFFF4
> r4 = C0275C60
> [<c00c6104>] (yaffs2_read_super+0x0/0x24) from [<c007028c>]
> (do_kern_mount+0x5c)
> [<c0070230>] (do_kern_mount+0x0/0xf4) from [<c0085e68>]
> (do_new_mount+0x88/0xb0)
> [<c0085de0>] (do_new_mount+0x0/0xb0) from [<c0086520>]
> (do_mount+0x130/0x168)
> [<c00863f0>] (do_mount+0x0/0x168) from [<c0086988>] (sys_mount+0xa4/0xe8)
> [<c00868e4>] (sys_mount+0x0/0xe8) from [<c001c820>]
> (ret_fast_syscall+0x0/0x2c)
> r8 = C001C9A4 r7 = 00000015 r6 = BEFFFCC8 r5 = 000211D0
> r4 = 00000000
> Code: bad PC value.
> Segmentation fault
>
> Also I've try not mount but simply call
> ioctl(fd,MEMWRITEOOBFREE,&oob); - result was totlay same.
>
> So, can you help me and provide your opinion about?
>
> Thank you,
> Yuri Golovach
>
>
> *Vitaly Wool <vwool@ru.mvista.com>*
>
> 26.01.2006 14:51
>
>
> To
> yuri.golovach@mindspeed.com
> cc
> linux-mtd@lists.infradead.org, manningc2@actrix.gen.nz
> Subject
> Re: [PATCH] treat OOB as a single chunk of oobavail bytes
>
>
>
>
>
>
>
>
>
> Hi Yuri,
>
> well, lemme just summarize what you hafta do in order to make YAFFS2
> work with my patches.
>
> 1. Apply the following patch to the mtd code:
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014648.html
> (yes, it's a single patch!)
> 2. Modify the fs/yaffs2/yaffs_mtdif2.c to use read_oobfree/write_oobfree
> where appropriate.
>
> Hope that helps,
>
> Vitaly
>
> yuri.golovach@mindspeed.com wrote:
>
> >
> > Hi Vitaly,
> >
> > Sure:
> >
> > flash device Samsung K9F1G08UOM
> >
> > patches:
> >
> >
> http://lists.infradead.org/pipermail/linux-mtd/2005-November/014494.html
> >
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014522.html
> >
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014523.html
> >
> http://lists.infradead.org/pipermail/linux-mtd/2005-November/014496.html
> >
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014521.html
> >
> >
> >
> > P.S: I've also downloaded ithe mtd version from 24th of November,
> > implements it in my kernel and patched with the same results. Is it
> > possible for you to say me where can I find your mtd version?
> >
> > Thank you,
> > Yuri Golovach
> >
> >
> >
> > *Vitaly Wool <vwool@ru.mvista.com>*
> >
> > 24.01.2006 15:02
> >
> > > To
> > yuri.golovach@mindspeed.com
> > cc
> > linux-mtd@lists.infradead.org
> > Subject
> > Re: [PATCH] treat OOB as a single chunk of oobavail
> bytes
> >
> >
> >
> > >
> >
> >
> >
> >
> > Hello Yuri,
> >
> > can you please specify what patches you did apply and what flash you're
> > using. Thanks!
> >
> > Vitaly
> >
> > yuri.golovach@mindspeed.com wrote:
> >
> > >Good day Vitaly.
> > >
> > >I've tried your patches which modifies nand_base.c, other mtdfiles and
> > >mtdutils to be compatible with yaffs2.
> > >
> > >Unfortunately, I've some issues with them.
> > >
> > >1)
> > > my version of mtd is newer then your and I was unable to patch
> > >nand_base.c with your patch. So, I add this patch manually (but I'm
> not
> > >sure - have I done some mistakes or not).
> > >
> > >2) After the kernel compiling with your patches I've started it
> > and
> > >receive a long list of
> > > Bad eraseblock1 ... at ...x..................
> > >
> > > After "mount" and "df" commands I saw that there is no free
> > space
> > >on flash because all bloks were marked as "bad block" .
> > > Than I've tried patched version of flash_eraseall but it
> was not
> > >able to see blocks also.
> > >
> > >
> > >3) I've changed nand_bbt.c file (in the patched kernel) where simply
> > >comment the bad blocks checking. Have booted from it and
> _successfully_
> > >used patched flash_eraseall.
> > >
> > >4) Than I've start the patched kernel _with bad blocks checking_ but
> > these
> > >(previously erased blocks) were marked like "bad blocks" again (in a
> > >kernel booting procedure).
> > >
> > >
> > >So, can you, please, provide your vision what should I do to run your
> > >patch. Or you can send the link on the mtd line which supports yaffs2,
> > >because I was unable to find your updates in CVS mainline :(
> > >
> > >Thank you,
> > > Yuri Golovach
> > >
> > >
> > > > >
> >
> >
> >
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
[parent not found: <OFD870B79D.90A804FE-ON88257101.0037ED08-C2257101.0037DF6B@mindspeed.com>]
* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
[not found] <OFD870B79D.90A804FE-ON88257101.0037ED08-C2257101.0037DF6B@mindspeed.com>
@ 2006-01-26 12:51 ` Vitaly Wool
2006-01-26 22:26 ` Charles Manning
0 siblings, 1 reply; 10+ messages in thread
From: Vitaly Wool @ 2006-01-26 12:51 UTC (permalink / raw)
To: yuri.golovach; +Cc: manningc2, linux-mtd
Hi Yuri,
well, lemme just summarize what you hafta do in order to make YAFFS2
work with my patches.
1. Apply the following patch to the mtd code:
http://lists.infradead.org/pipermail/linux-mtd/2005-December/014648.html
(yes, it's a single patch!)
2. Modify the fs/yaffs2/yaffs_mtdif2.c to use read_oobfree/write_oobfree
where appropriate.
Hope that helps,
Vitaly
yuri.golovach@mindspeed.com wrote:
>
> Hi Vitaly,
>
> Sure:
>
> flash device Samsung K9F1G08UOM
>
> patches:
>
> http://lists.infradead.org/pipermail/linux-mtd/2005-November/014494.html
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014522.html
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014523.html
> http://lists.infradead.org/pipermail/linux-mtd/2005-November/014496.html
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014521.html
>
>
>
> P.S: I've also downloaded ithe mtd version from 24th of November,
> implements it in my kernel and patched with the same results. Is it
> possible for you to say me where can I find your mtd version?
>
> Thank you,
> Yuri Golovach
>
>
>
> *Vitaly Wool <vwool@ru.mvista.com>*
>
> 24.01.2006 15:02
>
>
> To
> yuri.golovach@mindspeed.com
> cc
> linux-mtd@lists.infradead.org
> Subject
> Re: [PATCH] treat OOB as a single chunk of oobavail bytes
>
>
>
>
>
>
>
>
>
> Hello Yuri,
>
> can you please specify what patches you did apply and what flash you're
> using. Thanks!
>
> Vitaly
>
> yuri.golovach@mindspeed.com wrote:
>
> >Good day Vitaly.
> >
> >I've tried your patches which modifies nand_base.c, other mtdfiles and
> >mtdutils to be compatible with yaffs2.
> >
> >Unfortunately, I've some issues with them.
> >
> >1)
> > my version of mtd is newer then your and I was unable to patch
> >nand_base.c with your patch. So, I add this patch manually (but I'm not
> >sure - have I done some mistakes or not).
> >
> >2) After the kernel compiling with your patches I've started it
> and
> >receive a long list of
> > Bad eraseblock1 ... at ...x..................
> >
> > After "mount" and "df" commands I saw that there is no free
> space
> >on flash because all bloks were marked as "bad block" .
> > Than I've tried patched version of flash_eraseall but it was not
> >able to see blocks also.
> >
> >
> >3) I've changed nand_bbt.c file (in the patched kernel) where simply
> >comment the bad blocks checking. Have booted from it and _successfully_
> >used patched flash_eraseall.
> >
> >4) Than I've start the patched kernel _with bad blocks checking_ but
> these
> >(previously erased blocks) were marked like "bad blocks" again (in a
> >kernel booting procedure).
> >
> >
> >So, can you, please, provide your vision what should I do to run your
> >patch. Or you can send the link on the mtd line which supports yaffs2,
> >because I was unable to find your updates in CVS mainline :(
> >
> >Thank you,
> > Yuri Golovach
> >
> >
> >
> >
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2006-01-26 12:51 ` Vitaly Wool
@ 2006-01-26 22:26 ` Charles Manning
2006-01-28 9:19 ` Vitaly Wool
0 siblings, 1 reply; 10+ messages in thread
From: Charles Manning @ 2006-01-26 22:26 UTC (permalink / raw)
To: linux-mtd, yaffs; +Cc: yuri.golovach, Vitaly Wool
On Friday 27 January 2006 01:51, Vitaly Wool wrote:
> Hi Yuri,
>
> well, lemme just summarize what you hafta do in order to make YAFFS2
> work with my patches.
>
> 1. Apply the following patch to the mtd code:
> http://lists.infradead.org/pipermail/linux-mtd/2005-December/014648.html
> (yes, it's a single patch!)
> 2. Modify the fs/yaffs2/yaffs_mtdif2.c to use read_oobfree/write_oobfree
> where appropriate.
>
> Hope that helps,
>
> Vitaly
Hi Vitaly
Is this in CVS yet? If not, I hope it will be there soon.
From what I see, this is going to be just what we need.
YAFFS2 does not need to write_oobfree as a seperate function (it is always
written as a single page write). YAFFS2 only needs read_oobfree.
However, YAFFS1 could use the write_oobfree function at some future date if
YAFFS1 gets moved to this interface to remove the current reliance on hanging
the ugly ECC parameter stuff through the interface.
I am pretty busy right now, but will try get the YAFFS2 side sorted ASAP. If
the YAFFS2 stuff is CVSed before the mtd then I'll just point people to this
patch.
Thanx!
Charles
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2006-01-26 22:26 ` Charles Manning
@ 2006-01-28 9:19 ` Vitaly Wool
0 siblings, 0 replies; 10+ messages in thread
From: Vitaly Wool @ 2006-01-28 9:19 UTC (permalink / raw)
To: Charles Manning; +Cc: yuri.golovach, linux-mtd, yaffs
Hi Charles,
no it's not yet in CVS. I think I'll be able to commit it if we get any
positive feedback on this patch (i. e. if it's actually working for
anyone else than me :))
As for write_oobfree, it looks to be useful for JFFSx to stop messing
with oobinfos in JFFSx code.
Best regards,
Vitaly
Charles Manning wrote:
>On Friday 27 January 2006 01:51, Vitaly Wool wrote:
>
>
>>Hi Yuri,
>>
>>well, lemme just summarize what you hafta do in order to make YAFFS2
>>work with my patches.
>>
>>1. Apply the following patch to the mtd code:
>>http://lists.infradead.org/pipermail/linux-mtd/2005-December/014648.html
>>(yes, it's a single patch!)
>>2. Modify the fs/yaffs2/yaffs_mtdif2.c to use read_oobfree/write_oobfree
>>where appropriate.
>>
>>Hope that helps,
>>
>> Vitaly
>>
>>
>
>Hi Vitaly
>
>Is this in CVS yet? If not, I hope it will be there soon.
>
>From what I see, this is going to be just what we need.
>
>YAFFS2 does not need to write_oobfree as a seperate function (it is always
>written as a single page write). YAFFS2 only needs read_oobfree.
>
>However, YAFFS1 could use the write_oobfree function at some future date if
>YAFFS1 gets moved to this interface to remove the current reliance on hanging
>the ugly ECC parameter stuff through the interface.
>
>I am pretty busy right now, but will try get the YAFFS2 side sorted ASAP. If
>the YAFFS2 stuff is CVSed before the mtd then I'll just point people to this
>patch.
>
>Thanx!
>
>Charles
>
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] treat OOB as a single chunk of oobavail bytes
@ 2005-11-29 15:02 Vitaly Wool
2005-11-29 22:12 ` Charles Manning
0 siblings, 1 reply; 10+ messages in thread
From: Vitaly Wool @ 2005-11-29 15:02 UTC (permalink / raw)
To: linux-mtd
Hi,
the patch below implements treating the OOB data as a chunk of _free_ OOB bytes of mtd->oobavail size.
This is what was announced several times. This patch is a working one (verified with yaffs2 and jffs2), however, it's not completely ready to work with 16bit NAND flashes.
Anyway, I'd like to ask for a permission to commit it to let other people start using it/report the problems/etc. etc.
Of course input of any kind is welcome.
Best regards,
Vitaly
diff -uNr linux-2.6.10.orig/drivers/mtd/nand/nand_base.c linux-2.6.10.nand/drivers/mtd/nand/nand_base.c
--- linux-2.6.10.orig/drivers/mtd/nand/nand_base.c 2005-11-24 16:07:18.000000000 +0300
+++ linux-2.6.10.nand/drivers/mtd/nand/nand_base.c 2005-11-29 16:55:13.634260952 +0300
@@ -117,42 +117,8 @@
#define FFCHARS_SIZE 2048
static u_char ffchars[FFCHARS_SIZE];
-static struct page_layout_item hw3_256_layout[] = {
- { .length = 256, .type = ITEM_TYPE_DATA, },
- { .length = 3, .type = ITEM_TYPE_ECC, },
- { .length = 5, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw3_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 3, .type = ITEM_TYPE_ECC, },
- { .length = 13, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw6_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 6, .type = ITEM_TYPE_ECC, },
- { .length = 10, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw8_512_layout[] = {
- { .length = 512, .type = ITEM_TYPE_DATA, },
- { .length = 8, .type = ITEM_TYPE_ECC, },
- { .length = 8, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-static struct page_layout_item hw12_2048_layout[] = {
- { .length = 2048, .type = ITEM_TYPE_DATA, },
- { .length = 12, .type = ITEM_TYPE_ECC, },
- { .length = 52, .type = ITEM_TYPE_OOB, },
- { .length = 0, },
-};
-
-#define HW_AUTOOOB_LAYOUT_SIZE 8 /* should be enough */
+#define HW_AUTOOOB_LAYOUT_SIZE 32 /* should be enough */
+#define SW_ECC_LAYOUT_SIZE 8
/*
* NAND low-level MTD interface functions
@@ -893,11 +859,10 @@
static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int page,
u_char *oob_buf, struct nand_oobinfo *oobsel, int cached)
{
- int i, oobidx, status;
+ int j = 0, oobidx = 0, status;
u_char ecc_code[40];
int eccmode = oobsel->useecc ? this->eccmode : NAND_ECC_NONE;
- int *oob_config = oobsel->eccpos;
- int datidx = 0, eccidx = 0, eccsteps = this->eccsteps;
+ int datidx = 0, last_datidx = 0, eccidx = 0;
int eccbytes = 0;
/* FIXME: Enable cached programming */
@@ -914,41 +879,35 @@
this->write_buf(mtd, this->data_poi, mtd->oobblock);
break;
- /* Software ecc 3/256, write all */
- case NAND_ECC_SOFT:
- for (; eccsteps; eccsteps--) {
- this->calculate_ecc(mtd, &this->data_poi[datidx], ecc_code);
- for (i = 0; i < 3; i++, eccidx++)
- oob_buf[oob_config[eccidx]] = ecc_code[i];
- datidx += this->eccsize;
- }
- this->write_buf(mtd, this->data_poi, mtd->oobblock);
- this->write_buf(mtd, oob_buf, mtd->oobsize);
- break;
default:
eccbytes = this->eccbytes;
- for (oobidx = 0; eccsteps; eccsteps--) {
- int j = 0, last_datidx = datidx, last_oobidx;
- for (; this->layout[j].length; j++) {
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
+ for (; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITE);
- this->write_buf(mtd, &this->data_poi[datidx], this->layout[j].length);
- datidx += this->layout[j].length;
- break;
- case ITEM_TYPE_ECC:
+ this->write_buf(mtd, &this->data_poi[datidx], this->layout[j].length);
+ last_datidx = datidx;
+ datidx += this->layout[j].length;
+ break;
+ case ITEM_TYPE_ECC:
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
- this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[eccidx]);
- for (last_oobidx = oobidx; oobidx < last_oobidx + this->layout[j].length; oobidx++, eccidx++)
- oob_buf[oobidx] = ecc_code[eccidx];
- this->write_buf(mtd, ecc_code, this->layout[j].length);
- break;
- case ITEM_TYPE_OOB:
+ this->calculate_ecc(mtd, &this->data_poi[last_datidx], &ecc_code[eccidx]);
+ this->write_buf(mtd, &ecc_code[eccidx], this->layout[j].length);
+ break;
+ case ITEM_TYPE_OOB:
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
- this->write_buf(mtd, &oob_buf[oobidx], this->layout[j].length);
- oobidx += this->layout[j].length;
- break;
- }
+ this->write_buf(mtd, ffchars, this->layout[j].length);
+ break;
+ case ITEM_TYPE_OOBFREE:
+ if (eccmode != NAND_ECC_SOFT)
+ this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: writing %02x %02x...\n", __FUNCTION__, oob_buf[oobidx], oob_buf[oobidx+1]);
+ this->write_buf(mtd, &oob_buf[oobidx], this->layout[j].length);
+ oobidx += this->layout[j].length;
+ break;
}
}
@@ -1003,7 +962,7 @@
static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int page, int numpages,
u_char *oob_buf, struct nand_oobinfo *oobsel, int chipnr, int oobmode)
{
- int i, j, datidx = 0, oobofs = 0, res = -EIO;
+ int j, datidx = 0, oobofs = 0, res = -EIO;
int eccsteps = this->eccsteps;
int hweccbytes;
u_char oobdata[64];
@@ -1014,50 +973,33 @@
this->cmdfunc (mtd, NAND_CMD_READ0, 0, page);
for(;;) {
- for (j = 0; j < eccsteps; j++) {
- /* Loop through and verify the data */
- if (this->verify_buf(mtd, &this->data_poi[datidx], mtd->eccsize)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- goto out;
- }
- datidx += mtd->eccsize;
- /* Have we a hw generator layout ? */
- if (!hweccbytes)
- continue;
- if (this->verify_buf(mtd, &this->oob_buf[oobofs], hweccbytes)) {
- DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
- goto out;
- }
- oobofs += hweccbytes;
- }
-
- /* check, if we must compare all data or if we just have to
- * compare the ecc bytes
- */
- 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);
- goto out;
- }
- } else {
- /* Read always, else autoincrement fails */
- this->read_buf(mtd, oobdata, mtd->oobsize - hweccbytes * eccsteps);
-
- if (oobsel->useecc != MTD_NANDECC_OFF && !hweccbytes) {
- int ecccnt = oobsel->eccbytes;
-
- for (i = 0; i < ecccnt; i++) {
- int idx = oobsel->eccpos[i];
- if (oobdata[idx] != oob_buf[oobofs + idx] ) {
- DEBUG (MTD_DEBUG_LEVEL0,
- "%s: Failed ECC write "
- "verify, page 0x%08x, " "%6i bytes were succesful\n", __FUNCTION__, page, i);
+ for (j = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ /* Loop through and verify the data */
+ if (this->verify_buf(mtd, &this->data_poi[datidx], this->layout[j].length)) {
+ DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+ goto out;
+ }
+ datidx += this->layout[j].length;
+ break;
+ case ITEM_TYPE_OOBFREE:
+ if (oobmode) {
+ if (this->verify_buf(mtd, &this->oob_buf[oobofs], this->layout[j].length)) {
+ DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
goto out;
}
+ oobofs += this->layout[j].length;
+ break;
}
+ case ITEM_TYPE_ECC:
+ case ITEM_TYPE_OOB:
+ /* Read always, else autoincrement fails */
+ this->read_buf(mtd, oobdata, this->layout[j].length);
}
+
}
- oobofs += mtd->oobsize - hweccbytes * eccsteps;
+
page++;
numpages--;
@@ -1153,13 +1095,13 @@
{
int i, j, col, realpage, page, end, ecc, chipnr, sndcmd = 1;
- int read = 0, oob = 0, oobidx, ecc_status = 0, ecc_failed = 0, eccidx;
+ int read = 0, oobidx, ecc_status = 0, ecc_failed = 0, eccidx;
struct nand_chip *this = mtd->priv;
u_char *data_poi, *oob_data = oob_buf;
u_char ecc_calc[32];
u_char ecc_code[32];
int eccmode, eccsteps;
- int *oob_config, datidx;
+ int *oob_config, datidx = 0, last_datidx = 0;
int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
int eccbytes;
int compareecc = 1;
@@ -1240,8 +1182,7 @@
}
/* get oob area, if we have no oob buffer from fs-driver */
- if (!oob_buf || oobsel->useecc == MTD_NANDECC_AUTOPLACE ||
- oobsel->useecc == MTD_NANDECC_AUTOPL_USR)
+ if (!oob_buf)
oob_data = &this->data_buf[end];
eccsteps = this->eccsteps;
@@ -1257,53 +1198,52 @@
break;
}
- case NAND_ECC_SOFT: /* Software ECC 3/256: Read in a page + oob data */
- this->read_buf(mtd, data_poi, end);
- for (i = 0, datidx = 0; eccsteps; eccsteps--, i+=3, datidx += ecc)
- this->calculate_ecc(mtd, &data_poi[datidx], &ecc_calc[i]);
- this->read_buf(mtd, &oob_data[mtd->oobsize - oobreadlen], oobreadlen);
- break;
-
default:
- for (oobidx = 0, datidx = 0, eccidx = 0; eccsteps; eccsteps--) {
- int last_datidx = datidx, last_oobidx = oobidx;
- for (j = 0; this->layout[j].length; j++) {
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d bytes of data\n", __FUNCTION__, this->layout[j].length);
+ oobidx = 0;
+ datidx = last_datidx = 0;
+ eccidx = 0;
+ for (j = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d bytes of data\n", __FUNCTION__, this->layout[j].length);
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_READ);
- this->read_buf(mtd, &data_poi[datidx], this->layout[j].length);
- datidx += this->layout[j].length;
- break;
-
- case ITEM_TYPE_ECC:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d ecc bytes\n", __FUNCTION__, this->layout[j].length);
- /* let the particular driver decide whether to read ECC */
+ this->read_buf(mtd, &data_poi[datidx], this->layout[j].length);
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: read %02x %02x...\n", __FUNCTION__, data_poi[datidx], data_poi[datidx+1]);
+ last_datidx = datidx;
+ datidx += this->layout[j].length;
+ break;
+
+ case ITEM_TYPE_ECC:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d ecc bytes\n", __FUNCTION__, this->layout[j].length);
+ /* let the particular driver decide whether to read ECC */
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_READSYN);
- this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
- if (!compareecc) {
- /* We calc error correction directly, it checks the hw
- * generator for an error, reads back the syndrome and
- * does the error correction on the fly */
- ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &oob_data[last_oobidx], &ecc_code[eccidx]);
- if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
- DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
- "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
- ecc_failed++;
- }
- } else
- this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[eccidx]);
- oobidx += this->layout[j].length;
- eccidx += this->layout[j].length;
- break;
- case ITEM_TYPE_OOB:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d free oob bytes\n", __FUNCTION__, this->layout[j].length);
+ this->read_buf(mtd, &ecc_code[eccidx], this->layout[j].length);
+ if (!compareecc) {
+ /* We calc error correction directly, it checks the hw
+ * generator for an error, reads back the syndrome and
+ * does the error correction on the fly */
+ ecc_status = this->correct_data(mtd, &data_poi[last_datidx], &ecc_code[eccidx], &ecc_code[eccidx]);
+ if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
+ DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: "
+ "Failed ECC read, page 0x%08x on chip %d\n", page, chipnr);
+ ecc_failed++;
+ }
+ } else
+ this->calculate_ecc(mtd, &data_poi[last_datidx], &ecc_calc[eccidx]);
+ eccidx += this->layout[j].length;
+ break;
+ case ITEM_TYPE_OOB:
+ case ITEM_TYPE_OOBFREE:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: reading %d oob bytes\n", __FUNCTION__, this->layout[j].length);
+ if (eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_READOOB);
- this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
+ this->read_buf(mtd, &oob_data[oobidx], this->layout[j].length);
+ if (this->layout[j].type == ITEM_TYPE_OOBFREE)
oobidx += this->layout[j].length;
- break;
- }
+ break;
}
}
break;
@@ -1311,11 +1251,7 @@
/* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
if (!compareecc)
- goto readoob;
-
- /* Pick the ECC bytes out of the oob data */
- for (j = 0; j < oobsel->eccbytes; j++)
- ecc_code[j] = oob_data[oob_config[j]];
+ goto readdata;
/* correct data, if neccecary */
for (i = 0, j = 0, datidx = 0; i < this->eccsteps; i++, datidx += ecc) {
@@ -1324,43 +1260,12 @@
/* Get next chunk of ecc bytes */
j += eccbytes;
- /* Check, if we have a fs supplied oob-buffer,
- * This is the legacy mode. Used by YAFFS1
- * Should go away some day
- */
- if (oob_buf && oobsel->useecc == MTD_NANDECC_PLACE) {
- int *p = (int *)(&oob_data[mtd->oobsize]);
- p[i] = ecc_status;
- }
-
if ((ecc_status == -1) || (ecc_status > (flags && 0xff))) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_read_ecc: " "Failed ECC read, page 0x%08x\n", page);
ecc_failed++;
}
}
- readoob:
- /* check, if we have a fs supplied oob-buffer */
- if (oob_buf) {
- /* without autoplace. Legacy mode used by YAFFS1 */
- switch(oobsel->useecc) {
- case MTD_NANDECC_AUTOPLACE:
- case MTD_NANDECC_AUTOPL_USR:
- /* Walk through the autoplace chunks */
- for (i = 0; oobsel->oobfree[i][1]; i++) {
- int from = oobsel->oobfree[i][0];
- int num = oobsel->oobfree[i][1];
- memcpy(&oob_buf[oob], &oob_data[from], num);
- oob += num;
- }
- break;
- case MTD_NANDECC_PLACE:
- /* YAFFS1 legacy mode */
- oob_data += this->eccsteps * sizeof (int);
- default:
- oob_data += mtd->oobsize;
- }
- }
readdata:
/* Partial page read, transfer data into fs buffer */
if (!aligned) {
@@ -1432,7 +1337,6 @@
int read = 0;
struct nand_chip *this = mtd->priv;
u_char *oob_data = oob_buf;
- int eccsteps;
int blockcheck = (1 << (this->phys_erase_shift - this->page_shift)) - 1;
@@ -1463,7 +1367,7 @@
/* Loop until all data read */
while (read < len) {
- if (this->eccmode == NAND_ECC_SOFT || this->eccmode == NAND_ECC_NONE) {
+ if (this->eccmode == NAND_ECC_NONE) {
int thislen = mtd->oobsize - col;
if (sndcmd) {
this->cmdfunc (mtd, NAND_CMD_READOOB, col, page);
@@ -1480,81 +1384,48 @@
sndcmd = 0;
}
- eccsteps = this->eccsteps;
+ for (j = 0; this->layout[j].length; j++) {
+ i = 0;
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_DATA:
+ case ITEM_TYPE_OOB:
+ case ITEM_TYPE_ECC:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: dummy data read\n", __FUNCTION__);
+ reallen += this->layout[j].length;
+ if (this->options & NAND_BUSWIDTH_16)
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
+ else
+ this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
+ break;
- for (; eccsteps; eccsteps--) {
- for (j = 0; this->layout[j].length; j++) {
- i = 0;
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: dummy data read\n", __FUNCTION__);
- reallen += this->layout[j].length;
+ case ITEM_TYPE_OOBFREE:
+ DEBUG (MTD_DEBUG_LEVEL3, "%s: free oob bytes read\n", __FUNCTION__);
+ i = min_t(int, col, this->layout[j].length);
+ if (i) {
+ reallen += i;
if (this->options & NAND_BUSWIDTH_16)
this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
else
this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- break;
-
- case ITEM_TYPE_ECC:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: ecc bytes read\n", __FUNCTION__);
- i = min_t(int, col, this->layout[j].length);
- if (i) {
- reallen += i;
- if (this->options & NAND_BUSWIDTH_16)
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
- else
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- }
- col -= i;
- i = min_t(int, len - read, this->layout[j].length - i);
- this->enable_hwecc(mtd, NAND_ECC_READSYN);
- if (i) {
- if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
- oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
- oob_data++; i--; reallen++;
- }
-
- this->read_buf(mtd, oob_data, i);
- reallen += i;
- }
- if (oob_buf + len == oob_data + i) {
- read += i;
- goto out;
- }
- break;
- case ITEM_TYPE_OOB:
- DEBUG (MTD_DEBUG_LEVEL3, "%s: free oob bytes read\n", __FUNCTION__);
- i = min_t(int, col, this->layout[j].length);
- if (i) {
- reallen += i;
- if (this->options & NAND_BUSWIDTH_16)
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen & ~1, page);
- else
- this->cmdfunc (mtd, NAND_CMD_READ0, reallen, page);
- }
- col -= i;
+ }
+ col -= i;
+ if (this->eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_READOOB);
- i = min_t(int, len - read, this->layout[j].length - i);
- if (i) {
- if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
- oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
- oob_data++; i--; reallen++;
- }
-
- this->read_buf(mtd, oob_data, i);
- reallen += i;
+ i = min_t(int, len - read, this->layout[j].length - i);
+ if (i) {
+ if (this->options & NAND_BUSWIDTH_16 && reallen & 1) {
+ oob_data[0] = cpu_to_le16(this->read_word(mtd)) >> 8;
+ oob_data++; i--; reallen++;
}
- if (oob_buf + len == oob_data + i) {
- read += i;
- goto out;
- }
-
- break;
+ this->read_buf(mtd, oob_data, i);
+ reallen += i;
}
read += i;
oob_data += i;
-
+ if (oob_buf + len == oob_data)
+ goto out;
+ break;
}
}
}
@@ -1664,67 +1535,6 @@
return 0;
}
-
-/**
- * nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
- * @mtd: MTD device structure
- * @fsbuf: buffer given by fs driver
- * @oobsel: out of band selection structre
- * @autoplace: 1 = place given buffer into the oob bytes
- * @numpages: number of pages to prepare
- *
- * Return:
- * 1. Filesystem buffer available and autoplacement is off,
- * return filesystem buffer
- * 2. No filesystem buffer or autoplace is off, return internal
- * buffer
- * 3. Filesystem buffer is given and autoplace selected
- * put data from fs buffer into internal buffer and
- * retrun internal buffer
- *
- * Note: The internal buffer is filled with 0xff. This must
- * be done only once, when no autoplacement happens
- * Autoplacement sets the buffer dirty flag, which
- * forces the 0xff fill before using the buffer again.
- *
-*/
-static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct nand_oobinfo *oobsel,
- int autoplace, int numpages)
-{
- struct nand_chip *this = mtd->priv;
- int i, len, ofs;
-
- /* Zero copy fs supplied buffer */
- if (fsbuf && !autoplace)
- return fsbuf;
-
- /* Check, if the buffer must be filled with ff again */
- if (this->oobdirty) {
- memset (this->oob_buf, 0xff,
- mtd->oobsize << (this->phys_erase_shift - this->page_shift));
- this->oobdirty = 0;
- }
-
- /* If we have no autoplacement or no fs buffer use the internal one */
- if (!autoplace || !fsbuf)
- return this->oob_buf;
-
- /* Walk through the pages and place the data */
- this->oobdirty = 1;
- ofs = 0;
- while (numpages--) {
- for (i = 0, len = 0; len < mtd->oobavail; i++) {
- int to = ofs + oobsel->oobfree[i][0];
- int num = oobsel->oobfree[i][1];
- memcpy (&this->oob_buf[to], fsbuf, num);
- len += num;
- fsbuf += num;
- }
- ofs += mtd->oobavail;
- }
- return this->oob_buf;
-}
-
#define NOTALIGNED(x) (x & (mtd->oobblock-1)) != 0
/**
@@ -1817,7 +1627,7 @@
startpage = page;
/* Calc number of pages we can write in one go */
numpages = min (ppblock - (startpage & (ppblock - 1)), totalpages);
- oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel, autoplace, numpages);
+ oobbuf = eccbuf ? eccbuf : ffchars;
bufstart = (u_char *)buf;
/* Loop until all data is written */
@@ -1867,8 +1677,7 @@
numpages = min (totalpages, ppblock);
page &= this->pagemask;
startpage = page;
- oobbuf = nand_prepare_oobbuf (mtd, eccbuf, oobsel,
- autoplace, numpages);
+ oobbuf = eccbuf ? eccbuf : ffchars;
oob = 0;
/* Check, if we cross a chip boundary */
if (!page) {
@@ -1910,6 +1719,7 @@
{
int column, page, status, ret = -EIO, chipnr, eccsteps, fflen, ooblen;
struct nand_chip *this = mtd->priv;
+ int i, j;
DEBUG (MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", __FUNCTION__, (unsigned int) to, (int) len);
@@ -1950,7 +1760,7 @@
if (page == this->pagebuf)
this->pagebuf = -1;
- if (this->eccmode == NAND_ECC_SOFT || this->eccmode == NAND_ECC_NONE) {
+ if (this->eccmode == NAND_ECC_NONE) {
if (NAND_MUST_PAD(this)) {
/* Write out desired data */
this->cmdfunc (mtd, NAND_CMD_SEQIN, mtd->oobblock, page & this->pagemask);
@@ -1972,41 +1782,43 @@
eccsteps = this->eccsteps;
- for (fflen = 0, ooblen = 0; eccsteps; eccsteps--) {
- int i, j;
- for (j = 0; this->layout[j].length; j++) {
- switch (this->layout[j].type) {
- case ITEM_TYPE_DATA:
+ fflen = 0;
+ ooblen = 0;
+ for (j = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_OOB:
+ case ITEM_TYPE_DATA:
+ if (this->eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITE);
- this->write_buf(mtd, ffchars, this->layout[j].length);
- fflen += this->layout[j].length;
- break;
+ this->write_buf(mtd, ffchars, this->layout[j].length);
+ fflen += this->layout[j].length;
+ break;
- case ITEM_TYPE_ECC:
+ case ITEM_TYPE_ECC:
+ if (this->eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITESYN);
- this->write_buf(mtd, ffchars, this->layout[j].length);
- ooblen += this->layout[j].length;
- break;
+ this->write_buf(mtd, ffchars, this->layout[j].length);
+ fflen += this->layout[j].length;
+ break;
- case ITEM_TYPE_OOB:
+ case ITEM_TYPE_OOBFREE:
+ if (this->eccmode != NAND_ECC_SOFT)
this->enable_hwecc(mtd, NAND_ECC_WRITEOOB);
- i = min_t(int, column, this->layout[j].length);
- if (i)
- this->write_buf(mtd, ffchars, i);
- column -= i;
- fflen += i;
- i = min_t(int, len + column - ooblen, this->layout[j].length - i);
-
- if (i)
- this->write_buf(mtd, &oob_buf[ooblen], i);
- ooblen += i;
- if (ooblen == len) {
- if (NAND_MUST_PAD(this))
- this->write_buf(mtd, ffchars, mtd->oobsize + mtd->oobblock - fflen - ooblen);
- goto finish;
- }
- break;
+ i = min_t(int, column, this->layout[j].length);
+ if (i)
+ this->write_buf(mtd, ffchars, i);
+ column -= i;
+ fflen += i;
+ i = min_t(int, len + column - ooblen, this->layout[j].length - i);
+ if (i)
+ this->write_buf(mtd, &oob_buf[ooblen], i);
+ ooblen += i;
+ if (ooblen == len) {
+ if (NAND_MUST_PAD(this))
+ this->write_buf(mtd, ffchars, mtd->oobsize + mtd->oobblock - fflen - ooblen);
+ goto finish;
}
+ break;
}
}
}
@@ -2026,17 +1838,57 @@
*retlen = len;
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
- if (this->eccmode == NAND_ECC_SOFT | this->eccmode == NAND_ECC_NONE) {
+ if (this->eccmode == NAND_ECC_SOFT || this->eccmode == NAND_ECC_NONE) {
/* Send command to read back the data */
this->cmdfunc (mtd, NAND_CMD_READOOB, column, page & this->pagemask);
- if (this->verify_buf(mtd, buf, len)) {
+ if (this->verify_buf(mtd, oob_buf, len)) {
DEBUG (MTD_DEBUG_LEVEL0, "nand_write_oob: " "Failed write verify, page 0x%08x\n", page);
ret = -EIO;
goto out;
}
+ } else {
+ int oobofs;
+ int read_len;
+ int real_ofs = 0;
+
+ column = to & (mtd->oobsize - 1);
+
+ /* Send command to read back the data */
+ this->cmdfunc (mtd, NAND_CMD_READ0, 0, page & this->pagemask);
+ for (j = 0, oobofs = 0; this->layout[j].length; j++) {
+ switch (this->layout[j].type) {
+ case ITEM_TYPE_OOBFREE:
+ i = min_t(int, column, this->layout[j].length);
+ if (i) {
+ real_ofs += i;
+ this->cmdfunc (mtd, NAND_CMD_READ0, real_ofs, page);
+ }
+ column -= i;
+
+ read_len = min_t(int, i, len);
+ if (this->verify_buf(mtd, &oob_buf[oobofs], read_len)) {
+ DEBUG (MTD_DEBUG_LEVEL0, "%s: " "Failed write verify, page 0x%08x ", __FUNCTION__, page);
+ ret = -EIO;
+ goto out;
+ }
+ oobofs += read_len;
+ real_ofs += read_len;
+ if (len == oobofs) {
+ ret = 0;
+ goto out;
+ }
+ break;
+ case ITEM_TYPE_ECC:
+ case ITEM_TYPE_OOB:
+ case ITEM_TYPE_DATA:
+ real_ofs += this->layout[j].length;
+ this->cmdfunc (mtd, NAND_CMD_READ0, real_ofs, page & this->pagemask);
+ break;
+ }
+
+ }
}
-#warning "Verify for OOB data in HW ECC case is NOT YET implemented"
#endif
ret = 0;
out:
@@ -2150,7 +2002,7 @@
numpages = (vecs->iov_len - len) >> this->page_shift;
/* Do not cross block boundaries */
numpages = min (ppblock - (startpage & (ppblock - 1)), numpages);
- oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
+ oobbuf = eccbuf ? eccbuf : ffchars;
bufstart = (u_char *)vecs->iov_base;
bufstart += len;
this->data_poi = bufstart;
@@ -2194,7 +2046,7 @@
this->data_poi = this->data_buf;
bufstart = this->data_poi;
numpages = 1;
- oobbuf = nand_prepare_oobbuf (mtd, NULL, oobsel, autoplace, numpages);
+ oobbuf = eccbuf ? eccbuf : ffchars;
ret = nand_write_page (mtd, this, page & this->pagemask,
oobbuf, oobsel, 0);
if (ret)
@@ -2513,13 +2365,66 @@
}
+/**
+ * fill_swecc_layout - [NAND Interface] build the layout for software ECC case
+ * @mtd: MTD device structure
+ * @eccbytes: Number of ECC bytes per page
+ *
+ * Build the page_layout array for NAND page handling for software ECC
+ * handling basing on the number of the ECC bytes per page
+ */
+static int fill_swecc_layout(struct mtd_info *mtd, int eccbytes)
+{
+ struct nand_chip *this = mtd->priv;
+
+ this->layout = kmalloc(SW_ECC_LAYOUT_SIZE * sizeof (struct page_layout_item), GFP_KERNEL);
+
+ if (this->layout == NULL)
+ return -ENOMEM;
+ else
+ this->layout_allocated = 1;
+
+ memset(this->layout, 0, sizeof(struct page_layout_item) * SW_ECC_LAYOUT_SIZE);
+ this->layout[0].type = ITEM_TYPE_DATA;
+ this->layout[0].length = mtd->oobblock;
+
+ if (this->badblockpos == 0) {
+ this->layout[1].type = ITEM_TYPE_OOB;
+ this->layout[1].length = 1;
+ this->layout[2].type = ITEM_TYPE_OOBFREE;
+ this->layout[2].length = mtd->oobsize - 1 - eccbytes * this->eccsteps;
+ this->layout[3].type = ITEM_TYPE_ECC;
+ this->layout[3].length = 3 * this->eccsteps;
+ } else {
+ this->layout[1].type = ITEM_TYPE_OOBFREE;
+ this->layout[1].length = this->badblockpos;
+ this->layout[2].type = ITEM_TYPE_OOB;
+ this->layout[2].length = 1;
+ this->layout[3].type = ITEM_TYPE_OOBFREE;
+ this->layout[3].length = mtd->oobsize - 1 - this->badblockpos - eccbytes * this->eccsteps;
+ this->layout[3].type = ITEM_TYPE_ECC;
+ this->layout[3].length = 3 * this->eccsteps;
+ }
+
+ return 0;
+}
+
+/**
+ * fill_autooob_layout - [NAND Interface] build the layout for hardware ECC case
+ * @mtd: MTD device structure
+ * @eccbytes: Number of ECC bytes per page
+ *
+ * Build the page_layout array for NAND page handling for hardware ECC
+ * handling basing on the nand_oobinfo structure supplied for the chip
+ */
static int fill_autooob_layout(struct mtd_info *mtd)
{
struct nand_chip *this = mtd->priv;
struct nand_oobinfo *oob = this->autooob;
+ int oobfreesize = 0;
int datasize = mtd->oobblock / this->eccsteps;
- int i = 0, res = 0;
- int eccpos = 0, eccbytes = 0, cur = 0;
+ int i = 0, j = 0, res = 0;
+ int eccpos = 0, eccbytes = 0, cur = 0, oobcur = 0;
this->layout = kmalloc(HW_AUTOOOB_LAYOUT_SIZE * sizeof (struct page_layout_item), GFP_KERNEL);
@@ -2529,32 +2434,47 @@
this->layout_allocated = 1;
while (i < HW_AUTOOOB_LAYOUT_SIZE - 1 &&
- cur < (mtd->oobsize + mtd->oobblock) / this->eccsteps - 1) {
- if (cur == 0) {
+ cur < (mtd->oobsize + mtd->oobblock)) {
+ if (cur % ((mtd->oobblock + mtd->oobsize) / this->eccsteps) == 0) {
this->layout[i].type = ITEM_TYPE_DATA;
this->layout[i].length = datasize;
- } else if (oob->eccpos[eccpos] == cur - datasize) {
+ j++;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: data type, length %d\n", this->layout[i].length);
+ } else if (oob->oobfree[oobcur][0] == cur - j * datasize) {
+ this->layout[i].type = ITEM_TYPE_OOBFREE;
+ this->layout[i].length = oob->oobfree[oobcur][1];
+ oobfreesize += this->layout[i].length;
+ oobcur++;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oobfree type, length %d\n", this->layout[i].length);
+ } else if (oob->eccpos[eccpos] == cur - j * datasize) {
int eccpos_cur = eccpos;
do {
eccpos++;
eccbytes++;
- } while (eccbytes < oob->eccbytes / this->eccsteps && oob->eccpos[eccpos] == oob->eccpos[eccpos+1] - 1);
+ } while (eccbytes < oob->eccbytes && oob->eccpos[eccpos] == oob->eccpos[eccpos+1] - 1);
eccpos++;
eccbytes++;
this->layout[i].type = ITEM_TYPE_ECC;
this->layout[i].length = eccpos - eccpos_cur;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: ecc type, length %d\n", this->layout[i].length);
} else {
+ int len = min_t(int, oob->eccpos[eccpos], mtd->oobsize / this->eccsteps);
+ len = min_t(int, len, oob->oobfree[oobcur][0]);
this->layout[i].type = ITEM_TYPE_OOB;
- if (eccbytes < oob->eccbytes / this->eccsteps)
- this->layout[i].length = datasize - cur + oob->eccpos[eccpos];
- else
- this->layout[i].length = mtd->oobsize / this->eccsteps - (cur - datasize);
+ this->layout[i].length = len;
+ DEBUG (MTD_DEBUG_LEVEL3, "fill_autooob_layout: oob type, length %d\n", this->layout[i].length);
}
cur += this->layout[i].length;
i++;
}
if (cur < (mtd->oobsize + mtd->oobblock) / this->eccsteps - 1)
res = -1;
+ else {
+ /* XXX */
+ oob->oobfree[0][0] = 0;
+ oob->oobfree[0][1] = oobfreesize;
+ oob->oobfree[1][0] = oob->oobfree[1][1] = 0;
+ }
return res;
}
@@ -2911,29 +2831,15 @@
/* We consider only layout allocation performed in nand_base */
this->layout_allocated = 0;
if (!this->layout) {
- if (this->autooob)
+ if (this->eccmode == NAND_ECC_SOFT)
+ fill_swecc_layout(mtd, 3);
+ else if (this->autooob)
fill_autooob_layout(mtd);
- else {
- switch (this->eccmode) {
- case NAND_ECC_HW12_2048:
- this->layout = hw12_2048_layout;
- break;
- case NAND_ECC_HW3_512:
- this->layout = hw3_512_layout;
- break;
- case NAND_ECC_HW6_512:
- this->layout = hw6_512_layout;
- break;
- case NAND_ECC_HW8_512:
- this->layout = hw8_512_layout;
- break;
- case NAND_ECC_HW3_256:
- this->layout = hw3_256_layout;
- break;
- }
- }
+ else
+ printk(KERN_WARNING "Couldn't generate layout. "
+ "Only NAND_ECC_NONE will work\n");
}
-
+
/* Initialize state, waitqueue and spinlock */
this->state = FL_READY;
init_waitqueue_head (&this->wq);
diff -uNr linux-2.6.10.orig/drivers/mtd/nand/nand_ecc.c linux-2.6.10.nand/drivers/mtd/nand/nand_ecc.c
--- linux-2.6.10.orig/drivers/mtd/nand/nand_ecc.c 2005-11-24 15:58:37.000000000 +0300
+++ linux-2.6.10.nand/drivers/mtd/nand/nand_ecc.c 2005-11-25 21:20:19.000000000 +0300
@@ -38,6 +38,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h>
/*
@@ -116,34 +117,40 @@
*/
int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code)
{
+ struct nand_chip *this = mtd->priv;
u_char idx, reg1, reg2, reg3;
- int j;
+ int i, j;
+ u_char *ecc_calc = ecc_code;
- /* Initialize variables */
- reg1 = reg2 = reg3 = 0;
- ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
+ for (i = 0; i < this->eccsteps; i++) {
+ /* Initialize variables */
+ reg1 = reg2 = reg3 = 0;
+ ecc_calc[0] = ecc_calc[1] = ecc_calc[2] = 0;
- /* Build up column parity */
- for(j = 0; j < 256; j++) {
+ /* 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);
+ /* 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);
+ /* 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);
+ /* Create non-inverted ECC code from line parity */
+ nand_trans_result(reg2, reg3, ecc_calc);
- /* Calculate final ECC code */
- ecc_code[0] = ~ecc_code[0];
- ecc_code[1] = ~ecc_code[1];
- ecc_code[2] = ((~reg1) << 2) | 0x03;
+ /* Calculate final ECC code */
+ ecc_calc[0] = ~ecc_calc[0];
+ ecc_calc[1] = ~ecc_calc[1];
+ ecc_calc[2] = ((~reg1) << 2) | 0x03;
+
+ ecc_calc += 3;
+ }
return 0;
}
diff -uNr linux-2.6.10.orig/include/linux/mtd/nand.h linux-2.6.10.nand/include/linux/mtd/nand.h
--- linux-2.6.10.orig/include/linux/mtd/nand.h 2005-11-24 15:59:00.000000000 +0300
+++ linux-2.6.10.nand/include/linux/mtd/nand.h 2005-11-23 17:50:32.000000000 +0300
@@ -171,6 +171,7 @@
enum {
ITEM_TYPE_DATA,
ITEM_TYPE_OOB,
+ ITEM_TYPE_OOBFREE,
ITEM_TYPE_ECC,
} type;
};
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2005-11-29 15:02 Vitaly Wool
@ 2005-11-29 22:12 ` Charles Manning
2005-11-30 8:54 ` Vitaly Wool
0 siblings, 1 reply; 10+ messages in thread
From: Charles Manning @ 2005-11-29 22:12 UTC (permalink / raw)
To: linux-mtd; +Cc: Vitaly Wool
On Wednesday 30 November 2005 04:02, Vitaly Wool wrote:
> Hi,
>
> the patch below implements treating the OOB data as a chunk of _free_ OOB
> bytes of mtd->oobavail size. This is what was announced several times. This
> patch is a working one (verified with yaffs2 and jffs2), however, it's not
> completely ready to work with 16bit NAND flashes. Anyway, I'd like to ask
> for a permission to commit it to let other people start using it/report the
> problems/etc. etc.
>
> Of course input of any kind is welcome.
>
> Best regards,
> Vitaly
Bloody Marvelous! This is very good news for the yaffs folk.
My only concern/query is a taste issue:
Should the read_oob funtion be used to do the available read or should is it
better to use a different function like read_ecc() using NULL for the data
argument?
I have enumerated what I believe to be the pros and cons a few times, and I
prefer using read_ecc with NULL because this is unambiguous.
However this is a taste issue and to me having a solution is better than
having an argument!
-- CHarles
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2005-11-29 22:12 ` Charles Manning
@ 2005-11-30 8:54 ` Vitaly Wool
2005-12-01 22:03 ` Charles Manning
0 siblings, 1 reply; 10+ messages in thread
From: Vitaly Wool @ 2005-11-30 8:54 UTC (permalink / raw)
To: Charles Manning; +Cc: linux-mtd
Hi Charles,
I've kept the read_ecc/read_oob interface as it was. The reasons behind are:
- permitting NULL data for read_ecc in order to facilitate pure OOB read
will overcomplicate the implementation and will require API change (i.
e. how much of the OOB to read, at least)
- read_oob provides additional capabilities like reading the OOB from a
specified offset.
The problem remaining is that yaffs2 can/t work unmodified with my
target (ARM926-based board with Sandisk NAND flash controller).
The reason is that the HW ECC engine uses 40 bytes per 2k page so the
remaining amount of OOB is no more than 23 (64 - 40 - 1 byte for
badblockpos). On the other hand, yaffs_PackedTags2 size is 28 bytes, so
I'm in trouble.
What I suggest to overcome this issue is:
- use "__attribute__ (packed) " for all the structures put into the OOB;
- limit the number of bits for yaffs_PackedTags2TagsPart and members.
For instance, the patch inlined reduces the size of yaffs_PackedTags2 to
12 bytes without impacting the functionality.
One may say that using "packed" limits the portability, but I will argue
that statement since the alignments within the structure may also change
from compiler to compiler and from arch to arch (i. e. GNU ABI vs EABI
for ARM). So the best way would be not to mess with the structures for
packed tags at all, but as for now, I'm worried just about reducing the
size of yaffs_PackedTags2 :)
Best regards,
Vitaly
diff -uNr linux.orig/fs/yaffs2/yaffs_ecc.h linux/fs/yaffs2/yaffs_ecc.h
--- linux.orig/fs/yaffs2/yaffs_ecc.h 2005-11-24 16:51:17.000000000 +0300
+++ linux/fs/yaffs2/yaffs_ecc.h 2005-11-30 11:05:18.000000000 +0300
@@ -26,10 +26,10 @@
#ifndef __YAFFS_ECC_H__
#define __YAFFS_ECC_H__
-typedef struct {
+typedef struct __attribute__((packed)) {
unsigned char colParity;
- unsigned lineParity;
- unsigned lineParityPrime;
+ unsigned short lineParity:12;
+ unsigned short lineParityPrime:12;
} yaffs_ECCOther;
void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
diff -uNr linux-2.6.10.orig/fs/yaffs2/yaffs_packedtags2.h
linux-2.6.10/fs/yaffs2/yaffs_packedtags2.h
--- linux-2.6.10.orig/fs/yaffs2/yaffs_packedtags2.h 2005-11-24
16:51:17.000000000 +0300
+++ linux-2.6.10/fs/yaffs2/yaffs_packedtags2.h 2005-11-30
11:04:52.000000000 +0300
@@ -6,14 +6,14 @@
#include "yaffs_guts.h"
#include "yaffs_ecc.h"
-typedef struct {
- unsigned sequenceNumber;
- unsigned objectId;
- unsigned chunkId;
- unsigned byteCount;
+typedef struct __attribute__((packed)) {
+ unsigned short sequenceNumber;
+ unsigned short objectId;
+ unsigned short chunkId;
+ unsigned short byteCount;
} yaffs_PackedTags2TagsPart;
-typedef struct {
+typedef struct __attribute__((packed)) {
yaffs_PackedTags2TagsPart t;
yaffs_ECCOther ecc;
} yaffs_PackedTags2;
Charles Manning wrote:
>On Wednesday 30 November 2005 04:02, Vitaly Wool wrote:
>
>
>>Hi,
>>
>>the patch below implements treating the OOB data as a chunk of _free_ OOB
>>bytes of mtd->oobavail size. This is what was announced several times. This
>>patch is a working one (verified with yaffs2 and jffs2), however, it's not
>>completely ready to work with 16bit NAND flashes. Anyway, I'd like to ask
>>for a permission to commit it to let other people start using it/report the
>>problems/etc. etc.
>>
>>Of course input of any kind is welcome.
>>
>>Best regards,
>> Vitaly
>>
>>
>
>
>Bloody Marvelous! This is very good news for the yaffs folk.
>
>My only concern/query is a taste issue:
>Should the read_oob funtion be used to do the available read or should is it
>better to use a different function like read_ecc() using NULL for the data
>argument?
>
>I have enumerated what I believe to be the pros and cons a few times, and I
>prefer using read_ecc with NULL because this is unambiguous.
>
>However this is a taste issue and to me having a solution is better than
>having an argument!
>
>-- CHarles
>
>
>
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] treat OOB as a single chunk of oobavail bytes
2005-11-30 8:54 ` Vitaly Wool
@ 2005-12-01 22:03 ` Charles Manning
0 siblings, 0 replies; 10+ messages in thread
From: Charles Manning @ 2005-12-01 22:03 UTC (permalink / raw)
To: linux-mtd
On Wednesday 30 November 2005 21:54, Vitaly Wool wrote:
> Hi Charles,
>
> I've kept the read_ecc/read_oob interface as it was. The reasons behind
> are: - permitting NULL data for read_ecc in order to facilitate pure OOB
> read will overcomplicate the implementation and will require API change (i.
> e. how much of the OOB to read, at least)
> - read_oob provides additional capabilities like reading the OOB from a
> specified offset.
No worries at all.
<snip yaffs2 stuff shifted to yaffs list>
-- CHarles
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2006-01-30 5:43 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <OFFED20C5C.C2FC40DE-ON882570FF.005D6B36-C22570FF.005ED903@mindspeed.com>
2006-01-24 13:02 ` [PATCH] treat OOB as a single chunk of oobavail bytes Vitaly Wool
[not found] <OF1F9E1072.64E03318-ON88257102.0060A9BE-C2257102.0060ED3A@mindspeed.com>
2006-01-28 9:15 ` Vitaly Wool
2006-01-29 15:19 ` Vitaly Wool
[not found] <OFD870B79D.90A804FE-ON88257101.0037ED08-C2257101.0037DF6B@mindspeed.com>
2006-01-26 12:51 ` Vitaly Wool
2006-01-26 22:26 ` Charles Manning
2006-01-28 9:19 ` Vitaly Wool
2005-11-29 15:02 Vitaly Wool
2005-11-29 22:12 ` Charles Manning
2005-11-30 8:54 ` Vitaly Wool
2005-12-01 22:03 ` Charles Manning
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox