if the controller does not provide it. AFAIK (unconfirmed, so I could very
checked in. These allow the use of inband tags and store a yaffs_Packedtags2
structure (without ECC on the tags) in the data area. This would give the
circumstances where they cannot at present (eg. devices with no oob, block
>
> fs/yaffs2/yaffs_mtdif2.c | 30 +++++++++++++++++++-----------
> fs/yaffs2/yaffs_packedtags2.c | 22 ++++++++++++----------
> fs/yaffs2/yaffs_packedtags2.h | 4 ++--
> 3 files changed, 33 insertions(+), 23 deletions(-)
>
> Signed-off-by: Vitaly Wool <vitalywool@gmail.com>
>
> diff --git a/fs/yaffs2/yaffs_mtdif2.c b/fs/yaffs2/yaffs_mtdif2.c
> index 5a18725..12b5ce3 100644
> --- a/fs/yaffs2/yaffs_mtdif2.c
> +++ b/fs/yaffs2/yaffs_mtdif2.c
> @@ -38,10 +38,14 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
> size_t dummy;
> #endif
> int retval = 0;
> + /* low on OOB space? write only tags then */
> + int do_ecc = mtd->oobavail < sizeof(yaffs_PackedTags2) ? 0 : 1;
>
> loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
>
> yaffs_PackedTags2 pt;
> + void *oob = do_ecc ? (void *)&pt : (void *)&pt.t;
> + int ooblen = do_ecc ? sizeof(yaffs_PackedTags2) :
> sizeof(yaffs_PackedTags2TagsPart);
>
> T(YAFFS_TRACE_MTD,
> (TSTR
> @@ -50,34 +54,34 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
>
> #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
> if (tags)
> - yaffs_PackTags2(&pt, tags);
> + yaffs_PackTags2(&pt, tags, do_ecc);
> else
> BUG(); /* both tags and data should always be present */
>
> if (data) {
> ops.mode = MTD_OOB_AUTO;
> - ops.ooblen = sizeof(pt);
> + ops.ooblen = ooblen;
> ops.len = dev->nDataBytesPerChunk;
> ops.ooboffs = 0;
> ops.datbuf = (__u8 *)data;
> - ops.oobbuf = (void *)&pt;
> + ops.oobbuf = oob;
> retval = mtd->write_oob(mtd, addr, &ops);
> } else
> BUG(); /* both tags and data should always be present */
> #else
> if (tags) {
> - yaffs_PackTags2(&pt, tags);
> + yaffs_PackTags2(&pt, tags, do_ecc);
> }
>
> if (data && tags) {
> if (dev->useNANDECC)
> retval =
> mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
> - &dummy, data, (__u8 *) & pt, NULL);
> + &dummy, data, oob, NULL);
> else
> retval =
> mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
> - &dummy, data, (__u8 *) & pt, NULL);
> + &dummy, data, oob, NULL);
> } else {
> if (data)
> retval =
> @@ -86,7 +90,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
> if (tags)
> retval =
> mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
> - (__u8 *) & pt);
> + oob);
>
> }
> #endif
> @@ -106,10 +110,14 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
> #endif
> size_t dummy;
> int retval = 0;
> + /* low on OOB space? write only tags then */
> + int do_ecc = mtd->oobavail < sizeof(yaffs_PackedTags2) ? 0 : 1;
>
> loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
>
> yaffs_PackedTags2 pt;
> + void *oob = do_ecc ? (void *)&pt : (void *)&pt.t;
> + int ooblen = do_ecc ? sizeof(yaffs_PackedTags2) :
> sizeof(yaffs_PackedTags2TagsPart);
>
> T(YAFFS_TRACE_MTD,
> (TSTR
> @@ -122,8 +130,8 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
> &dummy, data);
> else if (tags) {
> ops.mode = MTD_OOB_AUTO;
> - ops.ooblen = sizeof(pt);
> - ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt);
> + ops.ooblen = ooblen;
> + ops.len = data ? dev->nDataBytesPerChunk : ooblen;
> ops.ooboffs = 0;
> ops.datbuf = data;
> ops.oobbuf = dev->spareBuffer;
> @@ -154,10 +162,10 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
> }
> #endif
>
> - memcpy(&pt, dev->spareBuffer, sizeof(pt));
> + memcpy(oob, dev->spareBuffer, ooblen);
>
> if (tags)
> - yaffs_UnpackTags2(tags, &pt);
> + yaffs_UnpackTags2(tags, &pt, do_ecc);
>
> if(tags && retval == -EBADMSG && tags->eccResult ==
> YAFFS_ECC_RESULT_NO_ERROR) tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
> diff --git a/fs/yaffs2/yaffs_packedtags2.c b/fs/yaffs2/yaffs_packedtags2.c
> index 6860876..55e5149 100644
> --- a/fs/yaffs2/yaffs_packedtags2.c
> +++ b/fs/yaffs2/yaffs_packedtags2.c
> @@ -57,7 +57,8 @@ static void yaffs_DumpTags2(const yaffs_
>
> }
>
> -void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
> +void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t,
> + int do_ecc)
> {
> pt->t.chunkId = t->chunkId;
> pt->t.sequenceNumber = t->sequenceNumber;
> @@ -93,7 +94,7 @@ void yaffs_PackTags2(yaffs_PackedTags2 *
> yaffs_DumpTags2(t);
>
> #ifndef YAFFS_IGNORE_TAGS_ECC
> - {
> + if (do_ecc) {
> yaffs_ECCCalculateOther((unsigned char *)&pt->t,
> sizeof(yaffs_PackedTags2TagsPart),
> &pt->ecc);
> @@ -101,7 +102,8 @@ void yaffs_PackTags2(yaffs_PackedTags2 *
> #endif
> }
>
> -void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
> +void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt,
> + int do_ecc)
> {
>
> memset(t, 0, sizeof(yaffs_ExtendedTags));
> @@ -110,12 +112,8 @@ void yaffs_UnpackTags2(yaffs_ExtendedTag
>
> if (pt->t.sequenceNumber != 0xFFFFFFFF) {
> /* Page is in use */
> -#ifdef YAFFS_IGNORE_TAGS_ECC
> - {
> - t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
> - }
> -#else
> - {
> +#ifndef YAFFS_IGNORE_TAGS_ECC
> + if (do_ecc) {
> yaffs_ECCOther ecc;
> int result;
> yaffs_ECCCalculateOther((unsigned char *)&pt->t,
> @@ -140,8 +138,12 @@ void yaffs_UnpackTags2(yaffs_ExtendedTag
> default:
> t->eccResult = YAFFS_ECC_RESULT_UNKNOWN;
> }
> - }
> + } else
> #endif
> + {
> + t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
> + }
> +
> t->blockBad = 0;
> t->chunkUsed = 1;
> t->objectId = pt->t.objectId;
> diff --git a/fs/yaffs2/yaffs_packedtags2.h b/fs/yaffs2/yaffs_packedtags2.h
> index 7c4a72c..b2e8d6b 100644
> --- a/fs/yaffs2/yaffs_packedtags2.h
> +++ b/fs/yaffs2/yaffs_packedtags2.h
> @@ -33,6 +33,6 @@ typedef struct {
> yaffs_ECCOther ecc;
> } yaffs_PackedTags2;
>
> -void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags *
> t); -void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 *
> pt); +void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags
> * t, int); +void yaffs_UnpackTags2(yaffs_ExtendedTags * t,
> yaffs_PackedTags2 * pt, int); #endif
>
>
>
>
> _______________________________________________
> yaffs mailing list
> yaffs@lists.aleph1.co.uk
> http://lists.aleph1.co.uk/cgi-bin/mailman/listinfo/yaffs