If unsure, say Y.
+config YAFFS_DISABLE_TAGS_ECC
+ bool "Disable YAFFS from doing ECC on tags by default"
+ depends on YAFFS_FS && YAFFS_YAFFS2
+ default n
+ help
+ This defaults Yaffs to using its own ECC calculations on tags instead of
+ just relying on the MTD.
+ This behavior can also be overridden with tags_ecc_on and
+ tags_ecc_off mount options.
+
+ If unsure, say N.
+
config YAFFS_DISABLE_LAZY_LOAD
bool "Disable lazy loading"
depends on YAFFS_YAFFS2
* This is only intended as test code to test persistence etc.
*/
-const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.18 2009-01-16 02:26:56 charles Exp $";
+const char *yaffs_flashif2_c_version = "$Id: yaffs_fileem2k.c,v 1.19 2009-10-14 00:01:57 charles Exp $";
#include "yportenv.h"
else
{
yaffs_PackedTags2 pt;
- yaffs_PackTags2(&pt,tags);
+ yaffs_PackTags2(dev,&pt,tags);
__u8 * ptab = (__u8 *)&pt;
nRead = read(h,localBuffer,sizeof(pt));
else
{
yaffs_PackedTags2 pt;
- yaffs_PackTags2(&pt,tags);
+ yaffs_PackTags2(dev,&pt,tags);
__u8 * ptab = (__u8 *)&pt;
nRead = read(h,localBuffer,sizeof(pt));
{
yaffs_PackedTags2 pt;
nread= read(h,&pt,sizeof(pt));
- yaffs_UnpackTags2(tags,&pt);
+ yaffs_UnpackTags2(dev,tags,&pt);
#ifdef SIMULATE_FAILURES
if((chunkInNAND >> 6) == 100) {
if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){
*/
-const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.4 2008-05-05 07:58:58 charles Exp $";
+const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.5 2009-10-14 00:01:57 charles Exp $";
#ifndef __KERNEL__
#define CONFIG_YAFFS_RAM_ENABLED
{
x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
- yaffs_PackTags2((yaffs_PackedTags2 *)x,tags);
+ yaffs_PackTags2(dev,(yaffs_PackedTags2 *)x,tags);
}
{
x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE];
- yaffs_UnpackTags2(tags,(yaffs_PackedTags2 *)x);
+ yaffs_UnpackTags2(dev,tags,(yaffs_PackedTags2 *)x);
}
return YAFFS_OK;
/* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
/* #define CONFIG_YAFFS_DOES_ECC */
+/* Default: Selected */
+/* Meaning: Yaffs does its own ECC on tags for packed tags rather than use mtd */
+#define CONFIG_YAFFS_DOES_TAGS_ECC
+
/* Default: Not selected */
/* Meaning: ECC byte order is 'wrong'. Only meaningful if */
/* CONFIG_YAFFS_DOES_ECC is set */
*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.83 2009-09-23 23:24:55 charles Exp $";
+ "$Id: yaffs_fs.c,v 1.84 2009-10-14 00:01:56 charles Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/version.h>
int skip_checkpoint_read;
int skip_checkpoint_write;
int no_cache;
+ int tags_ecc_on;
+ int tags_ecc_overridden;
} yaffs_options;
#define MAX_OPT_LEN 20
memset(cur_opt, 0, MAX_OPT_LEN + 1);
p = 0;
+ while(*options_str == ',')
+ options_str++;
+
while (*options_str && *options_str != ',') {
if (p < MAX_OPT_LEN) {
cur_opt[p] = *options_str;
if (!strcmp(cur_opt, "inband-tags"))
options->inband_tags = 1;
- else if (!strcmp(cur_opt, "no-cache"))
+ else if (!strcmp(cur_opt, "tags-ecc-off")){
+ options->tags_ecc_on = 0;
+ options->tags_ecc_overridden=1;
+ } else if (!strcmp(cur_opt, "tags-ecc-on")){
+ options->tags_ecc_on = 1;
+ options->tags_ecc_overridden = 1;
+ } else if (!strcmp(cur_opt, "no-cache"))
options->no_cache = 1;
else if (!strcmp(cur_opt, "no-checkpoint-read"))
options->skip_checkpoint_read = 1;
dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
dev->inbandTags = options.inband_tags;
+#ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
+ dev->noTagsECC = 1;
+#endif
+ if(options.tags_ecc_overridden)
+ dev->noTagsECC = !options.tags_ecc_on;
+
/* ... and the functions. */
if (yaffsVersion == 2) {
dev->writeChunkWithTagsToNAND =
buf +=
sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
+ buf += sprintf(buf, "noTagsECC.......... %d\n", dev->noTagsECC);
buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
int useHeaderFileSize; /* Flag to determine if we should use file sizes from the header */
- int useNANDECC; /* Flag to decide whether or not to use NANDECC */
+ int useNANDECC; /* Flag to decide whether or not to use NANDECC on data (yaffs1) */
+ int noTagsECC; /* Flag to decide whether or not to do ECC on packed tags (yaffs2) */
void *genericDevice; /* Pointer to device context
* On an mtd this holds the mtd pointer.
/* mtd interface for YAFFS2 */
const char *yaffs_mtdif2_c_version =
- "$Id: yaffs_mtdif2.c,v 1.23 2009-03-06 17:20:53 wookey Exp $";
+ "$Id: yaffs_mtdif2.c,v 1.24 2009-10-14 00:01:57 charles Exp $";
#include "yportenv.h"
yaffs_PackedTags2 pt;
+ int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt);
+ void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t : (void *)&pt;
+
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
yaffs_PackTags2TagsPart(pt2tp, tags);
} else
- yaffs_PackTags2(&pt, tags);
+ yaffs_PackTags2(dev, &pt, tags);
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
ops.mode = MTD_OOB_AUTO;
- ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
+ ops.ooblen = (dev->inbandTags) ? 0 : packed_tags_size;
ops.len = dev->totalBytesPerChunk;
ops.ooboffs = 0;
ops.datbuf = (__u8 *)data;
- ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
+ ops.oobbuf = (dev->inbandTags) ? NULL : packed_tags_ptr;
retval = mtd->write_oob(mtd, addr, &ops);
#else
if (!dev->inbandTags) {
retval =
mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
- &dummy, data, (__u8 *) &pt, NULL);
+ &dummy, data, (__u8 *) packed_tags_ptr, NULL);
} else {
retval =
mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
yaffs_PackedTags2 pt;
+ int packed_tags_size = dev->noTagsECC ? sizeof(pt.t) : sizeof(pt);
+ void * packed_tags_ptr = dev->noTagsECC ? (void *) &pt.t: (void *)&pt;
+
T(YAFFS_TRACE_MTD,
(TSTR
("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
&dummy, data);
else if (tags) {
ops.mode = MTD_OOB_AUTO;
- ops.ooblen = sizeof(pt);
- ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt);
+ ops.ooblen = packed_tags_size;
+ ops.len = data ? dev->nDataBytesPerChunk : packed_tags_size;
ops.ooboffs = 0;
ops.datbuf = data;
ops.oobbuf = dev->spareBuffer;
}
} else {
if (tags) {
- memcpy(&pt, dev->spareBuffer, sizeof(pt));
- yaffs_UnpackTags2(tags, &pt);
+ memcpy(packed_tags_ptr, dev->spareBuffer, packed_tags_size);
+ yaffs_UnpackTags2(dev, tags, &pt);
}
}
}
-void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t)
+void yaffs_PackTags2(yaffs_Device *dev, yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t)
{
yaffs_PackTags2TagsPart(&pt->t, t);
-#ifndef YAFFS_IGNORE_TAGS_ECC
- {
+ if(!dev->noTagsECC)
yaffs_ECCCalculateOther((unsigned char *)&pt->t,
sizeof(yaffs_PackedTags2TagsPart),
&pt->ecc);
- }
-#endif
}
}
-void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt)
+void yaffs_UnpackTags2(yaffs_Device *dev, yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt)
{
yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR;
- if (pt->t.sequenceNumber != 0xFFFFFFFF) {
- /* Page is in use */
-#ifndef YAFFS_IGNORE_TAGS_ECC
- {
- yaffs_ECCOther ecc;
- int result;
- yaffs_ECCCalculateOther((unsigned char *)&pt->t,
- sizeof
- (yaffs_PackedTags2TagsPart),
- &ecc);
- result =
- yaffs_ECCCorrectOther((unsigned char *)&pt->t,
- sizeof
- (yaffs_PackedTags2TagsPart),
- &pt->ecc, &ecc);
- switch (result) {
+ if (pt->t.sequenceNumber != 0xFFFFFFFF &&
+ !dev->noTagsECC){
+ /* Chunk is in use and we need to do ECC */
+
+ yaffs_ECCOther ecc;
+ int result;
+ yaffs_ECCCalculateOther((unsigned char *)&pt->t,
+ sizeof(yaffs_PackedTags2TagsPart),
+ &ecc);
+ result = yaffs_ECCCorrectOther((unsigned char *)&pt->t,
+ sizeof(yaffs_PackedTags2TagsPart),
+ &pt->ecc, &ecc);
+ switch (result) {
case 0:
eccResult = YAFFS_ECC_RESULT_NO_ERROR;
break;
break;
default:
eccResult = YAFFS_ECC_RESULT_UNKNOWN;
- }
}
-#endif
}
yaffs_UnpackTags2TagsPart(t, &pt->t);
yaffs_DumpPackedTags2(pt);
yaffs_DumpTags2(t);
-
}
} yaffs_PackedTags2;
/* Full packed tags with ECC, used for oob tags */
-void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t);
-void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt);
+void yaffs_PackTags2(yaffs_Device *dev, yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t);
+void yaffs_UnpackTags2(yaffs_Device *dev, yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt);
/* Only the tags part (no ECC for use with inband tags */
void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ExtendedTags *t);