X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_mtdif2.c;h=e6b08e44c5d116fd04293624779a881c183e9c2e;hp=3768b9b079652a979841cecd31c85a87e2e5faa3;hb=fbf2605a5dad8cf93170499d4227064996cce12f;hpb=e8cfe05cf0d057f6978c37943e51b17bb14664e3 diff --git a/yaffs_mtdif2.c b/yaffs_mtdif2.c index 3768b9b..e6b08e4 100644 --- a/yaffs_mtdif2.c +++ b/yaffs_mtdif2.c @@ -14,10 +14,10 @@ /* mtd interface for YAFFS2 */ const char *yaffs_mtdif2_c_version = - "$Id: yaffs_mtdif2.c,v 1.20 2008-05-05 07:58:58 charles Exp $"; + "$Id: yaffs_mtdif2.c,v 1.26 2010-01-11 21:43:18 charles Exp $"; #include "yportenv.h" - +#include "yaffs_trace.h" #include "yaffs_mtdif2.h" @@ -31,12 +31,12 @@ const char *yaffs_mtdif2_c_version = * We assume that the data buffer is of size totalBytersPerChunk so that we can also * use it to load the tags. */ -int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, - const __u8 * data, - const yaffs_ExtendedTags * tags) +int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND, + const __u8 *data, + const yaffs_ExtendedTags *tags) { struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) +#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) struct mtd_oob_ops ops; #else size_t dummy; @@ -47,42 +47,44 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, 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" TENDSTR), chunkInNAND, data, tags)); - + addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk; - + /* For yaffs2 writing there must be both data and tags. * If we're using inband tags, then the tags are stuffed into * the end of the data buffer. */ - if(!data || !tags) - BUG(); - else if(dev->inbandTags){ + if (!data || !tags) + BUG(); + else if (dev->inbandTags) { yaffs_PackedTags2TagsPart *pt2tp; pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk); - yaffs_PackTags2TagsPart(pt2tp,tags); - } - else - yaffs_PackTags2(&pt, tags); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + yaffs_PackTags2TagsPart(pt2tp, tags); + } else + yaffs_PackTags2(&pt, tags, !dev->noTagsECC); + +#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, @@ -96,45 +98,48 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, return YAFFS_FAIL; } -int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, - __u8 * data, yaffs_ExtendedTags * tags) +int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND, + __u8 *data, yaffs_ExtendedTags *tags) { struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -#if (MTD_VERSION_CODE > MTD_VERSION(2,6,17)) +#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17)) struct mtd_oob_ops ops; #endif size_t dummy; int retval = 0; int localData = 0; - loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; + loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk; 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" TENDSTR), chunkInNAND, data, tags)); - - if(dev->inbandTags){ - - if(!data) { + + if (dev->inbandTags) { + + if (!data) { localData = 1; - data = yaffs_GetTempBuffer(dev,__LINE__); + data = yaffs_GetTempBuffer(dev, __LINE__); } - + } -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)) if (dev->inbandTags || (data && !tags)) retval = mtd->read(mtd, addr, dev->totalBytesPerChunk, &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; @@ -159,25 +164,24 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, #endif - if(dev->inbandTags){ - if(tags){ - yaffs_PackedTags2TagsPart * pt2tp; - pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk]; - yaffs_UnpackTags2TagsPart(tags,pt2tp); + if (dev->inbandTags) { + if (tags) { + yaffs_PackedTags2TagsPart *pt2tp; + pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk]; + yaffs_UnpackTags2TagsPart(tags, pt2tp); } - } - else { - if (tags){ - memcpy(&pt, dev->spareBuffer, sizeof(pt)); - yaffs_UnpackTags2(tags, &pt); + } else { + if (tags) { + memcpy(packed_tags_ptr, dev->spareBuffer, packed_tags_size); + yaffs_UnpackTags2(tags, &pt, !dev->noTagsECC); } } - if(localData) - yaffs_ReleaseTempBuffer(dev,data,__LINE__); - - if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) - tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; + if (localData) + yaffs_ReleaseTempBuffer(dev, data, __LINE__); + + if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) + tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; if (retval == 0) return YAFFS_OK; else @@ -194,7 +198,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) retval = mtd->block_markbad(mtd, blockNo * dev->nChunksPerBlock * - dev->nDataBytesPerChunk); + dev->totalBytesPerChunk); if (retval == 0) return YAFFS_OK; @@ -204,7 +208,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) } int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, - yaffs_BlockState * state, int *sequenceNumber) + yaffs_BlockState *state, __u32 *sequenceNumber) { struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); int retval; @@ -214,7 +218,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, retval = mtd->block_isbad(mtd, blockNo * dev->nChunksPerBlock * - dev->nDataBytesPerChunk); + dev->totalBytesPerChunk); if (retval) { T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));