From patchwork Tue Jul 28 17:19:56 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: UBIFS Corrupt during power failure Date: Tue, 28 Jul 2009 07:19:56 -0000 From: Eric Holmberg X-Patchwork-Id: 30310 Message-Id: To: "news" , Cc: linux-mtd@lists.infradead.org, Stefan Roese , Jamie Lokier , Adrian Hunter > We have similar problems with a SPANSION falsh (S29GL01GP). > I think the reason of the problem is a feature of the chip. > > I reduced the problem to the MTD access (without ubi/ubifs). > We noticed toggle flash-bit(s) after power off during a write cycle. > The toggle flash-bit(s) may occure after power of during an > sector-erase > too. > > Simple testsequence: > * flash_erase ... > * cp testfile /dev/mtd0 > - automatic or manuel power off during the cp > Check the flash after reboot (e.g md5sum /dev/mtd0 helps). > > We used the default settings from the CFI (MaxBufWriteSize=6 > == 64 byte > buffer). I think writing to /dev/mtd0 will also perform an erase if needed, so you are probably seeing the interrupted erase. If you're doing this because you are having UBIFS errors, then you should set the MaxBufWriteSize to 3 to limit the write size to 2^3=8 bytes since this is a known problem. Here's the patch (it's also attached to this email) for the debug code that I added to limit the write buffer size to 2**3=8 bytes and have been using for all of the recent robustness testing. I'm using the S29GL256 chip (256Mbit) which is in the same family as your S29GL01G (1Gbit), so with this patch and the latest patches from http://git.infradead.org/users/dedekind/ubifs-v2.6.27.git should get you to the same place that I'm at. So far, with over 10,000 power cycles, I haven't seen any problems. -Eric #ifdef DEBUG_CFI /* Dump the information therein */ print_cfi_ident(cfi->cfiq); Index: drivers/mtd/chips/cfi_probe.c =================================================================== --- drivers/mtd/chips/cfi_probe.c (revision 4477) +++ drivers/mtd/chips/cfi_probe.c (working copy) @@ -18,7 +18,7 @@ #include #include -//#define DEBUG_CFI +#define DEBUG_CFI #ifdef DEBUG_CFI static void print_cfi_ident(struct cfi_ident *); @@ -251,6 +251,18 @@ cfi->cfiq->InterfaceDesc = le16_to_cpu(cfi->cfiq->InterfaceDesc); cfi->cfiq->MaxBufWriteSize = le16_to_cpu(cfi->cfiq->MaxBufWriteSize); + //DEBUG - BEGIN - force max write size to 8 bytes (2^3) + if (cfi->cfiq->MaxBufWriteSize) + { + printk("Warning: Overriding MaxBufWriteSize from 2^%d to 2^%d\n", + cfi->cfiq->MaxBufWriteSize, + 3 + ); + cfi->cfiq->MaxBufWriteSize = 3; + } + //DEBUG - END + +