Peter Barada wrote:
>On Thu, 2006-02-09 at 23:13 +0000, Sergei Sharonov wrote:
>
>
>Yes, I have. I use a YAFFS1 NOR-based system, and in the writes, we lay
>down the data chunk, and then the tag. In the unlikely event that a
>power-cycle occurs while writing the data, the tag is still empty, but
>some of the data chunk is not erased, and then next time a write occurs
>into that chunk, YAFFS sees that the write fails since the previous data
>was written(and retires the whole block), even though the tag indicated
>the chunk is empty.
>
>To fix this, I used two bits in the pageStatus byte in the tag, and
>write the tag first, then the data, and then update the tag. Assuming
>that the pageStatus starts out as 0xff, then the first tag write puts in
>the value of the tag, but writes a pageStatus byte of 0xfe to indicate
>that a write is in progress, then writes the chunk data, and then comes
>back an re-writes the tag with the same data, and a pageStatus of 0xfc.
>In the rest of the code, the chunk is assumed to be valid if the
>pageStatus is 0xff(and objectId is non-0xfffff) or if 0xfc, empty if the
>objectId is 0xfffff, and deleted if the pageStatus is either 0xfe, or
>0x00(the value written to delete a tag).
>
>This solved the problem for me. I assume an approach like this would
>work for NAND...
>
>
If works for NAND only if the additional partial page programming
fits NAND specifications.
I have looked at Samsung datasheet and it say:
"The number of consecutive partial page programming
operation within the same page without an intervening erase
operation should not exceed 2 for main array and 3 for spare array."
So it should be ok for Samsung since in this case is 1 + 2.
However Toshiba say: "Multiple partial page programming attempts
in a block can aggravate this error symptom" referring to Program
disturb soft error.
I think a better solution is to check the power fail flag before any
erase/programming cycle as suggested by Charles.
Unfortunately this means modify the MTD driver, something like this:
static int my_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
{
if ( check_powerfail() )
return -EIO;
else
return nand_erase_nand (mtd, instr, 0);
}
and in nand_write_ecc()
/* Check, if it is write protected or power fail */
if ( nand_check_wp(mtd) || check_powerfail() )
goto out;
Cheers,
Claudio Lanconelli