X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_mtdif2.c;h=2c4795112621538728f30b387726e38fe03c81dd;hp=5e9e91c8eac44ed4f255088fbeeba5a9ab5e5d89;hb=378bbdf4d64b8b26db55a495ab6ae520ff62e471;hpb=243aa7be93c21c85d5114cae623ad80ac635fa18 diff --git a/yaffs_mtdif2.c b/yaffs_mtdif2.c index 5e9e91c..2c47951 100644 --- a/yaffs_mtdif2.c +++ b/yaffs_mtdif2.c @@ -16,7 +16,7 @@ /* mtd interface for YAFFS2 */ const char *yaffs_mtdif2_c_version = - "$Id: yaffs_mtdif2.c,v 1.10 2005-12-07 22:00:38 charles Exp $"; + "$Id: yaffs_mtdif2.c,v 1.14 2006-10-03 10:13:03 charles Exp $"; #include "yportenv.h" @@ -34,10 +34,14 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, const yaffs_ExtendedTags * tags) { struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#else size_t dummy; +#endif int retval = 0; - loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk; + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; yaffs_PackedTags2 pt; @@ -46,6 +50,23 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" TENDSTR), chunkInNAND, data, tags)); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + if (tags) + yaffs_PackTags2(&pt, tags); + else + BUG(); /* both tags and data should always be present */ + + if (data) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = sizeof(pt); + ops.len = dev->nBytesPerChunk; + ops.ooboffs = 0; + ops.datbuf = (__u8 *)data; + ops.oobbuf = (void *)&pt; + retval = mtd->write_oob(mtd, addr, &ops); + } else + BUG(); /* both tags and data should always be present */ +#else if (tags) { yaffs_PackTags2(&pt, tags); } @@ -53,16 +74,16 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, if (data && tags) { if (dev->useNANDECC) retval = - mtd->write_ecc(mtd, addr, dev->nBytesPerChunk, + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, &dummy, data, (__u8 *) & pt, NULL); else retval = - mtd->write_ecc(mtd, addr, dev->nBytesPerChunk, + mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk, &dummy, data, (__u8 *) & pt, NULL); } else { if (data) retval = - mtd->write(mtd, addr, dev->nBytesPerChunk, &dummy, + mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy, data); if (tags) retval = @@ -70,6 +91,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, (__u8 *) & pt); } +#endif if (retval == 0) return YAFFS_OK; @@ -81,45 +103,66 @@ int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data, yaffs_ExtendedTags * tags) { struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + struct mtd_oob_ops ops; +#endif size_t dummy; int retval = 0; - loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk; + loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk; yaffs_PackedTags2 pt; T(YAFFS_TRACE_MTD, (TSTR - ("nandmtd2_ReadChunkWithTagsToNAND chunk %d data %p tags %p" + ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p" TENDSTR), chunkInNAND, data, tags)); +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) + if (data && !tags) + retval = mtd->read(mtd, addr, dev->nBytesPerChunk, + &dummy, data); + else if (tags) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = sizeof(pt); + ops.len = data ? dev->nBytesPerChunk : sizeof(pt); + ops.ooboffs = 0; + ops.datbuf = data; + ops.oobbuf = dev->spareBuffer; + retval = mtd->read_oob(mtd, addr, &ops); + } +#else if (data && tags) { if (dev->useNANDECC) { retval = - mtd->read_ecc(mtd, addr, dev->nBytesPerChunk, + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, &dummy, data, dev->spareBuffer, NULL); } else { retval = - mtd->read_ecc(mtd, addr, dev->nBytesPerChunk, + mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk, &dummy, data, dev->spareBuffer, NULL); } } else { if (data) retval = - mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy, + mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy, data); if (tags) retval = mtd->read_oob(mtd, addr, mtd->oobsize, &dummy, dev->spareBuffer); } +#endif memcpy(&pt, dev->spareBuffer, sizeof(pt)); if (tags) yaffs_UnpackTags2(tags, &pt); + + if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR) + tags->eccResult = YAFFS_ECC_RESULT_UNFIXED; if (retval == 0) return YAFFS_OK; @@ -137,7 +180,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) retval = mtd->block_markbad(mtd, blockNo * dev->nChunksPerBlock * - dev->nBytesPerChunk); + dev->nDataBytesPerChunk); if (retval == 0) return YAFFS_OK; @@ -157,7 +200,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, retval = mtd->block_isbad(mtd, blockNo * dev->nChunksPerBlock * - dev->nBytesPerChunk); + dev->nDataBytesPerChunk); if (retval) { T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));