X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs2.git;a=blobdiff_plain;f=yaffs_mtdif2.c;h=7985f1ed03be7f268c8486b917a5099dcd9f6555;hp=0dfb942e39100698f5f510d85dadf1c7476931c2;hb=6f1de4473200f31d1ca1cf4672baf7afcdec2db0;hpb=9f361d87ca8c3d331ed1a4ffea53dd9a8d55ee88 diff --git a/yaffs_mtdif2.c b/yaffs_mtdif2.c index 0dfb942..7985f1e 100644 --- a/yaffs_mtdif2.c +++ b/yaffs_mtdif2.c @@ -1,8 +1,7 @@ /* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * yaffs_mtdif.c NAND mtd wrapper functions. + * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. * - * Copyright (C) 2002 Aleph One Ltd. + * Copyright (C) 2002-2007 Aleph One Ltd. * for Toby Churchill Ltd and Brightstar Engineering * * Created by Charles Manning @@ -16,11 +15,10 @@ /* mtd interface for YAFFS2 */ const char *yaffs_mtdif2_c_version = - "$Id: yaffs_mtdif2.c,v 1.7 2005-08-11 01:07:43 marty Exp $"; + "$Id: yaffs_mtdif2.c,v 1.16 2007-02-12 16:55:26 wookey Exp $"; #include "yportenv.h" -#ifdef CONFIG_YAFFS_YAFFS1 #include "yaffs_mtdif2.h" @@ -35,10 +33,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; @@ -47,6 +49,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->nDataBytesPerChunk; + 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); } @@ -54,16 +73,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 = @@ -71,6 +90,7 @@ int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, (__u8 *) & pt); } +#endif if (retval == 0) return YAFFS_OK; @@ -82,45 +102,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->nDataBytesPerChunk, + &dummy, data); + else if (tags) { + ops.mode = MTD_OOB_AUTO; + ops.ooblen = sizeof(pt); + ops.len = data ? dev->nDataBytesPerChunk : 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; @@ -138,7 +179,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; @@ -158,7 +199,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))); @@ -190,4 +231,3 @@ int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, return YAFFS_FAIL; } -#endif